从 Loop 到 Graph:用 LangGraph 搭建多 Agent 协作骨架,TaoToken 配置你跟上了吗?
发布时间:2026/9/29 21:16:38来源:尧图网络
1. 从 Loop 到 Graph多 Agent 协作到底变了什么如果你最近在折腾 Agent大概率会撞上同一个困惑昨天还在调 Loop 的停止条件今天满屏都在聊 Graph。LangGraph、多 Agent 协作、节点编排这些词堆在一起很容易让人以为又要推倒重来。其实不是。Loop 解决的是「一个 Agent 怎么持续干」Graph 解决的是「多个 Agent 怎么配合干」它们不在一个维度上也不存在谁替代谁。我试过把一个单 Agent 的修 bug 循环硬改成多节点图结果发现任务本身根本不需要并行拆完反而更难排查。所以这篇不聊虚的架构演进史直接落地一件事用 LangGraph 搭一个「需求拆解 → 并行开发 → 汇总审查」的多 Agent 协作骨架并且把模型调用通道统一收敛到 TaoToken让你不用在多个 Key 之间来回切换。适合已经写过单 Agent Loop、想往多 Agent 走一步的开发者也适合团队里要统一模型接入方式的同学。整篇的节奏是先讲清楚 Loop 和 Graph 的边界再给可复制的config.toml和settings.json骨架然后跑一次真实的多 Agent 调用验证最后把常见的报错挨个排掉。代码都能直接抄参数都有说明。2. TaoToken 前置统一 Key 与 API 通道多 Agent 系统最先崩的地方往往不是图逻辑而是模型接入。三个 Agent 各配一套 Key、各写一份 base_url改一个环境就得同步改三处迟早出错。TaoToken 在这里的作用就是把模型调用收敛成一条通道一个 Key、一个 API 地址LangGraph 里所有节点共用同一套客户端配置。你需要先拿到两样东西一个 API Key在控制台的 API Keys 页面创建形如sk-开头的一串字符统一的 API 地址https://taotoken.net/api注意这个地址不带任何查询参数直接作为 base_url 使用。创建 Key 的入口在这里https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite如果你还没决定用哪个模型可以先在模型对话页面试几条 prompt确认模型对代码类任务的响应质量再写进配置https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面列了兼容 OpenAI SDK 的调用方式LangGraph 节点里直接用openai客户端就能接上不需要额外适配层。注意Key 只放在环境变量或本地配置文件里不要提交到 Git。多 Agent 项目尤其容易在节点代码里硬编码 Key一旦仓库公开就是事故。3. 可复制配置config.toml 与 settings.json 骨架配置分两层config.toml管模型通道和运行参数settings.json管图结构和 Agent 角色定义。这样拆的好处是换模型只动 toml改协作流程只动 json互不干扰。3.1 config.toml模型通道与运行参数# config.toml [llm] # 统一走 TaoToken 通道所有 Agent 节点共用 base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY # 从环境变量读取不写死 default_model gpt-4o-mini timeout 60 max_retries 3 [llm.params] temperature 0.2 max_tokens 2048 [graph] # 图运行相关 max_parallel_nodes 3 # 并行开发节点上限 checkpoint_backend memory # 生产可换 sqlite / postgres recursion_limit 25 # 防止图无限循环 [agents] # 每个角色的模型可以单独覆盖不写则用 default_model planner_model gpt-4o-mini coder_model gpt-4o-mini reviewer_model gpt-4o-minirecursion_limit这个参数很关键。Graph 里如果有回退边比如审查不通过打回重写没有上限就会一直转。25 是个保守值复杂流程可以调到 50但别不设。3.2 settings.json图结构与角色定义{ graph_name: multi_agent_dev, entry: planner, nodes: { planner: { type: agent, role: 需求拆解, system_prompt: 你是需求分析师把用户需求拆成可独立开发的子任务列表输出 JSON 数组每项含 id、title、desc。, output_key: subtasks }, coder: { type: agent, role: 并行开发, system_prompt: 你是开发工程师根据分配到的子任务写代码只输出代码块不要解释。, input_key: subtasks, output_key: code_map, parallel: true }, reviewer: { type: agent, role: 汇总审查, system_prompt: 你是代码审查员检查各子任务代码是否满足需求输出 PASS 或 FAIL 加原因。, input_key: code_map, output_key: review_result } }, edges: [ { from: planner, to: coder }, { from: coder, to: reviewer }, { from: reviewer, to: coder, condition: review_result.startswith(FAIL) } ] }edges里最后一条就是条件回退边审查不通过就打回 coder 重写配合recursion_limit兜底。这套结构对应的是「扇出 → 并行 → 扇入」的经典 Graph 形态planner 一个节点拆出多个子任务coder 并行处理reviewer 汇总。3.3 环境变量与依赖安装export TAOTOKEN_API_KEYsk-你的key pip install langgraph openai python-dotenv tomliPython 3.11 以下用tomli读 toml3.11 以上标准库tomllib直接可用。4. 验证请求跑通一次多 Agent 调用配置就位后写一个最小可运行的图。核心是把 config.toml 里的通道读进来构造一个共享的 OpenAI 客户端所有节点复用它。# main.py import os, json, tomllib from openai import OpenAI from langgraph.graph import StateGraph, END from typing import TypedDict, List with open(config.toml, rb) as f: cfg tomllib.load(f) client OpenAI( base_urlcfg[llm][base_url], api_keyos.environ[cfg[llm][api_key_env]], ) def call_llm(system: str, user: str, model: str | None None) - str: resp client.chat.completions.create( modelmodel or cfg[llm][default_model], messages[ {role: system, content: system}, {role: user, content: user}, ], temperaturecfg[llm][params][temperature], max_tokenscfg[llm][params][max_tokens], timeoutcfg[llm][timeout], ) return resp.choices[0].message.content.strip() class DevState(TypedDict): requirement: str subtasks: List[dict] code_map: dict review_result: str def planner_node(state: DevState): raw call_llm( 你是需求分析师把需求拆成子任务输出 JSON 数组每项含 id、title、desc。, state[requirement], ) raw raw.replace(json, ).replace(, ).strip() return {subtasks: json.loads(raw)} def coder_node(state: DevState): code_map {} for task in state[subtasks]: code call_llm( 你是开发工程师根据子任务写代码只输出代码块。, f子任务{task[title]}\n说明{task[desc]}, ) code_map[task[id]] code return {code_map: code_map} def reviewer_node(state: DevState): joined \n\n.join(f# {k}\n{v} for k, v in state[code_map].items()) result call_llm( 你是代码审查员检查代码是否满足需求输出 PASS 或 FAIL 加原因。, joined, ) return {review_result: result} def route_review(state: DevState): return END if state[review_result].startswith(PASS) else coder g StateGraph(DevState) g.add_node(planner, planner_node) g.add_node(coder, coder_node) g.add_node(reviewer, reviewer_node) g.set_entry_point(planner) g.add_edge(planner, coder) g.add_edge(coder, reviewer) g.add_conditional_edges(reviewer, route_review, {coder: coder, END: END}) app g.compile() out app.invoke( {requirement: 写一个用户登录接口包含参数校验和异常处理}, config{recursion_limit: cfg[graph][recursion_limit]}, ) print(out[review_result])跑起来后你会看到 planner 先输出子任务 JSONcoder 逐个生成代码reviewer 给出 PASS 或 FAIL。如果 FAIL图会自动回到 coder 重写直到 PASS 或撞上 recursion_limit。成功的结果长这样PASS - 子任务1 登录参数校验已实现 user_id 非空与长度校验 - 子任务2 异常处理已用 try-except 包裹 - 子任务3 返回结构已统一为 code msg看到这个输出说明多 Agent 协作骨架已经通了而且所有模型调用都走的是同一条 TaoToken 通道。5. 本篇常见错排查5.1 401 Unauthorized最常见的原因是环境变量没生效。export只在当前 shell 有效换个终端就没了。建议写进.env用python-dotenv加载或者确认TAOTOKEN_API_KEY拼写和 config.toml 里的api_key_env完全一致。另一个坑是 Key 前后带了空格或引号复制时容易带上。5.2 base_url 写错导致 404base_url必须是https://taotoken.net/api不要在后面加/v1或/chat/completions。OpenAI SDK 会自己拼路径你多写一段就变成/api/v1/v1/chat/completions直接 404。这个错我踩过排查了半天才发现是地址多了一截。5.3 planner 返回的 JSON 解析失败模型有时会在 JSON 外面包 json 代码块或者加一句「以下是拆解结果」。代码里已经做了replace清洗但如果模型输出格式飘得厉害可以在 system prompt 里加一句「只输出 JSON不要任何其他文字」稳定性会明显提升。5.4 图跑飞了一直循环两个原因一是recursion_limit没设或设太大二是回退边的条件写反了。检查route_review的返回值确认 PASS 时返回 END。另外 reviewer 的 prompt 里如果没明确要求输出 PASS/FAIL模型可能返回「通过」这种中文startswith(PASS)就永远为 False图会一直转。5.5 并行节点没真正并行LangGraph 的并行需要显式用SendAPI 或把节点设计成可并发调度的形式。上面示例里 coder 是单节点内 for 循环属于串行。要真并行得把每个子任务拆成独立节点用Send分发。这是从「能跑」到「跑得快」的下一步但先跑通串行版再优化别一上来就上并行。6. 把通道和骨架固定下来多 Agent 系统真正难的不是画图是让每个节点稳定地拿到模型能力。把 Key 和 base_url 收敛到 TaoToken 一条通道后你换模型、加节点、调角色都不用再动接入层。上面这套 config.toml settings.json LangGraph 的骨架可以直接作为你项目的起点。如果你后面要长期跑编码类 Agent或者把多 Agent 接进 CI 流程可以看下 Coding Plan 的额度方案比按次调用更适合高频场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite接入过程中遇到通道配置问题直接翻接入文档对照参数https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite先把单图跑通再考虑双图架构和并行调度。Graph 不是银弹能 Loop 解决的就别急着上 Graph这句话我在项目里验证过不止一次。
网站建设高端定制企业官网