很多人看到 HumanLayer 发布的这期软件工厂设计模式播客,第一反应可能是:设计模式不是早就聊烂了吗,软件工厂又是什么新概念?我个人的理解是,这期内容并没有停留在传统设计模式那套“类怎么组织”的讨论上,而是把“工厂”这个隐喻放进了 AI Agent 协作场景里。你真正要处理的不是某个类该怎么写,而是一组 Agent 怎么分工、怎么传料、怎么避免互相干扰、怎么在单个环节出错时不拖垮整条产线。这个问题如果只靠直觉去搭,很容易搭出一个“看着能跑、一加批量就崩”的系统。
先给结论:软件工厂设计模式最适配的场景是多个智能体协同完成一条任务流水线,典型任务包括批量内容生产、代码自动修复、数据分析、客服工单处理。它的核心价值不取决于某一个 Agent 有多聪明,而是整个流程的稳定性、可追溯性和失败兜底能够被预先设计出来。下面按“概念澄清、协作模式、环境准备、参数标准、排查链路、落地建议”的顺序拆一遍,尽量让读完的人能照着搭一个最小可运行的工厂式 Agent 系统。
1. 先分清:软件工厂设计模式和传统设计模式不是一回事
传统设计模式里的 Factory Pattern,解决的是“创建对象”的问题;Singleton 解决对象唯一性,Observer 解决通知解耦,策略模式解决算法替换。它们的粒度在类和方法这一层,讨论的是开发者写代码时怎么组织结构。
软件工厂设计模式把粒度上升到了“任务流水线”这一层。工厂隐喻里几个关键部件,在 Agent 系统里都有对应:
- 流水线:对应任务的阶段拆分。内容生产可以拆成选题、写作、校对、排版四个阶段。
- 工位:对应每个 Agent 的角色。一个工位只做一件事,只拿到自己需要的输入。
- 制品:对应阶段之间的产物。选题阶段的输出是选题卡,写作阶段的输入就是这张选题卡。
- 质检:对应阶段结束时的检查点。格式、内容完整性、关键词密度、引用来源,都能做成质检规则。
- 线长:对应调度者或 Orchestrator。它不亲自干活,但负责分配任务、收回结果、决定是否返工。
1.1 传统模式解决代码结构,工厂模式解决任务编排
传统设计模式解决的是“代码怎么写才不容易烂”,软件工厂设计模式解决的是“任务怎么编排、制品怎么流转、失败怎么兜底”。这两者的关注点完全不同。
打个比方。传统工厂模式是帮你把“创建一个 Excel 报告对象”的代码封装好;软件工厂设计模式则是帮你回答:哪个 Agent 负责采集数据,哪个 Agent 负责生成图表,哪个 Agent 负责写结论,图表生成失败时是整体重跑还是只重跑图表工位。
这两层的最大差别在于:前者是人写代码,代码出错有堆栈,你可以单步调试;后者是 Agent 干活,Agent 的输出天然带有不确定性和格式漂移。你不能靠堆栈快速定位“为什么这一步的 Markdown 表格突然变成了普通文本”,只能靠输入输出契约、任务日志和制品快照来排查。所以软件工厂设计模式里,第一优先级不是模型多强,而是 流程可观测 。
1.2 为什么“工厂”比喻能讲清楚多 Agent 协作
多 Agent 协同最常见的失败方式不是单个 Agent 能力不够,而是角色边界模糊、产物格式不统一、返工没有规则。工厂比喻的价值在于,它逼着你把这些问题显性化:
- 产线有几道工位,每道工位是谁,任务书长什么样。
- 上一道工位交出来的制品,下一道工位必须能直接消费。
- 质检不合格的制品,是退回上一工位返工,还是直接打回重来。
- 整条产线什么时候算完工,验收标准是什么。
这些在单 Agent 场景里基本不需要考虑,一旦把 Agent 数量升到三个以上,就变成每天都会撞上的问题。关于多 Agent 系统设计的讨论里反复出现的一个观点我很认同:多 Agent 系统的复杂度主要不在模型调用,而在编排层。你把编排层当软件工程来做,问题就能被拆解、测试、改进;你把它当“多开几个对话窗口”来做,最后只会得到一堆不可复现的手工操作。
2. 这期内容值得拆解的三种 Agent 协作模式
从公开讨论和最近的智能体设计趋势来看,软件工厂设计模式里有三种协作模式出现频率最高:主从模式、Subagent 作为 Tool 调用模式、流水线模式。这三种不是互斥关系,实际项目里经常混用。
2.1 主从模式:一个调度者,多个执行者
主从模式也叫 Orchestrator-Worker。核心结构是一个调度者负责拆解任务、分配任务、汇总结果,多个执行者只负责执行自己分到的子任务并返回结果。
这个模式适合任务层级清晰、子任务可以并行处理的场景。比如市场调研:主 Agent 先拆出“竞品信息”“用户评价”“定价策略”三个子任务,分配给三个 Worker 并行执行,最后主 Agent 汇总输出报告。
落地时要注意几个点:
- 主 Agent 不要自己做具体工作,它的职责是分配和汇总。一旦主 Agent 开始写具体内容,就容易出现任务和产出错位。
- Worker 之间不要直接通信,所有信息通过结果返给主 Agent 流转。否则协作关系会变成网状,日志和排查都会失控。
- 主 Agent 要约束 Worker 的输出格式,最好要求返回结构化结果,而不是自由文本。
2.2 把 Subagent 当 Tool 调用:接口化而不是聊天式协作
最近智能体设计讨论里有个说法很精辟:本质上可以把 Subagent 视作一种另类的 Tool 进行调用。这个视角我觉得价值很大。
传统上 Tool 是函数,输入 JSON,输出 JSON,有超时,有异常,有重试。如果你把 Subagent 也当成一个“由大语言模型驱动的 Tool”,设计逻辑就变得清楚了:每个 Subagent 必须声明输入参数、输出格式、超时时间、失败时的行为。它不需要像聊天伙伴一样“理解”你的完整意图,只需要像函数一样接收任务书、返回结果。
这种模式的好处是大幅降低系统耦合度。主流程不关心 Subagent 内部用了什么提示词、哪个模型,只关心它的输入输出契约是否满足。伪代码示意:
def call_subagent(task_spec: dict) -> dict:
"""
把 subagent 当作一个函数调用:
入参是有明确结构的任务书,返回值是有明确结构的制品。
"""
# 1. 校验入参
validate(task_spec, schema="task_v1")
# 2. 调用 subagent,设置超时和重试
result = run_with_retry(task_spec, timeout=60, retries=2)
# 3. 校验返回值格式,不满足直接抛出
validate(result, schema="artifact_v1")
return result
上面这段不是某个项目的正式代码,只是表达“接口化”这个设计思路。关键点在于:调用 Subagent 之前校验入参,返回之后校验出参,中间设置超时和重试。这样 Subagent 内部崩溃也好、输出漂移也好,都不会静默污染下游。
2.3 流水线模式:前一个工位的输出是后一个工位的输入
流水线模式是最符合“工厂”直觉的模式。任务被拆成固定顺序的多个阶段,每个阶段由一个或一组 Agent 完成,前一阶段的输出制品直接成为后一阶段的输入。
比如一个典型的内容生产流水线:
- 选题工位:产出选题卡(标题方向、目标读者、核心论点、参考资料清单)。
- 写作工位:根据选题卡产出初稿。
- 校对工位:检查事实错误、格式问题、版权风险,输出修订建议或修订稿。
- 排版工位:把定稿转换为目标平台格式。
流水线模式的关键是 制品规范 。每个阶段输出的制品必须有稳定的 schema,比如选题卡必须包含标题、目标读者、核心论点这三个字段。如果某个阶段输出缺字段,下游必须能立刻发现,而不是进入让大模型“尽量理解一下”的模式。
三种模式各有适用场景,我整理了一个粗略对比:
| 模式 | 适合场景 | 核心优点 | 主要风险 |
|---|---|---|---|
| 主从模式 | 任务可拆解、子任务可并行 | 并行度高,调度清晰 | 主 Agent 容易成为瓶颈,汇总可能遗漏 |
| Subagent 即 Tool | 子系统边界清晰、需要接口化 | 耦合低,可测试,可替换 | 需要严格定义契约,前期成本高 |
| 流水线模式 | 阶段强依赖、顺序固定的任务 | 流程稳定,制品可追溯 | 单个阶段失败会阻塞整条产线 |
实际项目很少只用一种。常见做法是:外层用主从模式拆任务,中间某几个子任务内部再套流水线,个别能力复用度高的小任务直接按 Tool 方式调用。
3. 从零搭一个最小软件工厂:环境、规格与审批
这一节进入实操。先说明:下面给的是通用做法,不绑定具体厂商或框架。你用什么模型、什么编排框架,结论都适用。
3.1 环境与依赖
搭建最小系统,通常需要这几类东西:
- 编程环境:Python 3.10 或更高版本就可以,Windows、macOS、Linux 都行。
- 大模型接口:需要一个能通过 API 调用的大模型,配置好 API Key 和基础调用地址。
- 编排框架:可以用市场常见的 Agent 编排框架,也可以不用框架,直接自己写编排逻辑。第一版尽量用框架,因为状态管理、断点续跑这些功能自己写很容易漏。
- 存储:至少需要一个目录或一个轻量数据库,用来放任务状态、制品和日志。文件目录在早期够用。
必须提醒的是:原始材料没有给明确版本,落地时先确认你自己的运行环境里相关依赖版本是兼容的,尤其是 Python 版本和框架版本的组合。
3.2 任务规格书:比代码更重要的输入
工厂式系统里,Agent 之间传递的不是“自然语言段落”,而是有结构的任务规格书。下面是一个简化示例:
{
"task_id": "article-20250101-001",
"workflow": "content_factory_v1",
"current_station": "writer",
"input_artifact": {
"type": "topic_card",
"title": "软件工厂设计模式入门",
"target_audience": "具备基础编程经验的开发者",
"core_points": ["多智能体编排", "主从模式", "流水线模式"],
"reference_links": ["官方文档", "内部知识库"]
},
"output_schema": {
"type": "draft_article",
"required_fields": ["title", "sections", "word_count"]
},
"quality_gate": {
"min_words": 3000,
"must_include": ["主从模式"]
}
}
这个 JSON 的作用是让每个工位都知道:我当前在哪个环节、我要消费什么输入、我要产出什么结构、我的质检要求是什么。比提示词里写一大堆“你要写一篇高质量文章”有用得多。
我一般建议先做小事:选一个真实任务,手工写好任务规格书,再让 Agent 跑。跑通之后再考虑要不要加字段、加质检规则。任务规格书要稳定,不要每个任务临时改 schema。
3.3 人工审批环节怎么嵌入
人机协作类产品的核心能力之一是“人在回路”,也就是在 Agent 执行关键动作之前插入人工审批。这在软件工厂里就是一个质检工位:Agent 完成某个高风险动作前,先生成审批请求,等待人确认后才继续。
实际嵌入方式有两种:
- 阻塞式审批:Agent 执行到审批点就停下来,等人工批准或拒绝后才继续。适合高成本、高风险动作,比如向外部发送邮件、执行数据库写操作、支付相关操作。
- 异步审批:Agent 先继续推进不影响的环节,审批结果回来后再合并。适合耗时较长但风险不高的环节。
第一版建议全部用阻塞式审批。原因很简单:异步审批要处理的状态更多,一旦你处理不好“审批没回来但 Agent 已经跑到下一步”的状态,就会产出一堆半成品。先把审批链路跑稳,再考虑优化等待时间。
4. 关键参数和判断标准:不要只盯着“能不能跑”
很多人在搭完多 Agent 系统后只关心“能不能跑通”。能不能跑通当然重要,但它只是最基础的一条。真正决定这个系统能不能长期用的,是下面这些参数和判断标准。
4.1 调度参数
主从模式和流水线模式都要关注调度参数。下表是几个通用参数:
| 参数 | 含义 | 新手建议 | 生产建议 |
|---|---|---|---|
| 并发数 | 同时执行子任务的数量 | 1 到 2,先验证稳定性 | 按任务类型和模型限流逐步上调 |
| 超时时间 | 单个子任务最长执行时间 | 60 到 120 秒 | 按实际任务历史耗时设置,留 2 倍余量 |
| 重试次数 | 子任务失败后自动重试次数 | 1 到 2 | 3 次以内,重试前要检查失败原因 |
| 最大返工次数 | 质检不合格时退回重做的上限 | 1 | 2,超过上限应该转人工处理 |
这里有一个容易忽视的点:重试次数不是越大越好。如果失败原因是“模型输出格式不合法”,直接重试大概率还会失败,因为触发条件没变。更合理的做法是先记录失败样本,检查输出格式校验逻辑是否有问题,再决定要不要重试。
4.2 主从模式下角色边界怎么约束
主从模式最常见的翻车现场是:两个 Worker 的职责边界模糊,导致同一个信息被多个 Agent 反复处理,最终汇总时内容冲突。
约束角色边界的方式有两个层面:
- 系统提示词层面:每个 Agent 的系统提示词必须明确“你只负责 X,不要做 Y”,并且不要共享同一个提示词模板。很多人图省事,给所有 Worker 用同一套提示词,只改角色名,这恰恰是角色混乱的根源。
- 数据结构层面:任务规格书里明确给出每个 Worker 只能读哪些字段、只能写哪些字段。没有写权限的字段,在处理阶段直接过滤掉。
数据结构层面的约束比提示词可靠得多。提示词可以绕过,表格结构更容易被遵守。所以我在实际项目里更依赖数据层面的权限控制。
4.3 批量任务要看什么指标
能跑通一条任务,不代表能跑通一百条。批量任务至少要盯这四个指标:
- 成功率:完成且通过质检的任务数占总任务数的比例。第一次跑如果低于 70%,不要急着加并发,先查原因。
- 吞吐:单位时间完成的任务数。它由单任务耗时和并发数共同决定,只调并发不一定线性提升。
- 产出一致性:同类任务的输出格式是否稳定,字段是否齐全。不稳定说明 schema 校验或提示词还有问题。
- 人工介入率:需要人工审批或人工修复的任务比例。这个比例过高,说明自动化流程还不成熟。
我一般会先用 5 条小样本任务验证流程,再扩到 20 条,最后才上完整批量。不要一上来就跑全量。小样本能让你更快发现格式、命名、存储这类基础问题。
5. 常见问题排查链路:卡住、乱输出、批量失败
多 Agent 系统的错误,很多时候不是“代码崩溃”式的,而是“看起来正常运行但结果不对”。下面给一套我自己常用的排查顺序。
5.1 任务卡住先看队列、审批和接口限流
现象是任务跑着跑着就不动了,日志也没有明显报错。这时候按顺序检查:
- 先看任务是否在等待人工审批。很多卡住其实是审批没通过,人工不知道有审批请求。
- 再看队列状态。如果某个 Worker 还在跑,主 Agent 又在等它的结果,就是正常的等待,不是卡死。
- 再看接口调用是否被限流。模型接口在并发升高时会返回限流状态,如果重试逻辑没写好,任务就会一直处于等待中。
- 最后看是否存在死循环。比如返工次数判断条件写错,导致同一个子任务被无限次退回重做。
排查时先看两个东西:任务状态表和各阶段耗时日志。没有状态和日志,所有排查都只能靠猜。
5.2 输出混乱先看输入契约和提示词边界
现象是任务跑完了,但输出缺字段、格式不对、内容张冠李戴。这类问题别急着去调模型的参数,先检查两件事:
- 输入给 Agent 的任务规格书是否完整。字段缺失、JSON 被截断、Markdown 格式污染,都会导致 Agent 输出混乱。
- 每个 Agent 的提示词是否严格限制了输出范围。如果同一个 Agent 既负责写作又负责校对,很可能产出既不是初稿也不是修订稿的混杂物。
我的经验是:先检查“Agent 拿到的输入是什么”,再检查“Agent 被要求输出什么”。这两个检查好了,剩下再怀疑模型能力。十次里有七次,问题出在输入或格式契约上,而不是模型不行。
5.3 批量任务失败先看制品传递和输出命名
批量任务失败的典型场景是:跑第 30 条时突然报错,前面 29 条都正常。这种问题往往和单条数据本身有关,比如某条输入里包含特殊字符、超长文本、空字段。
排查顺序:
- 定位失败任务 ID,找到它的输入制品和输出目录。
- 对比失败任务和成功任务的输入差异,重点看长度、编码、特殊字符。
- 检查输出文件命名是否冲突。多个任务并发写入同一个文件名,会导致文件被覆盖,看起来像丢数据。
- 检查是否设置了断点续跑。批量任务中断后,要从上次完成的位置继续,而不是从头重跑,更不是无脑跳过失败任务。
批量场景下,我强烈建议给每个任务单独建目录,目录名用任务 ID,任务内部的所有制品、日志、中间结果都放在这个目录里。这样排查任何一条失败任务,都能快速找到现场,而不是在几十个文件里翻找。
6. 落地建议:先跑通最小工厂,再谈扩展
最后聊几点我自己的落地建议。如果你正准备按软件工厂设计模式搭一套多 Agent 系统,下面这些边界可以先记在心里。
6.1 从单条任务到批量,分三步走
第一步,手工调用一个 Agent,确认它的输入输出契约能正常工作。第二步,把两三个 Agent 接到流水线里,跑通一条完整任务,重点看制品流转和质检逻辑。第三步,再加批量调度、并发、重试和人工审批。
每一步都要留下日志和样例。不要一步到位。我见过很多项目一次把所有 Agent 都接好,结果出错时根本不知道问题出在哪一环。
6.2 低配置环境也能试,但要降低规模预期
如果你的机器是普通办公电脑,没有高性能显卡,也能跑这类系统,但要注意:本地大模型推理在资源受限时,单任务耗时和稳定性都会变差。建议用云端模型接口完成第一版验证,本地模型放在后续做优化时再试。
如果你的场景是学习,用默认配置跑通最小示例就够了;如果是要长期生产使用,就要把任务队列、日志、输出目录、失败重试、人工审批这些基础设施提前整理好。这两件事难度差很多,别用学习的标准去衡量生产场景。
6.3 真正该长期盯住的事情
把这套系统跑起来之后,我建议每周复盘几个数字:批量任务成功率、平均单任务耗时、人工介入率、失败任务的失败原因分布。这些数字比“某个模型又有了新版本”更能反映你的编排层到底健康不健康。
踩过几次坑之后我的体会是:很多问题看起来像模型能力不够,实际是编排层没把输入输出契约、角色边界、失败兜底设计好。软件工厂设计模式提供的就是这么一套“把 Agent 协作当工业流程管理”的思路。先跑通最小工厂,再谈扩大产能,这条路径比一上来就追求大而全要稳得多。
170




被折叠的 条评论
为什么被折叠?



