第六章:帽子系统——给 AI 分配专属角色
📌 本章李明轩在做什么:他注意到一个怪现象——让一个 AI 既当选题人又当写作者又当审校,AI 会给自己的稿子打满分。他需要把创作流程拆成不同角色,让角色之间互相制衡。这就是帽子系统要解决的问题。
为什么需要角色分工
想象你在一家公司工作,有一个同事承担了所有工作:他同时是策划、开发、测试、审计、项目经理。
这种安排有一个致命的问题:没有制衡。开发者很难客观地审查自己写的代码,策划者在设计方案时很难避免自己的偏见,执行者在验收时很容易对自己已经完成的工作"手下留情"。
Ralph 的帽子系统解决了这个问题:同一个 AI,通过扮演不同角色,实现了内部制衡。
帽子是什么
在 Ralph 里,一顶"帽子"(Hat)是一个 AI 角色配置,包含:
hats:
planner: # 帽子的内部 ID
name: "📋 Planner" # 显示名称
description: "制定实现计划" # 角色描述
triggers: ["work.start"] # 触发条件(监听哪些事件)
publishes: ["tasks.ready"] # 完成后发布什么事件
default_publishes: "tasks.ready" # 默认发布的事件
instructions: | # 角色指令(告诉 AI 怎么工作)
你是规划师。你的职责是...
每顶帽子定义了一个 AI 的工作边界:
- 在什么条件下被激活(triggers)
- 应该做什么(instructions)
- 完成后触发什么(publishes)
内置预设中的帽子角色
Ralph 的 code-assist 预设包含四顶核心帽子:
🎩 规划师(Planner)
触发条件:work.start(循环刚开始)或 queue.advance(需要推进任务队列)
职责:
- 读取你的需求描述
- 把需求分解成有编号的实现步骤
- 为当前步骤创建具体的运行时任务
- 把任务信息传递给构建者
典型输出:一个 plan.md 文件,包含像这样的内容:
# 实现计划
1. 步骤一:创建项目骨架
- 创建入口文件
- 配置依赖
- 演示目标:程序能启动并显示帮助信息
2. 步骤二:实现核心功能
- 实现文字转换逻辑
- 添加参数解析
- 演示目标:核心命令能正常执行
3. 步骤三:完善和测试
- 添加错误处理
- 编写单元测试
- 演示目标:所有测试通过
关键约束:规划师只能规划,不能实现。这个角色分离防止了"规划者思维定势"影响实现决策。
⚙️ 构建者(Builder)
触发条件:tasks.ready(有新任务),或 review.rejected(被审查者打回来了),或 finalization.failed(终结者判定需要继续)
职责:严格遵循 TDD(测试驱动开发)流程:
RED → 先写失败的测试
GREEN → 写最少的代码让测试通过
REFACTOR → 清理代码,保持测试绿色
关键约束:
- 每次只做一个任务,不允许批量做
- 测试必须先于实现
- 不能添加需求以外的功能
构建者的每个输出都要经过审查者的检验,不能绕过。
🧪 审查者(Critic)
触发条件:review.ready(构建者完成了一个任务)
职责:以"全新眼光"(Fresh Eyes)审查构建者的工作:
- 需求符合度:实现是否真的满足了任务要求?
- 代码质量:是否有多余的代码(违反 YAGNI)?是否过度复杂(违反 KISS)?
- 验证:自己重新运行测试,不相信构建者的"测试通过了"声明
- 实际测试:运行实际的程序,而不只是看代码
关键约束:
- 必须假设构建者没有检查过"显而易见"的东西
- 不允许"有小问题但以后再修"的审查结论
- 必须实际运行程序,不能只做静态代码审查
审查者可以发布两种结果:
review.passed:这个任务合格,交给终结者判断是否整体完成review.rejected:不合格,打回给构建者重做,并附上具体原因
🏁 终结者(Finalizer)
触发条件:review.passed(某个任务通过了审查)
职责:做出最终判断:整体任务是否完成?
终结者比审查者要求更严格,因为它看的是全局,不只是最后一个任务:
- 检查所有任务是否都完成了
- 运行完整的测试套件
- 检查代码质量(YAGNI/KISS/代码风格)
- 判断是否还有需求没有实现
可能的结论:
queue.advance:这个步骤完成了,推进到下一步LOOP_COMPLETE:全部完成,循环结束finalization.failed:还有工作没做完,发回给构建者
PDD 预设中的完整帽子团队
如果你使用 pdd-to-code-assist 预设,会有一支更完整的帽子团队(11 顶帽子)参与工作:
设计阶段:
🎯 审问者(Inquisitor) → 问你问题,明确需求
💭 架构师(Architect) → 根据回答设计方案
⚖️ 设计批评者(Design Critic) → 挑战设计方案
探索阶段:
🔍 探索者(Explorer) → 研究代码库,找出模式和约束
实现阶段:
📋 规划师(Planner) → 制定测试策略和实现计划
📝 任务写手(Task Writer)→ 把计划转成代码任务文件
⚙️ 构建者(Builder) → TDD 实现
🧪 审查者(Critic) → 每个任务的代码审查
🏁 终结者(Finalizer) → 任务队列管理
验收阶段:
✅ 验证者(Validator) → 最终质量关卡
📦 提交者(Committer) → 创建规范的 Git 提交
帽子的工作流程图
把两种预设放在一张图上对比——code-assist 只跑中间的"实现阶段",pdd-to-code-assist 跑完整的四阶段:
实现阶段内部的事件环(两种预设共享)
上图里的"实现阶段"是两种预设共有的核心,内部还有一个小循环:
这张图只是"实现阶段"内部的放大视图。完整的事件流细节(包括所有 9 个事件名和 4 顶帽子的
triggers/publishes)在第七章会逐行从 yaml 源码里拆解。
查看可用帽子
讲了这么多帽子,怎么知道你这台电脑上现在能用哪些?Ralph 提供了一组"帽子目录"命令。
列出所有内置预设
ralph init --list-presets
会输出当前 Ralph 版本官方支持的内置帽子集(5 个核心 + 一些内部 / 实验性预设):
Supported built-in hat collections:
code-assist — 默认的 TDD 实现(planner / builder / critic / finalizer)
debug — 根因调试(investigator / tester / fixer / verifier)
research — 只读研究(researcher / synthesizer)
review — 对抗式代码审查(reviewer / analyzer)
pdd-to-code-assist — 从想法到代码的完整管道(11 顶帽子)
上游仓库
presets/目录里其实还有bugfix、deploy、docs、feature、fresh-eyes、pr-review、refactor、spec-driven、wave-review等更多预设。它们没进官方推荐清单(避免文档膨胀),但同样可以用——直接-H builtin:<name>试,跑得通就能用;或者把仓库里对应的.yml下载到本地按需修改。
列出当前配置激活的帽子
ralph hats list
ralph hats list --format json # 给脚本读
读取当前目录 ralph.yml 和 -H 指定的预设,告诉你这次循环会用到哪些帽子(含内置 + 你自定义的)。
查看某顶帽子的完整指令
ralph hats show planner
打印这顶帽子的 emoji、触发事件、发布事件、完整 instructions——相当于"翻开这个角色的剧本看一眼"。当你想知道某个内置帽子背后的提示词到底是怎么写的,这是最直接的方式。
把帽子工作流可视化成图
ralph hats graph # 默认 ASCII / Unicode 流程图
ralph hats graph --format mermaid # 输出 Mermaid 文本,贴到任何支持 Mermaid 的工具里渲染
这是理解"事件在帽子之间怎么流动"最快的方式,比逐行读 yaml 直观得多。
验证帽子配置
ralph hats validate
不实际启动循环,只检查事件连线是否完整:有没有"发布的事件没人订阅"、"订阅的事件没人发布"、"循环开不起来"这类配置错误。改完帽子配置后第一时间跑这个,能省掉一晚上 debug。
自定义帽子
除了使用内置预设,你也可以创建自己的帽子集合——这是 Ralph 适配你个人工作流的关键能力。比如李明轩想给"明轩说"加一顶"敏感词审校帽",或者把内容流水线的 6 顶帽子打包复用,就需要写自己的帽子文件。
第一步:写一个帽子集合文件
帽子集合是一个 YAML 文件,至少包含两个部分:event_loop(这个集合的入口和出口事件)和 hats(具体的帽子定义)。
最小可用例子:
# .ralph/hats/compliance.yml
event_loop:
starting_event: "build.start" # 循环从哪个事件开始
completion_promise: "LOOP_COMPLETE" # 收到哪个事件就算完工
hats:
compliance_reviewer:
name: "📜 合规审查者"
triggers: ["review.ready"]
publishes: ["compliance.passed", "compliance.failed"]
instructions: |
你是合规审查者。检查以下几点:
1. 所有用户输入是否经过了 SQL 注入防护
2. 敏感信息(密码、API 密钥)是否绝不出现在日志里
3. 错误信息是否对终端用户安全(不暴露系统信息)
只有三项全部通过,才能发布 compliance.passed。
任何一项失败,发布 compliance.failed 并说明原因。
第二步:放在哪里
Ralph 不会自动扫描任何目录去发现你的帽子文件——你必须用 -H 显式告诉它去哪里加载。但社区惯例是把帽子文件放在以下两个位置之一:
| 位置 | 适合 |
|---|---|
.ralph/hats/<name>.yml | 项目级帽子(跟着仓库走,团队共享) |
~/.ralph/hats/<name>.yml | 个人级帽子(你自己常用,跨项目共用) |
这只是约定,Ralph 不强制。你想放在
presets/或者别的目录都可以——重要的是-H后面写对路径。
第三步:加载它
-H 接受三种来源:内置名(builtin:<name>)、本地文件路径、URL。每次只能指定一个 -H:
# 加载项目级自定义帽子集合
ralph run -c ralph.yml -H .ralph/hats/mx-content.yml -p "你的需求"
# 加载个人级自定义帽子集合
ralph run -c ralph.yml -H ~/.ralph/hats/mx-content.yml -p "你的需求"
⚠️ 想在内置预设之上"加补丁"?没有这种叠加机制。
-H在命令行里是单值参数(不像-c可以多个)。而且-H文件的hats:段会整体替换-c里的hats:段,不是逐帽子合并。所以ralph run -H builtin:code-assist -H my.yml这种写法不能让两边的帽子共存。要"在内置预设之上加东西",正确做法是——把 上游仓库 的
.yml文件下载到本地,在本地文件里加自己的帽子并改相关帽子的 triggers(这一点第七章最后一节会详细讲——仅仅加一顶新帽子是不够的,需要重新连线事件流),然后用这个 fork 出来的文件作为唯一的-H源:curl -L -o .ralph/hats/mx-review.yml \ https://raw.githubusercontent.com/mikeyobrien/ralph-orchestrator/main/presets/code-assist.yml # 编辑 mx-review.yml,加新帽子 + 改下游 triggers ralph run -c ralph.yml -H .ralph/hats/mx-review.yml -p "..."
第四步:验证再上场
写完帽子文件后,先验证再启动循环:
# 检查事件连线是否合理
ralph hats validate -H .ralph/hats/compliance.yml
# 用图直观确认事件流
ralph hats graph -H .ralph/hats/compliance.yml --format mermaid
想每次都自动带上某个自定义帽子?
如果你不想每次 ralph run 都重复打 -H,有两种办法:
办法 A:单文件模式(向后兼容写法)——直接把 event_loop / hats 写进 ralph.yml 里:
# ralph.yml
event_loop:
starting_event: "build.start"
completion_promise: "LOOP_COMPLETE"
hats:
my_custom_hat:
name: "..."
triggers: [...]
# ...
这样直接 ralph run -p "..." 就会用 ralph.yml 里的帽子,不再需要 -H。
办法 B:写一个 shell 别名:
# ~/.zshrc 或 ~/.bashrc
alias mxrun='ralph run -H ~/.ralph/hats/mx-content.yml'
之后 mxrun -p "..." 就等于自动带上了那顶帽子。
实际怎么用:李明轩的 "明轩说" 帽子集
李明轩为自己的内容流水线写了 6 顶帽子,全部放在项目下的 .ralph/hats/mx-content.yml:
.ralph/hats/
└── mx-content.yml # 选题 / 撰写 / 审校 / 排版 / 发布 / 客服 6 顶帽子
平时跑:
ralph run -H .ralph/hats/mx-content.yml -p "把今天的草稿改成 4 平台版本"
如果某次他想用内置的 code-assist 来给 mx 工具本身加功能,就不带 -H mx-content.yml,临时换成 -H builtin:code-assist——同一个项目可以根据当下的工作类型切换不同的帽子集,互不冲突。
帽子配置的关键参数
除了基本的触发和发布,帽子还支持一些高级配置:
并发数(concurrency):允许同一顶帽子同时处理多个任务(并行执行,详见第十一章):
hats:
reviewer:
concurrency: 4 # 同时审查 4 个文件
聚合(aggregate):等待所有并行工作完成后再激活:
hats:
synthesizer:
aggregate:
mode: wait_for_all
timeout: 300 # 最多等待 300 秒
本章小结
- 帽子是 Ralph 里的 AI 角色配置,每顶帽子有明确的职责边界
code-assist预设有四顶帽子:规划师、构建者、审查者、终结者pdd-to-code-assist预设有 11 顶帽子,覆盖从想法到提交的完整流程- 帽子通过事件总线协作,每顶帽子只能做自己"职责内"的事
- 可以自定义帽子来实现特定业务需求
李明轩的"选题 / 撰写 / 审校 / 排版 / 发布 / 客服"六顶帽子已经配好。但他马上遇到下一个问题:这些帽子之间怎么知道谁做完了、该谁接手?下一章讲事件总线——帽子们的"共享公告板"。