三省六部:一种多Agent协作框架的顶层设计与实践 1. 为什么是“三省六部”协作框架的顶层设计思路1.1 多Agent协作的几个老难题做AI Agent的人应该都有类似的经历单个Agent跑一个简单任务挺顺利一旦让两三个Agent配合干一件稍微复杂的事问题就开始冒出来。最常见的几个坑我列一下第一个是职责混乱。比如让一个Agent负责“写方案”另一个Agent负责“修改方案”如果没有明确边界两个Agent都觉得自己应该做最后决定结果来回覆盖对方的输出产生大量无效调用。第二个是死锁与循环。A等B给结果B等C给结果C又等A给结果三个Agent互相依赖最后全部卡死。这种情况在上古时期的框架里特别常见本质是缺少一个集中式的任务调度节点。第三个是上下文漂移。多个Agent共享同一个历史记录时低层Agent看到的上下文可能已经被高层Agent删改过导致它基于错误信息做决策。更麻烦的是中间一个Agent的幻觉输出会顺着上下文传递给后面的所有Agent错误被层层放大。第四个是资源竞争和并发控制。当多个Agent同时请求同一个工具比如同时调搜索API或读写同一个数据库如果没有限流和排队机制轻则API报错重则脏数据写进系统。我拆解下来发现这些问题背后的核心矛盾其实是同一个缺少一套明确的分工、制衡和流程控制机制。谁该做什么、谁有权审批、任务怎么流转、出错了找谁这些在代码层面没有约束光靠提示词约束Agent行为效果非常不稳定。于是我试着把古代“三省六部”的权力制衡与流程分权思路搬进来搞了一个协作框架的原型效果意外地好。1.2 三省六部给了什么启发“三省六部”是古代中央行政体制的一套成熟结构核心逻辑值得任何分布式系统借鉴。三省的分工很有意思中书省负责“决策”也就是起草方案门下省负责“审核”也就是审核驳斥尚书省负责“执行”也就是落地实施。三道工序彼此独立互相制衡谁也不能一手遮天。映射到AI Agent协作里就是决策Agent、审核Agent、执行Agent三权分立。决策Agent只负责给出计划和目标不直接碰工具审核Agent只负责检查计划的合法性、资源可行性不直接执行执行Agent只负责调用工具和API不修改整体计划。六部的分职更典型吏、户、礼、兵、刑、工六个部门各管一摊彼此之间没有模糊地带。放在Agent协作框架里我们可以把Agent按“职能域”拆分有的Agent专门管用户交互有的管数据存取有的管权限校验有的管任务分派有的管异常处理有的管审计日志。这样任何一个Agent的职责都可以用一句话说清楚不会被大模型发挥成另一个职能。我当初选这套隐喻还有一个现实原因它自带一套叙事语言。跟同事、社区里的人解释一个多Agent框架时说“中书省负责生成OKR门下省负责卡合规性尚书省照着干”所有人都能秒懂。古代官制的Tag本身也容易让人记住比“Coordinator / Validator / Executor”这类命名印象深得多。1.3 框架的总体定位与设计目标基于这个灵感我把这个框架命名为“三省六部Agent协作框架”简称为SSLB。它的定位不是替换LangChain或LangGraph这类底层编排工具而是一个站在它们上面的组织治理层。就像公司里有了OA系统不等于有了组织制度LangGraph解决了Agent之间怎么连边但没解决谁有最终拍板权、任务卡住了该怎么升级、两个Agent抢同一个资源时听谁的。SSLB要补充解决的正是这些“组织制度”问题。我给自己定了几个硬性设计目标模型无关底层接GPT、还是国产模型、还是开源模型对上层框架透明。工具无关既能调LangChain的工具也能直接裸调API不锁定厂商。并发友好支持多任务并行、请求排队、限流退避满足“怎么扛并发”这个高频需求。可观测像古代给皇帝汇报实况一样任何一次Agent行为都能追踪到三省六部的具体环节。有了这套目标接下来就能进入架构设计。下面我从整体角色划分开始把骨架搭起来。2. 框架整体架构五类角色与三条主线2.1 三省决策、审核、执行三权分立在我的设计里三省不是三个独立运行的Agent进程而是三个只有唯一实例的协调者节点。为什么必须唯一因为多Agent协作的每一步决策都需要有唯一权威来源如果同时存在两个“中书省”就会出现命令打架。中书省的任务是接收一个用户目标拆解成一张计划任务表。这个任务表不是简单的“把任务发给谁”而是一个结构化的JSON包含任务ID、父任务ID、目标描述、所需能力标签、预期的输入输出Schema、优先级、时间约束。在拆解时我会明确要求模型“只能产出计划不能执行任何外部调用”从机制上阻断决策Agent偷偷调用工具。门下省的任务是审核这个计划任务表。它做五件事检查任务之间有没有循环依赖检查每个任务所需的能力是否在已注册Agent列表里检查输入输出Schema是否匹配检查资源配额是否超出预算比如本窗口最大token数限制检查是否遵守合规红线比如不许伪造用户身份。审核通过则返回“准奏”信号并附审核批次号不通过则返回具体修改意见让中书省改写计划。尚书省是最忙的一个节点相当于执行阶段的调度中心。它拿到审核通过的计划后负责把每个任务分发给对应的“六部”Agent管理并发数量收集结果汇总中间状态。尚书省本身不调用具体业务工具只做调度和路由。这有点像Kubernetes里的控制面节点把所有复杂的执行细节下沉到工作节点。三个省之间的调用链是严格单向的用户请求 → 中书省 → 门下省 → 尚书省 → 六部Agent。不允许六部Agent直接找中书省改计划也不允许门下省直接执行任务。这条单向约束大大减少了恶意循环和重复调用。2.2 六部六个职能域划分六部是我对业务Agent的归类方式。每个“部”不是一个单独运行的Agent而是一个能力域。具体映射关系如下吏部对应“人员与权限管理”负责Agent实例注册、身份校验、API密钥管理、角色权限判断。任何一个外部调用先过吏部这一关确认“这个人有没有权限让系统执行这个动作”。户部对应“数据与资源管理”负责数据库读写、KV存储、内存状态管理。所有Agent需要读写数据时都必须通过户部暴露的接口不允许直接在Prompt里塞全套数据库内容。礼部对应“交互与格式规范”负责校验输入输出格式、内容风格、消息礼仪。比如微信客服场景里礼部会检查回复是否包含敏感词是否符合“不允许自称为客服人员”之类的约束。兵部对应“任务与并发调度”负责队列管理、并行分支、重试机制。负责干“怎么扛并发”的活相当于整个框架的交通警察。刑部对应“异常与容错”负责捕获失败、链路追踪、降级策略。任何Agent抛出异常最终都汇总到刑部由刑部判断是“重试一次”还是“终止整个任务”还是“换一条备选路径”。工部对应“工具与API集成”负责连接外部系统搜索引擎、内部代码仓库、企业微信机器人、支付接口等。工部Agent是最典型的“干脏活累活”的Agent它只负责把工具动作执行好不参与决策。2.3 三省六部之间的通信与上下文传递多Agent协作最容易翻车的环节就是上下文传递。我的策略是绝对不直接传原始Prompt链。三省六部之间传递的是一份标准格式的“奏折文书”对象包含以下字段{ task_id: UUID, trace_id: 全局唯一追踪ID, source: 中书省, target: 门下省, action: 审核计划, payload: { plan: [ ... ], resources_estimate: { max_tokens: 4000, api_calls: 12 } }, snapshot_version: 3, deadline_ts: 1710000000 }所有Agent读取上下文时只读取与自身职责相关的字段。比如吏部Agent只需要看身份字段工部Agent只需要看工具调用参数户部Agent只需要看数据操作的DSL语句。至于别人产生的那一大段“思考过程”一律不传给执行层。这样能极大避免上下文漂移也让每个Agent的输入token量小很多。2.4 核心设计如何划分Agent粒度在实施过程中我发现一个很重要的原则不要为了多Agent而多Agent。如果你一个Prompt能完成的事就不要拆成两个Agent。Agent划分的唯一依据是“职责边界能否清晰描述、是否存在利益冲突、是否需要独立的资源并发生命周期”。举个例子一个任务“根据销售数据生成周报”如果只涉及读一个表、生成一段文字一个普通Agent就能搞定拆成三省反而是灾难。但如果任务是“从多数据源拉数据 → 清洗分析 → 生成图表 → 配文案 → 发布到公众号”这里面每一步的技术栈差异很大且可能出现分析结果不合法、图片生成失败等情况那么拆成执行层的多个Agent就很有价值。我建议的粒度标准是中等偏粗。也就是说宁可让一个Agent多干几件同类型的事也不要切成几十个细粒度Agent。因为Agent数量一多通信开销呈指数级增长出错的概率也大幅上升。六部这个数量级是我觉得比较舒服的上限。3. 关键机制与实操要点并发、负载均衡、容错3.1 如何让Agent扛住高并发聊到AI Agent很多人会问“AI Agent怎么扛并发”。其实核心思路和传统后端没有本质区别关键是把Agent调用当成普通服务来治理。我的框架里并发的控制点在兵部。所有六部Agent的调用都要走兵部的“令牌桶”限流器。每个Agent实例在注册时上报自己的支持速率和最大并发数。比如“搜索Agent”支持每秒2次请求那么兵部给它的令牌桶速率就是2。当一个用户任务拆出10个子任务需要搜索时不可能同时发出10个请求而是由兵部排队每0.5秒放行一个。另外一个重要手段是异步任务分片。如果一个大任务包含很多独立的小任务比如给100个客户发送个性化通知我不建议一次性让所有Agent并行执行而是把任务拆成固定大小比如每次10个的分片用队列慢慢喂给六部。这个策略看起来保守其实整体吞吐量反而高——因为大模型代理API如果一下子来100个并发请求很快就触发限流退避重试会吃掉大量时间。3.2 状态管理与上下文隔离我现在实现的方式是“三级状态”全局全局状态存在户部的Redis里键是trace_id值是当前任务的汇总进度局部状态存在执行Agent的本地内存里只包含该Agent负责的子任务上下文消息快照存在消息队列里每一条流转记录都是只读的。举个例子中书省写了一份计划把计划内容存为“全局状态”的plan字段。执行Agent根本不拿到全文只拿到分派给自己的那部分。当用户问“现在进展到哪一步”时我会让礼部Agent去查全局状态里的进度字段汇总成一句人话回复。关键原则是每个Agent只持有完成自己工作所必需的最小上下文。这样token开销能下降40%左右而且幻觉传播也被切断了。3.3 审核制衡机制防止Agent互相踢皮球引入门下省之后一个直接的好处是计划质量变高但刚开始也遇到了“踢皮球”的问题中书省写出来的计划门下省老驳回中书省改完门下省再驳回来回五六次最后任务超时。后来我加了两条规则。第一条是驳回意见必须具体门下省不允许只回复“计划不完整”必须指出“第3个子任务缺少输出Schema”。第二条是升级裁决机制当同一个任务被驳回超过3次自动转给一个“裁决Agent”由它强行选择一个最合理的版本进入执行阶段。这个裁决Agent其实是六部之外的备选专门用来打破死锁。这套机制看起来很简单但在没有它的时候两个大模型Agent互相说服能吵到天荒地老。有了“三次驳回强制裁决”之后系统行为稳定了很多。3.4 工具选型基于Rust还是PythonFastAPILangGraph实践我在选型时纠结过一段时间。看到不少人在搜“基于rust语言ai agent”Rust确实在并发和性能上有天然优势但是生态上还是Python更成熟。对我这个项目来说核心瓶颈不在计算而在API延迟所以用Python完全够用。我最后采用了FastAPI LangGraph的组合。LangGraph负责底层的状态图和条件跳转三省就是三个特殊的Node六部Agent则是可以动态注册的ToolExecutor。FastAPI负责对外提供HTTP接口把用户请求变成异步任务。这种选型的好处是开发效率高而且LangGraph本身支持checkpoints可以在进程崩溃后恢复。如果你对Rust情有独钟我建议在边缘服务上使用Rust比如工部的某个高并发网关核心编排层还是用Python。没必要为了炫技把整个框架都用Rust重写AI Agent项目里更重要的是快速迭代。# 伪代码示例三省节点的FastAPI接口 app.post(/api/agent/run) async def run_task(req: UserRequest): trace_id uuid.uuid4() # 1. 中书省生成计划 plan await zhongshu.generate_plan(req.goal, trace_id) # 2. 门下省审核最多重试3次 plan await menxia.review_plan_with_retry(plan, max_retries3) # 3. 尚书省分配执行 result await shangshu.execute(plan, trace_id) return {trace_id: trace_id, result: result}这段代码概括了最核心的调用链。实际项目里我会把每一步都放进消息队列方便观察每个环节的耗时和token消耗。4. 从零搭建一个“三省六部”Agent框架的参考实现4.1 定义数据结构与消息协议动手写代码前先把数据结构定好。这一步偷懒后面会非常痛苦尤其是多个Agent传递消息时字段名不统一会发生“礼部纠正格式、户部读取失败”这类问题。我定义了三个最核心的数据类PlanItem一个计划任务项包含task_id、target_agent、goal、input_schema、output_schema、priority。ReviewVerdict门下省的审核结论包含pass、reason、suggestions数组。ExecutionResult尚书省回传的执行结果包含task_id、status、output_data、token_usage、error_code。所有类的字段统一用snake_case时间戳统一用ISO8601字符串金额/ID统一用字符串而不是数字。别问为什么问就是JSON数字精度坑过我好几次。4.2 实现三省核心循环规划-审核-执行规划过程我用了一个经过调优的SystemPrompt核心指令是“你是中书省决策辅星只输出计划清单不调用任何工具”。为了保证输出稳定我用了结构化输出比如Pydantic的JSON Schema校验不让模型自由发挥。审核过程更有意思。我把门下省设计成“多个校验插件的组合器”其中有一个插件是调用外部的“依赖环检测算法”检查计划DAG里是否包含环。这个算法是纯代码实现不依赖大模型速度快且100%准确。另一个插件是“Schema匹配器”用来检查PlanItem的input_schema能否对上目标Agent的声明函数签名。执行过程则全部走LangGraph的StateGraph。我把“六部”注册成LangGraph的Tool节点尚书省作为Router自动判断某个PlanItem给哪个部门。由于有上一步的Schema校验Router的判断失误率很低但偶尔还是会出错我会在兵部配置一个“兜底路由”规则如果某个部门Agent自评“这个任务不在我的职责范围”就自动转给礼部记录一条异常并回调中书省重规划。4.3 六部Agent的注册与动态调度不同项目的功能域不一样所以我把六部做成一个可扩展注册表而不是写死六个类。注册表里每一项包含「部门名称、能力描述、调用端点、令牌桶速率、参数Schema、超时时间」。当一个外部工具想加入框架只需要在注册表里注册一次并声明自己属于哪个部。动态调度最大的难题是能力匹配。例如“生成一张销售趋势图”这个子任务可能既适合工部画图工具也适合数据分析Agent怎么选我的策略是给每个注册项加“匹配权重”由门下省在审核时根据目标关键词和参数Schema打分得分最高的部门获得执行权。如果两个部门分数持平就按注册顺序取第一个避免随机选择带来的不稳定性。4.4 通过一个“写行业报告”的例子串起全流程我用一个真实跑通的例子来串一遍。用户请求“写一份2025年AI Agent应用现状报告不少于2000字要包含市场数据和应用案例。”第一步中书省收到这个目标生成一个8个节点的PlanItem列表查行业趋势、查市场规模、查典型案例、整理数据、设计报告大纲、撰写初稿、格式润色、最终输出。第二步门下省逐项审核。发现“查市场规模”这个任务没有明确的数据来源就给出驳回意见“需要指定数据来源例如公开行业报告或权威媒体”。中书省修改后加入“来源公开行业报告”通过。第三步尚书省按依赖关系派发任务“查行业趋势”和“查市场规模”无依赖并行执行“整理数据”依赖前两者等它们完成后启动“撰写初稿”依赖“整理数据”和“设计报告大纲”所以最先执行的是那几个查资料的Agent。第四步每个查资料的Agent由工部路由到搜索工具返回结果经过户部存储再由分析Agent去重和提炼。兵部控制在每轮最多3个并发API调用。最后刑部监控全局有一个搜索API超时了自动重试一次成功。第五步礼部检查初稿格式把字数不足的部分标红提示“数据报告建议补充图表”。工部调起图表生成工具为报告配上图。最终完整报告交付给用户。整个过程耗时约两分多钟token消耗约13000比单Agent方式稳定多了。更重要的是中间任何一个环节出错了都可以通过trace_id定位到具体是哪一省哪一部出了问题。5. 踩坑实录运行中碰到的五个典型问题5.1 审核Agent永远不通过过度校验问题上线第二周我发现一个现象某个任务的中书省计划总被门下省驳回系统日志里全是“不通过请修改”。点开审核意见一看内容是“第2个子任务的目标描述不够正能量”。这可太让人抓狂了门下省把一些模板化的“积极向上”要求当成硬性校验导致正常业务被卡住。排查后发现门下省的SystemPrompt里混合了“政治审查”和“技术审核”两类职责模型一乱就把语义扩大了。我的解决方法是把合规校验拆成独立的Policy Agent由它输出0/1合规结论门下省只做技术性校验。技术校验必须用明确规则和Schema绝不能只靠模型感觉。做完拆分之后驳回率从35%降到4%。5.2 串行执行太慢并行度调优早期版本的三省六部是纯串行一个PlanItem执行完才执行下一个。结果是“查资料”这种本该并行的任务硬生生变成排队整个报告生成要花10分钟。后来我在尚书省加了一个“依赖图执行器”把没有依赖关系的PlanItem打包成一批并行发给兵部。第一批的3个查资料Agent同时跑整个流程缩短到2分钟。不过并行度不是越大越好。我压测过5、10、20三个并发档位发现并发数超过某个阈值后API限流导致的退避重试反而让总耗时长。不同供应商的API限流策略差异极大建议上线前做一次阶梯压测找到自己的“最优并发数”。5.3 上下文越滚越长token开销爆炸有段时间我图省事把所有Agent的中间结果都拼进上下文传给下一个Agent。结果跑一次复杂任务消耗了6万token费用高得吓人。后来我彻底重构了上下文传递遵循“最小上下文原则”。每个Agent开始时只收到当前任务的目标、输入数据和必要的参考链接其余一概不收。效果非常显著token消耗平均下降45%。代价是需要额外写一些“摘要Agent”专门把前一个Agent输出的长内容压缩成结构化摘要。这看起来多了一步但算总账还是划算的。5.4 某个Agent挂掉导致整体任务失败降级策略多Agent系统最怕“单点故障”。有一次我们挂接的图表生成API正好维护整个报告任务因为这个子任务失败而全部失败。刑部最初的策略是“任一环节失败通知用户失败”这当然不行。后来我加了两级降级策略。第一级如果工部的某个工具失败自动尝试同类的备选工具比如图片生成失败改用模板图库。第二级如果某个子任务连续失败超过3次就把该子任务标记为“跳过”并让礼部在最终交付时向用户说明“由于外部服务不可用这部分内容暂缺”。靠这两级策略任务总体完成率从82%提高到97%真正做到了“让AI下地干活”。5.5 日志太多不知道看哪个链路追踪三省六部框架里有几十次调用日志散落在不同进程里出了问题只能一篇篇翻。后来我在每个“奏折文书”对象里塞进trace_id在每一处入口和出口打结构化日志字段包含trace_id、node_name、action、time_ms、token_count。配合Jaeger做可视化追踪每个任务耗时分布一眼可见。我强烈建议任何多Agent项目一开始就上链路追踪不要等出了问题再补。我自己在这上面吃过亏补一套链路的成本远远高于一开始就建好。5.6 常见问题速查表问题现象可能原因快速解法计划反复被驳回审核职责不规范含非技术校验拆出独立Policy Agent审核只做技术Schema与环检测任务总卡住不动有循环依赖未被发现在门下省强制加入依赖环检测算法API频繁超时并发数过高触发限流通过兵部令牌桶限流降低峰值并发Token消耗巨大全量上下文传递改用最小上下文传递加摘要Agent一个Agent失败全盘崩溃没有降级策略配置备选工具兜底超3次失败跳过该子任务定位问题困难没有链路追踪统一trace_id接Jaeger可视化以上这些坑每一个我都亲身踩过。现在框架稳定性已经很高了但每次跑新场景时我仍然习惯先看链路追踪图再决定要不要调某一块的并发、超时或者降级策略。最后再分享一点个人体会做AI Agent协作框架难点其实不在模型质量而在“组织设计”。模型能力会随着版本迭代越来越强但如果Agent之间的流程和职责一团糟再强的模型也救不回来。三省六部是一个很顺手的隐喻但背后的分权、制衡、流程化的思想才是真正让Agent团队变得可靠的关键。如果你也在折腾多Agent协作不妨试着把任务拆成“决策、审核、执行”三段然后把每个业务Agent绑到某个清晰的职能域下。你会发现乱糟糟的Agent群一下子就有了章法。这比堆一百个无所不能的通用Agent要实用得多。