Skip to content

第 14 章 · Secondmate:持久第二副手与隔离章程

本章目标:理解 secondmate(第二副手)的定位与隔离模型,学会用 config/secondmate-harness 配置其启动方式,并掌握"secondmate 不孵化 secondmate"这条关键边界。

14.1 为什么需要第二副手

随着舰队规模扩大,一个常见问题浮现:所有 crewmate 都从主 home 派出,任务类型一多,主 firstmate 的监督面就越来越宽——前端修复、后端审计、文档巡检混在同一个 backlog 和同一套 state 里。

FirstMate 的解法不是引入新架构,而是复制现有架构

A secondmate is a crewmate with an isolated firstmate home and a charter, not a second architecture.

也就是说,secondmate 本质上仍然是一个 ordinary direct report(普通直接下属)——它和普通 crewmate 一样接受主 firstmate 的路由与监督;区别在于它运行在一个隔离的、持久的 firstmate home 里,并携带一份 charter(章程)界定自己的职责域。

这种设计的收益:

  • 职责域划分:每个 secondmate 只接自己章程范围内的工作,路由按工作性质而非克隆清单进行;
  • 状态隔离:各自的 backlog、state、projects 互不干扰;
  • 可长期存在:secondmate 是持久实体,空闲队列是健康态,不需要时也不必销毁。

14.2 隔离的 FM_HOME:每个 secondmate 一个家

AGENTS.md 对此有一条明确约定:

Each secondmate has a persistent isolated FM_HOME, including its own state, backlog, projects, and session lock.

回顾第 5 章的布局知识:FM_HOME 选定一个实例私有的 data/state/config/projects/。对 secondmate 而言,这意味着:

text
主 home(PRIMARY)
├── FM_HOME=~/firstmate-home-main
│   ├── data/backlog.md          # 主 backlog:只记工作项
│   ├── data/secondmates.md      # secondmate 路由表
│   ├── state/                   # 主 home 运行记录
│   └── projects/                # 主 home 的项目克隆
└── 注册的 secondmate
    └── FM_HOME=~/firstmate-home-infra   # 完全独立的第二个家
        ├── data/backlog.md      # 自己的积压队列
        ├── state/               # 自己的运行记录 + session lock
        ├── config/              # 自己的本地运营配置
        └── projects/            # 在自己家里克隆的项目

几个关键点值得展开:

  1. session lock 独立:每个 home 有自己的会话锁,两个 home 的引导流程互不竞争;
  2. backlog 分账:路由给 secondmate 的工作记在该 secondmate home 自己的 backlog 里,而不是主 backlog;
  3. projects 各自克隆:secondmate home 需要哪些项目就在自己家克隆,主 home 的 projects/ 对它是不可见的。

data/secondmates.md 是主 home 维护的 local and remote secondmate routing table(本地与远程 secondmate 路由表),由 secondmate seed 辅助脚本维护,记录每个已注册 secondmate 的位置信息。

14.3 charter 章程:职责域的书面边界

每个 secondmate 携带一份 charter brief。在 data/ 布局中可以看到它的存放形式:

text
data/
├── <id>/brief.md    # per-task crewmate brief,
│                    # 或 kind=secondmate 时的 per-secondmate charter brief

charter 回答的问题是:"这个 secondmate 负责哪一类工作?" 主 firstmate 路由时遵循的规则是:

Route by the nature of the work against each registered secondmate scope.

即按工作的性质对照各 secondmate 的注册范围来路由,而不是看某个仓库恰好登记在谁名下。若没有合适的 secondmate 范围能承接某项工作,就用主 home 处理,或者讨论创建一个新的 secondmate。

另外两条路由纪律值得记住:

  • 范围匹配的工作默认发给对应的 secondmate,除非它被阻塞或 captain 明确改道;
  • 不要去翻 secondmate 的聊天窗口——标记路由的回复会通过 status 或文档指针返回。

14.4 启动配置:config/secondmate-harness

主 home 用 config/secondmate-harness 指定用哪个 harness 启动 secondmate agent:

sh
# config/secondmate-harness(LOCAL, gitignored)
# 格式:<harness> [<model>] [<effort>],三段写在同一行

# 例:用 Claude Code 启动 secondmate
claude

# 例:指定模型与 effort
pi sonnet medium

回落顺序是本章的重点记忆点:

text
config/secondmate-harness 存在且有效?
 ├─ 是 → 用它启动 SECONDMATE
 └─ 否(缺失或值为 default)
      └─ 回落到 config/crew-harness
           └─ 再回落到 firstmate 自己正在用的 harness

注意它与 config/crew-harness 的分工:

文件控制对象继承行为
config/crew-harness本 home 派出的 crewmate作为字面文件被继承:具体的 primary adapter 值也会控制 secondmate home 自己的 crewmate
config/crew-dispatch.json每任务的 harness/model/effort 选择规则Inherited by secondmate homes
config/secondmate-harnessPRIMARY 启动 SECONDMATE 的方式NOT inherited into secondmate homes

crew-harness 的继承语义比较特殊——它是"inherited as the literal file":如果主 home 写了 claude,那么 secondmate home 自己派 crewmate 时也用 claude。而 secondmate-harness 只属于 primary 一侧。

14.5 关键边界:secondmate 不孵化 secondmate

这是整个 secondmate 体系最重要的一条安全设计:

The primary's own setting; NOT inherited into secondmate homes (secondmates do not spawn secondmates).

为什么这样设计?因为一旦允许 secondmate 再创建自己的 secondmate,舰队就会形成任意深度的树状结构,带来三类问题:

  1. 监督链失控:主 firstmate 的恢复协议明确写着"Do not reconstruct or supervise a secondmate's child tree from the main home"——主 home 不跨层重建或监督子树。层级超过两层后,故障恢复的确定性无法保证;
  2. 责任稀释:硬规则要求所有沟通经由 firstmate 汇报给 captain,中间层越多,信息保真度越差;
  3. 资源不可控:嵌套孵化会让 agent 数量指数增长。

所以 FirstMate 把层级严格限制为两代:captain → firstmate → {crewmate, secondmate},而 secondmate 手下只能有普通 crewmate:

text
you (the captain)
 └── firstmate(主 home,PRIMARY)
      ├── crewmate × N        ← 由 config/crew-harness / crew-dispatch.json 决定
      └── secondmate × M      ← 由 config/secondmate-harness 决定
           └── 它自己的 crewmate × K(受继承的 crew-harness 控制)
                (到此为止,不能再有第三代 secondmate)

14.6 secondmate-provisioning:供给流程概览

创建、供给、校验、启动、交接 backlog、恢复、推送继承材料、退役 secondmate home,以及编辑 data/secondmates.md——这些操作全部由内部技能 secondmate-provisioning 负责(第 13 章讲过 .agents/skills/ 下的 agent-only 技能体系)。作为 captain,你只需要知道流程骨架:

text
1. 提出需求     "我想为一个长期维护的基础设施项目设一个专职 secondmate"
2. 加载技能     firstmate 加载 secondmate-provisioning
3. 创建 home    建立独立 FM_HOME,写入 charter brief
4. 注册路由     更新 data/secondmates.md 路由表
5. 继承材料     按 allowlist 同步继承配置(如 crew-harness、crew-dispatch.json)
6. 校验启动     校验通过后按 secondmate-harness 启动
7. 日常路由     范围内工作自动发往该 home;回复经 status/文档返回
8. 退役         仅在 captain 或主 firstmate 明确决定时执行,
               且该 home 必须无进行中的工作

两条补充纪律:

  • A secondmate is idle by default and acts only on work routed by the main firstmate. secondmate 默认闲置,只做主 firstmate 路由来的工作,不会自找活干;
  • 持久实体不进 backlog。 AGENTS.md 明确写道:"It tracks work items only, never agents; persistent secondmates never appear as backlog items." secondmate 记录在注册表与运行时状态里,绝不作为积压工作项管理。

14.7 何时值得引入 secondmate

引入 secondmate 有成本(多一个 home 要维护、多一份章程要写),以下场景才划算:

  • 职责域长期稳定:比如一个需要持续巡检的基础设施 monorepo,或一条固定的内容生产流水线;
  • 状态需要硬隔离:主 home 的 backlog 已混杂多个领域,希望各领域的任务队列、学习记录(learnings)、captain 偏好分开管理;
  • 并行规模超出单 home 舒适区:多个长期项目同时推进,各自需要独立的 session lock 与 projects 克隆。

反之,偶发的并行需求用普通 crewmate 就够了——worktree 隔离(第 9 章)已经能保证互不冲突。

本章小结

  • secondmate = 带隔离 firstmate home 和 charter 的普通直接下属,不是第二种架构;
  • 每个 secondmate 拥有持久的独立 FM_HOME:自己的 state、backlog、projects 与 session lock;
  • config/secondmate-harness 决定 PRIMARY 用哪个 harness 启动 SECONDMATE,缺省依次回落到 crew-harness 与 firstmate 自身;
  • crew-harnesscrew-dispatch.json 被 secondmate home 继承,secondmate-harness 不被继承——secondmates do not spawn secondmates,舰队严格限制为两代;
  • 供给全流程由 secondmate-provisioning 技能负责;secondmate 默认 idle,是持久实体而非 backlog 工作项。

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. 按照官方定义,secondmate 最准确的描述是?

2. 当 config/secondmate-harness 缺失或值为 default 时,PRIMARY 会如何选择启动 harness?

3. 关于 secondmate 的嵌套,正确的说法是?

4. 下列哪项符合 secondmate 的日常纪律?

🛠️ 动手实践

  1. 在纸上(或文本编辑器里)画出你的目标舰队拓扑图:标注主 home、计划中的 secondmate 数量、每个 secondmate 的章程职责域,以及每个 home 将使用的 harness。检查是否存在任何需要"第三代 secondmate"的场景,若有,重新划分职责域使其落在两代结构内。
  2. 在你的主 home 中创建 config/secondmate-harness,写入与你当前 harness 不同的另一款验证过的 harness(例如主会话用 pi,则写 claude),然后向 firstmate 提问"你现在会用什么 harness 启动 secondmate?crewmate 又用什么?",核对回答是否体现了两者的回落与继承关系。
  3. 向 firstmate 发起一次真实供给对话:"请为 <某个你长期维护的项目> 创建一个 secondmate,章程是……"。观察它是否加载了 secondmate-provisioning 技能、是否建立了独立 FM_HOME 并更新了 data/secondmates.md;随后给它发一项范围外的工作,验证它是否会拒绝或转回主 home 处理。