选 Agent 框架最容易踩的坑,不是框架本身不够好,而是团队在讨论阶段就讨论错了方向。我见过太多次这种会:有人在白板上画框、画线、写"LangGraph 好,生态全,支持状态图";对面马上接"AutoGen 多角色对话更灵活";然后一群人开始比 GitHub Star、比社区活跃度,争论一两个小时,最后各写各的。每次我都会让讨论停一下,换个问题:你的系统里,下一步要做什么,到底由谁决定?这个问题一旦想清楚,框架选型往往就水落石出。
这篇东西不是框架的完整评测,更不是某个框架的教程。我想分享的是一套从决策权出发的 Agent 框架选型思路,外加我在真实项目里踩过的坑。适合谁看?准备上 Agent 项目的工程师、要拍板技术方案的架构师,以及被"框架太多不知道怎么选"困扰的技术负责人。
1. 选Agent框架先想清楚:下一步由谁决定
1.1 一个案例把问题逼出来
先说一个我实际做过的客服工单系统。需求听起来很简单:收到用户邮件,判断意图,回复,或者转人工。团队有人提议用 Agent 框架,理由是"现在不都这么做吗"。我让他们先别急,把流程拆开:邮件进来以后,先做垃圾邮件过滤,这是一个规则判断,代码写死就行;然后解析发件人信息、提取关键词,这也是确定性的;到了意图识别,问题开始不一样——这条邮件到底是投诉、咨询还是退款,模型说了算;识别完以后,要不要转人工?公司定了条规则:高价值客户或者模型置信度低于 0.6,强制转人工;最后回复内容生成出来,是自动发出去,还是先让人扫一眼,又要看客户等级。
拆完以后,答案已经清楚了:这个系统里,"下一步由谁决定"在每个节点都不一样。有的节点由代码决定,有的由模型决定,有的由人决定。搞清楚这一点,再回头看框架,你会发现大多数框架其实都在回答同一个问题:它默认把决策权交给你、交给模型,还是交给用户。
1.2 决策权分三种,编排模式也要分三种
我在项目里习惯把决策权分成三类,跟代码、模型、人一一对应。
第一类,确定性逻辑说了算。流程是预先定义好的:A 做完做 B,条件满足走 C,不满足走 D。这是传统软件工程最擅长的事,用普通函数、消息队列、工作流引擎都能写。这一类决策的特点是"可预测":同样的输入永远走同样的路径。
第二类,模型说了算。大模型在每一步通过推理决定调哪个工具、拆成几个子任务、要不要继续。这类决策最大的特点是"不可预测":同一个输入,今天可能走三条工具调用,明天可能走五条,甚至可能跑偏。这就是 ReAct 模式的本质——模型根据当前上下文自己决定下一步行动。
第三类,人说了算。系统运行到某个关键节点,停下,等人工审核、批准、补充信息再继续。这不是简单的"人在线兜底",而是业务上的硬性要求:该签字的地方必须签字。
三种决策权对应三种不同的编排模式,这是框架选型的第一层判断维度。你先想清楚自己的系统里哪一类决策占主导,再去看框架,比对着 feature list 选要靠谱得多。
1.3 为什么市面上的框架对比总是不够用
市面上大多数 Agent 框架对比,比的都是 token 消耗、响应速度、调试体验、生态丰富度。这些指标不是没用,但它们是第二层、第三层的问题。第一层问题是:这个框架的编排哲学是什么?它默认的控制流长什么样?
打个比方,选车的时候如果只比百公里加速和内饰,可能选出一辆根本装不下全家行李的车。框架也一样:LangGraph 的控制流是显式有向图,AutoGen 的控制流是动态对话,LlamaIndex Workflows 的控制流是事件驱动,CrewAI 的控制流是预设角色加层级管理。它们对"下一步由谁决定"有自己的默认答案和扩展方式。如果你要的是强控制、审批节点、可审计流程,却选了一个默认开放对话、模型自由决定下一步的框架,后面每个环节都会别扭,而且越到生产越痛苦。
反过来说,如果项目本身就是要探索开放式问题,让它自己发散,你非要用强约束的图编排框架去框死它,那也是互相折磨。搞清楚自己的决策权分布,等于把选型坐标系的 X 轴定下来了。
2. 决策权图谱:三种编排模式与真实混合形态
2.1 代码决策:确定性编排
先聊最不性感但最常见的情况。任务流程是固定的:数据清洗后做字段映射,然后调用一次模型,再根据结果走分支,最后写库。这种流程里没有"模型自己决定要不要调工具"的空间,你也不需要框架给你一个"自主循环"。普通函数加一个 if/else 就完成了,顶多用一个轻量级工作流库把步骤管理起来。
这个阶段我见过最典型的问题,是团队为了"上 Agent 框架"而把简单流程复杂化。几个固定步骤的管道任务,硬要用状态机框架,搞出十几个节点,维护成本暴涨。所以我的建议是:如果整个流程里没有分支会依赖模型自主判断,你根本不需要 Agent 框架——别把架构选型变成 KPI。
2.2 模型决策:自主循环
当任务本身没有固定路径,要靠模型动态规划时,就进入了模型决策区。典型场景是自主编程助手:读需求、改代码、跑单测、看报错、再改代码,这个循环的执行次数不确定,什么时候停下,模型要想,测试结果也在起作用。
这里的核心控制点有三个:循环的跳入条件、循环的跳出条件、每一步调用的工具集合。跳入条件一般由需求触发,跳出条件最理想的是"外部验证通过",比如测试通过、用户确认、任务完成度达到阈值;只有极少数情况才允许模型自行判断"我完成了"。框架在这个区域的价值,是有没有提供机制让你优雅地表达"模型可以决定要不要继续调工具、调什么工具"这件事,同时给你留好终止条件和降级出口。
2.3 人工决策:人在回路
人工决策在业务系统里最常见,但写技术博客的人经常忽略它。内容审核要人工确认,大额交易要人工批准,生成的重要外发文件要人工签字。这种场景对框架的要求很直接:能暂停、能持久化、能恢复。
暂停意味着 Agent 在一个中间状态停住,等待外部输入;持久化意味着进程崩了、服务重启了,状态还在;恢复意味着人给完意见以后,流程能接着往下走,而不是从头重来。这个能力在框架里通常叫 interrupt、suspend 或者 human-in-the-loop。如果框架不支持,你就得靠业务系统自己做状态存储,等于把流程引擎的活外包给数据库表,非常痛苦。
2.4 混合编排:真实系统的常态
用我开头那个客服系统来总结:节点 A 过滤垃圾邮件是代码决策,节点 B 意图识别是模型决策,节点 C 是否转人工是规则决策(但规则里掺着模型输出的置信度),节点 D 是否发送是人工决策。真实系统几乎永远是混杂的,问题只在于不同决策类型占的比例。
这意味着选框架时,不要只看它对单一决策类型支持得多好,要看它对"混合编排"的支持能力:能不能在一个图里既有代码条件分支,又有模型决定的边,还能在关键节点上暂停等人工?这个维度直接决定了框架的容错度和工程化上限。
3. 主流Agent框架的默认答案:谁的编排理念更适合你
3.1 LangGraph:把决策权显式画在图里
LangGraph 是我目前最常用的框架,核心思路是状态图(StateGraph)。你定义节点,节点之间用边连接,边可以是"常规边",走完一个节点必然进下一个;也可以是"条件边",走哪条分支由自定义函数决定,这个函数里可以读模型输出、读业务数据、读规则结果。
所以 LangGraph 对"下一步由谁决定"的答案是:你来定。代码写死的部分由代码定,模型参与的部分由条件边里的逻辑定,人工参与的部分用 interrupt 把图挂起。它不像早期 LangChain 的 AgentExecutor 那样把决策权隐含在一个自动循环里,而是把所有控制权都交回给你。代价是你的心智负担变高:要理解状态如何流转、checkpointer 怎么保存、replay 怎么用,设计不好很容易把图画得又大又乱。
我在生产项目里用 LangGraph 做内容审核流水线,分支逻辑很直观:先模型分类,分类结果进条件边,置信度低于阈值走人工节点,人工节点 interrupt 等审核,审核反馈后走 post 处理。这套落地很顺,因为它的模型和我的决策权分布恰好一致。
3.2 AutoGen:让对话决定下一步
AutoGen 的理念是 conversation-driven。多个 Agent 互相发消息,你来我往,就像一群人开讨论会。谁先说、说什么、谁接话,由对话机制决定;什么时候散会,由终止条件决定(比如某个 Agent 说任务完成,或者达到最大轮次)。这个模式下,"下一步由谁决定"不是预先画好的,而是在对话过程中动态涌现的。
这种模式优势是探索性强,适合研究型任务:让一个 Agent 出方案,另一个 Agent 挑毛病,第三个 Agent 做整合,来回几轮可能产出单模型做不出来的结果。但同样的特性放到生产环境就变成问题:流程比较难预判,每一步不可复现,对话轮次多了以后 token 成本失控,排查问题也要沿着消息记录一条条捋。AutoGen 也提供 GroupChatManager 这类角色来约束对话走向,但整体上它默认把更多决策空间让给了模型。
3.3 CrewAI:角色分工下的流程控制
CrewAI 把 Agent 包装成"角色":每个角色有职责、目标和背景故事,多个角色组成一个 Crew,按顺序或层级方式执行任务。顺序模式下,人把任务列表排好,每个任务指定给某个角色跑,流程是相对确定的;层级模式下,会有一个 Manager Agent 负责拆解任务、分配任务、汇总结果,这部分权力给了模型。
用决策权的语言来说,CrewAI 的默认答案偏"人定流程,模型演角色,manager 在局部做动态分配"。它的抽象非常友好,新人上手快,因为你不需要设计状态图,只要声明角色和任务。但代价是精细控制不如图编排框架:如果你需要"环节 A 的结果大于阈值才允许角色 B 发言,否则直接走人工",表达起来就没有 LangGraph 那么自然。
3.4 LlamaIndex Workflows:用事件信号驱动决策
LlamaIndex 的 Workflows 走的是事件驱动路线。你用装饰器把函数声明成一个 step,step 之间通过 Event 通信:一个 step 处理完,负责 emit 一个事件,框架根据事件路由到下一个 step。每个 step 内部既可以是纯代码,也可以调 LLM,微博的写法很轻量。
这里有个很巧妙的点:事件本身就是"决策结果"。代码决定下一步,就 emit 一个明确的事件名;模型决定下一步,就让它输出一个结构化结果,你把这个结果翻译成事件类型。这种设计比 LangGraph 的图更松散一点,比 AutoGen 的对话更可控一点,很适合 RAG 管线、文档处理这类以数据和内容为中心的任务。不过 event-driven 的隐式路由会带来一个问题:事件类型多了以后,全局的路由关系要自己去梳理,不如一张图直观。
3.5 Semantic Kernel 与工作流引擎:企业级编排的备选
微软的 Semantic Kernel 在企业环境里更受欢迎,它的编排态度偏克制:插件化、模板化,LLM 调用尽量收敛在明确的功能边界里。它不鼓励把核心业务流全交给模型自由编排,而是让开发者在 Kernel 周围组织确定性代码,再用模型做局部决策。如果你的团队有严格的审计、合规和可测试性要求,这种"模型做助手、代码做主人"的思路会少很多麻烦。
还有一类容易被忽略的方案是通用工作流引擎,比如 Temporal、Prefect。它们本来不做 Agent 编排,但长任务执行、超时重试、人工等待审批这些能力做得比 Agent 框架成熟得多。我的实际做法是:核心执行用 Temporal 管状态和重试,Agent 框架只在每个需要智能决策的步骤里被调用。这种"流程引擎兜底、Agent 框架负责智能节点"的组合,在严肃业务里非常稳。
3.6 一张表看懂主流框架的决策模型
| 框架 | 默认决策权 | 编排模型 | 最合适的场景 | 主要短板 |
|---|---|---|---|---|
| LangGraph | 开发者显式控制 | 状态图 + 条件边 + interrupt | 强控制、混合决策、生产流程 | 学习曲线陡,状态设计复杂 |
| AutoGen | 动态对话涌现 | 多 Agent 消息循环 | 研究探索、多角色讨论 | 生产可控性弱,流程难预判 |
| CrewAI | 人定流程 + 角色执行 | 顺序/层级角色协作 | 快速原型、角色化任务 | 精细控制不如图编排 |
| LlamaIndex Workflows | 事件信号驱动 | step + 事件路由 | RAG 管线、文档处理 | 复杂路由难梳理 |
| Semantic Kernel | 代码主导 + LLM 辅助 | 插件化 + 目标调用 | 企业合规、强审计需求 | Agent 灵活性受限 |
| 工作流引擎(Temporal/Prefect) | 流程定义 + 人工信号 | 持久化执行 + 审批 | 长任务、审批、高可靠 | 无原生 LLM 决策抽象 |
这张表不是打分表,而是给你一张"默认答案"清单。你的系统偏哪一列,就去哪一行里找参考。
4. 实操选型清单:几个关键问题锁定框架范围
4.1 先画一张决策路径图
在打开任何框架文档之前,我会先做一件事:把核心业务流程画出来,每个节点写清楚两件事——这个节点做什么,以及做完以后下一步由谁决定。这一步不花半小时,但能救你后面几个月。
画的时候用最简单的记号就行。方框是任务节点,箭头是流转,箭头上的标注写决策主体:CODE 表示代码决定,LLM 表示模型决定,HUMAN 表示人工决定。如果箭头是"LLM 判断 + 规则兜底",就标成 HYBRID 并补一句兜底条件。画完以后数一下:全流程里有几个 LLM 决策点?几个 HUMAN 决策点?决策点之间有没有循环?
我画过的最典型的一个助手项目,最后的路径图是:用户请求进来,意图判断是 LLM 决策,参数提取是 LLM 决策,但"参数合法吗"是代码决策,"是否确认执行"是人工决策,"执行结果是否重试"是代码决策。这个项目最终选了 LangGraph,就是因为图里有两个需要挂起等人工的位置,而它正好有 interrupt 机制,匹配度很高。
4.2 六个问题锁定框架范围
画完路径图,我会让团队回答六个问题。全部答完,框架范围基本就锁定了。
第一个问题:工作流是闭合的还是开放的?闭合意味着路径有限且可枚举,开放意味着模型可能不断开辟新路径。闭合偏 LangGraph、Workflows,开放偏 AutoGen 或自研循环。
第二个问题:流程里会出现"下一步我也拿不准"的节点吗?如果存在这种节点,你必须给模型决策权,但同时要想清楚兜底。框架就得支持动态工具调用和终止条件。
第三个问题:你有没有审计和可观测性要求?有的话,优先看那些状态模型清晰、决策路径可导出的框架。AutoGen 的对话流能审计,但审计起来很累。
第四个问题:人工审批的等待时间多长?如果等一天,框架必须支持持久化状态和重启恢复,光有内存里的 interrupt 是不够的。Temporal 加 LangGraph 的组合在这里会明显胜过纯 Agent 框架。
第五个问题:团队里谁会长期维护?如果团队不熟状态图,却熟 Python 函数,LlamaIndex Workflows 或者 CrewAI 的接受度会高很多。
第六个问题:你愿意为框架写多少胶水代码?所有框架都不会完全匹配你的决策路径,预留 20% 到 30% 的胶水代码是常态,谁的模式贴近你的业务,谁的胶水就少。
4.3 生产环境还要看的三个点
决策模型匹配之后,还要从生产视角过一遍。第一个是 trace。Agent 跑的每一步都应该能拉出来看,包括决策输入、模型输出、工具返回、token 消耗。LangGraph 生态有 LangSmith,自研方案就自己定义 trace 结构,但反正不能没有。
第二个是状态持久化。人审可能等很久,进程重启以后流程要能恢复。LangGraph 有 checkpointer,Temporal 有 durable execution,它们解决了同一个问题:流程不会因为服务抖动而丢。
第三个是成本控制。模型决策的次数直接决定账单。我习惯在框架层面对"模型决策次数"做全局配额,比如单任务最多 15 次 LLM 调用,超出就降级转人工。这个配额不是写完代码再想的,最好在选型阶段就确定它要能通过配置控制。
5. 落地避坑:Agent框架选型后的常见问题
5.1 把决策权全交给 LLM:循环失控与 token 黑洞
我最早期的一个项目,为了让 Agent 显得"智能",让模型在一个循环里反复自测:自己写代码、自己跑、报错就自己改,没有外部验证,也没有迭代上限。看起来很美,实际跑起来就是灾难——模型陷入同一个 bug 改来改去,prompt 越来越长,token 越烧越多,最后把任务当成"完成"了,但交付的东西根本不能看。
后来我加的看门狗有三层:第一层是硬性迭代上限,超过就断;第二层是外部验证器,比如单测必须真实跑过才允许进入下一阶段;第三层是异常降级,发现连续 N 次修改都没改变测试结果,就转人工介入。这些都是为了回答"什么时候停下来"——答案不能只靠模型自觉,业务逻辑必须接管兜底。
5.2 为流程而流程:过度编排的真实现场
另一个反面是过度编排。我见过团队接手一个只有三个固定步骤的翻译任务,SSR 要求上 LangGraph 建图,画了十几个节点,包括错误恢复、回退、多级缓存,写了一个多月。上线之后的复杂度和故障率远超普通函数版本,最后整个模块被删掉重写。
判断是不是过度编排,我有个土办法:数决策点。如果你的真实流程里只有一个 LLM 决策点,其余全是顺序执行,用函数加 if/else 就够了。图编排、状态机、对话框架解决的是"决策点密集且互相影响"的问题,不是所有任务都需要。
5.3 可观测性:给每个决策点建立日志档案
LLM 的问题和普通代码不一样:同一个 bug,代码是稳定复现的,LLM 可能是概率性出现,而且上一次复现时的输入输出已经不可见了。所以所有关键决策点必须留日志,而且要留结构化日志。
我在项目里用的决策日志结构大致长这样:
{ "node_id": "intent_classification", "decision_maker": "llm", "model": "gpt-4o", "prompt_version": "v3", "input_snapshot": "用户消息摘要", "output": "COMPLAINT", "logprobs": 0.82, "token_usage": 1250, "next_action": "route_to_human_review", "timestamp": "2025-06-01T10:30:00Z" }这样每一条决策都有据可查。排查一个事故的时候,你把决策日志按时间轴拉出来,很快就知道是哪个节点的模型判断出了问题,还是规则分支设计错了,而不是面对着一堆非结构化的聊天记录猜。
5.4 换框架的姿势:把流程资产和执行引擎解耦
框架一定会迭代,团队也会换框架,这不是失败,是常态。想让自己不被动,核心思路是把"流程定义"和"执行引擎"分开。流程定义是你业务决策路径的语义化描述,最好独立成配置或 DSL;执行引擎管状态、调度、工具调用。分开以后,换框架等于换一台发动机,车身和内饰还是你的。
我在两个项目里验证过这个思路。一个项目从 AutoGen 迁到 LangGraph,流程定义文件几乎没改,只重写了引擎适配层,一周完成切换。还有一个项目更极端,生产环境直接把脚本引擎和 Agent 引擎并存,通过配置决定某个任务走哪条路,灰度切流量,零停服。能做到这样,靠的就是当初没有把决策逻辑焊死在某个框架的 API 里。
我自己选型的原则已经越来越简单:先数一遍系统里的决策点,看每个决策点由谁决定,再去找对这类决策节点支持得最顺手的框架。框架是执行器,决策模型才是灵魂。先想清楚"下一步由谁决定",后面每一步都会省很多力气。