W
AI-Wiki
CONCEPT

复杂 Agent 图式编排

定义

复杂 Agent 图式编排,是指把 Agent 在真实业务中的执行流程、业务状态、分支路由、人工审批、失败恢复等机制,从“模型在对话循环里临场决定”改造成“开发者预先定义的可执行图结构”的工程化方法。

它的核心目标不是继续依赖模型自由发挥,而是把真实业务里本来就存在的步骤、条件、边界和例外,写成结构化程序。换句话说,复杂 Agent 不再主要依靠一个黑盒式 Agent Loop 反复思考“下一步做什么”,而是把路先画出来,只让模型在需要模型判断的局部节点里做决策。

在本文语境中,这种方法以 LangGraph 为代表,可以概括为:把 Agent 从“黑盒循环”拆成“可控状态机”。文中给出的直观分工是:业务工程由 Java 或 Spring Boot 一侧承载,模型组件可由 LangChain 一类框架组织,而复杂 Agent 的流程编排由 LangGraph 负责。

为什么会成为复杂 Agent 的演化方向

普通 Agent Loop 的基本模式是:模型判断下一步、模型决定调用哪个工具、工具结果再塞回模型,再由模型继续判断。这个模式适合 Demo,也适合标准化、短链路的工具调用;但一旦进入真实业务,问题会迅速暴露。

普通 Agent Loop 的典型局限

  1. 流程不可控:模型可能多查、漏查、乱跳。
  2. 状态不清楚:上一步结果散落在 messages 里,订单号、用户 ID、风险级别、审批结果、召回文档、工具返回值等业务字段难以治理。
  3. 失败难恢复:任务跑到一半崩掉后,很难从中间继续。
  4. 人工介入困难:审批、驳回、要求修改、确认后继续执行,都不是单靠一个 Prompt 能优雅表达的。

因此,复杂 Agent 走向图式编排,本质上不是为了“更花哨”,而是为了“更可控”。真实业务不是聊天,它天然具有流程、状态、分支、审批和恢复要求;这些东西如果继续藏在 Prompt 或 messages 里,系统复杂度一上来就很难维护。

图式编排的核心构成

文中把 LangGraph 一句话概括为:State + Node + Edge + Runtime。这四部分也可以视为复杂 Agent 图式编排的基本骨架。

State:状态

State 表示任务当前的结构化状态。它不是泛泛的聊天上下文,而是业务真正关心、需要跨步骤保存和更新的数据。 例如在复杂业务里,应该进入 State 的往往包括:订单号、用户 ID、风险级别、审批结果、召回文档、工具返回值等。文中强调:消息是上下文,State 才是业务状态。

Node:节点

Node 表示每一步具体要做的事。节点可以是 LLM 调用、RAG 检索、工具调用、数据库查询,也可以是人工审批或普通 Python 逻辑。 节点的关键约束是:读入 State,返回 Partial State。 也就是说,节点不必也不应返回整份状态,而只返回自己改动的那部分。

Edge:边

Edge 负责定义下一步往哪里走。 它可以是固定跳转,例如 A 执行完就去 B;也可以是条件跳转,例如 A 执行完后,根据当前状态决定去 B、C,还是结束。

图式编排的关键价值之一,就在于把这些“下一步怎么走”的逻辑,从 Prompt 内部抽出来,变成真正可审查、可校验的程序结构。

Runtime:运行时

Runtime 负责把整张图运行起来,并提供实际工程能力,例如流式执行、持久化、中断与恢复。 因此,图式编排不只是“画流程图”,而是让该流程能在系统里可靠执行。

关键工程原则

复杂 Agent 图式编排强调的,不只是把节点和连线堆出来,而是一组工程原则。

1. 流程显式

业务系统不接受“模型觉得应该这么做”。 企业侧需要明确知道:当前处于哪一步、下一步是什么、失败后怎么办、什么情况下需要人工接管。图式编排要求把这些流程显式写出来。

2. 状态结构化

复杂任务不能只靠 messages 堆上下文。 业务字段应该进入结构化 State,被明确命名、更新和合并。这样才能稳定支持分支、恢复、审计和后续分析。

3. 节点职责单一

文中的智能客服示例特别强调:一个节点只做一件事。 意图识别节点只负责分类;RAG 节点只负责查资料;工具节点只负责调用业务接口;人工节点只负责审批;质检节点只负责拦截风险答案。

这意味着图式编排不是把一个“大而全”的万能 Agent 放进图里,而是把复杂业务拆成多个边界清晰的功能块。这样做的好处是可控、可测试,也更容易排查问题。

4. 状态增量更新

节点不返回整份 State,只返回自己改动的部分,再由 reducer 合并。 这一点在复杂流程里非常关键,因为并行节点、多个结果汇聚、列表追加、消息合并等情况很常见;如果每个节点都覆盖整份状态,状态冲突会非常频繁。

5. 错误可定位

复杂 Agent 出错时,必须能定位问题到底发生在哪一步。 是路由错、检索错、工具参数错,还是模型生成错?图结构把步骤拆开后,错误才有可能被准确归因,而不是只看到“最后答案不对”。

LangGraph 中的典型落地方式

在文中的具体语境里,StateGraph 是 builder,而不是运行器。它负责收集和组织图的结构;真正能执行的是 compile() 之后得到的 CompiledStateGraph

StateGraph 负责什么

StateGraph 初始化时会准备若干核心容器,包括:

  • nodes:存放节点
  • edges:存放固定边
  • branches:存放条件分支
  • channels:存放状态通道

同时,它会解析 State schema,提前确定哪些字段可以更新、怎么合并。

节点如何注册

通过 add_node 把节点注册进图。 节点本质可以是函数或 Runnable。框架不关心节点内部到底是 LLM、数据库、搜索、人工审批还是普通 Python 逻辑;它关心的是这个节点是否遵守“输入 State,输出 Partial State”的约定。

路线如何注册

通过 add_edge 注册固定路线,通过 add_conditional_edges 注册条件路线。 固定路线对应“这一步后一定去下一步”;条件路线对应“根据状态判断下一步去哪里,甚至是否结束”。

这一步非常关键,因为它等于把原本写在 Prompt 里的业务流程,真正提升为程序结构。

compile() 做什么

compile() 会做结构校验,例如:

  • 是否存在孤立节点
  • 入口与出口是否合理
  • 分支目标是否存在

校验通过后,builder 才会变成可执行的 CompiledStateGraph。在这之后,才具有 invokestreamainvoke 等执行能力。

运行机制与恢复能力

图式编排的运行不是一条“死链”,而更像消息传递:节点被激活,读取当前状态,执行自身逻辑,写回状态更新,再沿着边把控制权交给下一个节点。

失败恢复

真实系统一定会遇到超时、报错、中断。 文中指出,LangGraph 可以通过 checkpointer 保存线程状态。这样任务跑到一半失败后,下次可以从 checkpoint 继续,而不是整条链路从头重跑。

这也是复杂 Agent 与简单 Agent Loop 的重大分界:后者往往只能重新开始,前者则可以具备“长流程、可续跑”的业务能力。

人工介入

在退款、转账、删除数据、修改合同、下单交易等高风险业务中,不能让模型直接执行最终动作。 文中提到,LangGraph 可以通过 interrupt 暂停图执行,等待人工审批,再决定继续、驳回或修改后重试。

这使人工审批不再是对话外的临时补丁,而成为流程图中的正式节点。

可观测与排障

复杂 Agent 出问题时,企业并不满足于“模型答错了”这种笼统结论。