开头
这几年代理(Agent)这个概念被聊得很多,但真正把它从一个单体助手做成一支能打仗的“队伍”,中间隔着不少坑。我最近一直在打磨一个叫“agency-agents”的实践项目,核心思路很简单:不搞一个全能大Agent,而是让多个职责单一的Agent像一家代理机构那样分工协作——有人接单、有人规划、有人执行、有人质检,最后统一交付。这种用“团队作战”取代“单兵突击”的思路,在真实业务里非常实用,尤其适合内容生产、数据分析、客服响应这类需要多步骤串联的场景。
如果你已经在用单Agent做自动化,但经常碰到上下文越搅越乱、任务一做长就失控、或者想加新功能却把老功能搞崩的情况,那这套多智能体协作模式大概率能解你的燃眉之急。这篇文章我不打算讲那些号称“开箱即用”的框架噱头,而是把从需求拆解到落地实现的关键环节原原本本掰开说清楚,包括角色怎么分、消息怎么传、状态怎么管、坑怎么避。无论你是捡起了LangChain但没想清楚编排思路,还是准备从零手写一套轻量级Agent调度系统,这篇文章都适合先读一遍。
1. 整体设计与思路拆解
1.1 从“一个Agent干到底”到“一家代理机构协同作战”
先聊聊为什么会有这个项目。以前我干活儿习惯用一个主Agent,把所有指令交给它:帮写文章、帮查资料、帮做总结、帮回消息。前期挺爽,后来越用越难受,原因其实就三条。
第一,上下文窗口有限。一个Agent能记住的上下文就那么多,不想让它金融化使用上下文,但任务一多、轮数一长,早期的重要信息就被挤出窗口了。比如让它先分析一份数据,再根据分析结果生成图表,最后写一段汇报。这三个步骤共享同一份长上下文,越往后AI越迷糊,甚至开始把前几步的结果自己脑补出来。
第二,职责混杂导致表现不稳定。写文案的Agent拿去让它统计数据,数据分析的Agent让它生成营销措辞,往往两边都做不好。不同任务需要不同的提示词策略、不同的输出风格、不同的参数设置(比如temperature高低),硬放在一个Agent里,要么统一低温度导致创意不足,要么统一高温度导致逻辑稀碎。
第三,没法并行。单Agent只能串行处理,数据查询、资料检索、初稿生成这些本来互不依赖的步骤居然要排队完成,白白浪费时间。
后来我就想,与其训练一个“全能型选手”,不如组建一支分工明确的团队。就像外面那些代理机构一样:客户找上门,前台接待;项目经理拆需求、排计划;执行人员各干各的活儿;最后还有专门的人审稿、质检、交付。这套逻辑映射到程序里,就是把“一个全能的AI”改造成“多个各司其职的AI节点,配上通信机制和调度策略”。
1.2 为什么叫“agency-agents”而不是“multi-agent”
我特意把这个项目命名为“agency-agents”,而不用更常见的multi-agent,是因为我关心的不只是“多个Agent”,而是“像机构一样运作的Agent集群”。一个真正的代理机构有几个特质:
- 有明确的组织架构:谁接活、谁干活、谁把关。
- 有标准化的SOP:订单进来该走什么流程、每步输出什么格式,都有规矩。
- 有质量兜底:交付前有人检查,不合格要打回重做。
- 有协作接口:部门和部门之间靠标准单据衔接,而不是互相猜。
这些特质映射到系统设计里就是一套编排哲学,相比multi-agent那种偏靠Agent自动协商讨论的模式,agency-agents更强调流程的可控性和角色的清晰边界。用工程类比来说,multi-agent像是让一堆专家自由开会讨论出一个结论,能不能收敛全靠运气;而agency-agents像是工厂流水线,每个工位只干一件事,干完把半成品传给下一个工位。前者灵活但不可控,后者刻板但可预测。做真实业务,稳定可预测往往比灵活更重要。
顺着这个思路,我的方案不依赖Agent之间的自由对话来互相“说服”,而是把每一步的结果当成标准数据,在明确的流程节点之间传递。这不是说不能有反馈回路,而是反馈回路拥有清晰的触发条件和出口。
1.3 目标场景与适用边界
这套设计并不是所有场景都合适。我实际测试下来,最适合的是“流程长、步骤多、每步产出清晰、需要质量把关”的任务,举几个例子。
内容生产:选题策划Agent产出大纲,资料Agent检索补充素材,写作Agent产出初稿,审核Agent按标准质检(查重、事实错误、结构问题),修订Agent返工。每一步都有明确的输入输出,查一个环节的产出就能定位问题。
数据分析报告:规划Agent拆解分析问题,数据Agent写SQL查询,分析Agent做结论推理,可视化Agent生成图表,最后审校Agent统一格式。
客服工单处理:意图识别Agent分类问题,信息提取Agent抽取订单号、问题类型,处理Agent生成回复,风险Agent识别是否有退款、投诉升级风险,再把高危工单转人工。
至于那些需要高度自由推理、答案没有固定结构、过程比结果还重要的任务,比如头脑风暴、开放式对话聊天,硬套这套“流水线”反而会显得呆板。我做的原则就一句话:先想清楚每个环节的输入输出是不是明确的,如果不明确,就不要强行走流程化。
2. 核心细节解析与实操要点
2.1 角色设计:每个Agent必须有且只有一个核心职责
角色设计是整个系统的地基,这一步做好了后面全是顺水推舟,做不好后面天天补窟窿。我踩过最深的坑,是自己的“贪心”导致Agent职责模糊。一开始我搞了一个“全能执行Agent”,既管查资料,又管写代码,还要处理用户反馈。实际跑起来的结果,就是它经常在代码生成时自带分析报告、在分析报告里夹带代码片段,输出格式乱成一锅粥,下游解析逻辑天天报异常。
后来我立了一条铁规矩:一个Agent只干一件事,用一句话能说清它干嘛。比如:
- 规划Agent:拆解任务,输出结构化步骤清单。
- 检索Agent:去外部数据源检索资料,输出带引用来源的内容摘要。
- 写作Agent:基于规划框架和检索摘要撰写正文,输出Markdown。
- 审核Agent:按既定质量标准检查正文,输出通过/不通过+问题清单。
- 修订Agent:根据问题清单逐条修改,输出修订版正文。
每个角色不仅职责单一,输出格式还必须用JSON严格定义。这样做有两个明显好处:一是每个Agent的提示词不会太长,模型更容易照着做;二是下游Agent接收上游输出时不需要猜,直接解析JSON字段就能用。
角色数量也不是越多越好。初期我设计过十几个角色,又是查重Agent又是排版Agent又是SEO助手Agent,结果光是角色之间的流转关系就让调度代码变得极其复杂,排查问题时脑壳疼。后来的经验是:能用三个角色完成就别用五个,角色每多一个,消息传递和状态管理的复杂度就上一个台阶。我从十几人砍到五六人的时候,系统稳定性明显提升。
2.2 任务流程编排:不要自由讨论,要标准流水线
任务编排是agency-agents的核心骨架。我尝试过两种极端方式,现在比较推荐中间态。
第一种极端是“放任自由主义”:所有Agent聚在一起,用同一个上下文自由发言。这种方式在写创意文案时确实能产生意外的点子,但也非常容易陷入死循环。A说完了B说,B说完了A反驳,说来说去没有收敛信号,最后钱花了、时间过了、答案却停在半路。
第二种极端是“固定死路”:预先定义好每一步走哪个Agent,不允许任何偏离。这种方式的优点是稳定,但因为现实任务往往有分支,比如检索没找到资料需不需要换个关键词再试一次?审核不过要修订几轮?一味写死,系统在真实业务里的适用性就肉眼可见地下降。
我最终采用的是“主流程固定 + 有限回退分支”:主流程就是规划→检索→写作→审核→修订→输出,这五段顺序不搞乱。但每个阶段内部允许小范围自适应,比如检索结果为空时,检索Agent可以调整查询词重试两次;审核不通过时,修订Agent拿到问题清单再改,最多迭代三轮,超过三轮就转人工确认。主流程稳定保证下限,有限回退保住灵活。
这种编排方式的落地载体很简单,不需要什么复杂框架,一个状态对象加一个循环调度器就够了。每一个Agent处理完,往状态对象里写入自己的产出,调度器根据产出里的字段判断下一步该走哪条边。
2.3 上下文策略:共享什么、隔离什么,必须划清界限
这个是我认为整个项目里技术含量最高的地方。“多Agent交流”如果只是把所有东西塞到同一个上下文里传递,那和单Agent长对话没有任何区别,反而更乱。正确的做法是分层管理信息:
- 全局共享区:放任务目标、用户约束、背景资料。这块每个Agent都有只读权限,但只有协调器能写。
- 环节产物区:放每个环节的输出,比如规划结果、检索汇总、初稿。下游Agent读上游产物,但读不到平级或下游的。
- 私有工作区:各Agent自己的历史会话、中间推理过程,为自己的后续轮次服务,对别人不可见。
我用字典结构维护这三个区域,key分别是global、stage、private。每次给Agent发消息之前,调度器先按它的角色权限组装一个当前可读上下文集,再拼上系统提示词和用户指令。这就避免了“什么都能看到”带来的信息干扰,也让每轮消耗的token减少不少。
有一说一,一开始我对上下文共享太吝啬,导致审核Agent拿不到原始需求文档,只凭写作Agent的产出就去做判断,结果经常误伤“符合要求的稿子”。后来调整原则:审核Agent一定同时读取全局需求与写作产出,两相对照再给结论。实践证明,上下文隔离不是一刀切,该给的信息给足,不该给的一律不给,“最小够用”才是真的合理。
2.4 通信协议与状态机设计
Agent和Agent之间怎么通信,决定整个系统的可观测性和可维护性。我用的不是拿自然语言聊来聊去,而是标准消息信封加状态机流转。
一件消息固定包含:
- msg_id:消息唯一编号。
- sender:发送方角色名。
- receiver:接收方角色名。
- msg_type:类型,比如request、response、approval、reject。
- payload:正式的产出数据。
- expires_at:过期时间,防止队列里积压太多陈旧消息。
消息本身不携带业务逻辑,只管传递。真正驱动流程的是状态机。我定义的状态集合包括NOT_STARTED、PLANNED、RESEARCHED、DRAFTED、REVIEWED、REVISED、COMPLETED、HUMAN_NEEDED,每条边写明触发条件和新状态。比如从DRAFTED跳到REVIEWED的触发条件是写作Agent成功写入产物;从REVIEWED可能回跳到REVISED(未通过)也可能跳到COMPLETED(通过)。
这套设计给排查问题带来很大便利。哪个Agent卡住了、哪条消息没送达、状态卡在哪个环节,一眼就能定位。项目跑到后段,我甚至在每次状态变迁时都打日志,后续复盘基本不看聊天记录,只看状态流转记录就够了。
3. 实操过程与核心环节实现
3.1 技术选型:不追新,选能快速落地的组合
先说选型。我承认那些重量级的多Agent编排框架功能很全,但对于一个自己从零打磨的“轻量中型”项目来说,很多高级特性用不上,反而平添复杂度。我自己的技术栈是这些:
- 语言用Python,生态最全,写脚本和对接模型都方便。
- 模型调用先用统一的接口封装一层,底层具体用哪家大模型可以随时切换。不建议在代码里到处直接调用模型SDK,那样换供应商时会想砸电脑。
- 消息队列不引入Kafka或者RabbitMQ,直接用Python的Queue内存队列就行。单机多进程场景足够用,搞太快太重容易把自己淹没在运维里。
- 状态存储用一个轻量的关系型数据库SQLite即可,等复杂到需要并发写大量数据了再换PostgreSQL。前期我用Orm框架操作数据库,后面发现直接写SQL反而更清晰可控,排查问题时少跳一层封装。
一言以蔽之:选型的核心是让代码能尽快跑起来,同时把关键边界留出扩展接口,不要第一版就为了“以后可能用得上的功能”把系统和自身工作量搞得过于臃肿。
3.2 搭建最小骨架:五个Agent的协作Demo
下面手把手搭一个能跑通的最小demo。为了演示,我做一个简化版的内容生产流水线,包含规划Agent、检索Agent、写作Agent和审核Agent,再加一个调度器协调。注意,这个demo专注在“协作链路通顺”,具体Agent的技能本身先不强求。
第一步,定义角色配置文件,用YAML填清楚每个角色的名字、职责描述、输入字段、输出字段:
planner: role: "规划Agent" description: "拆解用户需求,输出步骤清单" input_fields: ["user_demand"] output_fields: ["steps"] researcher: role: "检索Agent" description: "按关键词检索资料,输出引用摘要" input_fields: ["steps"] output_fields: ["research_notes"] writer: role: "写作Agent" description: "按规划框架和检索素材撰写正文" input_fields: ["steps", "research_notes"] output_fields: ["article"] reviewer: role: "审核Agent" description: "检查文章完整性和事实一致性" input_fields: ["article", "steps"] output_fields: ["verdict", "comments"]第二步,写Agent基类。每个Agent只有一个入口方法execute,参数是从调度器传来的上下文袋子,返回是标准字典。这段代码是简化版的,但结构可以沿用:
class BaseAgent: def __init__(self, name: str, role_desc: str, model_api): self.name = name self.role_desc = role_desc self.model_api = model_api def execute(self, context: dict) -> dict: prompt = self.build_prompt(context) response = self.model_api.chat(prompt) return self.parse_response(response)build_prompt里面把角色描述、全局需求、上游产物拼接成字符串,parse_response负责把模型输出转成JSON。这里有个关键点:解析响应时不要假设模型每次都严格吐合法JSON,我通常用“找最外层花括号再json.loads”的策略,外加一次字符串清理,实在解析失败就让Agent重试一次。
第三步,写调度器。核心逻辑就一个循环:判断当前状态,决定调用哪个Agent,取它的返回,更新状态,直到走到COMPLETED或HUMAN_NEEDED。一个粗略的实现如下:
class Coordinator: def __init__(self, agents: dict): self.agents = agents self.state = "NOT_STARTED" self.global_context = {} self.stage_artifacts = {} def run(self, user_demand: str): self.global_context["demand"] = user_demand self.state = "PLANNED" while self.state not in ("COMPLETED", "HUMAN_NEEDED"): if self.state == "PLANNED": result = self.agents["planner"].execute({"demand": user_demand}) self.stage_artifacts["steps"] = result["steps"] self.state = "RESEARCHED" elif self.state == "RESEARCHED": result = self.agents["researcher"].execute( {"steps": self.stage_artifacts["steps"]} ) self.stage_artifacts["research_notes"] = result["research_notes"] self.state = "DRAFTED" elif self.state == "DRAFTED": result = self.agents["writer"].execute( { "steps": self.stage_artifacts["steps"], "research_notes": self.stage_artifacts["research_notes"], } ) self.stage_artifacts["article"] = result["article"] self.state = "REVIEWED" elif self.state == "REVIEWED": result = self.agents["reviewer"].execute( { "article": self.stage_artifacts["article"], "steps": self.stage_artifacts["steps"], } ) if result["verdict"] == "pass": self.state = "COMPLETED" else: # 回退到修订态,这里简化处理 self.stage_artifacts["comments"] = result["comments"] self.state = "REVISED" elif self.state == "REVISED": result = self.agents["writer"].execute( { "article": self.stage_artifacts["article"], "steps": self.stage_artifacts["steps"], "reviewer_comments": self.stage_artifacts["comments"], } ) self.stage_artifacts["article"] = result["article"] self.state = "REVIEWED"这样循环就能跑起来。真实项目里,状态分支会比这个多不少,可能还有并行节点、兜底逻辑、人工介入接口,但骨架思路基本如此。
3.3 关键参数怎么定:轮次上限、模型温度、上下文裁剪
这些参数每一个都值得单独细说,因为它们直接决定系统的稳定性。
轮次上限。修订Agent和审核Agent之间如果反复通不过,就会死循环烧钱。我给修订流程设了MAX_REVISION_ROUNDS=3,超过就强制置为HUMAN_NEEDED,通知人类介入。这个参数是根据业务成本定的:普通内容生产迭代三轮已经能修正大部分问题,再迭代下去提升有限但成本翻倍。
模型温度。不同角色用不同temperature:规划Agent用0.2,要让它的步骤拆解尽量稳一点;检索Agent用0.3,稍微留一点探索空间重写关键词;写作Agent用0.7,保证语言有点弹性不呆板;审核Agent用0.1,标准严格,不带过多创作色彩。实测下来,这种“分角色差异化调参”比全局统一温度的效果好很多。
上下文裁剪。每个Agent并不是都需要全部历史产物。比如审核Agent只需要文章、步骤清单和原始需求,不需要看检索Notes的长篇大论。裁剪策略:根据角色的输入字段白名单,“按需组装上下文”。我观察过,优化裁剪后单轮调用token消耗平均下降40%左右,整体成本缩水明显,同时模型响应质量和稳定性不降反升。
3.4 扩展并行能力:让检索Agent分头行动
串行链路搭建完之后,会明显感觉到一个瓶颈:检索阶段如果只有一个Agent跑,每个关键词挨个查,速度是真的慢。我后来把检索Agent拆成了多个并行worker,每个worker负责一类关键词,用线程池并发去查询,最后汇总统一格式。
实现上其实不复杂,核心就是用Python的concurrent.futures.ThreadPoolExecutor。每个worker输入一组关键词,返回一组引用摘要。调度器这里要做一个“合并等待”动作,拿到全部结果后才进入下一步写作。这里踩过一个坑:刚开始没有设置“超时时间”,某个检索worker因为外部服务响应慢卡了很久,整条流水线被它拖住。后来在每个worker上设置timeout=30秒,超时就把已返回的部分结果合并,并标记“部分检索缺失”,不阻塞后续流程。
这个改动让整体交付时间缩短了一半,代价是有了信息缺失的可能性。我的红线是:核心事实性内容不允许缺失,如果检索缺失导致关键数据点没采集到,宁可转人工补数据。
4. 常见问题与排查技巧实录
4.1 多智能体消息死循环:怎么发现、怎么打断
死循环是这类型系统最经典的事故现场。症状就是任务卡在某两个Agent之间反复调度,日志刷屏,token哗啦啦地扣,但状态永远没进展。
我遇到比较典型的死循环是写作Agent和审核Agent较劲:审核Agent觉得文章“深度不够,句式太短小”,写作Agent听懂了加了复杂度,结果审核Agent又觉得“太绕了,不够流畅”。一来二去没完没了。
排查方法我用两板斧。第一板斧做循环检测:在调度器里维护一个状态访问计数表,任何一个状态被进入超过N次就直接降级转人工。第二板斧是查消息轨迹:因为消息里有msg_id和sender、receiver字段,可以按链路把Agent之间的“聊天记录”拉出来看,一眼就能看出是哪个环节的on-going指标出了问题。
打断机制再强调一遍:不要试图在业务逻辑上“劝两个Agent和好”,那是很不靠谱的做法。发现循环就该立即把它踢到人类工作台,让标注一下到底哪条质量标准被误判了,后面把质量标准写得再细一些。
4.2 输出格式不稳定:JSON解析失败和缺失字段
让模型稳定输出JSON,这是每个做Agent开发的人都绕不开的坎。就算写了再详细的“你必须输出JSON”的提示词,偶尔还是会遇到胡说八道的情况。
我的常规防御是这么几层:
- 提示词里给出一个具体的JSON模板,用示例值填好,让模型照着填。
- 解析时先去掉Markdown代码块标记,再定位最外层大括号。
- 解析失败后,把报错信息回填给Agent,让它“修正输出”重试一次。这句话很有用,模型看到自己的格式报错后,多半能自己纠正。
- 重试仍然失败,就降级为文本提取,比如用正则抓关键字段,抓不到就标记为“解析异常”,走人工通道。
另外一个观察:缺失字段往往是因为上游产出里就没有这个数据。比如要求“引用来源”字段,但检索Agent在实际检索时没有记录链接,那怎么写都写不出来。后期我在每个Agent的提示词里把“如果某个字段没有真实数据,请输出空字符串,不要编造”这句话加了进去,缺失字段就变成了空值,大大减少幻觉编造。
4.3 任务状态不同步:异常中断怎么恢复现场
真实系统里,进程随时可能被杀掉,外部API随时可能超时,不能在Resume之后从头再来一遍。我做一个轻量级的“检查点恢复”机制,把状态对象定时序列化成JSON,落到磁盘上。
序列化内容包含:当前状态、各环节产物、全局上下文、迭代计数。启动时检测到上一次任务没走到COMPLETED时,可以直接加载检查点,从那个状态继续。有一个格式上要注意的点:轮次计数也要保存,否则恢复后修订轮次重新从零计数,死循环保护等于失效。
做这个功能的动机很朴素——某个不加班的深夜,我跑一个多步骤任务跑到一半,因为手滑重启了程序,结果全部状态蒸发,重跑了一遍还多花了一笔钱。从那以后,不落盘的调度器我都不想碰。
4.4 上下文污染与信息错位
最后一个高频问题:Agent拿到的上下文里混入了不该有的信息,导致回答风格错乱或者事实混用。比如写作Agent本来只需要外部资料,结果把审核Agent过去的评论也当成参考资料写进了文章里面。
这个问题的主要来源是懒省事——统一把全部历史消息塞给所有Agent。装上“按需裁剪上下文”机制之后基本就管住了。裁剪之外,我还会在每轮prompt的最前面醒目标注一段“你现在是X角色,你只能基于下面这些Y资料完成Z任务,其他一切内容不参考”,用这种显式的角色约束来抑制上下文污染。
顺带一提,聊天历史越长,这种污染风险越高。我的经验值是单Agent内保留最近3轮对话就够,多余的历史为了避免“埋雷”直接丢失。真正该长期保留的信息只进入全局共享区,不需要靠聊天记录来承载。
5. 进阶优化:让代理集群更聪明、更省钱
5.1 失败兜底与自动重试策略
Agent调用外部API,超时、限流、返回乱码都是日常。我总结了一套分级重试策略,效果好又不会白白烧钱:
- 网络层的瞬时错误(超时、连接中断),立刻重试1次,间隔2秒,再失败就等30秒重试第2次。
- 模型返回的内容不合法(比如JSON解析失败),带错误信息让模型自己修正重试2次。
- 质量标准没有达到,走修订Agent回退,而不是在同一Agent内无限Loop。
关键细节是每次重试都要换一个新的消息ID,不然日志里全部重叠在一起,后面复盘会很难受。另外,如果同一个Agent连续失败次数超过5次,我直接停掉整条流水线,让人类介入,而不是让它无意义地撞南墙。
5.2 多Agent并行加速与资源抢占
并行不是万能药,它带来的复杂度也需要匹配的处理手段。当检索Agent拆成多个worker并行时,调度器要保持一个并发度上限。我默认设置MAX_CONCURRENT_WORKERS=4,多下来的任务先排队,避免线程爆掉或者外部API被限流打崩。
资源抢占的观察结果是:并行度上去了,单个任务延迟明显下降,但整体的token消耗反而可能上升,因为多个worker可能检索到互相重叠的信息。应对办法是合并去重,让汇总Agent把每个worker丢出来的资料按来源和主题去重后再入库存放。这个合并步骤是不可省的,否则写作Agent拿到的素材大量冗余,反而影响质量。
5.3 成本治理:按角色预算限额
多Agent系统烧钱的速度,不看不知道,一看吓一跳。一篇长文走完完整流水线,如果每个环节都用贵模型且每次触发多轮修订,费用轻松是单Agent调用的好几倍。我后来给每个角色设了一个预算配额:
- 规划Agent和审核Agent,用性价比强的高性能轻量模型,一个重在拆解、一个重在判断,不需要特别强的创作力。
- 写作Agent用更强的模型,毕竟要出正经内容。
- 修订Agent介于两者之间。
除了模型分档,还给整个流程设置总token上限。接近上限时调度器自动把后置环节降级到更省的模型,虽然质量有一丁点下降,但至少不会被账单吓到。账要算明白:质量的核心是流程设计,模型只是执行者,该省的地方就省。
5.4 可观测性:状态流转日志与追踪
最后一个优化方向是把整个系统的运行过程变得可见。我做了三样东西:
- 状态流转日志:每发生一次状态迁移就写一行结构化日志,包含时间、旧状态、新状态、触发Agent、消息ID。
- 产物版本记录:任何Agent产出新结果都存一份历史版本,方便回溯“初稿在哪里被改成什么样”。
- 运行时仪表盘:用简单的Web页面展示当前所有任务的运行状态(排队中、执行中、卡在哪个环节),这个对后续上生产环境帮助特别大。
本质上这就是“可观测性三件套:日志、追踪、指标”在Agent系统里的落地。没有这三样东西,想优化只能靠玄学,有了它们才有持续迭代的底气。
6. 避坑心得与扩展思路
6.1 几条最实用的避坑心得
项目做了这么久,有一些经验是书面文档里不太会写的,但实际比什么都重要。
第一,先把单个Agent的提示词调好,再谈多Agent协作。如果你连单独一个写作Agent都写不好一篇稳定结构的文章,把它丢进多Agent流水线只会放大问题,不会因为“团队合作”自动变好。我的习惯是一个Agent单独上线跑一周,输出稳定了,才让它进编排。
第二,不要迷信“让Agent自己协商”的自动化魔幻主义。自由协商在业务场景里大概率是不稳定的,流程的确定性和角色的明确分工才是业务系统的定海神针。真要灵活,也是在确定性骨架里面给有限分支。
第三,多Agent系统开发要时刻保留人工兜底的逃生口。系统再怎么设计,总有预料之外的情况,一定要有“转人工”的开关。这不是示弱,而是工程素养。
6.2 这套模式还能往哪些方向扩展
做成一套通用机制后,其实能玩的场景很多。我目前想尝试的方向至少有几个,都值得分享。
一个是把普通的文本Agent扩展到“工具调用Agent”,让检索Agent不仅仅检索资料,还能调用搜索API、请求数据库查询、访问内部文档库。给它加上工具列表定义和“调用-返回”循环,整个系统的能力边界会大很多。
另一个是把单条流水线升级成“并行流水线网络”。某些业务一个任务会产生几条互相独立的支线,比如写一份季度汇报,销售数据部分、市场活动部分、财务分析部分可以完全并行。调度器按DAG图并行派发,最后合并汇总,这对吞吐量的提升是量级的。
还有一个方向是把“人机协同”做得更顺滑。比如审核Agent发现问题时,不要只给一个“不通过”的结论,而是生成带批注的问题清单,让作者Agent在修订时能够逐一对照修改。人机协同不是把人类踢出流程,而是让人在AI系统里以更聪明的方式工作。
6.3 最后分享一个冷门但好用的经验
最后说一个不起眼但对体验影响很大的细节:给每个Agent生成的用户指令,第一句话一定要带上它在这个流程中的“定位”,而不是直接甩任务内容。
举例来说,给写作Agent的指令开头是“你是写作Agent,你前面是规划Agent和检索Agent,你后面是审核Agent;你只能输出正文,不要输出任何与正文无关的话”。这句定位词看起来是废话,但实测能显著减少Agent“跑偏”的概率。原因很简单:模型有了明确角色和上下游位置后,才知道自己处在一个流程节点里,不是在跟用户闲聊。这是我试过许多提示词技巧后觉得性价比最高的一招。
agency-agents这套模式的魅力在于,它把“AI做事”从“一个人的单打独斗”变成了“一个机构的专业服务”。背后的思想并不复杂,复杂的是你要真正去拆解业务、定角色、定流程、控成本、兜风险。如果这个项目能帮你在设计自己的多Agent系统时少走几步弯路,那这篇文章的价值也就到了。