Agent 不是会调工具就行:规划、状态机和工作流编排怎么落地
Agent 不是会调工具就行:规划、状态机和工作流编排怎么落地
摘要:很多团队做 Agent,第一步刚学会接工具,第二步就开始翻车。问题往往不在工具接少了,而在系统根本没想清楚“这件事该怎么跑”。这就好比你给新员工配了电脑和权限,却不告诉他公司流程。本文承接上篇的评测体系,专门拆解 Agent 内部的执行骨架:什么时候该用“麦当劳后厨”式的固定工作流?什么时候该上“医院看病”式的状态机?什么时候才真的需要放手让 Agent 自己当“包工头”做规划?
预计阅读时间:10 分钟

系列承接:
如果上一篇 Agent 怎么证明自己真的变好了:评测、回放和 A-B 对比 解决的是“怎么证明它变强了”,这一篇解决的就是另一个更致命的工程问题:它在系统里到底该怎么跑,才不会把自己绕晕。
目录
- 会调工具,不等于系统就会干活
- 三把斧头:流水线、办事大厅与包工头
- 第一把斧:固定工作流(麦当劳后厨流水线)
- 第二把斧:状态机(医院看病挂号流程)
- 第三把斧:规划式 Agent(全能包工头)
- 工程落地建议:先把确定性吃满
- 一个最小可跑的状态机代码骨架
- 结语:编排才是 Agent 的真骨架
会调工具,不等于系统就会干活
我见过很多团队第一次做 Agent 的过程,基本都出奇地一致。
第一周,大家兴致勃勃地把搜索 API、公司数据库、发邮件接口全接上了。在终端里跑通的那一刻,看着大模型自己调用搜索查资料,很容易产生一种错觉:“哇,它会自己干活了,这事稳了。”
到了第二周,画风突变,各种诡异的“翻车”接踵而至:
- 同一个客服请求,昨天它先查知识库再回复,今天它竟然先乱编了一通,然后再去查库。
- 走到中间某一步失败了,它不知道重试,直接原地死机,或者干脆给用户返回一串报错代码。
- 明明上一秒系统提示“已进入人工审批”,下一秒大模型突然“戏瘾发作”,自己把单子给批了往下走。
- 明明只是查个天气,模型非要先规划三步走,慢得让人抓狂,token 账单还高得离谱。
这些问题的根源其实就一个:系统缺乏明确的执行地图。
工具只是“手”,编排才是“路”。你给一个人再多工具,如果不告诉他什么情况下走直路、什么情况下进岔路、什么情况下必须停下来等老板签字,他照样会把事情做砸。这也是为什么 Anthropic 在其最新的架构文档中,死磕 workflow(工作流) 和 agent(智能体) 的边界。这绝不是学术上的术语洁癖,而是实打实的工程保命指南。
今天我们不谈玄乎的“涌现”和“自进化”,就聊最接地气的骨架设计:如何管好你的 Agent,别让它乱跑。
三把斧头:流水线、办事大厅与包工头
如果把 Agent 执行任务的“自由度”排个序,业内现在主流的玩法大概分这三档:
- 固定工作流(Workflow):步骤写死,模型只负责在特定节点干苦力。
- 状态机(State Machine):定义好一堆节点和状态,系统根据手里的“状态票”决定下一步去哪。
- 规划式 Agent(Planning Agent):扔个目标过去,模型自己拆解任务、排期、执行。

这三者没有高低贵贱,只有谁更匹配当前的业务。很多失败的业务,最大的错就是把低不确定性的任务,交给了高自由度的架构。明明一条流水线就能搞定的事,非要让模型先开个会、再写个 PPT、最后才决定去按那个按钮。
第一把斧:固定工作流(麦当劳后厨流水线)
如果任务的步骤是死的,千万别犹豫,直接上固定工作流。
比喻一下,这就是麦当劳后厨的炸薯条流水线。 你不需要厨师有创意,只需要他按部就班:拿土豆 → 切条 → 下锅炸 3 分钟 → 捞起撒盐。要是你雇个米其林大厨(大模型)来干这个,还让他自由发挥,他可能今天给你炸个爱心形状,明天心血来潮给你加点黑松露(幻觉),不仅贵,还乱套。
比如做一个“客服工单分类与回复”机器人,最稳的做法是:
- 读取用户请求
- 判断意图分类(大模型介入)
- 查阅内部文档
- 生成初步回复(大模型介入)
- 发送给用户
在这个流程里,大模型只需要在“分类”和“生成”这两个节点打工,其他环节全靠死代码(if-else)焊死。它的最大优势是极度可控、极度好测、成本极低。
def handle_ticket(user_message: str) -> dict:
intent = classify_intent(user_message)
if intent != "password_reset":
return {"route": "fallback"}
docs = search_docs("how to reset password")
reply = draft_reply(user_message=user_message, docs=docs)
return {"route": "send_reply", "reply": reply}
代码很土?土就对了。只要单次串行流程够用,就别整什么高并发多节点。
但当你发现这套流程里分支越来越多、动不动要等人工审批,满屏的 if-else 像个接满插头的劣质插线板时,你就该拔掉它,换第二把斧头了。
第二把斧:状态机(医院看病挂号流程)
一旦任务不再是“一条路走到黑”,状态机(State Machine)就成了救命稻草。
这就像去医院看病。 整个过程不是线性的,而是状态的流转:
- 挂号处(
初始草稿状态) - 医生初诊(
系统机器校验状态) - 去验血(挂起等待,转入
材料缺失状态) - 拿报告回诊(状态恢复,回到机器校验节点)
- 开药走人(
审核已通过状态)
在这套逻辑里,系统关心的不再是“下一步执行什么函数”,而是:当前手里捏着什么状态?满足什么条件才能切换到下一个状态?
最经典的例子就是“报销审批 Agent”。

用流水线做审批是做不下去的。当单子金额过大,触发了 挂起待人工审批 状态时,系统必须优雅地暂停,把当前的数据存下来;等第二天老板点完“同意”,系统还要能优雅地恢复,接着往下跑。
这也是为什么 LangGraph 这类前沿框架,核心全都在搞 state + node + edge(状态 + 节点 + 边)。它把聊天的过程,变成了在不同状态节点中跳跃的图结构。
状态机的魅力在于:不是函数在瞎跑,而是状态在指挥。 只要业务里出现“多分支”、“人工审批(Human-in-the-loop)”、“中断与恢复”、“审计留痕”,闭着眼睛选状态机准没错。
第三把斧:规划式 Agent(全能包工头)
再往上,才是大家平时被各种科幻宣传洗脑的“完全自主 Agent”。
这就像你雇了一个资深包工头。 你只丢给他一句:“帮我把这套毛坯房精装了,预算 20 万。”
至于他是先买水泥还是先买瓷砖,遇到墙里有暗管怎么改方案,全靠他自己定夺。
在代码里,这就是经典的 ReAct(推理与行动)模式:模型先思考(大脑思考),再决定调什么工具(调用工具),拿到结果后观察(观察结果),再决定下一步干嘛。
这种模式极度强大,能解决路径根本无法提前预判的开放性问题。比如让 Agent 去网上调研某个开源库的竞品分析,它可能查到一半发现搜不到,得临时换搜索词,或者转头去爬 GitHub issue。
但代价也是极其惨痛的:
- 成本刺客:随便一跑就是几万 token 进去了。
- 延迟爆炸:用户等得黄花菜都凉了。
- 犹如开盲盒:你永远不知道它下一次运行会不会突然发癫把系统搞崩。
所以,把业务全交给规划式 Agent,就等于把公司命运交给一个随时可能喝醉的包工头。
工程落地建议:先把确定性吃满
这三把斧头看懂了,落地时该怎么选?教你一个极其势利的判断顺序:
- 步骤是死的吗? 如果是,上流水线。把模型关进笼子里,只让它做阅读理解和填空。
- 需要暂停、恢复或人工介入吗? 如果需要,上状态机。用明确的状态管理取代糊涂的对话历史。
- 问题真的无解、只能走一步看一步吗? 只有被逼到这份上,才放手让 Agent 自己去规划。
核心心法就是:先把确定性吃满,再把不确定性留给模型。
真正成熟的工业级 Agent,从来不是单打独斗,而是外围套着稳如老狗的状态机,遇到复杂局部问题时,再召唤一个小型规划式 Agent 解决单点问题。大框架死死管住,小局部保留弹性。
一个最小可跑的状态机代码骨架
抛弃那些花里胡哨的 Prompt 补丁,这里提供一个最纯粹的 Python 状态机骨架。它比流水线坚固,又比规划式 Agent 听话。
from typing import Literal, TypedDict
# 1. 明确定义你拥有的状态
class State(TypedDict):
用户输入: str
意图: str
状态: Literal["已接收", "需人工审核", "可自动处理", "已完成"]
回复: str
# 2. 节点只做一件事:改变状态
def classify(state: State) -> dict:
intent = detect_intent(state["用户输入"])
if intent in {"退款", "账单风险"}:
return {"意图": intent, "状态": "需人工审核"}
return {"意图": intent, "状态": "可自动处理"}
def human_review(state: State) -> dict:
# 模拟暂停等待人工
approved = get_human_decision(state)
if approved:
return {"回复": "已人工确认,继续处理。", "状态": "已完成"}
return {"回复": "未通过审核,任务结束。", "状态": "已完成"}
def auto_handle(state: State) -> dict:
reply = generate_reply(state["用户输入"], state["意图"])
return {"回复": reply, "状态": "已完成"}
# 3. 显式的路由:用状态决定去向,别让大模型瞎猜
def route(state: State) -> str:
if state["状态"] == "需人工审核":
return "人工审核节点"
if state["状态"] == "可自动处理":
return "自动处理节点"
return "结束"
记住两个原则:节点只干一件事,路由逻辑靠代码而不是靠 Prompt。一旦这副骨架搭起来,后续不管你怎么加重试、加人机协同,都只是在骨架上长肉,系统绝对不会垮。
结语:编排才是 Agent 的真骨架
一个能真正在生产环境活下来的 Agent,不是因为它接入了 100 个工具,而是因为它知道什么时候该直走,什么时候该转弯,什么时候该停下来等老板签字。
别再沉迷于让大模型帮你规划一切了。用死板的流程管住确定性,用严谨的状态机管住分支,只把最难啃的骨头扔给大模型的聪明才智。这才是让你的 Agent 项目不烂尾的唯一出路。
更多推荐


所有评论(0)