给 AI 立规矩
你可能遇到过这种情况
你让 AI 帮你“修一下登录页面的样式“。30 秒后你看了一眼代码–
AI 不但改了样式,还:
- “顺手“重构了整个登录组件的目录结构
- 把 CSS 模块改成了 Tailwind(你项目没用 Tailwind)
- 删除了 3 个它认为“没用“的测试文件
- 把 package.json 里的依赖升级到了最新版
等你发现的时候,代码已经提交了。
💡 AI 越能干,越需要规矩。能力强但没有边界,造成的破坏反而更大。
两道防线:Shepherd 和 Context
pi-atelier 提供了两层防护机制:
第一道:pi-shepherd - 行为守卫
Shepherd(牧羊犬)是一个规则驱动的事件钩子引擎,在 AI 的关键动作前后做检查,相当于“门卫“。
AI 准备执行动作(工具调用)
│
▼
┌──────────────────────────────┐
│ Shepherd tool_call 钩子 │
│ 检查:该不该做?该怎么做? │
└──────┬───────────────────────┘
│
┌───┴────┐
│ │
放行 改写/阻止 + 提示原因
... 工具执行完毕 ...
┌──────────────────────────────┐
│ Shepherd tool_result 钩子 │
│ 检查:需要后续动作吗? │
└──────┬───────────────────────┘
│
注入提醒 / 追加动作
支持的钩子时机:
| 钩子 | 触发时机 | 典型用途 |
|---|---|---|
tool_call | AI 调用工具前 | 改写命令、阻止危险操作 |
tool_result | 工具执行后 | 自动提醒跑测试、lint 检查 |
message_end | AI 回复完成时 | 匹配回复文本,拦截错误猜测 |
agent_end | AI 完成对话时 | 提醒提交代码、更新记忆 |
session_shutdown | 会话关闭时 | 清理临时数据 |
Shepherd 的四种动作:
| 动作 | 效果 | 典型用途 |
|---|---|---|
block | 阻止工具执行 | 禁止危险操作 |
notify | 向 AI 上下文注入提醒 | “编辑了 TS 文件,记得跑测试” |
steer | 静默注入引导(不显示给用户) | 引导 AI 查阅规范 |
rewrite | 改写工具调用参数 | 自动给命令加前缀 |
第二道:pi-context-manager - 信息质量与诊断
Context Manager(上下文管家)控制 AI 能看到什么信息,还能帮你诊断 token 消耗问题。
核心能力:
- Distill(蒸馏):自动压缩工具返回的大段内容,保留关键信息
- Tool Result Processor(后处理器):对特定工具输出做格式化精简
- Aging(老化淘汰):自动淘汰长期未被引用的旧工具输出
- Payload 分析:用数据诊断 token 都花在哪了
工具返回大量内容(可能 50KB)
│
▼
┌────────────────────────┐
│ Context Manager │
│ Distill + Processor │
│ 压缩到 ~5KB 关键信息 │
└────────────────────────┘
│
▼
AI 看到精炼后的信息,做出更好的判断
详细原理见 3.3 Context Manager 原理。
实际案例:防止 AI 犯错
场景 1:编辑后自动提醒跑测试
{
"comment": "[TypeScript] 编辑后必须跑测试",
"hook": "tool_result",
"tool": "edit",
"action": "notify",
"conditions": [
{ "field": "path", "pattern": "\\.ts$", "flags": "" }
],
"reason": "编辑了 TypeScript 文件,必须跑覆盖该代码的单元测试(如无测试则先补充),修复所有测试问题确保通过。",
"enabled": true
}
当 AI 编辑了 .ts 文件后,Shepherd 自动提醒 AI 跑测试。
场景 2:会话结束提醒提交代码
{
"comment": "[收尾] 编辑后提醒 commit + 记忆更新 + 总结",
"hook": "agent_end",
"action": "notify",
"conditions": [{ "builtin": "has_edits" }],
"reason": "检测到文件编辑,执行收尾工作:\n1️⃣ Git commit...\n2️⃣ 更新记忆...\n3️⃣ 会话总结",
"stopReason": ["stop"],
"enabled": true
}
conditions: [{ builtin: "has_edits" }] 表示只有本轮会话确实编辑了文件才触发。stopReason: ["stop"] 表示只在 AI 正常结束(而非被中断)时触发。
场景 3:自动改写命令
{
"comment": "[rtk] 自动代理高频 bash 命令",
"tool": "bash",
"action": "rewrite",
"pattern": "^(git\\s+(status|log|diff)|cargo\\s+(test|build|clippy)|pytest)\\b",
"flags": "",
"reason": "rtk command rewrite:自动加 rtk 前缀压缩输出",
"enabled": true
}
当 AI 尝试执行 git status 等命令时,Shepherd 自动改写为 rtk git status(rtk 是一个输出压缩工具)。
场景 4:代码风格检查
{
"comment": "[TS] 禁止空格缩进 - TS 文件必须用 Tab",
"hook": "tool_call",
"tool": "edit",
"action": "notify",
"conditions": [
{ "field": "path", "pattern": "\\.ts$", "flags": "" },
{ "field": "text", "pattern": "\\n [\\S ]", "flags": "" }
],
"reason": "❌ TS 文件要求 Tab 缩进,不是空格。请用 Tab 缩进重写代码。",
"enabled": true
}
两个条件同时满足才触发:文件是 .ts 且代码内容包含空格缩进。
场景 5:连续出错时提醒翻记忆
{
"comment": "[debug] 工具反复出错时提醒翻记忆",
"hook": "tool_result",
"action": "steer",
"state": { "countKind": "errors", "gte": 5 },
"reason": "🔍 **工具反复出错**:连续失败多次,翻看 .pi/memory/ 目录下的记忆文件,看是否已有踩坑记录。",
"enabled": true,
"subagent": false
}
state 实现了状态追踪–Shepherd 会记住工具出错的次数,累计到阈值才触发。subagent: false 表示子代理中不触发此规则。
Shepherd 规则管理
规则可以通过两种方式管理:
shepherd_rules工具:让 AI 帮你安全地增删改规则,内置写入校验和回滚机制- 直接编辑 JSON 文件:全局规则在
~/.pi/agent/extensions/shepherd/rules.json,项目规则在.pi/extensions/shepherd-rules.json
规则文件修改后即时生效,无需重启。
📖 完整的字段说明和参数文档,见 pi-shepherd README。
典型用法:
# 让 AI 帮你添加一条规则
你:帮我加一条规则,编辑 .rs 文件后提醒跑 cargo clippy
AI 调用 shepherd_rules(action="add", rule={...})
# 查看项目级规则
AI 调用 shepherd_rules(action="list", scope="project")
Context 的配置方式
pi-context-manager 提供以下命令:
| 命令 | 用途 |
|---|---|
/record [on|off] | 开关 payload 录制 |
/context | TUI 面板:可视化上下文使用情况 |
/distill-config [N] | 查看/设置 distill token 阈值 |
/distill-config --cap [N] | 查看/设置首次全文上限(firstSeenCap,0 = 不设上限) |
/processor-config [N|off] | 查看/设置 tool-result-processor 阈值 |
/aging-config [N|off] | 查看/设置 aging 淘汰轮数 |
/context-clean [sessionId] | 清理持久化数据 |
💡 所有命令无参调用时显示当前配置和用法说明,例如直接输入
/distill-config即可查看当前阈值和用法。
详细原理见 3.3 Context Manager 原理。
最佳实践
✅ 好的规则设计
- 精确的条件:用
conditions限定触发范围,不要一刀切 - 清晰的提示:告诉 AI “为什么不行“和“应该怎么做”
- 分层防护:重要的事情用
block(强制阻止),次要的用notify(提醒),内部引导用steer(静默) - 善用状态追踪:连续出错 3 次再提醒,比每次都提醒更有效
❌ 不好的规则设计
- 过于频繁:每个工具调用都
notify,AI 会被提醒淹没 - 过于严厉:
deny所有bash命令,AI 连ls都不能执行 - 模糊的提示:
"reason": "注意"– 注意什么? - 忽略子代理:某些规则用
"subagent": false排除子代理场景,避免干扰独立任务
规则的优先级
当多条规则同时匹配时:
block>notify>steer(阻止 > 提醒 > 静默引导)- 同优先级下,按规则文件中的定义顺序依次执行
agent_end钩子中,check条件不满足的规则直接跳过
下一步
有了记忆、规划和规矩,AI 已经是一个靠谱的助手了。但一个会话做了很多事之后–你怎么知道它具体做了什么?哪些文件改了?哪些决策做了?
下一章,我们来看如何让 AI 学会复盘。