【免费下载链接】super-simple-software-factory
Repeatable agents-plus-code workflows, packaged as one skill, stamped into any repo. Deterministic Python owns the graph; coding agents are bounded nodes inside it.
Super Simple Software Factory(简称 SSSF)是一个"可复用的 Agent 加代码工作流工厂",本文聚焦它的两大核心机制——Envelope(信封)和Gate(门禁),讲清楚类型化 JSON 如何让多个 AI Agent 之间的上下文无缝交接,整条流水线既确定性又可观测。读完你会明白:为什么把控制平面从 prompt 挪到 Python 代码里,多 Agent 协作才跑得稳。
为什么 Agent 上下文交接总是"掉链子"?
先看看没有 SSSF 时的窘境:把一个完整开发流程交给一个大模型,你会得到一台"没有接缝"的机器——
- 🕳️ 没有阶段边界,说不出哪一步失败了;
- ❓ 没有可命名的验收标准,"做完"只意味着 Agent 停止说话;
- 💸 重试等于冷启动,Agent 刚才学到的东西全部丢掉;
- 📄 唯一的记录是一长段对话,读起来像写小说。
SSSF 的解法是一句话:代码拥有流程编排、重试与验收,Agent 只负责单个有界阶段内的工作。而信封(Envelope)就是上下文跨越阶段边界时唯一允许走的"门"——Context transfers in code, not in conversation(上下文靠代码传递,而不是靠对话传递)。
信封机制:Agent 只有两个输出通道
在 SSSF 中,每个 Agent 的输出被严格限定为两种,没有第三种:
- 引用文件:写入本次会话的
context_handoff/目录(计划、笔记、产物); - 一条最终的有效 JSON 响应:也就是信封本体,除此之外不带任何内容。
所有信封类型都继承自 data_types.py 中的EnvelopeBase,它只有四个字段:
class EnvelopeBase(BaseModel): status: Literal["success", "fail"] # 唯一必填字段 summary: str = "" # 一句话:发生了什么 artifacts: list[str] = [] # 写出的产物路径 notes_for_next_agent: str = "" # 下一个 Agent 必须知道的事这里有几个精妙的设计点:
status字段是承重墙。JSON 能解析、但status="fail"的信封会直接抛出异常、让阶段失败——Agent 自己声明失败,就不可能是成功阶段。- 信封是"声明清单"而非自由文本。以 BuildOutput 为例,
changed_files声明改了哪些文件、commit_message留给 git 提交阶段消费、notes_for_next_agent写给下游。下一位 Agent 拿到的不是模糊的"上一步大概干了什么",而是结构化的、可核对的事实。 - 同一份合同写在三个地方:
data_types.py里的类型定义、该 Agent 的user.md中## Report段的 JSON 示例、以及调用处的output_type=参数。改一处,必须同一笔提交里改齐三处,否则会白白烧掉纠错轮次。
开箱即用的信封类型一览(定义见 data_types.py):
| 信封类型 | 归属 Agent | 关键字段 |
|---|---|---|
PlanOutput | planner | 计划 + 提交信息 |
BuildOutput | builder | changed_files、commit_message |
ScoutOutput | scout | findings(文件 + 说明) |
ReviewOutput | reviewer | approved、findings、blocking |
DocumentOutput | documenter | document_path、documented_files |
还有一个反直觉的细节:代码块的结果也会被包装成信封(VerifyOutput、ChangesOutput)。测试跑挂了的报错,会以和 Agent 报告完全相同的"门"流回 builder——下游 Agent 根本分不清信封来自模型还是来自代码。这正是"代码拥有流程"的具体体现。
门禁机制:验证声明,从不预测
Agent 说完"我改了这些文件、测试都过了",该信吗?SSSF 的 Gate(门禁)给出的答案是:事后拿事实对账。
一个门禁就是一个函数,签名固定为gate(envelope, run) -> GateReport,每检查一项就调用一次report.check(item, ok, note)。绿色门禁会告诉你它验证了什么,而不只是"通过了"。内置门禁都在 gates.py 中:
| 门禁 | 验证什么 |
|---|---|
artifacts_exist | 声明的产物文件真实存在(附文件大小作证据) |
files_non_empty | 产物不是 0 字节空文件 |
json_parses | 声明的 JSON 产物真的能解析 |
diff_matches_claims | 声明改过的文件确实在磁盘上 |
tests_pass(command) | 指定命令以 exit 0 结束,失败时保留输出尾部 1000 字符作证据 |
verdict_consistent | 评审结论自洽:approved=true却带着 blocking 项?当场驳回 |
注意门禁的哲学边界:它只验证机械上可验证的声明,不评判计划质量或代码品味——那是 reviewer Agent 的工作。门禁的每个失败项会精确地拼成一句"你哪里说错了",直接发回给 Agent(下一节讲它怎么发)。
出错怎么办:同会话纠正,拒绝冷重启
这是信封 + 门禁组合里最省钱的一环。两种失败场景:
- JSON 解析失败:harness 不会重启 Agent,而是在同一个会话里补发一条纠正消息,列明缺失的字段和错误原因,最多重试
JSON_FIX_ATTEMPTS = 2次(见 agents.py); - 门禁返回违规:走完全相同的机制,纠正消息里写明哪条 check 失败、证据是什么,重试次数受阶段
retries约束。
为什么坚持"同会话纠正"?因为冷重启会把产生"差一点就对"的那份上下文全部扔掉——Agent 忘了自己刚才为什么那样写。纠正只花一条消息的成本,上下文窗口完好无损。pi 把--session-id当作 create-or-continue,"运行 Agent"和"继续 Agent"本来就是同一个调用。
每次尝试(包括失败的)都会被持久化为一条 envelope 记录,所以你可以在追溯数据库里看到完整的纠错轨迹,而不是只知道"最终成功了"。
信封落在哪里:会话目录与追溯链路
session.ensure(cfg, adw_id)会为每次运行创建固定目录(布局详见 handoff.md):
adws/adw_data/sessions/{adw_id}/ ├── agent_map.json # Agent → 会话ID + 模型 ├── context_handoff/ # 所有 Agent 共享的交接文件区 └── {agent_name}/ ├── prompts/ # 实际发出的提示词(执行前存档) ├── raw_output.jsonl # Agent 原始输出流,实时追加 └── envelope.json # 最终有效JSON,由代码捕获、校验并持久化信封的生命周期是一条单向链路:Agent 产出 → 代码按声明类型解析 → 落盘envelope.json→ 写入 SQLite 追溯库的envelopes表 → 注入下一个 Agent 的 user prompt(通过 prompts.py 的{{previous_envelope}}占位符替换)。每一步都有据可查,文件是原始记录,数据库是可查询镜像——数据库丢了也丢不了任何无法重建的东西。
上手速查:要改什么,去哪里改
| 需求 | 改哪里 |
|---|---|
| 调整信封字段(加一个必填项) | data_types.py 的对应 Output 类 +user.md的## Report示例 + 调用处output_type=,三处同改 |
| 新增一条验收门禁 | gates.py:写一个report.check(...)循环 + 一个 return |
| 看懂完整的交接契约 | references/handoff.md(信封 schema、双通道规则、会话目录) |
| 理解纠错与重试实现 | agents.py 的JSON_FIX_ATTEMPTS与解析重试 |
| 配置 Agent 花名册 | templates/sssf.config.yaml |
| 查看运行中的信封事件 | 追溯 UI(apps/visualizer/,只读界面) |
总结:Agent 提议,代码拍板
信封与门禁看似只是两个 JSON 类和一个校验函数,它们共同解决的是多 Agent 协作的根本问题——上下文交接不再依赖对话的默契,而是依赖代码的契约:
- 📬 信封让每个阶段的产出变成结构化、可验证、可注入下游的事实;
- 🚪 门禁让"完成"有了机械定义:不是 Agent 说不说了,而是声明与事实对上了;
- 🔁 同会话纠正让失败变得廉价,上下文窗口是最大的资产,绝不轻易丢弃;
- 📈 一切事件实时入 SQLite,第 1000 次运行和第 1 次长一个样。
想进一步动手:把技能目录 .claude/skills/sssf/ 盖进你的仓库,运行一次adw_plan_build之类的短链,然后打开追溯库看看信封是怎么在 Agent 之间流转的——亲眼看一次,胜过读十遍文档。
【免费下载链接】super-simple-software-factory
Repeatable agents-plus-code workflows, packaged as one skill, stamped into any repo. Deterministic Python owns the graph; coding agents are bounded nodes inside it.
相关推荐
Super Simple Software Factory Agent团队详解:5个Agent分工与一份YAML配置全拆解
Super Simple Software Factory Agent团队详解:5个Agent分工与一份YAML配置全拆解 Super Simple Softw
如何快速用浏览器接入 OpenHands Software Agent SDK:TypeScript 客户端完整指南
如何快速用浏览器接入 OpenHands Software Agent SDK:TypeScript 客户端完整指南 OpenHands Software Ag
ACP完整指南:如何实现AI Agent间的无缝通信
ACP完整指南:如何实现AI Agent间的无缝通信 在当今快速发展的AI领域,ACP(Agent Communication Protocol)作为实现AI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考