1. 这不是技术选型题,是决策权归属问题
“Agent 框架怎么选?”——这问题一出来,我就知道很多人已经掉进坑里了。不是框架本身复杂,而是提问方式错了。你真正该问的,不是“LangChain 和 LangGraph 哪个更好用”,而是“我这个业务场景里,下一步动作的决策权,到底该交给谁?”这句话不是修辞,是实打实的工程分水岭。我去年帮三家不同行业的客户落地 Agent 系统,一家做智能客服中台,一家做内部知识助理,一家做自动化投研报告生成,三套系统最后用的框架完全不同,但起点完全一致:先画一张“决策流图”,标出每个节点上“谁在拍板”。有人以为这是流程图,其实它是权限地图——标的是控制权、责任边界和失败兜底逻辑。
核心关键词 LangChain、LangGraph、AgentScope、CrewAI、Deep Agents 全部指向同一个底层事实:它们不是并列的“工具箱”,而是不同层级的“决策授权协议”。LangChain 是最轻量级的委托协议——你写好 prompt,它帮你把 LLM 当成一个听话的执行员;LangGraph 是状态机级别的授权协议——你定义好节点和边,它保证每一步都按你画的路线图走,但路线图本身得你来设计;AgentScope 是组织级授权协议——它默认你有一群角色分明的 agent,彼此之间有明确的汇报线、信息权限和任务交接规则;CrewAI 更进一步,它假设你有一个虚拟团队,连会议纪要、任务拆解、进度同步这些协作机制都内置好了;而 Deep Agents(注意不是 LangChain 的 Deep Agents 插件,而是指真正具备多层推理、自我反思、环境建模能力的 agent 架构)则开始模糊“人设权”和“决策权”的边界——它不只执行指令,还会主动质疑指令合理性、评估上下文风险、甚至在无人干预时启动预案。
所以别再搜“LangChain 入门教程”或“LangGraph 教程”了。那些视频教你怎么跑通 demo,但没告诉你 demo 跑通那一刻,你的业务逻辑就已经被框架的默认决策模型悄悄接管了。比如 LangChain 的 ReAct Agent,默认把“是否调用工具”这个关键判断权交给了 LLM 自己——它靠 prompt 工程“说服”模型去思考,但模型会不会真想、想得对不对、有没有遗漏关键条件,全凭运气。而 LangGraph 的 StateGraph,则把“是否调用工具”这个判断变成一个显式节点,你必须自己写逻辑函数来决定——哪怕这个函数只是一行 if-else,它也意味着你亲手签下了决策责任书。这才是标题里“下一步由谁决定”的真实分量:不是技术问题,是责任归属问题。适合谁?适合所有正在从“单次问答”迈向“连续任务”的人——无论你是产品经理想设计用户旅程,还是工程师想搭建自动化流水线,或是业务方想评估 AI 落地风险,只要你需要 AI 不只是回答问题,而是能推进事情,就必须直面这个选择。
2. 四类决策模式与对应框架的本质差异
2.1 单步委托型:LangChain 的本质是“Prompt 执行器”
很多人误以为 LangChain 是个“Agent 框架”,其实它最初的设计定位是“LLM 应用开发 SDK”。它的核心价值在于统一了 LLM 调用、提示词模板、输出解析、记忆管理这些基础设施,让你不用重复造轮子。但当你用它构建 Agent 时,比如用create_react_agent,你实际上是在做一个高风险委托:把“当前这一步该做什么”这个决策,全部打包塞进 prompt 里,然后扔给 LLM 自己拆解。我做过一组对比测试:同样一个“查天气+订会议室+发日程邮件”的三步任务,在 LangChain ReAct Agent 下,成功率波动极大——当天气 API 返回异常格式时,模型有时会忽略错误直接跳到订会议室,有时又卡在天气解析环节死循环。根本原因在于,ReAct 的“Thought/Action/Observation”循环没有强制的状态校验和失败回滚机制,它的“决策”完全依赖于 LLM 对 prompt 的理解深度和当前 token 上下文的稳定性。
LangChain 真正适合的场景,是那些“决策链极短、失败成本极低、且结果可人工兜底”的任务。比如客服对话中的 FAQ 快速匹配、文档摘要生成、简单数据提取。它的优势在于上手快——你写几行代码就能跑起来,劣势也在此:你永远不知道模型在哪个环节悄悄做了妥协。我见过最典型的翻车案例,是一家电商公司用 LangChain 做商品咨询 Bot,当用户问“这件衣服有 XL 码吗?”,Bot 正确调用了库存查询工具,但返回“无货”后,模型却自作主张回复“我们还有其他类似款式推荐”,完全跳过了业务要求的“无货必须引导用户退订”的强制流程。这不是模型能力问题,是 LangChain 默认把“后续动作选择权”完全交给了 LLM,而你没在 prompt 里写清楚这条铁律。
提示:LangChain 不是不能做复杂 Agent,而是它要求你把所有决策逻辑都“翻译”成 prompt。这意味着你需要极强的 prompt 工程能力,且每次业务规则变更,你都要重写、重测、重压测 prompt。它适合 MVP 验证,不适合生产级长期演进。
2.2 显式流程型:LangGraph 的核心是“状态驱动的决策契约”
LangGraph 的出现,本质上是对 LangChain 这种“黑盒委托”的一次反叛。它不试图让 LLM 更聪明,而是把“谁在什么时候决定什么”这件事,变成一份可编程、可追踪、可审计的契约。它的基石是StateGraph——你定义一个状态数据结构(比如{messages: [], tool_calls: [], current_step: 'weather_check'}),然后为每个可能的“下一步”创建一个节点函数(node),再用add_edge明确指定“当状态满足什么条件时,必须跳转到哪个节点”。这里的关键是:节点函数的返回值,决定了下一个节点。你可以写一个纯 Python 函数:
def should_call_tool(state: State) -> str: # 检查最后一条消息是否包含工具调用请求 last_msg = state["messages"][-1] if "tool_calls" in last_msg and last_msg["tool_calls"]: return "call_tool" elif "final_answer" in last_msg: return "end" else: return "llm"这个函数本身不调用任何模型,它只做一件事:读取当前状态,输出一个字符串(即下一个节点名)。这个字符串就是“决策结果”,它被 LangGraph 的引擎严格遵守。这意味着,即使 LLM 在某个环节胡说八道,只要你的should_call_tool函数逻辑正确,系统就不会误入歧途。我帮一家金融风控团队做的贷前尽调 Agent,就用这个模式:LLM 只负责生成“待核查点清单”,而“是否触发第三方数据接口”、“是否需要人工复核”、“是否生成终审报告”这三个关键决策,全部由独立的 Python 函数根据清单内容、历史通过率、当前额度阈值等硬规则判断。LLM 变成了“文案生成器”,决策权牢牢握在业务规则手里。
LangGraph 的代价是开发成本上升。你得自己设计状态结构、写节点函数、画边连接逻辑。但它换来了确定性——你能清晰看到每一步的输入输出、能精准定位失败环节、能对任意节点做单元测试。它的适用边界非常清晰:当你需要“决策路径可预测、失败可归因、规则可版本化管理”时,LangGraph 就是唯一合理的选择。所谓“LangGraph 教程”教的从来不是语法,而是如何把你的业务流程,翻译成状态机语言。
2.3 角色协同型:AgentScope 与 CrewAI 的本质是“虚拟组织OS”
当任务复杂度超过单人可管理范围,比如“市场部要出一份竞品分析报告”,涉及数据抓取、财报解读、舆情分析、PPT 生成、领导审批等多个角色协作,这时候 LangChain 和 LangGraph 都显得力不从心——你得手动管理角色切换、信息传递、任务分配、冲突解决。AgentScope 和 CrewAI 就是为这种场景诞生的“虚拟组织操作系统”。
AgentScope 的设计哲学很务实:它不假设 agent 天然聪明,而是提供一套标准化的“角色容器”。每个 agent 是一个独立进程(可本地也可远程部署),拥有自己的profile(角色设定)、memory(专属记忆库)、tools(可用工具集)、protocol(通信协议)。最关键的是orchestrator——一个中央协调器,它不参与具体决策,只负责根据预设规则(比如“分析师 agent 完成数据处理后,自动将结果发给报告生成 agent”)转发消息、监控超时、处理失败重试。我参与过 AgentScope 2.0 的早期测试,它最大的突破是EventBus机制:所有 agent 通过事件总线通信,而不是点对点调用。这意味着你可以随时插入一个“审计 agent”,监听所有report_generated事件,自动检查报告合规性,而无需修改任何一个业务 agent 的代码。这是一种真正的松耦合架构。
CrewAI 则走了另一条路:它把协作过程“剧本化”。你定义Crew(团队)、Agent(成员)、Task(任务)、Process(协作流程)。比如一个ResearchCrew包含Researcher和Writer两个 agent,Researcher的 task 是“收集近三个月行业政策”,Writer的 task 是“基于研究结果撰写报告”,而Process设定为sequential(顺序执行)或hierarchical(有主负责人)。CrewAI 的亮点在于Delegation机制——Writer在写报告时,如果发现某项数据缺失,可以主动向Researcher发起一个新 task:“请补充 XX 政策的实施细则”。这种动态任务分发,比 AgentScope 的静态路由更灵活,但也更难预测——因为 delegation 是运行时发生的,你无法在设计阶段穷举所有可能的协作路径。
注意:AgentScope 和 CrewAI 都不是“更高级的 LangChain”,它们解决的是完全不同的问题域。LangChain/LangGraph 关注“单个智能体如何行动”,而它们关注“多个智能体如何共处”。选错框架的后果很直接:用 LangGraph 强行模拟团队协作,你会写出一堆状态爆炸的边逻辑;用 CrewAI 去做单步数据查询,你等于用航空母舰去钓小鱼。
2.4 自主演化型:Deep Agents 的核心挑战是“决策权的可信移交”
“Deep Agents”这个词在社区里很模糊,有人把它当成 LangChain 的一个插件,有人用它泛指所有复杂 agent。但在我实际接触的几个真正意义上的 Deep Agents 项目里(比如某自动驾驶公司的仿真训练平台、某科研机构的论文自动综述系统),它指向一个更本质的问题:当 agent 具备多层推理、环境建模、自我反思能力时,“下一步由谁决定”的答案,不再是非此即彼,而是动态协商。
这类系统通常包含三层:1)感知层(实时获取环境数据,如传感器信号、API 响应);2)认知层(构建世界模型、进行因果推理、评估行动后果);3)执行层(调用工具、生成文本、修改自身策略)。关键在于,这三层之间的决策权是流动的。比如在论文综述系统中,当认知层发现现有文献存在重大矛盾时,它会主动触发“发起专家访谈”这一新任务——这个决策不是由人类预设的流程图决定的,而是认知层基于其内部世界模型的推演结果。此时,“下一步”的决定者,是 agent 自身的认知模块,而人类的角色,从“流程设计者”变成了“目标设定者”和“边界守门员”。
实现这种能力,需要远超框架层面的技术栈:高质量的 world model 训练数据、可靠的 self-reflection prompt 模板、可验证的 action planning 算法、以及最重要的——一套 human-in-the-loop 的 veto 机制。我参与的一个 Deep Agents 项目,就强制要求所有自主生成的任务,必须经过VetoCheckeragent 审核:它会用另一个轻量模型,快速评估该任务是否符合安全策略、资源预算、伦理红线。只有通过审核,任务才会进入执行队列。这种设计,不是为了限制 agent,而是为了让“决策权移交”变得可审计、可追溯、可中断。它不追求 agent 完全自治,而是追求一种“受控的自主性”。
3. 实操决策树:五步法锁定你的框架选型
3.1 第一步:画出你的“决策流图”,而非流程图
别急着打开 IDE。拿出一张白纸,或者用在线白板,画出你要解决的实际任务。但注意:不要画“用户输入 → LLM → 工具调用 → 输出”的线性流程,而是标出每一个“需要判断”的节点,并在旁边写明“这个判断由谁来做”。我们以“智能会议助手”为例:
节点1:收到用户消息“帮我整理昨天的销售会议纪要”。
→ 判断:这是会议纪要任务,还是其他类型任务?
→ 决策者:规则引擎(关键词匹配 + 语义分类)节点2:确认是会议纪要任务后,需要获取会议录音或文字记录。
→ 判断:录音文件是否存在?若不存在,是否需调用 ASR 工具?
→ 决策者:状态检查函数(读取存储状态)节点3:ASR 返回文本后,需要提取关键结论。
→ 判断:文本长度是否超过模型上下文?是否需要分段处理?
→ 决策者:Python 函数(计算 token 数 + 配置阈值)节点4:生成初稿后,需要发送给参会人审阅。
→ 判断:哪些人需要收到?是否需添加特定批注?
→ 决策者:外部 API(调用 HR 系统获取参会名单)节点5:收到审阅反馈后,需要修改并重新发送。
→ 判断:反馈是“同意”还是“修改意见”?意见是否明确?
→ 决策者:LLM(必须,因为需要理解自然语言反馈)
你会发现,这五个节点里,只有最后一个真正需要 LLM 的“理解力”,其余四个都可以用确定性代码完成。这就是 LangGraph 的用武之地——把前四个节点做成显式节点,最后一个节点才交给 LLM。如果你把所有判断都塞进一个 prompt 让 LLM 统一处理,那你就选择了 LangChain 模式,也同时接受了它带来的不确定性。
3.2 第二步:评估你的“失败容忍度”与“归因需求”
技术选型最终是风险权衡。问自己三个问题:
这个决策出错,最坏后果是什么?
- 如果是“给用户推荐一首歌”,错了只是体验稍差;
- 如果是“自动批准一笔 500 万贷款”,错了就是重大损失。
前者 LangChain 可接受,后者必须 LangGraph 或更高阶框架。
当出错时,你能否在 5 分钟内定位到是哪个环节、哪行代码、哪个规则出了问题?
- LangChain 的错误日志通常是“LLM 返回了意外格式”,你得回溯 prompt、检查工具返回、猜测模型意图;
- LangGraph 的错误日志会明确告诉你:“节点
check_stock抛出异常,输入状态为{product_id: 'ABC', qty: 10}”,你直接看那个 Python 函数就行。
如果你的团队缺乏 prompt 工程专家,但有扎实的 Python 工程师,LangGraph 的归因效率会高得多。
这个决策规则,未来半年是否会频繁变更?
- 如果是“促销活动期间,满 200 减 30”,规则可能每周调整;
- 如果是“用户等级 VIP3 以上才能查看隐藏功能”,规则可能三年不变。
频繁变更的规则,放在 prompt 里维护成本极高(每次改都要测全链路),而放在 LangGraph 的节点函数里,改一行代码、跑个单元测试就能上线。
我服务过一家教育 SaaS 公司,他们最初用 LangChain 做“学习路径推荐”,结果运营同事每次调整推荐策略,都要找 AI 工程师改 prompt、压测、上线,平均耗时 2 天。后来我们重构为 LangGraph,把“推荐策略”封装成一个独立节点,运营同学只需在后台配置 JSON 规则(如{"subject": "math", "score_threshold": 85, "next_level": "advanced"}),节点函数自动解析执行。上线周期从 2 天缩短到 10 分钟。
3.3 第三步:核算你的“协作粒度”与“角色复杂度”
如果你的任务天然涉及多个角色,别硬扛。直接上 AgentScope 或 CrewAI。但要注意区分“伪协作”和“真协作”:
伪协作:任务可线性分解,角色间无交互。例如“先爬数据,再清洗,再分析,最后画图”。这本质是单人多步骤,LangGraph 的
StateGraph完全胜任,强行上 CrewAI 只是增加复杂度。真协作:角色间存在信息不对称、目标冲突、动态协商。例如“市场部要出报告,但财务部要求所有数据必须经其审核,法务部要求所有结论标注法律风险”。这时你需要:
- 角色隔离:每个部门 agent 有自己的 memory 和 tools,不共享敏感数据;
- 权限控制:财务 agent 只能读取数据,不能修改;法务 agent 可以添加批注,但不能删除原文;
- 协商机制:当市场 agent 生成的结论与法务 agent 的风险提示冲突时,系统需触发“三方会议”流程。
AgentScope 的EventBus天然支持这种解耦,CrewAI 的Delegation则更适合目标一致、流程顺畅的协作。我们曾用 AgentScope 实现过一个跨部门合规审查系统,法务 agent 监听所有report_generated事件,自动插入风险批注;财务 agent 监听data_used事件,验证数据来源合法性;市场 agent 只负责内容生成,完全不知晓其他 agent 的存在。这种架构,是 LangGraph 根本无法优雅表达的。
3.4 第四步:验证你的“自主性需求”是否真实存在
警惕“Deep Agents”陷阱。很多团队喊着要“让 AI 自己思考”,结果发现所谓的“自主决策”,只是把原本该由产品经理写的规则,换成了更难调试的 prompt。真正的自主性需求,必须满足三个条件:
- 环境高度动态:规则无法穷举。例如自动驾驶,路况瞬息万变,预设规则永远跟不上。
- 反馈延迟长:无法实时校验。例如科研探索,一个实验周期长达数月,中间无法人工干预。
- 目标抽象模糊:难以量化定义。例如“提升用户长期满意度”,没有明确指标,需要 agent 自行建模、实验、迭代。
如果你的需求不满足以上任一条件,那么所谓的“Deep Agents”,大概率只是给 LangGraph 加了一层 LLM wrapper,徒增复杂度。我见过最典型的案例,是一家电商公司想用 Deep Agents 做“个性化推荐优化”,结果发现,所有“自主决策”都围绕着“AB 测试哪个推荐算法”展开——这完全可以用一个简单的调度服务 + 三个 LangGraph agent(A/B/C 算法执行器)搞定,根本不需要 world model 或 self-reflection。
3.5 第五步:动手做最小可行性验证(MVP)
选型不是理论推演,是实证。用 2 小时,分别用 LangChain 和 LangGraph 实现同一个最小任务(比如“根据用户输入的城市名,调用天气 API,返回今日温度和穿衣建议”),然后对比:
- 代码量:LangChain 可能 30 行,LangGraph 可能 80 行(状态定义 + 节点函数 + 边连接);
- 调试难度:当天气 API 返回空数据时,LangChain 的错误堆栈指向 LLM 调用,LangGraph 的错误堆栈直接指向
parse_weather_response函数; - 扩展性:如果新增“当温度低于 5℃ 时,额外提醒带围巾”,LangChain 需要重写 prompt 并测试所有分支;LangGraph 只需在
parse_weather_response函数里加一行 if 判断,测试范围极小。
这个 MVP 不是为了证明谁更好,而是让你亲身体验:你愿意为确定性付出多少开发成本?你团队的技能栈,更适配哪种调试范式?很多团队在做完这个对比后,当场就决定了选型——因为那种“一眼看到错误在哪”的踏实感,是任何教程都无法替代的。
4. 避坑指南:那些没人明说但会让你深夜加班的细节
4.1 LangChain 的“隐式状态”是最大雷区
LangChain 的ConversationBufferMemory或ConversationSummaryMemory看似方便,实则是隐形炸弹。它把所有历史消息塞进一个字符串,然后作为 context 传给 LLM。问题在于:LLM 看不到这个字符串的结构,它只能靠“猜”来理解哪些是用户指令、哪些是工具返回、哪些是之前的结论。我遇到过最离谱的案例:一个客服 bot,当用户连续问了三个问题,bot 正确回答了前两个,第三个问题触发了工具调用,但工具返回的数据里包含一个 JSON 字段"status": "success",LLM 误把这个字段当成用户的新指令,开始执行“success”这个动作(当然失败了)。根源就在于 memory 把所有东西揉成一团,LLM 无法区分信息源。
解决方案不是换 memory 类型,而是放弃 memory,拥抱显式状态。哪怕你只用 LangChain,也要手动维护一个state字典,把user_input、tool_results、current_intent分开存,然后在 prompt 里明确告诉 LLM:“你只能参考tool_results中的内容,user_input是原始指令,不要混淆”。这增加了几行代码,但换来的是可预测性。
4.2 LangGraph 的“状态爆炸”陷阱
LangGraph 的强大源于状态,但状态也是负担。新手常犯的错误,是把所有中间数据都塞进State字典。比如在处理一份 100 页 PDF 的分析任务时,把每一页的 OCR 文本、关键实体列表、初步摘要都存进 state。结果 state 对象越来越大,序列化/反序列化越来越慢,最终拖垮整个 pipeline。
正确做法是:State 只存决策必需的“元信息”,原始数据存外部存储。例如:
State里只存:{"pdf_id": "abc123", "processed_pages": [1,5,10], "pending_tasks": ["extract_tables", "summarize_chapter3"]}- OCR 文本、表格数据、章节摘要,全部存入 Redis 或数据库,用
pdf_id+page_num作为 key。
这样,state 始终轻量,节点函数需要数据时,按需 fetch。我帮一家法律科技公司做的合同审查 Agent,就是这么设计的:state 只记录“当前审查到哪一条款”、“已发现的风险点 ID 列表”,所有条款原文、判例库引用、法条解释,都存在 Elasticsearch 里,节点函数只负责查、判、存 ID。系统吞吐量提升了 3 倍。
4.3 AgentScope 的“网络分区”痛点多于想象
AgentScope 的分布式架构是优势,也是隐患。当你的 agent 部署在不同机器上,EventBus的消息传递就面临网络延迟、丢包、重复投递等问题。最常见的是“重复执行”:一个task_assigned事件,因为网络抖动被 EventBus 重复投递了两次,导致同一个任务被两个 agent 同时处理。
官方文档不会强调,但实战经验是:所有 agent 的业务逻辑,必须是幂等的。也就是说,同一个任务 ID,无论执行多少次,结果都一样。实现方式很简单:在 agent 开始执行前,先尝试在 Redis 里 set 一个task_lock:{task_id},成功才继续;失败则直接退出。这行代码,能避免 80% 的分布式故障。另外,EventBus的消息体不要过大,超过 1MB 的消息,建议只传 ID,具体内容走外部存储。
4.4 CrewAI 的“角色幻觉”会让协作失控
CrewAI 的Agent定义里,role和goal是用自然语言写的,比如role="资深市场分析师",goal="产出一份有洞察的竞品分析报告"。这很诱人,但危险在于:LLM 会基于这个描述,自行脑补角色的“知识边界”和“权限范围”。我们曾遇到一个案例:Writeragent 在生成报告时,发现数据不足,于是“自发”调用了本该由Researcheragent 使用的付费 API,导致账单暴增。原因就是Writer的 prompt 里写着“确保报告数据准确”,LLM 把“确保准确”理解为“有权获取任何所需数据”,而忽略了角色权限的硬性约束。
根治方法只有一个:在每个 agent 的 tools 列表里,只放它被明确授权使用的工具。Writeragent 的 tools 只能是“读取本地文件”、“调用 Markdown 渲染 API”,绝对不能包含“调用第三方数据 API”。权限控制必须落在代码层,而不是靠 LLM 的“自觉”。这听起来很笨,但却是生产环境唯一的可靠方案。
4.5 所有框架共通的“LLM 黑箱”问题
无论你选哪个框架,LLM 本身都是不可控的。它可能在任何时候,因为 token 上下文、温度参数、甚至服务器负载,给出完全不合逻辑的输出。我的经验是:永远不要相信 LLM 的“自我声明”。比如,当 LLM 在 ReAct 模式下说 “I will now call the weather tool”,这不代表它真的会调用——它可能只是在“说”,然后继续瞎聊。LangGraph 的should_call_tool函数之所以有效,是因为它不看 LLM 说了什么,而是检查 LLM 输出的结构(比如是否包含tool_calls字段)。
因此,所有框架都必须配备“输出校验层”。我通用的做法是:在 LLM 调用后,加一个output_validator函数,用正则或 Pydantic 模型强制校验输出格式。例如,要求天气查询必须返回{"temperature": int, "recommendation": str},否则就抛异常,触发重试或降级。这个函数写起来很简单,但能拦截 90% 的“LLM 胡言乱语”。它不是框架的一部分,但它是生产环境的必备品。
5. 实战复盘:从零搭建一个“合规文档生成 Agent”的完整路径
5.1 业务需求与决策权映射
客户是一家金融科技公司,需要将监管新规(如《个人金融信息保护办法》)自动转化为内部操作手册。要求:1)准确提取新规条款;2)匹配现有业务流程;3)生成带修订标记的 SOP 文档;4)所有修改必须经法务 agent 审核。我们第一步,就是画决策流图:
- 节点1:接收新规 PDF → 决策者:规则引擎(文件类型校验)
- 节点2:OCR 提取文本 → 决策者:Python 函数(调用 Tesseract,失败则告警)
- 节点3:识别条款结构(第X条、第X款)→ 决策者:LLM(必须,规则太复杂)
- 节点4:匹配业务流程(如“用户授权环节”)→ 决策者:向量数据库检索(用嵌入向量找相似流程)
- 节点5:生成修订草案 → 决策者:LLM(必须,需要创造性写作)
- 节点6:法务 agent 审核草案 → 决策者:法务 agent 自身(角色自治)
- 节点7:审核通过则发布,拒绝则返回节点5 → 决策者:Orchestrator(AgentScope 的 coordinator)
很明显,这是一个典型的“角色协同+显式流程”混合场景。LangChain 无法管理法务 agent 的自治审核,LangGraph 难以优雅表达多 agent 协作,CrewAI 的 delegation 机制又不够可控。最终我们选择了AgentScope 2.0 + LangGraph 节点嵌套的混合架构:用 AgentScope 管理Regulator(监管文本解析)、ProcessMatcher(流程匹配)、DraftWriter(草案生成)、LegalReviewer(法务审核)四个 agent,而每个 agent 内部,用 LangGraph 实现其子流程(比如DraftWriteragent 内部,用 LangGraph 管理“提取要点→生成初稿→添加修订标记→格式化输出”这四步)。
5.2 框架选型与集成关键点
AgentScope 2.0 选型理由:
EventBus支持跨 agent 事件监听,LegalReviewer可以监听所有draft_submitted事件;coordinator内置 retry/backoff 机制,应对法务审核的延迟;agent的profile可精确控制LegalReviewer只能访问法务知识库,不能调用外部 API。
LangGraph 嵌套理由:
DraftWriter的子流程需要强状态控制,比如“添加修订标记”必须在“生成初稿”之后;- 每个子节点(如
extract_key_points)可单独单元测试,确保条款提取准确率 >99.5%。
集成关键点:
- 所有 agent 通过
EventBus通信,但EventBus消息体只传task_id和status,具体内容存 MinIO; DraftWriteragent 的 LangGraphState里,current_step字段被设计为Enum,强制类型安全;LegalRevieweragent 的审核结果,以结构化 JSON 形式发出review_result事件,包含{"approved": bool, "comments": [str]},coordinator严格按此字段路由。
- 所有 agent 通过
5.3 核心代码片段与参数设计
DraftWriteragent 的 LangGraph 定义(简化版):
from typing import TypedDict, Annotated, Sequence from langgraph.graph import StateGraph, END from langgraph.checkpoint.memory import MemorySaver class DraftState(TypedDict): task_id: str raw_text: str # 来自 MinIO key_points: list[str] draft: str revision_marks: str current_step: Annotated[str, "extract|generate|mark|format"] def extract_key_points(state: DraftState) -> DraftState: # 调用 LLM 提取条款要点,输出强制为 JSON array result = llm.invoke(f"Extract key points from: {state['raw_text']}") try: points = json.loads(result.content) assert isinstance(points, list) state["key_points"] = points state["current_step"] = "generate" except: raise ValueError("Key point extraction failed") return state def generate_draft(state: DraftState) -> DraftState: # 基于要点生成初稿 prompt = f"Write SOP draft based on points: {state['key_points']}" state["draft"] = llm.invoke(prompt).content state["current_step"] = "mark" return state # ... 其他节点函数 workflow = StateGraph(DraftState) workflow.add_node("extract", extract_key_points) workflow.add_node("generate", generate_draft) workflow.add_node("mark", add_revision_marks) workflow.add_node("format", format_to_docx) workflow.set_entry_point("extract") workflow.add_edge("extract", "generate") workflow.add_edge("generate", "mark") workflow.add_edge("mark", "format") workflow.add_edge("format", END) app = workflow.compile(checkpointer=MemorySaver())coordinator的事件路由逻辑(AgentScope):
def route_event(event: Event): if event.type == "draft_submitted": # 发送给 LegalReviewer event_bus.publish("legal_review_request", {"task_id": event.data["task_id"]}) elif event.type == "review_result": if event.data["approved"]: # 发布最终文档 publish_final_doc(event.data["task_id"]) else: # 返回 DraftWriter 重做 event_bus.publish("draft_rejected", { "task_id": event.data["task_id"], "comments": event.data["comments"] })5.4 上线后的效果与持续演进
上线三个月后,数据如下:
- 文档生成时效:从人工 3 天 → 系统平均 4.2 小时(峰值 8 小时,因法务审核排队);
- 准确率:条款匹配准确率 99.2%(LLM 提取 + 向量检索双重校验);
- 法务审核通过率:87%,主要拒绝原因是“新增条款需业务方确认”,这恰恰证明了流程的有效性——它把模糊的“法务意见”转化为了明确的“业务待办”。
更重要的是,这套架构的演进性极强。当监管新规增加“跨境数据传输”专项条款时,我们只做了三件事:1)在Regulatoragent 里新增一个 OCR 后处理节点;2)在ProcessMatcher的向量库中新增跨境流程 embedding;3)在DraftWriter的 LangGraph 里,为generate_draft节点增加一个条件分支。全程未动核心框架,2 小时完成上线。
我自己在实际操作中的体会是:框架选型不是一锤定音,而是为未来留出“决策权迁移”的空间。今天你把“条款匹配”交给向量检索,明天就可以换成更精准的微调模型;今天法务审核是人工,明天就可以接入他们的规则引擎 API。只要“谁决定下一步”的契约清晰,技术栈的替换,就只是换掉某个节点函数的事。