在 VPS 上用 LangGraph 跑通多 Agent 协作:从 503 错误到完整调度闭环

之前一直在 VPS 上折腾 OpenClaw 和 n8n,这次想验证一个更底层的问题:用 LangGraph 自己搭一个“主 Agent 调度子 Agent”的架构,到底能不能跑通。整个过程踩了几个坑,记录一下。

目标

用 LangGraph 搭一个最小多 Agent 系统:

  • 一个主 Agent(Supervisor)负责理解任务、决定调哪个子 Agent
  • 两个子 Agent 分别负责“诊断”和“写报告”
  • 主 Agent 拿到子 Agent 的结果后,汇总输出
  • 模型用 VPS 上已有的 One API 网关,不额外配 GPU。

第一个坑:One API 报“无可用渠道”

第一版脚本跑起来直接 503:

当前分组 default 下对于模型 deepseek-v4.1-flash 无可用渠道

去 One API 后台查了半天,渠道是启用的、分组也包含 default。最后对比 OpenClaw 的日志才发现:OpenClaw 用的模型名是 deepseek-ai/deepseek-v4.1-flash(带 deepseek-ai/ 前缀),而我脚本里写的是 deepseek-v4.1-flash(不带前缀)。One API 按精确名字匹配,少一个前缀就找不到渠道。

教训:One API 的模型名必须和渠道里注册的名字完全一致,拼写、大小写、前缀都不能错。

第二个坑:模型响应太慢,测试超时

改对模型名后,请求能通了,但单次响应要 75-150 秒。原来的脚本用 invoke 模式,黑盒等结果,4 分钟超时被杀。
改成 stream 模式后能看到每一步:

🔧 agent: ['call_diagnose']
💬 tools: 1+1等于2。
⚠️ 超时或失败,退出码 124

主 Agent 成功调了第一个子 Agent,子 Agent 也返回了结果,但第二次调用还没来得及发生就超时了。

教训:

  • 测试多 Agent 链路,任务要极简(比如“1+1 等于几”),不要用真实运维任务
  • 用 stream 而不是 invoke,否则看不到中间过程,超时了也不知道卡在哪
  • 模型选择很重要,deepseek-v4.1-flash 虽然带 “flash”,实际响应很慢

第三个坑:子 Agent 换快模型后,仍然要选对模型

想给子 Agent 换快模型,先试了 gpt-oss:20b,结果:

当前分组上游负载已饱和,请稍后再试

429,上游限流。又试了 meta/llama-3.2-11b-vision-instruct,这次正常返回,而且响应里带了 tool_calls: [] 字段,说明支持 tool calling。

最终方案:双模型混用

  • 主 Agent 用 deepseek-ai/deepseek-v4.1-flash:负责理解任务、决策、汇总,需要强推理
  • 子 Agent 用 meta/llama-3.2-11b-vision-instruct:负责执行具体子任务,需要快

跑通后的完整输出

任务: 让诊断专家回答 1+1 等于几,然后让报告专家把答案写成一句话报告。
=== 执行过程 ===
  🔧 agent: ['call_diagnose']
  💬 tools: 答案是:1+1 等于 2。
  🔧 agent: ['call_report']
  💬 tools: 报告:根据诊断专家的专业判断,1+1 的结果确实是 2。
  💬 agent: 已完成两步:
1. **诊断专家**:1+1 等于 2。
2. **报告专家**(一句话报告):根据诊断专家的专业判断,1+1 的结果确实是 2。
=== 完成 ===

验证通过的机制:

  • 主 Agent 理解任务 ✅
  • 主 Agent 按顺序调两个 tool ✅
  • 子 Agent 被调用并返回结果 ✅
  • 子 Agent 结果回传主 Agent ✅
  • 主 Agent 汇总输出 ✅
  • 双模型混用(强模型调度 + 快模型执行)✅

一个需要注意的弃用警告

跑的时候 LangGraph 提示:

LangGraphDeprecatedSinceV10: create_react_agent has been moved to `langchain.agents`.
Please update your import to `from langchain.agents import create_agent`.

create_react_agent 在 LangGraph V1.0 被标记弃用,V2.0 会移除。下次迭代要改成 from langchain.agents import create_agent,否则升级后会报错。

代码结构

核心就三段:

# 子 Agent(快模型)
diagnose_agent = create_react_agent(sub_model, tools=[], prompt="你是诊断专家...")
report_agent = create_react_agent(sub_model, tools=[], prompt="你是报告专家...")

# 把子 Agent 包装成 tool
@tool
def call_diagnose(task: str) -> str:
    r = diagnose_agent.invoke({"messages": [{"role": "user", "content": task}]})
    return r["messages"][-1].content

# 主 Agent(强模型),通过调 tool 来“派活”
supervisor = create_react_agent(
    supervisor_model,
    tools=[call_diagnose, call_report],
    prompt="你是主管。必须依次调用 call_diagnose 和 call_report,不要自己回答。",
)

下一步

这次验证的是“链路能通”。下一步要做的是:

  • 把子 Agent 从“只说一句话”换成真实工具(诊断 Agent 能跑 ps、free、journalctl)
  • 加 tracing(LangSmith 或自建日志),看每次调用的 token 和耗时
  • 加 token 预算,防止某个子 Agent 烧太多
  • 把整个服务用 systemd 管起来,和 OpenClaw 并存但不抢内存

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注