plan — 先想清楚,再动手改
导语
/plan 的价值不是多一个命令,而是给 agent 一套「先调研再动工」的制度:写工具暂时没收,计划可见可批,执行进度可盯。
简介
让 agent 直接改代码,常见失败模式不是「写不出代码」,而是:过早动手(仓库没摸清就 edit)、范围失控(小需求扯出半个重构)、进度不可见、上下文压缩丢状态。Plan Mode 解决的是工作流问题:先只读探索 → 产出可审批的编号计划 → 用户点头后再全工具执行 → 用 [DONE:n] 推进进度。
技术原理
两种模式两套工具边界:Plan 模式只留 read/bash(受限)/grep/find/ls,禁用 edit/write——不是提示词劝导,而是真正从 active tools 拿掉写工具。Execution 模式恢复全工具。
bash 走白名单 + shell 词法分析(默认拒绝、按规则放行):按 ;|&& 分段,重定向/子 shell/命令替换/变量展开/glob 一律拒绝;只读命令直接放行,git/find/sed/npm 带专属参数校验器。从「拦已知坏」换成「只放已知好」,绕过面收敛到白名单本身。
计划与提问走结构化工具 plan_complete/plan_question,从工具参数直取,Plan: 正则作 fallback。状态用 appendEntry 扛 compaction,计划落 PLAN.md;指令走 systemPrompt 每 turn 重建,消息历史不留 plan 制品。
使用说明
安装
pi install npm:@piex-dev/plan
仓库源码:extensions/plan
配置
plan 有额外 peer 依赖:@earendil-works/pi-tui、@earendil-works/pi-agent-core、@earendil-works/pi-ai(TUI 集成),不同于其他扩展仅需 pi-coding-agent。
用法
/plan
→ 只读探索(plan_question 澄清关键决策)
→ plan_complete 提交完整计划(含 Plan: 编号步骤)
→ UI 提供 Execute / Stay / Refine 选择
→ Execute:打开全工具,按步执行
→ [DONE:n] 推进
→ 全部完成提示 Plan Complete
辅助命令:/todos 开关 todo widget;CLI flag plan 启动即进入 plan mode。
验证
pi -e ./extensions/plan/src/plan.ts -p "what is 1+1" --no-session
实现方案
入口约 1430 行单文件。piex 里「扩展 API 用得最全」的包之一:registerCommand/registerTool/setActiveTools/on("tool_call") 拦截/on("before_agent_start") 注入 systemPrompt/on("turn_end") 解析 [DONE:n]/appendEntry 持久化/ctx.ui.select 交互。
工具集合并:进入 plan 记住 toolsBeforePlanMode,计划工具集 =(原 active 去掉 edit/write)∪ 只读工具集;退出时恢复并保留其它扩展注册的工具,与 hashline/lsp/dap 共存不误杀。
| omp | piex plan |
|---|---|
| 全屏 plan-review overlay | select 三选项级交互 |
| Plan TOC 侧栏 | 无(pi API 限制) |
| 子 agent plan handoff | 无(依赖未来 subagent) |
| write 禁用 | 一致 |
轻量的好处:依赖面小、行为可预测、和上游 pi 示例同源好维护。
设计参考
| 项目 | 机制 | piex 取舍 |
|---|---|---|
| pi 官方 plan-mode 示例 | registerCommand("plan") + setActiveTools + tool_call 拦截 bash | 采纳核心 API 方案。增强:appendEntry 持久化 + PLAN.md 落盘 + UI widget |
| oh-my-pi plan | 全屏 plan-review overlay + TOC 侧栏 + 子 agent handoff | 不采纳:pi API 不支持全屏 overlay、子 agent 未就绪。借鉴:步骤审批、工具白名单可配置、与 /review 联动 |
| pi-extensions pi-plan-mode | shell 词法 bash 白名单、结构化工具、systemPrompt 注入、context 制品清扫 | 采纳全部四项;不采纳:settings 文件与遗留迁移、thinking level 固定、放弃执行进度跟踪 |
核心取舍:坚持 pi 示例同源路线(轻、可预测、好维护),放弃 omp 式重 UI;用 appendEntry 扛 compaction。
迭代记录
路线图
| 方向 | 打算 |
|---|---|
[DONE:n] 靠自觉 | 弱验证:步骤点名的文件若 working tree 完全未动,提示「标了 DONE 但无变化」 |
| Refine 偏浅 | 在 pi API 能力范围内加强审批,不重做全屏 overlay |
| 白名单不是沙箱 | 白名单可配置(plan 阶段允许 lsp、收紧 bash),文档写死「降风险 ≠ 隔离」 |
| 单会话顺序执行 | 先与 /review 收尾联动;并行执行等子 agent 机制成熟 |
版本记录
| 版本 | 日期 | 变更 |
|---|---|---|
| 0.1.1 | 2026-07-19 | 正则黑名单 bash 拦截;正文 Plan: 标题正则提取计划;context 消息注入约束 |
| 0.2.0 | 2026-07-21 | shell 词法白名单;plan_complete/plan_question 结构化工具;systemPrompt 注入(默认拒绝按规则放行;计划与提问走专用工具参数;指令每 turn 重建系统提示,消息历史不留 plan 制品) |
0.1.1 教训:正则黑名单拦不住等价绕过,正文正则提取计划在模型不按格式输出时会漏,context 消息注入会被 compaction 吞掉。0.2.0 换成结构化方案:白名单收敛绕过面、工具参数取代正文解析、systemPrompt 取代消息注入。
附录:pi plan 生态能力逐项对比
四个项目(omp / pi 官方示例 / pi-extensions pi-plan-mode / piex plan)的客观能力差异。
| 能力 | omp | pi 示例 | pi-extensions | piex |
|---|---|---|---|---|
| 危险 bash 拦截 | ✅ 正则 | ✅ | ✅ 词法白名单 | ✅ 词法白名单(移植) |
| 结构化计划/提问工具 | ❌ | ❌ | ✅ | ✅ |
| 指令注入 | context 消息 | context 消息 | systemPrompt | systemPrompt |
| 执行进度追踪 | ✅ [DONE:n] | ✅ | ❌ 禁止 | ✅ [DONE:n] + widget |
| 计划审批弹窗 | ✅ 全屏 overlay | ❌ | ✅ select | ❌ select 替代 |
| 子 agent 计划传递 | ✅ plan-handoff | ❌ | ❌ | ❌ 依赖 subagent |
| Compaction 保护 | ✅ 计划文件 | ❌ | ✅ appendEntry | ✅ appendEntry |
源稿 Markdown: docs/packages/plan.md