☰
多智能体编排实践:用角色分工与任务流构建可靠的自动化系统
2026/10/10 4:16:00 网站建设 项目流程

我第一次把“agency-agents”这个项目完整跑通的时候,盯着终端里那些以不同身份输出的一条条记录,还真有点在带团队的感觉。简单说,这个项目就是用一套编排逻辑,把若干个大模型智能体组织在一起,让它们分别扮演策划、撰稿、编辑、质检之类的角色,像一家小型数字内容公司那样分工协作。

单个智能体做不了复杂项目吗?当然不是。但是当你需要在一个项目里反复切换身份、连续处理十几个环节、还要保证最终产出的一致性时,单次对话的体验很快就会崩掉:开头说好的风格到后面忘了、明明应该只做改错的步骤却开始大改结构、不同环节的产出互相矛盾。agency-agents解决的就是这类问题。如果你正在接触大模型自动化、想从“单轮对话”升维到“多角色工作流”,或者手头有大量流程固定的内容生产任务,这篇文章应该能帮你少走不少弯路。

这套系统听起来高大上,实际落地并不复杂。下面我按自己的实操顺序,把设计思路、核心细节、代码实现和踩坑记录都拆开讲。

1. 整体设计思路:为什么“一群人”比“一个超人”更可靠

1.1 单智能体的真正瓶颈:不是能力不足,而是角色混乱

很多人一上来就追求“一个超级智能体干完所有事”,做法是在一条系统提示词里塞上几十条规则:你既是策划,又是文案,还要当编辑,最后自己给自己质检。这种做法在小任务上能跑,一旦任务变长就会出现很典型的问题。

最典型的是“角色漂移”。开头它确实以策划视角思考,但对话进行到第20轮,它已经分不清自己是在修改错别字还是重新定义目标用户。另一个问题是“自我纠错失效”:让同一个智能体写完内容再检查内容,它往往觉得自己写得挺好,因为记忆里全是自己的推理过程,很难跳出立场挑毛病。我试过很多次,这种“自查”环节几乎形同虚设。

更深一层的问题是上下文污染。一个大对话里,前10轮关于选题方向的讨论会一直留在上下文里,干扰后面编辑环节的判断。你以为它在改稿,实际上它脑子里还想着选题会上的争论。这些小毛病单独看不严重,放在一条完整生产链上就是灾难。

所以agency-agents的核心思路很简单:不要做一个全能的超人,而是搭建一支各司其职的队伍。每个智能体只干一件事,上下文只保留和自己相关的部分,彼此通过“任务单”和“产出物”传递信息。队伍里的成员可以复用、替换、独立调优,这正是“机构”这个比喻成立的地方。

1.2 多智能体协作的三种常见组织方式

做这类系统之前,先得搞清楚智能体之间怎么排列组合。我见过的主流方式大致有三种:

流水线式:任务像工厂传送带,A做完交给B,B做完交给C。优点是链路清晰,适合环节固定、顺序明确的任务,比如“调研-写作-配图-发布”。缺点是前面出错会一路传导,后面的人很难纠正前面的思路性错误。

轮转式:所有智能体围着同一个目标反复讨论,你提意见我反驳,几轮之后得出共识。适合头脑风暴、方案评审这类开放性问题,但容易陷入无休止的争论,token消耗也大。

分层指挥式:一个“总指挥”智能体负责拆解任务、分派人手,下属智能体各自执行并汇报结果。优点是任务边界清楚、扩展性好,缺点是总指挥的判断质量会直接影响全局。

agency-agents最终采用的是“分层指挥 + 流水线执行”的复合模式:总指挥先拆任务,拆完之后各个执行智能体按依赖关系依次干活,最后由质检角色统一把关。这种结构既避免了纯流水线无法返工的僵硬,也避免了纯轮转式效率太低的问题。

1.3 项目定位:把智能体当成可复用的“项目成员”

我对这个项目的定位,从一开始就不是“写一个脚本”,而是“搭一套能给所有内容生产项目复用的底座”。这意味着几个隐性需求:角色可以被独立替换、任务清单可以被人为干预、运行过程可以被记录和回放。

在具体实现上,我把每个智能体设计成一个对象,包含角色名、系统提示词、模型标识三个字段。角色和实现逻辑分离之后,你可以让“编辑”角色用更强的模型,让“排版”角色用更便宜的模型,也可以随时给某个角色换一套提示词,而不影响其他成员的代码逻辑。

2. 角色、任务、消息:多智能体系统的三个地基

2.1 角色定义:越具体越好用

给智能体定义角色时,最容易犯的错是写得像职务说明书,比如“你是一名资深编辑,负责保证内容质量”。这种提示词等于什么都没说。我后来总结了一个公式,角色提示词至少要包含四个要素:身份、职责边界、硬性约束、输出格式。

身份决定了它看待任务的立场。职责边界决定了它能做什么、不能做什么。硬性约束是防止它越权的关键,比如“只做错别字和语法检查,不改动文章结构”这句话比“请认真检查”有效一百倍。输出格式则保证系统能稳定解析结果。

我在一个模拟内容工坊项目里,给“总指挥”写的提示词大致是:你是一个项目统筹,只能根据项目简报输出任务清单,每个任务必须包含任务编号、负责角色、任务说明、依赖关系和验收标准,严禁自己执行具体内容创作。外加一句“如果简报信息不足,先输出你需要的补充问题,不要编造需求”。加了这一句之后,任务拆解的质量明显提升,因为模型不再硬着头皮生成一个看起来完整但其实空泛的清单。

2.2 任务拆解:用结构化任务单替代口头嘱咐

智能体之间传递信息,最忌讳用自然语言长篇大论。我要求总指挥每次拆解任务都必须输出一个固定的JSON结构,字段包括task_id、assignee、content、depends_on、accept_criteria。一开始很多人觉得这么麻烦没必要,但跑到后面就会感谢这个决定。

有了结构化的任务单,编排器就能做三件事:检查字段是否齐全、按依赖关系排序、把前序任务的产出作为上下文注入后续任务。没有这套结构,你想在后端做流程控制就只能靠正则匹配自然语言,那才是真的噩梦。

任务单里的“验收标准”经常被忽略,但它恰恰是质检环节的重要依据。没有验收标准,质检智能体只能凭感觉说“看起来不错”;有了“必须包含三个论点”“字数不少于800”“禁止出现第一人称”这类可验证的条件,质检就从主观判断变成了清单核对。

2.3 消息与上下文协议:防止“两个人各说各话”

多智能体系统常见的失败方式之一,是上下文失控。给一个执行角色塞太多别人的产出,它就会分心;什么都不给它,它又没法干活。我的做法是设计了三级上下文:项目简报、任务相关产出、私有草稿。

项目简报是每个角色都能看到的,相当于公司的公共公告栏,里面只有项目背景、目标受众、交付要求这几项固定信息。任务相关产出是执行当前任务必需的前序结果,比如写作者需要看到策划结构,但不需要看到另一个写作者没完成的半成品。私有草稿则是各角色自己工作区里的内容,绝不跨角色传递。

这样隔离后,每个智能体每次调用时看到的上下文都很聚焦。我做过对比实验,同一篇文案,用全量上下文让编辑修改,和只给它“定稿正文 + 修改要求”两种方式,后者在改动准确度上明显更高,而且token消耗少一半以上。

2.4 反馈与质检:让系统拥有最后一道防线

多智能体系统最怕什么?怕所有角色都一本正经地胡诌,且没有一道关卡能拦住。所以我在系统里单独设置了一个“质检员”角色,它不参与任何创作,只做两件事:根据验收标准逐条核查任务产出,决定“通过”或“打回修改”。

质检员和创作者分开还有一个好处,就是提示词里可以写得非常苛刻:“你只负责挑毛病,任何一处违背验收标准的地方都要明确指出来,不允许给整体评价。”这样它的注意力就被强行扭到“找茬”上,不会说一堆“整体质量不错”之类的废话。

当然,质检打回之后不能让它无限返工。我会设置最大返工次数,达到上限就直接输出当前版本,让人工接手。这个兜底机制很重要,否则系统可能在某个环节死循环,白白烧token。

3. 从零实现一个轻量级多智能体编排器

3.1 目录结构和基础定义

我建议把系统拆成四个模块:agent定义、任务卡片定义、编排器、工具函数。目录结构大概是这样:

agency-agents/ ├── agents.py # 智能体数据类 ├── tasks.py # 任务卡片数据类 ├── agency.py # 编排器主逻辑 ├── prompts/ │ ├── director.txt │ ├── writer.txt │ ├── editor.txt │ └── qa.txt └── run_demo.py # 示例入口

这可能看起来简单,但我有意保持这种轻量结构。很多同类项目一上来就上重型框架,结果小团队根本维护不动。先用百来行代码把流程跑通,再考虑引入外部编排工具也不迟。

先看智能体数据类的定义:

# agents.py from dataclasses import dataclass @dataclass class Agent: role: str # 角色名,例如 director / writer / editor system_prompt: str # 系统提示词,从prompts目录读入 model: str = "default" # 实际使用时填模型标识 def run(self, user_prompt: str, context: str = "") -> str: # 真实项目中,在这里发起大模型API调用 # 传入 system_prompt + context + user_prompt # 这里先用占位实现,后面会替换成真实调用 return f"[{self.role} 模拟输出] 收到任务: {user_prompt[:30]}"

任务卡片定义:

# tasks.py from dataclasses import dataclass, field @dataclass class TaskCard: task_id: str assignee: str content: str accept_criteria: str = "" depends_on: list = field(default_factory=list) def to_dict(self): return { "task_id": self.task_id, "assignee": self.assignee, "content": self.content, "accept_criteria": self.accept_criteria, "depends_on": self.depends_on, }

3.2 编排器核心逻辑:任务解析、依赖注入、结果汇聚

编排器是整个系统的骨架,它得做三件事:调用总指挥拆解任务、按照依赖顺序调度执行角色、汇总所有产出并交给质检。

核心代码大致如下:

# agency.py import json from agents import Agent from tasks import TaskCard class Agency: def __init__(self): self.agents = {} def register(self, agent: Agent): self.agents[agent.role] = agent def _parse_task_list(self, raw_text: str): # 用一段容错逻辑把模型输出的JSON解析成任务卡片列表 # 具体容错见第4节 data = json.loads(raw_text) return [TaskCard(**item) for item in data] def run_project(self, brief: str): director = self.agents["director"] raw_tasks = director.run( user_prompt=f"根据以下简报输出任务清单:\n{brief}", context="你是项目统筹,只负责拆任务。" ) task_cards = self._parse_task_list(raw_tasks) results = {} # 按依赖关系执行,这里先用简单循环 for card in task_cards: if card.depends_on: deps = {k: results[k] for k in card.depends_on if k in results} context = json.dumps(deps, ensure_ascii=False) else: context = "" executor = self.agents[card.assignee] result = executor.run( user_prompt=card.content, context=context ) results[card.task_id] = result # 质检汇总 qa = self.agents["qa"] final_report = qa.run( user_prompt=json.dumps(results, ensure_ascii=False), context="请逐条核对验收标准并给出修改意见。" ) return final_report

这段代码当然还不是生产级,但它把核心循环完整表达出来了:任务清单驱动、结果按任务ID存放、上下文按依赖注入。实际接大模型的时候,你只需要在Agent.run里替换成真实的API调用即可。

3.3 接上真实大模型API后的注意事项

换成真实模型调用后,有几个细节会立刻浮出水面。

第一个是“总指挥输出不是合法JSON”。模型偶尔会在JSON外面包一层Markdown代码块,或者在里面加注释。可以在解析函数里加一个清理函数,用正则先把代码块标记和多余字符剥掉,再交给json.loads。实在解析失败,就让总指挥重试一次。

第二个是“并发执行”。后续任务如果依赖同一个前序结果,就没有并发空间;但同一层级的任务可以并行跑,节省整体耗时。我建议先用同步循环把正确性跑通,再考虑并发加速,千万不要一上来就上并发,否则调试时根本分不清是谁的问题。

第三个是“重试机制”。API调用有偶发超时,角色输出偶尔也会中断,最好在Agent.run里封装一个简单的重试逻辑,比如连续失败三次才抛出异常。这样系统不会因为一次网络抖动就整体挂掉。

接好真实模型之后,我习惯跑一个最小示例验证链路:简报是一句话“写一篇介绍家庭绿植养护的公众号文章”,预期结果是总指挥输出5个任务,执行角色依次完成,质检员给出验收结论。

3.4 加一个“人工审批”节点控制风险

完全自动化的多智能体系统在真实业务里很危险,因为大模型的输出总有概率性错误。我后来在关键节点加了一个“人工审批”开关,比如在最终质检报告出来后、对外发布前,强制要求人工确认。

实现方式不复杂:在任务卡片里加一个pending_human_review字段,或者干脆在编排器循环里检查指定任务ID。如果该任务启用了人工审批,就先把产出写到本地文件,打印提示,等人工输一个“approve”或者“deny”再继续。这一步操作成本极低,但能拦住大量低级错误,尤其是内容方向性错误。做自动化内容生产的人应该都有体会,错误发现得越晚,修正成本越高。

4. 常见问题与排查技巧实录

4.1 任务清单解析失败,程序直接崩掉

这是新手最容易遇到的问题。总指挥返回的内容里有个别字段格式不对,整个JSON解析就报错,系统停摆。我建议不要试图写一个万能解析器,而是采用“清理两次、重试一次”的简单策略:第一次清理掉代码块和首尾多余的标点,第二次如果仍然失败,就把报错信息回传给总指挥,让它自己修正。

给模型的提示词里也可以主动强调“只输出JSON数组,不要任何解释文字”。大多数人不知道,模型对输出格式的遵守程度和提示词的明确程度直接相关。你越是说“必须”“严格”“只输出”,它越听话。

4.2 token消耗爆炸,成本压不住

多智能体系统最大的隐藏成本来自上下文重复传递。如果每个执行角色都携带完整的项目历史,十个角色就能把上下文费用放大十倍。我的应对策略是“能用摘要就不用全文”。

具体做法是:在上下文注入之前,用一个摘要智能体(甚至可以继续用同一个模型,只是提示词不同)把前序任务的长输出压缩成三到五条要点,再注入给下一个执行角色。做了一次实测,在一个十环节的生成任务里,这个策略把总token消耗降了差不多六成,而且最终产出质量没有明显下降。

4.3 代理之间互相推翻、来回拉扯

当质检角色连续打回创作者的结果时,系统就会陷入“写-改-写-改”死循环。我也犯过这个错误,最初的实现里没有最大迭代次数上限,有一次任务跑了二十多轮还没有收敛,烧掉大量token之后才发现问题。

后来我在质检环节加了一个全局阀门:每个任务的返工次数最多3次,超过就直接放行并标记为“需人工确认”。这一步不是为了追求完美,而是为了保住系统的终点意识。自动系统最怕的不是输出不够好,而是永远没有输出。

4.4 输出内容“串味”,角色语气互相污染

有时候创作者会模仿上下文中其他角色的语气,比如写作者看了策划的结构,写着写着就操心起选题角度;编辑改稿时又忍不住重新定义目标受众。这本质上是角色边界没有贯彻到底。

我在系统提示词里专门加了一条“禁止讨论和修改其他角色的职责范围”。同时,上下文注入时严格只给“必要信息”,它的作用很明显:编辑的上下文里只有成品正文、修改要求和验收标准,没有策划方案和原始调研资料,它自然就不会越权。

4.5 模型选型与成本分层

不是所有角色都需要用同一档次的模型。总指挥、质检员这种统筹和把关角色,对推理能力要求高,可以用能力强一点的模型;写作者、排版员这种执行角色,用普通模型就能完成任务。

我自己常用的分层是:总指挥和质检员用最强档,执行角色用中档,需要大量重复劳动的格式化任务用最便宜的档位。这套分层跑下来,整个系统的成本大概能再降两成,同时核心环节质量没有受损。模型API价格是随时间波动的,建议在系统里把模型字段做成配置项,而不是写死在代码里。

5. 应用场景与扩展方向

content不是一个只能做文本的系统。agency-agents的架构把“角色”抽象成节点之后,可以套进不少真实场景。

内容工坊是最直白的应用:总指挥拆题、研究员查资料、写手成稿、编辑润色、质检把关,一整条内容生产链全部自动推进。另一个好用的场景是数据报告生成:数据员处理原始数据、分析师提炼结论、文案撰写报告、美工生成配图提示词,最后汇总为一份完整报告。

往复杂了说,这套模式也能用在多语言本地化、竞品分析、活动策划拆解这类任务上。关键不是智能体本身有多聪明,而是你定义的角色边界和消息协议是否清晰。

我最后想分享一个个人习惯:把每个角色的系统提示词放在单独文件里,用版本管理工具记录每一次改动。跑一段时间你会发现,真正需要频繁调整的不是代码,而是提示词。改一句“你可以质疑任务”和改一句“你无权质疑任务”,对系统行为的影响可能比重构一遍代码还要大。有了版本记录,才能放心大胆地试,因为改坏了随时能回退。

agency-agents这样的项目,本质上是给大模型套上一层“组织纪律”。模型本身依然是那个模型,但当你用结构化的角色、任务和消息协议约束它时,它会表现得像一个靠谱的团队成员,而不是一个时灵时不灵的聊天窗口。这一点,是我在这个项目里最大的收获。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询