ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于agency-agents的多智能体协作架构与工程实践

2026/10/8 14:09:04 拓冰建站 浏览量
基于agency-agents的多智能体协作架构与工程实践 看到“agency-agents”这个词我第一反应不是某个具体开源仓库而是一种正在被反复验证的多智能体协作模式把几个擅长不同事情的 AI Agent像一家小型公司那样组织起来让它们各自认领角色、互相传递中间结果、最后拼出一份高质量交付物。我最近在一个客户项目里完整跑了一版“代理机构”式的工作流用来做行业调研和内容生产前后折腾了三个星期踩了不少坑也摸到了一些很实用的规律。这篇就围绕 agency-agents 这个思路把架构设计、代码骨架、参数调优和问题排查一次说清楚。如果你正在做 AI 应用开发或者对 Agent 感兴趣但厌倦了“单智能体提示词越堆越长”的路子这篇文章很适合你。即使你只是用过 ChatGPT想理解“多个 AI 角色协作到底怎么玩”里面的大部分思路也都能直接套用。1. 项目概述与核心思路1.1 什么是 agency-agents把单点能力拼成专业团队传统的单 Agent 用法是“一个大模型 一大段系统提示词 一个完整任务”所有工作都由同一个模型完成。遇到简单任务还行一旦任务变成“先调研、再分析、然后写报告、最后校对”单 Agent 就开始露馅提示词里塞太多角色要求模型容易“精神分裂”上下文太长前面的结论到后面就忘了更麻烦的是你很难判断是哪一步出了问题。agency-agents 的做法是把任务拆开。项目经理 Agent 负责拆解任务和管理进度调研员 Agent 专门去搜索和整理资料分析师 Agent 负责提炼规律编辑 Agent 负责润色和排版。每个 Agent 只需要做好自己那一小块事prompt 可以写得很聚焦输出也更稳定。整个流程就像是把一个全能型员工替换成一个各司其职的小团队每个人只对最终目标的一部分负责。这种模式在开源社区里已经有 MetaGPT、AutoGen、ChatDev 等类似实践。agency-agents 更强调的是“代理机构感”你需要让 Agent 之间有明确汇报关系、清晰交接物、统一的通信协议而不是简单地把多个 Agent 丢进一个群里自由发言。否则很快就会出现“上下文大杂烩”和“没人对最终结果负责”的问题。1.2 为什么我放弃单智能体转向多智能体协作我做第一个 Agent 项目时把所有需求全写进了一个 system prompt。为了让它能“全网搜索、分析数据、写周报”我硬凑了一个超过 2000 字的提示词结果模型经常顾此失彼让它查数据的时候它开始总结让它写结论的时候它又开始列数据表。最离谱的一次它把上一轮调研的旧结论当成本轮结果直接交了一份错误报告。后来我尝试把任务手工拆开分多次调用模型每次干一件事再手动拼装结果。过程很痛苦但效果明显变好。这让我意识到问题不是模型不够聪明而是整个链路缺少结构和反馈。单 Agent 的上下文窗口再大也装不下“一个完整的业务项目周期”而 agency-agents 模式可以让每个 Agent 专注在自己的小上下文里通过消息传递和共享记忆让整体认知远远超过单 Agent 的窗口限制。这种模式还有一个隐性优势可解释性。一旦最终报告质量不行我可以直接定位是投资分析师 Agent 的输出有问题还是最后的编辑 Agent 改了风格。责任落到具体 Agent 上调优就有方向。而不是像单 Agent 那样拿一段黑盒输出反复猜 prompt 哪里写得不到位。2. 整体架构设计与智能体分工2.1 核心组件拆分编排器、角色智能体、消息总线搭一个可用的 agency-agents 系统至少要拆出四个核心组件。第一个是编排器Orchestrator。它不负责具体内容产出而是负责拆解任务、调度角色、判断何时该收尾。你可以把它理解成项目总监不写代码但盯着进度看见某个 Agent 卡住或结果不对就决定重试还是换人。编排器通常就是一个循环控制逻辑用代码实现不一定非要调模型。第二个是角色智能体Worker Agents。每个 Worker 有独立的 system prompt、模型参数、工具权限甚至独立的模型供应商。不同角色可以配不同模型简单的信息抽取用便宜快的小模型复杂分析用贵一点的大模型这样成本控制会好很多。第三个是消息总线Message Bus。它是 Agent 之间的“共享聊天群”所有中间输出都按统一的消息格式写入。其他 Agent 订阅到自己需要的消息类型后就能取用上一环节的产出。消息总线不一定要用消息队列中间件用 Python 里的 list 或者 Redis 都能实现关键是消息要有标准结构。第四个是外部工具层Tool Layer。Agent 需要搜索、查数据库、调 API 时不能直接裸写浏览器操作而是通过一组预定义的函数接口来调。工具层把“模型能发出的动作”限制在安全范围内同时把结果转成结构化的返回内容。这四个组件的关系很像一家真实公司编排器是管理层角色智能体是员工消息总线是内部 OA 系统工具层是办公用品和外部资源。少了任何一个多 Agent 协作就会退化成“几个模型互相对话”的玩具。2.2 角色分工设计的五个避坑原则设计角色时我总结出五个原则每条都是从踩坑里摸出来的。第一职责单一。不要设计一个“全能型专家”Agent什么都会等于什么都不专业。项目经理只管计划和进度不要让它去写市场分析。分析师只总结数据不要兼任编辑。职责边界混乱是系统跑偏的头号原因。第二输出标准化。每个 Agent 的输出都必须按约定好的格式返回可以是 JSON、Markdown 或 YAML。你甚至可以在 system prompt 里强制要求“先输出 JSON 再输出正文”。没有标准格式下游 Agent 解析时就会频繁出错有时候不是模型不聪明而是前一个 Agent 写了一堆“嗯、好的、明白了”这类废话把有效的交接物淹没了。第三闭环校验。设计任务流要有计划、执行、评审、复盘这样的闭环。最简单的方式是加一个 reviewer Agent专门检查上一个角色的输出质量。没有校验错误会一路传导到最终结果而且很难追溯。第四角色数量控制在 3 到 5 个。我试过 8 个角色的团队结果是消息总线里充斥着大量无用信息上下文迅速膨胀编排器自己也分不清当前状态。小团队运转效率远高于大团队。想扩能力不是加角色而是给现有角色加工具。第五人工兜底。不管流程设计得多好最终交付前要留一个“人工确认步骤”。尤其是用于客户报告或生产环境的内容一定要有一个环节允许人介入修改。Agent 协作能提高效率但还不能完全替代人的判断。2.3 一个典型的信息流转流程用一个“行业市场分析报告”举例。编排器先接收任务拆成四个阶段调研、分析、撰写、校对。第一阶段编排器把“收集行业规模和头部玩家数据”发给调研员 Agent调研员使用搜索工具拿到原始数据整理成带来源的结构化笔记写入消息总线。第二阶段编排器把这份笔记交给分析师 Agent分析师给出趋势判断和市场机会。第三阶段编辑 Agent 把分析和原始笔记改写成可读的报告初稿。最后校对 Agent 检查事实错误和格式问题通过后输出最终版本。整个流程中编排器只在阶段切换时介入平时不干预具体内容生成。这样既保持流程可控又不会因为频繁调用模型导致成本暴涨。我实测下来4 个角色的流程跑一个完整调研报告大概需要 8 到 12 轮模型调用时间在 2 到 5 分钟费用取决于所选模型。3. 实操过程搭建一个可运行的 agency-agents 工作流3.1 环境准备用一套最小可跑的代码启动下面这套代码我刻意写得非常简单不使用重框架方便理解底层机制。环境要求不高只需要 Python 3.10 及以上、OpenAI 兼容的 API Key以及两个基础库。pip install openai python-dotenv然后在项目根目录建一个.env文件写入你的 API KeyOPENAI_API_KEYsk-... MODEL_NAMEgpt-4o-mini关于模型选型我可以提供一条参考经验预算有限时通用文本任务用 gpt-4o-mini 或同等定位的小模型最终汇总和复杂分析用 gpt-4o 或同级别大模型。不要在每一步都上大模型否则成本是线性上升的而效果并不一定线性变好。3.2 定义角色与任务流程以市场分析报告为例我建了一个roles.py文件把每个角色定义成字典。之所以用字典而不是类是为了直观后续要接数据库或改配置也方便。roles { pm: { name: 项目经理, system_prompt: ( 你是项目经理。你的责任是把用户任务拆解为若干清晰、有序的执行步骤 并为每个步骤分配合适的角色。输出格式为 Markdown 列表每行以 - [ ] 开头。 ), temperature: 0.3, model: gpt-4o-mini, }, researcher: { name: 调研员, system_prompt: ( 你是调研员。根据项目经理给出的调研主题使用提供的搜索工具收集资料。 输出必须包含两个部分## 数据 和 ## 来源。数据部分用 Markdown 表格 来源部分用带链接的列表。不要输出无关分析。 ), temperature: 0.5, model: gpt-4o-mini, }, analyst: { name: 分析师, system_prompt: ( 你是行业分析师。基于调研员提供的原始数据找出趋势、风险和机会。 输出格式先给出三条核心洞察每条 50 字以内再给出两个需要进一步核实的问题。 ), temperature: 0.4, model: gpt-4o, }, editor: { name: 内容编辑, system_prompt: ( 你是内容编辑。将分析师和调研员的产出整合成一份逻辑通顺、段落清晰的中文报告。 报告结构包括摘要、市场现状、趋势分析、机会建议。不要添加新事实。 ), temperature: 0.7, model: gpt-4o-mini, }, }注意几个细节每个角色的 prompt 都明确写了“不要做什么”这比只写“要做什么”更能约束模型。调研员 prompt 用了输出模板“## 数据”“## 来源”这就是标准化的雏形。分析师用了更贵的大模型因为它要做深层推理其他角色用便宜模型整体成本就能压下来。3.3 编排循环实现关键参数怎么调稳我写了一个不到 60 行的编排器核心逻辑是“按阶段顺序调用角色 把上一阶段结果附加到上下文 阶段完成后自动终止”。from openai import OpenAI from config import roles import os client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) MODEL os.getenv(MODEL_NAME, gpt-4o-mini) def call_agent(role_key, task, context, max_tokens1500): role roles[role_key] messages [ {role: system, content: role[system_prompt]}, ] context [ {role: user, content: task}, ] resp client.chat.completions.create( modelrole.get(model, MODEL), messagesmessages, temperaturerole[temperature], max_tokensmax_tokens, ) return resp.choices[0].message.content def run_pipeline(topic): # 项目经理拆解任务 pm_task f请拆解以下任务并标记需要哪些角色协作{topic} steps call_agent(pm, pm_task, context[], max_tokens800) print( 项目经理拆解 ) print(steps) # 让调研员执行第一步 research_task f围绕主题 {topic} 收集行业数据重点包含市场规模与头部厂商。 research_out call_agent(researcher, research_task, context[{role:user,content: steps}]) print( 调研结果 ) print(research_out) # 分析师基于调研结果分析 analyst_out call_agent( analyst, 请基于以下调研结果给出行业洞察。, context[{role:assistant,content: research_out}], ) print( 分析结果 ) print(analyst_out) # 编辑整合报告 final_report call_agent( editor, 请整合调研分析和原始数据写出一份完整行业报告。, context[ {role:assistant,content: research_out}, {role:assistant,content: analyst_out}, ], ) return final_report if __name__ __main__: report run_pipeline(智能家居市场 2025) print( 最终报告 ) print(report)这段代码最重要的参数有三个temperature调研类角色要稳定建议设0.4 以下编辑类需要创造性可以设0.7。千万别所有角色都用同一个温度否则会出现“调研结果像散文、报告却像数据表”的错位感。max_tokens每个阶段的输出长度要提前限制。调研阶段 1500 字足够项目经理拆解任务 800 字足够。不限制的话模型容易啰嗦还会把上下文撑爆。context编排器只把关键交接结果作为上下文传给下一个 Agent而不是把整个历史对话全塞进去。这个设计非常重要能缓解上下文超限问题。4. 核心原理与关键细节解析4.1 通信协议设计让每个 Agent 都能接上话多 Agent 协作里最容易被低估的是通信协议。很多新手把所有历史消息一股脑塞给下一个 Agent最后得到一堆混乱输出。正确做法是约定一个最小消息结构每条消息包含四个字段{ from: researcher, to: analyst, type: research_note, payload: { data: ..., sources: [...], summary: ... } }from和to是路由信息type是消息类型告诉接收方“这条消息是数据笔记还是最终报告”payload是实际内容。用这个结构编排器可以轻松实现已经处理的消息不再重复发送。更重要的是模型看到的是清晰的结构化内容而不是一堆聊天噪音。我在实际项目里还加了一个“去重字段”每条消息生成时都带一个哈希值编排器比对后只保留最新的同类型消息。这个做法避免了调研员跑两次后分析师同时看到旧数据和新鲜数据互相打架的情况。4.2 上下文管理与记忆机制别让 Agent“忘事”多 Agent 系统最常遇到的问题是上下文爆掉。Agent 一多每个人都要看到其他所有人的输出对话历史指数级膨胀。解决思路是分级记忆工作记忆当前阶段需要的最近几条消息放在上下文里。项目记忆整个项目的关键结论存在本地文件或向量数据库中每轮结束后更新。长期记忆历史项目的总结供未来任务参考。在项目里我实现了一个简化版每轮 Agent 运行结束时用代码把它的输出里的“核心结论”提取出来压成摘要存到一个memory.md文件里。下一轮 Agent 需要做决策时就把摘要和当前任务一起作为上下文。这样即使上下文窗口很小也能保持对项目全貌的理解。这种做法的代价是“可能丢掉细节”所以我把原始输出完整保存在消息总线中摘要只是给 Agent 的“短期捷报”。如果你需要精确引用某条数据可以让调研员在输出里写清楚引用标识后续 Agent 直接去找对应的完整内容。4.3 工具调用与外部系统对接给 Agent 装上手和眼没有工具的 Agent 只能基于训练数据“想当然”。要真正完成调研你至少需要一个搜索工具和一个抓取网页内容的工具。在 OpenAI 兼容接口里工具调用可以通过tools参数声明。一个简化版搜索工具定义如下tools [ { type: function, function: { name: web_search, description: 搜索给定关键词返回前五条结果的标题和链接。, parameters: { type: object, properties: { query: { type: string, description: 搜索关键词尽量简短 } }, required: [query] } } } ]这样模型就会在需要时调用web_search而不是凭空编造数据。我把真实搜索函数写成一个 Python 函数调用搜索 API 后把结果解析成上文约定的消息格式。注意工具函数名称和描述写得越精确模型调用的准确率越高。如果你写“这个方法可以获取信息”模型很可能乱调如果你写“传入中文关键词返回带 URL 的结果列表”它就会规范很多。安全方面工具层必须做权限控制。不能让 Agent 随便删文件、改数据库。我习惯给每个工具加一个“白名单角色”只有调研员 Agent 能调搜索只有编辑 Agent 能写文件。这样即使某个 Agent 被提示词注入攻击损害范围也可控。4.4 成本与延迟优化多 Agent 不等于多花钱很多人一听“多 Agent”首先想到“那得多花多少 API 费用”。我实测下来如果只追求稳定其实并没有想象中那么贵。关键在于三件事第一角色分模型。简单任务用便宜模型复杂任务用贵模型。前面角色定义里我已经写好了调研员和编辑用gpt-4o-mini分析师用gpt-4o整体费用比全流程大模型降低 40% 左右质量几乎没下降。第二缓存中间结果。同一个话题的调研数据如果只是换一种报告风格就没有必要重新跑一遍调研员和分析师。我把每个阶段的结果按 topic 阶段名缓存到本地 JSON 文件第二次运行直接读缓存秒级出结果。第三并行化。如果任务可以拆成多个独立子调研就开多个线程同时跑不同调研员而不是串行等待。比如一个市场报告要分析“国内市场”和“海外市场”两个调研互相独立并发执行能把总耗时从 6 分钟压到 3 分钟。延迟优化要特别注意一个点不要让编排器在工作流中频繁阻塞等待。如果某个阶段需要人工确认就先把已完成内容持久化然后退出循环等待用户回调。不然一次真实验证可能让你白付好几轮等待费用。5. 常见问题与排查技巧实录5.1 问题排查速查表Agent 循环失控怎么处理在实际跑流程时我遇到过最多的问题是 Agent 陷入死循环或重复执行同一操作。比如调研员反复搜索同一个关键词三次或者项目经理在不该拆解任务的时候继续拆解。我把常见症状、原因和对应方案整理成了一张表症状可能原因解决方案Agent 重复执行同一工具调用工具返回结果未更新上下文模型看不到新信息在工具返回后强制插入 assistant 消息记录调用次数超过上限直接终止任务被拆解得越来越细项目经理的 system prompt 缺少“拆解到二级步骤为止”的约束在 prompt 里明确“只拆一次不要继续细分”设置拆解结果的 max_tokens两个 Agent 反复对话无法收敛缺少终止条件双方都以为对方在等自己编排器统一判断重复内容超过 2 次则强制合并或跳到评审角色某个 Agent 输出空内容或只有感谢语前一个 Agent 的输出不标准导致它理解错任务检查标准化输出要求加一个 reviewer Agent 做格式校验最终报告丢了一部分关键事实中间有一个 Agent 把上下文里的关键内容截断了启用完整消息存储让编辑 Agent 从原数据而不是摘要中获取关键数据这套排查表可以当成通用调试清单先看症状再按顺序检查对应模块。我自己的习惯是遇到问题先打印每一步的消息列表看消息从哪里断的。多 Agent 系统的问题 90% 出在消息结构或上下文传递上而不在模型本身。5.2 质量不稳定让结果更“靠谱”的三个技巧多 Agent 系统还有一个痛点同样的输入每次输出飘忽不定。别人演示时效果好到起飞你上手就翻车。这不是你的代码有问题而是采样随机性在叠加。第一个技巧是固定 seed。如果模型接口支持seed参数就在配置里固定一个值。很多 SDK 支持seed但不保证绝对一致可它至少能把波动压到最低。第二个技巧是多次采样 投票。让分析师角色跑三次把三次结果都用编辑 Agent 汇总取最一致的观点。这样能显著降低单次模型“跑偏”的概率。第三个技巧是增加评审 Agent。在最终交付前让一个独立的 reviewer Agent 对照任务要求检查报告缺点和错误直接当成附加任务交给编辑修改。我试过最夸张的一次让一个审核 Agent 检查调研报告它直接把“2024 年市场规模”写进报告的编辑版本标红并附了一句“该数据来源时间较早建议更新到 2025 年”。这个检查效果不是靠提示词魔法而是靠“职责分离”实现的。5.3 成本超预期怎么看账本并优化跑完整套流程后一定要有成本监控。最简单的方法是记录每次调用的 token 数量和模型名写入本地日志。我把每次调用信息按“角色名”聚合很快就能看出哪类角色花钱最多。如果调研员烧钱太狠就压缩它的输出长度或者用更便宜的小模型。如果分析师烧钱太狠就把它的输入上下文先做摘要只传关键结论而不是全部原始数据。如果编辑 Agent 的temperature太高导致多版本长度失控就把max_tokens压低。还有一个容易被忽略的成本陷阱调试时的重试。我在联调阶段开着频繁重试发现账单跑得飞快。后来我写了一个“调试模式”调试时所有 Agent 都使用最小模型只保留一个复杂的最终汇总用大模型。逻辑通了再切回正式模型成本能省一大半。6. 一些实际体会与后续扩展方向这套 agency-agents 流程我前后迭代了好几版从最初直接调接口到后来加入消息总线、工具层、缓存和评审才真正稳定下来。回头总结我最深的体会是多 Agent 系统的复杂度不在模型而在工程。通信协议、上下文管理、任务边界、终止条件这些看似枯燥的工程细节才是决定一个多 Agent 应用能不能从 demo 走到生产的关键。模型反而成了最不重要的变量——换个更强的模型如果不解决消息乱传的问题照样输出烂结果。后续如果在你的项目里继续扩展我建议优先做两件事一是给消息总线接入向量数据库让 Agent 能根据语义检索历史结论而不是每次都把所有内容硬塞进上下文二是做任务路由让每个任务自动匹配最合适的角色组合而不是固定一个流水线。我个人踩过最大的坑是“贪多”一开始恨不得让 Agent 什么都能干后来老老实实做减法每个角色只管一件事效果立刻上来了。做多智能体协作少即是多这不是一句鸡汤是真的能帮你省下大量调试时间的实战经验。