1. 从一次 subagent streaming 联调失败说起
LangChain v1.0 的 Deep Agent 把「主 Agent 调度 + 多个 subagent 并行干活」这套模式做成了开箱即用的能力,而 frontend 模块则负责把这套并行过程实时渲染到 Web 页面上。你如果正在做 Python 后端 + React 前端的 Deep Agent 项目,大概率会遇到一个很具体的问题:agent 端能跑通,前端也能启动,但 subagent streaming 的事件流就是接不上,页面一直转圈或者只显示主 Agent 的回复,看不到 researcher、analyzer、writer 这些子代理的并行输出。
这个问题的根子通常不在 React 代码,而在配置层。Deep Agent 的 frontend 示例默认把模型调用指向某一家厂商的 API,base_url、api_key、model 三处写死在 agent 端代码里;同时 langgraph.json 的 env 指向、.env 的存放位置、前端 useStream 的连接地址,任何一处对不上,streaming 就会静默失败。我试过把这三层配置拆开逐个核对,最后统一收敛到一套 Key/API 通道上,联调才稳定下来。
这篇就按「配置骨架 → 可复制文件 → 验证请求 → 排障」的顺序,把 LangChain v1.0 Deep Agent frontend 模块接入 TaoToken 统一通道的完整链路走一遍。适合已经跑过 Deep Agent 基础示例、准备把 subagent streaming 接到真实前端页面的 Python 开发者。核心检索词先摆出来:LangChain Deep Agent、frontend、subagent streaming、settings.json、config.toml、TaoToken 统一 Key。
2. TaoToken 前置:统一 Key 与 API 通道
在动手改配置之前,先把 TaoToken 这一层说清楚。TaoToken 提供的是统一的模型调用通道,你拿到一个 Key 之后,agent 端不需要为每个模型厂商单独维护 base_url 和鉴权逻辑,Deep Agent 里的 ChatOpenAI 只要把 base_url 指向 TaoToken 的 API 地址、api_key 填统一 Key,model 字段换成对应模型名即可。官网入口在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api 。
对 Deep Agent 的 frontend 场景来说,统一通道的价值在于:subagent streaming 会同时产生多条并行事件流,如果每个 subagent 走不同厂商、不同 Key,前端 useStream 拿到的 thread 状态会非常难对齐。统一到一个通道后,主 Agent 和所有 subagent 共用同一套鉴权与路由,streaming 事件的来源一致,前端解析逻辑就能保持简单。
你需要提前准备两样东西:一个 TaoToken API Key,以及确认你要用的模型名。Key 在控制台的 API Keys 页面创建,地址是 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。创建后先别急着写进代码,下面会用 settings.json 和 config.toml 两个骨架文件把它管起来,避免硬编码。
注意:Key 只放在本地 .env 或配置文件里,不要提交到 Git。Deep Agent 示例项目里 .env 通常已被 .gitignore 覆盖,确认一下再操作。
3. 可复制配置:settings.json 与 config.toml 骨架
Deep Agent frontend 示例的项目结构一般是 packages/agent 和 packages/frontend 两个子包。agent 端负责 LangGraph 服务,frontend 端是 React + useStream。我们要改的配置分三处:agent 端的模型初始化、langgraph.json 的 env 指向、以及前端 useStream 的连接参数。为了让这些参数不散落在代码里,用 settings.json 管前端连接、config.toml 管 agent 端模型与运行参数。
3.1 config.toml:agent 端模型与通道骨架
在 packages/agent 目录下新建 config.toml,把模型通道参数集中在这里:
# packages/agent/config.toml [model] provider = "openai-compatible" base_url = "https://taotoken.net/api" model = "deepseek-chat" temperature = 0.7 [agent] name = "deep-agent-subagent-cards" max_subagents = 3 stream_mode = "messages" [env] python_utf8 = true这里 base_url 指向 TaoToken 的 API 地址,model 按你实际要用的模型名填。stream_mode 设为 messages,对应 subagent streaming 的事件粒度。python_utf8 这一项是给 Windows 环境准备的,后面排障会讲到它解决什么报错。
3.2 settings.json:frontend 端连接骨架
在 packages/frontend 目录下新建 settings.json,管前端与 LangGraph 服务的连接:
{ "langgraph": { "apiUrl": "http://localhost:2024", "assistantId": "agent", "streamMode": "messages" }, "ui": { "showSubagentCards": true, "parallelColumns": 3 } }apiUrl 是 langgraph dev 默认监听的地址,assistantId 要和 agent 端 create_deep_agent 注册的名字一致。showSubagentCards 打开后,前端会把每个 subagent 的输出渲染成独立卡片,这正是 frontend 模块 subagent streaming 的展示形态。
3.3 agent 端代码改造:读取 config.toml
把原来硬编码的 ChatOpenAI 初始化改成读 config.toml:
import os import tomllib from pathlib import Path from langchain_openai import ChatOpenAI from deepagents import create_deep_agent CONFIG_PATH = Path(__file__).parent / "config.toml" with open(CONFIG_PATH, "rb") as f: cfg = tomllib.load(f) model = ChatOpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url=cfg["model"]["base_url"], model=cfg["model"]["model"], temperature=cfg["model"]["temperature"], ) agent = create_deep_agent( model=model, system_prompt=SYSTEM_PROMPT, subagents=[...], )api_key 从环境变量 TAOTOKEN_API_KEY 读,不写进 config.toml。这样 agent 端和所有 subagent 都走同一条 TaoToken 通道,streaming 事件来源统一。
3.4 .env 与 langgraph.json 的指向关系
langgraph.json 里的 env 字段指向的是当前目录,所以 .env 必须和 langgraph.json 放在同一个文件夹。在 packages/agent 下确认:
{ "dependencies": ["."], "graphs": { "agent": "./agent.py:agent" }, "env": ".env" }.env 内容:
TAOTOKEN_API_KEY=你的统一Key PYTHONUTF8=1PYTHONUTF8 直接写进 .env,比每次手动 set 更省事,Windows 下尤其明显。
4. 验证请求:从 langgraph dev 到前端联调
配置写完,按顺序启动两端,然后发一个会触发并行 subagent 的请求来验证 streaming。
4.1 启动 agent 端
cd packages/agent pip install -r requirements.txt langgraph dev看到服务监听在 2024 端口、graph 注册成功即可。如果报编码相关错误,检查 .env 里的 PYTHONUTF8=1 是否生效。
4.2 启动 frontend 端
cd packages/frontend npm install npm run dev前端默认起在 5173 端口,打开页面后 useStream 会按 settings.json 里的 apiUrl 去连 LangGraph 服务。
4.3 发一个触发并行 subagent 的请求
在输入框里提一个需要多角度覆盖的问题,比如「对比三种向量数据库的优缺点」。主 Agent 会先输出一句说明,然后在同一轮里发起 2 到 3 个 task() 调用,researcher、analyzer、writer 并行开工。前端页面上应该同时出现多张 subagent 卡片,每张卡片的内容随 streaming 逐步填充,最后主 Agent 汇总输出。
验证成功的标志有三个:主 Agent 的说明句先出现;多张 subagent 卡片同时进入 loading 状态;卡片内容逐字流式更新而不是一次性刷出。如果只看到主 Agent 回复、没有卡片,说明 subagent streaming 没接上,进下一节排查。
4.4 用 curl 单独验证通道
前端联调之前,可以先确认 TaoToken 通道本身通不通:
curl https://taotoken.net/api/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-chat", "messages": [{"role": "user", "content": "ping"}], "stream": true }'能收到流式 chunk 就说明 Key 和 base_url 没问题,问题只可能出在 Deep Agent 或前端配置层。
5. 本篇常见错排查
5.1 subagent 卡片不出现,只有主 Agent 回复
先查 settings.json 的 streamMode 是否和 agent 端 config.toml 的 stream_mode 一致,两边都应为 messages。再查 assistantId 是否和 langgraph.json 里 graphs 的 key 一致,不一致时 useStream 连得上服务但拿不到 subagent 事件。
5.2 langgraph dev 启动报编码错误
Windows 下典型表现是读取含中文的 system_prompt 或配置文件时抛 UnicodeDecodeError。解决办法就是在 .env 里加 PYTHONUTF8=1,或者启动前执行 set PYTHONUTF8=1。写进 .env 更稳,因为 langgraph dev 会自动加载它。
5.3 .env 找不到或 Key 读不到
langgraph.json 的 env 指向当前目录,.env 必须和它同级。如果你把 .env 放在项目根目录而 langgraph.json 在 packages/agent 下,就会读不到。统一放到 packages/agent 下即可。
5.4 前端连不上 LangGraph 服务
检查 settings.json 的 apiUrl 端口是否和 langgraph dev 实际监听端口一致,默认 2024。如果 agent 端换了端口,前端这里要同步改。另外确认浏览器控制台没有 CORS 报错,langgraph dev 默认允许本地来源。
5.5 subagent 串行执行而非并行
这通常不是配置问题,而是 system_prompt 里没有明确要求「在同一轮里发起多个 task() 调用」。Deep Agent 的并行依赖模型在同一轮 tool-calling 里返回多个 task 调用,prompt 里要写清楚「spawn exactly 2–3 subagents using multiple task() calls in that single turn」。如果模型仍串行,检查 temperature 是否过低导致输出过于保守。
6. 把配置收敛成一套通道之后
走到这里,agent 端读 config.toml、前端读 settings.json、Key 走环境变量、模型通道统一指向 TaoToken,整条 subagent streaming 链路就固定下来了。后续你要换模型,只改 config.toml 里的 model 字段;要调前端展示,只改 settings.json;Key 轮换只动 .env。三层配置各管各的,联调时出问题也能快速定位是哪一层。
如果你还在验证阶段,想先确认某个模型在 TaoToken 通道上的实际表现,可以直接用模型对话页面发几条请求对比:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 。如果准备把 Deep Agent 长期用在编码或 Agent 类项目上,Coding Plan 更适合持续调用:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。接入过程中遇到鉴权或 base_url 相关问题,接入文档里有完整的参数说明:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。Key 管理和新建在控制台:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。