AB
AiBoss
チュートリアル

Plandex

チュートリアル

Plandex 快速上手:用 plan-then-apply 做多文件重构

Plandex 是一个终端里的多文件代码编辑代理,它的改动先进入独立的 plan 沙箱,用 diff 审阅、用 rewind 逐步回退,确认后才 apply 到工作区。本文从安装、加载上下文、下达指令讲到审阅、回退与最终落盘,并用一个 camelCase 转 snake_case 的批量改名示例串起完整流程。

Plandex 是一个运行在终端里的多文件代码编辑代理,采用「先规划、后应用」的工作方式:模型提出的改动不会立刻写进工作区,而是累积在一个独立的 plan 沙箱里,你可以用 plandex diff 逐块查看,用 plandex rewind 回退到任意一步,只有显式执行 plandex apply 之后,改动才真正落到磁盘上。这个特性对需要改动第三方遗留代码的人尤其有价值——代理可以在几十个文件之间反复迭代,而仓库不会停留在半改完的不一致状态。如果你习惯在动手前先确认工具链,可以先看看站内的 Plandex 条目,再回到本文按步骤操作。

本文适合已经熟悉命令行与 Git、需要在一个仓库里做跨文件协调改动的开发者。典型场景包括:批量重命名公共 API、把一个大文件拆成模块、在几十个调用点上同步修改函数签名。下面用一个遗留 Python 库从 camelCase 迁移到 snake_case 的例子,把整个流程走一遍。

准备工作

仓库与基线

在开始之前,先把工作区整理干净。Plandex 的沙箱保护的是「plan 内的改动」,它不保护你的 Git 状态,所以仍然建议在专用分支上作业,并确保测试基线是绿的。

cd ~/projects/client/libX
git checkout -b refactor/snake_case
python -m pytest

如果测试本来就有失败项,先记录下来,否则后面无法判断新出现的失败是重构引入的还是原本就存在的。另外,即使 Plandex 自带改动沙箱,也建议在每次会话前做好备份——流程上的误操作仍然可能把不想要的 diff 应用出去。

安装 Plandex

Plandex 以 Go 编写的二进制形式分发,官方提供了一键安装脚本。安装完成后用版本命令确认可执行文件已经在 PATH 中:

curl -sL https://plandex.ai/install.sh | bash
plandex --version

具体安装方式与最新版本号请以官网当前信息为准,不同版本之间命令语法可能有差异。

配置模型提供方

Plandex 本身不内置模型,需要你指定一个可用的模型端点,可以是云端服务,也可以是本地或私有部署的推理端点。密钥不要写进会被提交的配置文件,用环境变量注入更稳妥:

read -rs OPENROUTER_API_KEY && export OPENROUTER_API_KEY

这里只是举例说明「用环境变量传密钥」这一做法,具体支持哪些提供方、各自的配置字段叫什么,请查阅你所安装版本的文档。需要特别提醒的是:Plandex 会把上下文发送给所配置的模型提供方。如果代码受保密协议约束,或者涉及受监管的数据,应当优先选择本地或私有的模型端点,并且不要把任何密钥写进提示词或配置文件。

操作步骤

第一步:在当前目录创建 plan

在仓库根目录执行新建命令。Plandex 会为当前目录关联一份状态,此时 Git 工作区完全不受影响:

plandex new

一个 plan 就是一次独立的改动会话。你可以在同一个目录下拥有多个 plan,它们彼此隔离,这一点后面还会提到。

第二步:显式加载上下文

Plandex 采用显式上下文模型:哪些文件参与本次任务,由你声明,而不是让它自己扫描整个仓库。这样做的好处是成本和噪声都可控,代价是你必须把相关文件挑准。

plandex load src/libX/*.py tests/*.py
plandex ls

plandex ls 用来确认当前 plan 里到底装了哪些文件。这一步值得多花几秒:上下文太窄,代理会在一个文件里改函数名却漏掉其他模块的调用点;上下文太宽,token 消耗和干扰信息都会迅速上升。合适的范围取决于这次重构的形状,没有通用答案。

第三步:下达规划指令

用 plandex tell 把任务描述清楚。指令写得越具体,产出的 diff 越接近你想要的结果。下面这条指令把改名范围、兼容性要求、不该碰的部分以及推进方式都写明了:

plandex tell "Rename all public functions from camelCase to snake_case. \
Update every call site inside src/libX/ and tests/. \
Keep a deprecated alias with DeprecationWarning for every previous name. \
Do not touch docstrings. \
Proceed file by file."

提交后模型开始工作,产生的改动进入 plan 沙箱,不会落到磁盘。在它运行期间,你可以随时查看进展:

plandex diff
plandex diff src/libX/core.py
plandex log

plandex diff 不带参数时展示累积的全部改动,带上文件路径则只看单个文件;plandex log 列出这个 plan 已经执行的各个步骤。把这三者配合起来用,就能在长任务进行中保持对整体走向的判断。

第四步:审阅并逐步回退

如果某一步产出的 diff 是错的,不必推翻整个 plan。plandex log 会给出带编号的步骤列表,例如:

[step 7] update test_core.py
[step 8] update core.py

此时可以回退到指定步骤,撤销该步及其之后的所有改动,保留之前的成果:

plandex rewind 7

这条命令会撤销第 7 步及之后的步骤,第 1 到第 6 步保持不变。这是 Plandex 在实际工作中最有价值的能力之一:如果第 12 步引入了 bug,你不需要把前面 11 个已经审阅通过的步骤一起丢掉,只需回退到出问题之前,重新下达更精确的指令。

第五步:应用改动并提交

当沙箱里的改动整体自洽、diff 也逐块看过之后,再执行落盘:

plandex diff
plandex apply
pytest
git status
git add -p
git commit -m "refactor: migrate public API to snake_case with deprecated aliases"

先完整看一遍 diff,再 apply,然后跑回归测试。提交时用 git add -p 做分块暂存,而不是一把 git add . 全量提交——这样即使测试失败,进入索引的内容也是有限的,可以用 git restore 把工作区恢复到可用的状态。

一个完整示例

把上面的步骤串起来,就是一次完整的迁移会话。假设内部 Python 库历史上一直用 camelCase 命名函数,与 PEP 8 以及客户新模块采用的约定冲突,需要把公共函数改名为 snake_case,同步更新约五十个文件里的调用点,同时为每个旧名字保留一个带 DeprecationWarning 的别名以维持向后兼容。

准备阶段:切出专用分支,确认测试基线为绿。

cd ~/projects/client/libX
git checkout -b refactor/snake_case
python -m pytest

安装与配置:装好二进制,用环境变量注入模型密钥。

curl -sL https://plandex.ai/install.sh | bash
plandex --version
read -rs OPENROUTER_API_KEY && export OPENROUTER_API_KEY

建 plan 并加载上下文:只把源码目录和测试目录纳入本次任务。

plandex new
plandex load src/libX/*.py tests/*.py
plandex ls

下达指令:明确改名范围、调用点、兼容别名、不动的部分,以及逐文件推进。

plandex tell "Rename all public functions from camelCase to snake_case. \
Update every call site inside src/libX/ and tests/. \
Keep a deprecated alias with DeprecationWarning for every previous name. \
Do not touch docstrings. \
Proceed file by file."

运行中审阅:边跑边看累积 diff 和步骤日志。

plandex diff
plandex diff src/libX/core.py
plandex log

局部回退:发现某一步改错了,回退到该步之前,保留前面的成果。

plandex rewind 7

落盘与验证:整体 diff 审阅通过后 apply,跑测试,分块暂存并提交。

plandex diff
plandex apply
pytest
git status
git add -p
git commit -m "refactor: migrate public API to snake_case with deprecated aliases"

如果测试失败,因为采用了分块暂存,进入索引的改动是有限的,可以用 git restore 把工作区拉回可用状态,再回到 plan 里继续调整。

注意事项

plan 不能替代 Git 分支

plan 沙箱保护的是「应用之前」的阶段。一旦执行 plandex apply,改动就落到了工作区,此时的安全网仍然是 Git。所以专用分支不是可选项,而是整个流程的基础。

上下文范围直接决定质量

加载得太窄,代理会在一个文件里改函数名,却漏掉其他模块里的调用点;加载得太宽,成本和噪声都会失控。这个平衡点取决于具体重构的形态,需要你在 plandex load 时自己判断,并在看到第一批 diff 后及时调整。

模型可能编造不存在的名字

在大量使用元编程的代码库里——动态 getattr、基于字符串的工厂函数——纯粹的重命名重构可能漏掉某些引用,甚至生成并不存在的名字。回归测试是必须的检查手段,不能只靠肉眼审阅 diff。

长任务的 token 成本

五十个文件放进同一个 plan 意味着大量模型调用。应当监控消耗,在可能的情况下拆成更小的 plan;对于重复性强的任务,可以考虑成本更低的模型。具体模型选择与计费请以各提供方官网当前信息为准。

并行 plan 要当心冲突

Plandex 支持在同一目录下存在多个 plan。但如果两个并发 plan 覆盖了重叠的代码区域,就会产生冲突,处理思路和两条交叉的 Git 分支类似:要么错开范围,要么串行推进。

命令语法随版本变化

new、tell、apply、diff 这些子命令的细节在不同版本之间可能不同。动手前先确认你安装的版本对应的文档,不要照搬别处的命令示例。

密钥与数据边界

不要把密钥写进提示词或配置文件。Plandex 会把上下文发送给所配置的模型提供方,受保密协议约束的代码或受监管的数据应当走本地或私有端点。