你写好了 Agent 的逻辑,但只能在终端里跑、只能自己用?本教程教你用 Gradio 给 Agent 套一个网页聊天界面——不用写一行前端代码,10 分钟就能生成一个可在浏览器里对话、还能分享给同事的界面。无论你的 Agent 背后是 OpenAI、DeepSeek 还是本地模型,只要它能被 Python 函数调用,都能接上。
🖥️ 本教程适合:已经能用 Python 调通一个大模型(哪怕只会在终端打印回答),想让 Agent 有个能用的界面、或想快速给别人演示的同学。你需要 Python 3.10+ 和一个大模型 API Key。
Step 1:准备环境
1 装好 Gradio 和模型 SDK
# 建议先建个虚拟环境(可选但推荐)
python -m venv .venv
# Windows 激活: .venv\Scripts\activate
# macOS/Linux 激活: source .venv/bin/activate
pip install --upgrade gradio openai
💡 Gradio 是专门给 AI/ML 做演示界面的库,几行代码就能出聊天框。openai 这个 SDK 我们用来调大模型(DeepSeek、通义、本地 Ollama 也都兼容 OpenAI 接口)。
Step 2:写一个最简单的聊天函数
2 函数签名固定为 (message, history)
Gradio 的 ChatInterface 要求你的函数接收两个参数:用户最新消息 message 和对话历史 history(OpenAI 格式字典列表),返回一个字符串。
import os
from openai import OpenAI
# 以 DeepSeek 为例(OpenAI 兼容)。换成 GPT/通义只需改 base_url 和 model
client = OpenAI(
api_key=os.environ["OPENAI_API_KEY"], # 建议用环境变量,别硬编码
base_url="https://api.deepseek.com",
)
def chat(message, history):
# 把历史拼成 OpenAI 消息格式
messages = [{"role": "system", "content": "你是一个 helpful 的中文助手。"}]
for turn in history:
messages.append({"role": "user", "content": turn["content"]})
messages.append({"role": "assistant", "content": turn["content"]})
messages.append({"role": "user", "content": message})
resp = client.chat.completions.create(
model="deepseek-chat", # 具体模型名以官方文档为准
messages=messages,
stream=False,
)
return resp.choices[0].message.content
# 先单独测试一下
if __name__ == "__main__":
print(chat("用一句话介绍你自己", []))
密钥安全:API Key 像家门钥匙,别写死在代码里、别发到群里或提交到 GitHub。用 export OPENAI_API_KEY=sk-xxx(Linux/Mac)或系统环境变量设置,代码里只读取。模型名(如 deepseek-chat)会随官方更新变化,以官方文档为准。
Step 3:套上聊天界面
3 三行代码出界面
import gradio as gr
demo = gr.ChatInterface(
fn=chat, # 上一步写好的函数
type="messages", # 务必用 messages 格式,旧 tuples 已弃用
title="我的第一个 Agent",
description="基于 DeepSeek 的智能助手",
)
demo.launch() # 默认打开 http://127.0.0.1:7860
🚀 运行
python app.py,浏览器自动打开 7860 端口就能对话了。type="messages" 一定要带,否则会遇到已弃用的历史格式,导致多轮对话错乱。Step 4:让回答「流式」蹦出来
4 用 yield 实现打字机效果
把函数改成生成器:边收 token 边 yield,体验更顺滑。注意此时要开 stream=True。
def chat_stream(message, history):
messages = [{"role": "system", "content": "你是一个 helpful 的中文助手。"}]
for turn in history:
messages.append({"role": "user", "content": turn["content"]})
messages.append({"role": "assistant", "content": turn["content"]})
messages.append({"role": "user", "content": message})
stream = client.chat.completions.create(
model="deepseek-chat", messages=messages, stream=True,
)
answer = ""
for chunk in stream:
delta = chunk.choices[0].delta.content or ""
answer += delta
yield answer # 每收到一点就吐出当前完整片段
demo = gr.ChatInterface(fn=chat_stream, type="messages")
demo.launch()
💡 流式时 Gradio 会自动把「提交」按钮变成「停止」,用户可以随时打断。这对长回答特别友好。
Step 5:进阶——加系统提示词、分享、上线
5 让界面更像产品
想给不同场景固定不同人设?用 additional_inputs 让用户填系统提示词;想给别人用?用 share=True 生成临时公网链接,或部署到 Hugging Face Spaces 长期托管。
import gradio as gr
def chat_with_sys(message, history, system_prompt):
messages = [{"role": "system", "content": system_prompt}]
for turn in history:
messages.append({"role": "user", "content": turn["content"]})
messages.append({"role": "assistant", "content": turn["content"]})
messages.append({"role": "user", "content": message})
resp = client.chat.completions.create(model="deepseek-chat", messages=messages)
return resp.choices[0].message.content
demo = gr.ChatInterface(
fn=chat_with_sys,
type="messages",
additional_inputs=[gr.Textbox("你是一个严谨的客服助手。", label="系统提示词")],
)
# 本地运行
demo.launch()
# 想临时分享:demo.launch(share=True) # 生成 *.gradio.live 公网临时链接
# 想长期托管:把 app.py 推到 Hugging Face Spaces(选 Gradio SDK),免服务器
分享链接要谨慎:share=True 会生成一个任何人都能访问的公网地址,且链接有时效、后端在你本机跑。切勿用它在公网处理含隐私/密钥的对话。正式对外请用 Hugging Face Spaces 或自有服务器 + 鉴权。
常见问题速查
| 现象 | 大概率原因 & 解决 |
|---|---|
| 界面打不开 / 端口被占 | 7860 被占用:demo.launch(server_port=7861) 换端口 |
| 多轮对话串台 | 忘了 type="messages",或 history 没正确拼进 messages |
| 回答报错 API key | 环境变量没设 / 模型名写错 / 账户没额度 |
| 想接本地模型 | 把 base_url 改成 Ollama 的 http://localhost:11434/v1,model 填模型名 |