Agent Graph 详解:用图组织 AI Agent 的工作流
Agent Graph 不是“把几个 Agent 画在一张图上”,而是把一次智能任务明确建模成:状态在节点之间流动,边根据结果决定下一步,直到任务完成或被安全终止。
它解决的核心问题也不是让模型变聪明,而是让原本藏在 Prompt 和循环里的执行逻辑变得可见、可控、可恢复。
本文脉络:
- 一、为什么需要 Agent Graph
- 二、Agent Graph 到底是什么
- 三、四个核心元素:节点、边、状态、运行时
- 四、一个客服 Agent Graph 是怎么运行的
- 五、它与 Agent Loop、DAG、多智能体有什么区别
- 六、Agent Graph 真正带来了什么
- 七、什么时候值得用,什么时候别用
- 八、怎样设计一张靠谱的 Agent Graph
- 九、常见陷阱
- 十、常见问题
一、为什么需要 Agent Graph
最简单的 Agent,通常只有一个循环:模型判断下一步,调用工具,读取结果,再判断下一步。只要任务不复杂,这种写法完全够用。
麻烦出现在流程开始分叉之后。
假设我们要做一个售后客服 Agent,它收到用户消息后可能需要:
- 查询订单;
- 判断是否符合退款规则;
- 缺少信息时追问用户;
- 高风险退款交给人工审核;
- 工具超时时重试;
- 退款完成后发送通知;
- 无法解决时转人工。
如果这些逻辑全塞进一个循环和一段 Prompt,系统很快会变成“模型自己看着办”。正常路径也许能跑,出错时却很难回答三个问题:它现在走到哪了,为什么走到这里,失败后应该从哪恢复?
Agent Graph 就是把这套隐含流程摊开。
模型仍然负责理解和判断,工具仍然负责执行动作;但谁先运行、下一步去哪、哪些状态要保存、什么条件必须停下来,由图结构明确表达。
二、Agent Graph 到底是什么
Agent Graph 可以翻译成“智能体图”或“Agent 图式工作流”。这个名字容易让人误以为图上的每个节点都是一个 Agent,其实并不是。
一个更准确的定义是:
Agent Graph 是一种用有向图描述 Agent 执行过程的编排模型。节点执行计算或动作,边控制流程跳转,共享状态承载任务上下文。
节点可以是一次 LLM 调用,也可以是普通代码、工具调用、规则校验、人工审批,甚至是另一个子图。真正构成图的,不是“用了几个模型”,而是流程是否被拆成了可识别的步骤和跳转关系。
例如,一个研究型 Agent 可以抽象为:
理解问题 → 制定检索计划 → 搜索 → 评估证据 |
这里最重要的是那条返回“搜索”的边。它说明 Agent Graph 往往不是一条流水线,而是允许循环:证据不够就继续搜,引用不可靠就退回重写。
三、四个核心元素:节点、边、状态、运行时
理解 Agent Graph,不需要先记框架 API。先把下面四样东西分清楚。
节点:在这里做一件事
节点接收当前状态,完成一项职责,然后返回更新后的状态。常见节点包括:
| 节点类型 | 例子 | 是否一定调用 LLM |
|---|---|---|
| 推理节点 | 意图识别、计划生成、结果归纳 | 通常是 |
| 工具节点 | 查订单、搜网页、执行代码 | 否 |
| 规则节点 | 金额校验、权限检查、格式验证 | 否 |
| 人工节点 | 审批退款、确认高风险操作 | 否 |
| 子图节点 | 调用一套完整的研究或写作流程 | 不一定 |
我的建议是:一个节点只承担一个容易描述、容易测试的职责。 “调用模型并处理所有事情”虽然也能成为节点,却失去了画图的意义。
边:决定下一步去哪
边连接节点。它既可以是无条件跳转,也可以根据当前状态选择不同分支。
例如退款判断之后:
def route_refund(state): |
这里的条件最好来自明确的结构化字段,而不是反复让模型用自然语言猜。能用规则稳定判断的事情,就别浪费一次 LLM 调用。
状态:整张图共享的任务快照
状态是 Agent Graph 的“工作台”。节点不应该靠不可见的全局变量互相传话,而应读写一份明确的数据结构:
class SupportState(TypedDict): |
状态与聊天记录不是一回事。聊天记录只是状态的一部分;订单数据、审批结果、错误次数和下一步计划也都可能属于状态。
状态设计得越含糊,后面越难调试。不要只放一个不断膨胀的 messages,然后期待每个节点都从自然语言历史里重新猜出事实。
运行时:让图真正跑起来
图只是声明,运行时负责执行。一个成熟的运行时通常还要处理:
- 状态持久化与检查点;
- 节点重试、超时与错误传播;
- 暂停和恢复;
- 并行分支与结果合并;
- 日志、链路追踪和成本统计;
- 人工介入。
这部分很容易被忽略。生产里的 Agent Graph,难点往往不在“画出节点”,而在中途挂掉以后能否安全续跑。
四、一个客服 Agent Graph 是怎么运行的
把前面的售后场景串起来,一次退款请求可能这样走:
classify_intent识别用户要退款,并提取订单号。- 如果订单号缺失,进入
ask_for_order_id,图暂停,等待用户补充。 load_order调用订单系统,查询商品、支付状态和金额。check_policy用确定性规则判断是否满足退款条件。- 不符合规则时,进入
explain_rejection;符合规则则继续。 - 小额退款由
execute_refund直接处理,大额退款进入human_review。 - 审核通过后执行退款,最后由
notify_user生成回复。
如果查询订单超时,流程不必从意图识别重新开始。运行时可以从最近的检查点恢复,只重试 load_order。如果人工第二天才审批,前一天的任务状态也还在。
这正是图式编排的价值:每一个关键状态都有落点,每一种重要结果都有去向。
五、它与 Agent Loop、DAG、多智能体有什么区别
这些概念经常混在一起,其实它们描述的是不同维度。
| 概念 | 核心关注点 | 能否循环 | 典型用法 |
|---|---|---|---|
| Agent Loop | 模型在“思考—行动—观察”中迭代 | 能 | 单 Agent 自主调用工具 |
| DAG 工作流 | 有依赖关系的任务按顺序或并行执行 | 不能形成环 | ETL、批处理、固定流水线 |
| Agent Graph | 状态驱动的节点编排和条件跳转 | 能 | 有分支、重试、人工介入的 Agent |
| 多智能体系统 | 多个角色或自治单元如何协作 | 取决于实现 | 专家协作、监督者—执行者模式 |
Agent Loop 可以放进一个节点,也可以由整张图表达。Agent Graph 可以只有一个 Agent,也可以让多个 Agent 分别占据不同节点。
所以,“用了多 Agent”不等于“用了 Agent Graph”,“画了一个 DAG”也不一定能支持 Agent 所需的循环和恢复。
更实用的判断方式是看控制权:
- 下一步几乎都由模型临场决定,这是偏自主的 Agent Loop;
- 下一步主要由程序预先规定,这是确定性工作流;
- 程序限定可走的路线,模型在局部做判断,这是 Agent Graph 最常见的形态。
最后一种通常更适合生产系统。它没有把控制权全部交给模型,也没有把每一步写死。
六、Agent Graph 真正带来了什么
可控,但不必牺牲灵活性
开发者可以限定 Agent 只能进入经过设计的节点,又允许模型在特定节点做语义判断。退款金额必须由规则校验,用户意图可以交给模型识别,两者不冲突。
可观察
“Agent 失败了”是个几乎没法行动的描述。“失败发生在 check_citation 节点,过去一周通过率从 96% 降到 81%”才是工程问题。
图提供了天然的观测边界:可以统计每个节点的耗时、错误率、Token 成本和分支分布,也能回放某次任务经过的路径。
可恢复
有了持久化状态和检查点,长任务不必因为一次网络超时全部重跑。人工审批、用户补充信息这类可能等待数小时的流程,也能先暂停再恢复。
可测试
可以单独测试一个节点,也可以固定状态,验证路由函数是否走向正确分支。相比“给同一个大 Prompt 输入各种案例”,这种测试更接近普通软件工程。
不过别把图当成可靠性的免费午餐。状态合并、幂等、重试上限、循环退出条件,一个都不会因为画了图自动消失。
七、什么时候值得用,什么时候别用
下面这些信号出现两个以上,就值得考虑 Agent Graph:
- 流程存在多个条件分支;
- 某些步骤失败后需要局部重试或回退;
- 任务会暂停,等待用户或人工审批;
- 多个专家节点需要共享结构化状态;
- 需要审计执行路径,或统计每一步的质量和成本;
- 单次任务持续很久,不能接受从头重跑。
反过来,一个“查一次数据,再让模型总结”的功能没必要上图。三步固定流水线也优先写普通函数。图编排会增加状态模型、持久化、调试和运维成本;节点拆得过细,读代码反而比看流程更累。
一个很朴素的起步标准是:当 while 循环里的 if/else 已经让你不敢改,才该认真考虑把它显式建模成图。
八、怎样设计一张靠谱的 Agent Graph
从状态开始,不要从节点开始
先列出任务必须保存的事实、过程数据和控制字段,再决定谁负责更新它们。状态不清楚,节点只会互相甩自然语言。
状态字段还要区分来源。例如 order_amount 来自订单系统,不能被模型生成的文本覆盖;user_intent 来自模型,应保留置信度或原始依据。
把确定性逻辑留给代码
权限、金额阈值、重试次数、必填字段、合规规则,都适合由代码判断。LLM 擅长理解模糊语义,不擅长充当稳定的规则引擎。
给循环设置硬边界
任何环都应有退出条件:最多检索几轮、最多重试几次、什么情况下转人工。否则“继续思考”很容易变成烧 Token 的无限循环。
让有副作用的节点幂等
发邮件、扣款、退款、创建工单都可能因为重试而执行两次。应使用幂等键、执行记录或业务侧去重,不能只相信图运行时“应该不会重复”。
把人工介入当成正常节点
Human-in-the-loop 不是失败兜底,而是一种正常路径。高风险操作在执行前暂停,展示理由和关键状态,等待批准后从检查点继续。这比事后让人收拾残局便宜得多。
节点输出尽量结构化
路由依赖的字段最好使用枚举、布尔值或受约束的对象,并做运行时校验。不要让下一条边依赖“模型回答里好像提到了同意”。
九、常见陷阱
| 陷阱 | 直接后果 | 改进方式 |
|---|---|---|
| 每个动作都包装成 Agent | 成本高、延迟大、结果不稳定 | 规则和普通代码继续用函数 |
| 所有信息都塞进消息历史 | 状态难查询,事实容易被覆盖 | 单独维护结构化业务状态 |
| 图只有成功路径 | 工具失败后无处可去 | 显式设计超时、重试、降级和转人工 |
| 循环没有次数限制 | 无限调用模型或工具 | 设置预算、轮次和终止条件 |
| 节点有副作用却不幂等 | 恢复或重试时重复执行 | 使用幂等键与执行日志 |
| 图拆得过细 | 节点数量爆炸,理解成本上升 | 按可测试的业务职责划分边界 |
| 把框架 API 当架构 | 换框架后设计全部推倒 | 先定义状态、节点契约和路由语义 |
还有一个常见误区:为了显得“智能”,把所有路由都交给 LLM。实际项目里,最稳的做法往往是混合控制——模型处理模糊判断,代码守住业务边界。
十、常见问题
| 问题 | 回答要点 |
|---|---|
| Agent Graph 是一个具体框架吗? | 不是。它是一种架构和编排方式,可以由不同框架实现,也可以自己实现。 |
| 图上的每个节点都是 Agent 吗? | 不是。节点可以是模型、工具、规则、人工步骤或子图。 |
| Agent Graph 必须是 DAG 吗? | 不必须。Agent 经常需要反思、重试和补充信息,因此有向图通常允许环。 |
| 单 Agent 能用 Agent Graph 吗? | 可以。图描述的是执行流程,不要求有多个 Agent。 |
| 多 Agent 一定需要图吗? | 不一定。简单的主从调用可以直接实现;协作关系复杂时,图会更清楚。 |
| 有了 Graph 就能避免幻觉吗? | 不能。图能约束流程、增加校验节点,但模型输出仍需证据、规则和评测。 |
| 最先应该观测什么? | 每个节点的成功率、延迟、Token 成本、重试次数,以及任务实际走过的路径。 |
| 最适合从哪里开始? | 先把现有流程画出来,只挑一个最痛的分支或恢复问题改造成图,不要一开始做“大一统工作流”。 |
如果你已经理解 Planner、Executor、Memory 和 Tools,可以把 Agent Graph 看成它们外面的一层“交通系统”:它规定状态怎么流动、执行何时转弯、失败从哪里回来。
真正值得追求的也不是一张看起来复杂的图,而是一条出了问题还能解释、还能恢复、还能继续改进的执行路径。