1. 为什么我要把 Pi 从"玩具"变成"主力"
第一次接触 Pi 的人,十有八九会经历同一个心理曲线:装好、跑通、觉得挺新鲜,然后……就没有然后了。它躺在终端里,偶尔被想起来跑两句,日常真正干活还是回到自己用惯的那套工具上。问题不在于 Pi 不够强,而在于默认配置下的 Pi 只是一个"能对话的壳子",它不知道你的项目结构、不知道你的代码风格、不知道你踩过哪些坑,每次都要从零开始解释背景,用几次就累了。
我自己的转折点是在一个多模块项目里。那段时间我每天要在三个仓库之间来回切,每个仓库的构建命令、测试命令、目录约定都不一样。用默认 Pi 的时候,我每次都得先花两分钟"喂背景",它才勉强给出能用的建议。后来我花了一个周末把settings.json、models.json、AGENTS.md、APPEND_SYSTEM.md这几个文件彻底捋了一遍,情况完全变了——Pi 开始像一个熟悉我项目的老同事,知道去哪找文件、知道用什么命令、知道哪些操作是禁区。
这篇就是那次折腾的完整记录。我会把配置拆成四块讲清楚:全局设置怎么定基调、模型清单怎么配才不浪费、AGENTS.md 怎么写才真正被"读懂"、APPEND_SYSTEM.md 怎么补上默认行为的短板。适合已经装好 Pi、但还没把它用顺手的人;也适合那些"配置改了一堆但感觉没生效"的人——大概率是改错了地方或者优先级搞反了。
先说一个反直觉的结论:Pi 的配置不是越多越好,而是越"分层"越好。全局配置管通用习惯,项目配置管具体上下文,两者职责不清,就会出现"在这个项目里好用、换个项目就抽风"的情况。下面按这个思路一层层拆。
2. 配置体系的整体设计与分层思路
2.1 四个配置文件到底各管什么
很多人第一次看到settings.json、models.json、AGENTS.md、APPEND_SYSTEM.md这四个文件是懵的,名字都挺像,功能边界模糊。我用一张表把它们的职责钉死:
| 文件 | 作用域 | 核心职责 | 改动频率 |
|---|---|---|---|
settings.json | 全局/项目 | 行为开关、路径、超时、权限等运行时参数 | 低,配好基本不动 |
models.json | 全局 | 模型清单、别名、参数、上下文窗口 | 中,换模型时改 |
AGENTS.md | 项目 | 项目专属上下文、命令、约定、禁区 | 高,随项目演进 |
APPEND_SYSTEM.md | 全局/项目 | 追加到系统提示的补充规则 | 中,调教行为时改 |
理解这张表的关键在于分清**"机制"和"内容"**。settings.json和models.json是机制层——它们决定 Pi 能做什么、用什么做;AGENTS.md和APPEND_SYSTEM.md是内容层——它们决定 Pi 知道什么、怎么表现。机制层配错了,内容层写得再好也白搭;内容层偷懒,机制层再精细也发挥不出来。
我见过最常见的错误,是把项目专属的命令写进APPEND_SYSTEM.md。这样做的后果是:换个项目,那些命令还在,Pi 会一本正经地建议你运行一个根本不存在的脚本。项目相关的东西一律进AGENTS.md,全局行为偏好才进APPEND_SYSTEM.md,这条线必须划清。
2.2 优先级与覆盖规则:谁说了算
分层配置绕不开优先级问题。Pi 的加载逻辑大致是:项目级配置覆盖全局级配置,后加载的覆盖先加载的。具体到四个文件:
settings.json:项目目录下的会与全局的做合并,同名键以项目级为准。models.json:通常只在全局维护一份,项目级很少单独覆盖,除非你有特殊需求。AGENTS.md:项目级是主力,全局的那份作为兜底。APPEND_SYSTEM.md:全局和项目级会叠加而不是覆盖,这点要特别注意,写重复了会啰嗦。
提示:调试配置是否生效时,先确认你改的是项目级还是全局级。我踩过最蠢的坑就是在全局
APPEND_SYSTEM.md里加了一条规则,然后在项目里怎么测都没反应,折腾半小时才发现项目级有一份同名文件把它盖住了。
2.3 为什么选择"文件驱动"而不是"命令行参数"
有人会问:为什么不直接在启动命令后面跟一堆参数?答案是可维护性和可复现性。命令行参数适合临时调试,但日常使用中,你需要的是"打开终端就是配好的状态"。文件驱动的好处是:
- 可版本控制:
AGENTS.md跟着项目走,团队里谁拉下来都是同一套上下文。 - 可复用:全局配置一次写好,所有项目受益。
- 可审计:出问题时能 diff,能回滚,命令行参数做不到。
这也是我把配置当成"项目资产"而不是"个人偏好"的原因。下面进入具体操作。
3. settings.json 与 models.json 的实操配置
3.1 settings.json:先把地基打稳
settings.json是 Pi 的行为中枢。我建议第一次配置时,只改真正影响体验的几项,别一上来就抄一堆网上来的配置——很多参数你根本用不到,改多了反而互相干扰。
一个我实际在用的精简版本长这样(字段名以你所用版本为准,逻辑是通用的):
{ "defaultModel": "main", "autoContext": true, "maxContextFiles": 20, "commandTimeout": 120000, "confirmBeforeWrite": true, "confirmBeforeExec": true, "ignorePatterns": [ "node_modules/**", "dist/**", ".git/**", "*.log" ] }逐项说下我的取舍逻辑:
defaultModel指向models.json里的别名,而不是直接写模型全名。这样换模型时只改一处。autoContext打开后,Pi 会自动把相关文件纳入上下文。这是"变聪明"的关键开关,但配合maxContextFiles用,否则大项目里它会一口气塞几十个文件,既慢又贵。commandTimeout我设成 120 秒。默认值对跑测试、装依赖这类操作经常不够,超时中断很烦。confirmBeforeWrite和confirmBeforeExec我强烈建议保持开启。让 Pi 自动改文件、自动跑命令听起来很爽,直到它某次理解偏了把你的配置覆盖掉。确认一下的成本,远低于恢复的成本。ignorePatterns是省钱的隐形功臣。把依赖目录、构建产物、日志排除掉,Pi 就不会浪费上下文去读那些没意义的文件。
注意:
ignorePatterns的写法跟.gitignore类似但不完全一样,不同版本对通配符的支持有差异。写完最好用一个已知的大目录测一下,确认真的被忽略了,别想当然。
3.2 models.json:别把所有模型都塞进去
models.json管理模型清单。新手容易犯的错是把能用的模型全列上,结果选择困难,还容易在关键时刻用错。我的做法是只保留三到四个有明确分工的别名:
{ "models": { "main": { "provider": "your-provider", "model": "your-main-model", "contextWindow": 128000, "temperature": 0.2 }, "fast": { "provider": "your-provider", "model": "your-fast-model", "contextWindow": 32000, "temperature": 0.1 }, "reason": { "provider": "your-provider", "model": "your-reasoning-model", "contextWindow": 200000, "temperature": 0.3 } } }分工逻辑是这样的:
main:日常主力,写代码、改 bug、解释逻辑都用它。温度调低(0.2 左右),保证输出稳定。fast:干杂活,比如格式化、重命名、写注释、生成提交信息。这类任务不需要强推理,用快模型省钱省时间。reason:遇到复杂架构问题、难缠的 bug 时才切过去。上下文窗口大,能一次吃下更多文件。
温度这个参数值得单独说。写代码场景下,温度高于 0.5 输出会开始飘,同样的输入两次结果差异明显,不利于复现。我基本把主力模型的温度压在 0.1 到 0.3 之间。只有做头脑风暴、起名字这类创意任务时,才会临时调高。
contextWindow一定要填准。填大了,Pi 以为能塞更多内容,实际超出模型上限会报错或截断;填小了,白白浪费模型的容量。这个值查你所用模型的官方文档,别猜。
3.3 两个文件的联动:别名是粘合剂
settings.json里的defaultModel和models.json里的别名是一对。我强烈建议永远不要在 settings 里写模型全名,全部走别名。原因很简单:模型会更新换代,全名会变,别名不变。哪天你从 A 模型换到 B 模型,只改models.json里main指向的那一行,其他所有配置纹丝不动。
这套别名机制还有个隐藏好处:团队协作时统一认知。大家在讨论时说的是"这个用 fast 跑就行",而不是"这个用某某某-3.5-turbo-0613 跑",沟通成本低很多。
4. AGENTS.md 与 APPEND_SYSTEM.md 的调教心法
4.1 AGENTS.md:让 Pi 秒懂你的项目
如果说前两个文件是"硬件配置",AGENTS.md就是"软件灵魂"。它决定了 Pi 打开你的项目时,第一眼看到什么、知道什么。我见过太多人把AGENTS.md写成一句"这是一个 Node 项目",然后抱怨 Pi 不好用——这相当于给新同事的入职文档只写了公司名字。
一份真正好用的AGENTS.md,我总结成五个模块:
第一,项目一句话定位。别写"这是一个 Web 应用"这种废话,要写清楚它解决什么问题、面向谁。比如"这是一个面向中小团队的内部工单系统,前端 React,后端 Go,数据库 PostgreSQL"。Pi 拿到这句话,后面所有建议都会围绕这个定位展开。
第二,目录结构速览。不用列全,只列关键目录和它们的职责:
- `cmd/` 各服务的入口 - `internal/` 核心业务逻辑,按领域分包 - `web/` 前端代码 - `scripts/` 构建与部署脚本 - `docs/` 设计文档,改架构前先看这里第三,常用命令。这是AGENTS.md里价值最高的部分。把构建、测试、lint、启动开发环境的命令原样写进去:
- 安装依赖:`make deps` - 跑测试:`make test`(单测)/ `make test-e2e`(端到端) - 本地启动:`make dev`,默认端口 8080 - 代码检查:`make lint`,提交前必须过写清楚之后,Pi 就不会再瞎猜"你试试 npm test",而是直接给你项目里真实存在的命令。这一条能省掉大量来回确认的时间。
第四,代码约定。团队里那些"只可意会"的规矩,全部显式写出来。比如错误处理用哪种模式、日志怎么打、命名用驼峰还是下划线、提交信息什么格式。这些约定不写,Pi 就会按它的默认习惯来,产出跟你项目风格不一致的代码,你还得手动改。
第五,禁区与红线。明确告诉 Pi 哪些事不能做。比如"不要直接改migrations/下的历史迁移文件"、"不要动vendor/目录"、"生产配置在config/prod/,任何情况下不要读取或修改"。这一块是安全网,写得越具体越好。
实操心得:
AGENTS.md不要一次写完就扔那。我习惯每次发现 Pi 犯了重复性错误,就往里补一条规则。比如它老是忘记跑 lint,我就在命令区加一句"任何代码改动后必须执行make lint"。这份文件是养出来的,不是写出来的。
4.2 APPEND_SYSTEM.md:补上默认行为的短板
APPEND_SYSTEM.md的内容会被追加到系统提示后面,用来微调 Pi 的"性格"和"习惯"。它和AGENTS.md的区别在于:AGENTS.md讲的是"这个项目是什么",APPEND_SYSTEM.md讲的是"你作为助手应该怎么做"。
我在这份文件里放的东西,主要是三类:
输出风格约束。比如"回答代码问题时,先给结论再给解释,不要长篇铺垫"、"涉及多步骤操作时用有序列表,不要写成大段文字"。这些偏好写进去,Pi 的输出会明显更贴合你的阅读习惯。
工作流程约束。比如"修改代码前先说明你打算改哪些文件、为什么"、"遇到不确定的地方先提问,不要自行假设"。这类规则能显著降低 Pi "自作主张"的概率。
安全与边界约束。比如"执行任何删除操作前必须二次确认"、"不要在没有明确指令的情况下安装新依赖"。这是最后一道防线。
一个我实际在用的片段:
- 回答优先给可执行的结论,解释放在后面。 - 改动超过三个文件时,先列出改动清单再动手。 - 不确定的接口或配置,先问,不要猜。 - 任何破坏性操作(删除、覆盖、重置)必须明确确认。注意:
APPEND_SYSTEM.md是叠加的,全局一份、项目一份会同时生效。所以别在两边写重复的规则,否则 Pi 会收到两遍同样的指令,虽然不至于出错,但浪费上下文。我的做法是全局放通用风格,项目放该项目特有的流程要求。
4.3 两个文件的配合:一个管"知道",一个管"怎么做"
把AGENTS.md和APPEND_SYSTEM.md的关系理清楚,配置就成功了一大半。打个比方:AGENTS.md是给新员工的项目手册,告诉他这个项目的历史、结构、规矩;APPEND_SYSTEM.md是岗位行为规范,告诉他作为助手应该怎么说话、怎么做事。
两者配合得好,效果是叠加的。举个例子:AGENTS.md里写了"提交前必须跑make lint",APPEND_SYSTEM.md里写了"改动完成后主动提醒下一步操作"。那么 Pi 在你改完代码后,会主动说"改动完成,建议执行make lint验证"。这就是配置带来的"主动性",而不是每次都要你提醒。
5. 常见问题与排查技巧实录
5.1 配置改了不生效?按这个顺序查
这是最高频的问题。我整理了一个排查顺序,基本能覆盖九成情况:
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| 改了没反应 | 改错层级(全局 vs 项目) | 确认文件路径,项目级优先 |
| 部分生效部分不生效 | 被更高优先级覆盖 | 检查是否有同名文件 |
| 规则重复出现 | 全局和项目都写了 | 去重,只留一处 |
| 模型切换无效 | 别名拼写不一致 | 核对 settings 与 models 的别名 |
| 上下文塞太多 | ignorePatterns 没生效 | 用大目录实测忽略规则 |
排查的核心思路是从加载顺序倒推。Pi 先读全局再读项目,后读的覆盖先读的。所以当你发现"改了没用",第一反应应该是"是不是有个更高优先级的文件把它盖了"。
5.2 上下文爆炸:Pi 变慢变贵的元凶
用一段时间后,很多人会发现 Pi 越来越慢、越来越贵。八成是上下文失控。常见诱因有三个:
- ignorePatterns 没配好,Pi 把
node_modules里的文件也读进去了。 - maxContextFiles 设太大,一次塞几十个文件。
- AGENTS.md 写太长,本身占用了大量上下文。
我的处理办法是给AGENTS.md设一个心理上限——控制在 200 行以内。超过这个长度,说明你把太多细节塞进去了,应该把详细文档放到docs/里,AGENTS.md只留索引和关键约定。Pi 需要细节时会自己去读docs/,不需要你一次性全喂给它。
实操心得:我习惯在
AGENTS.md末尾加一句"详细设计见docs/architecture.md,需要时再读"。这样既给了 Pi 线索,又不占用默认上下文。实测下来,响应速度和成本都有明显改善。
5.3 模型选错的典型场景
模型选错不会报错,但会让你觉得"Pi 今天怎么这么笨"。几个典型场景:
- 用 fast 模型做架构设计:快模型推理能力弱,给出的方案往往浮于表面。复杂问题一定切
reason。 - 用 reason 模型做格式化:杀鸡用牛刀,又慢又贵。杂活交给
fast。 - 温度设太高写代码:输出不稳定,同样的需求两次结果不一样,没法复现。
我的习惯是默认用 main,遇到卡壳手动切 reason,杂活切 fast。切换动作要养成肌肉记忆,别一个模型用到底。
5.4 一份可以直接抄的配置检查清单
最后给一份我每次新项目初始化时都会过一遍的清单:
- [ ]
settings.json里defaultModel指向别名而非全名 - [ ]
confirmBeforeWrite和confirmBeforeExec已开启 - [ ]
ignorePatterns覆盖了依赖、构建产物、日志目录 - [ ]
models.json里每个别名都填了准确的contextWindow - [ ] 主力模型温度在 0.1 到 0.3 之间
- [ ]
AGENTS.md包含定位、目录、命令、约定、禁区五块 - [ ]
AGENTS.md长度控制在 200 行以内 - [ ]
APPEND_SYSTEM.md全局和项目无重复规则 - [ ] 用一个真实任务跑一遍,确认命令和风格都符合预期
这份清单看着琐碎,但每一条背后都是我踩过的坑。尤其是最后一条——配置完一定要用真实任务验证,别配完就以为万事大吉。我见过太多"配置看起来很完美、实际一跑全是问题"的情况。
把这几块配好之后,Pi 才算真正从"玩具"变成了"主力"。它不再需要你每次从头解释背景,而是带着对你项目的理解直接进入工作状态。这个转变带来的效率提升,远比换一个更强的模型明显。后续如果要做更细的调教,比如针对特定语言或框架的专属规则,思路是一样的:先想清楚这条规则属于"机制"还是"内容",再决定它该进哪个文件。