给 AI 编程助手装一个「经验本」:从扩展到 Skill 的进化

· 更新于 2026-07-31

用 AI 编程助手(这里用的是 pi)排查问题有个通病:一次费尽九牛二虎之力搞定的环境难题,聊完那一刻知识密度最高,关掉会话后就慢慢蒸发,下次又得从头查。

我给它做了一个「经验本」:一句话就能把刚解决的经验沉淀成可复用的手册。有意思的是它经历了两版——第一版是正经的扩展插件,弹框问标题摘要、生成空模板;用了一次就发现别扭,于是砍掉代码和用户输入,简化成一个 Skill。这篇记录这两版的取舍,结论很简单:当任务的核心智力在 LLM 时,一个 Markdown 指令比一个插件更合适。

问题:经验聊完就蒸发

手写笔记当然可以,但有两个反人类的环节:

第二个问题更关键——既然每天都在和助手对话,让它「记得」自己曾经解决过什么,比给人看的笔记更有杠杆。

设计:正文 + 常驻索引

pi 约定 ~/.pi/agent/AGENTS.md用户级上下文文件,每个会话启动时自动读进系统提示。所以把它当「索引页」最合适:只放高复用的索引与摘要,正文放进 lesson/ 子目录。

~/.pi/agent/
├── AGENTS.md            # 每次会话自动加载:环境 + 索引表
├── lesson/              # 经验正文(一篇一事)
│   ├── network-proxy-tls-ca.md
│   └── publish-my-web.md
└── skills/
    └── lesson.md        # /skill:lesson(指令,agent 自主执行)

第一版:扩展插件(能用,但别扭)

pi 的扩展是一个导出默认工厂函数的 TypeScript 模块,用 jiti 加载。第一版我注册了一个斜杠命令,用 ctx.ui 弹框和用户交互:

pi.registerCommand("lesson", {
  handler: async (args, ctx) => {
    const title   = await ctx.ui.input("经验标题", "简短主题");
    const summary = await ctx.ui.input("一句话摘要", "症状/要点");
    writeFileSync(`lesson/${slugify(title)}.md`, buildTemplate(title, summary));
    ensureIndexRow(...);   // 置顶 + 去重的几十行 TS
  },
});

它工作正常,但有两个越想越不对劲的地方:

关键转折:提取与总结,本就该 agent 干

回头一看,这个任务的核心智力——提炼主题、起标题、写摘要、把对话整理成 runbook——全在 LLM 身上,不需要也不该用代码固化。代码只该负责确定性的事(文件路径、索引去重),而这些 agent 用它自带的 read/write/edit 工具就能做。

于是把扩展删了,换成 Skill:一个带 frontmatter 的 Markdown 文件,内容就是给 agent 的操作指令。pi 自动发现、注册为 /skill:lesson,hot-reload 改完即生效。

第二版:Skill(全自动、零代码)

整个 skill 就是一个文件(节选):

---
name: lesson
description: 把刚做完的有价值排查/踩坑沉淀成可复用经验。
  全自动——agent 自动提取标题、摘要、正文,无需用户输入……
---

# lesson — 沉淀一条经验(全自动,不要问用户)

## 流程
1. 提炼:从最近对话/操作归纳 症状 / 根因 / 解决 / 验证 / 注意
2. 标题、slug、一句话摘要(都自己定,别问用户)
3. 写正文到 ~/.pi/agent/lesson/<slug>.md(写满,别留空骨架)
4. 更新 ~/.pi/agent/AGENTS.md:表格分隔行后置顶插一行,按链接去重
5. 确认,不要让用户补任何字段

没有 ctx.ui.input,没有几十行 TS。agent 读完这段指令,用自己的工具把活干完。

工作流

  1. 触发:/skill:lesson,或直接说「记一笔 / 记录这个经验」——agent 从系统提示里看到 skill 描述,会自动按流程走。
  2. agent 自己:读对话 → 起标题 → 写满正文 → 索引置顶去重 → 告诉你路径。
  3. 全程零输入。本文配套的「发布到 my_web」那条经验,就是这么记下来的。

为什么 Skill 胜出

维度扩展 /lesson(v1)Skill /skill:lesson(v2)
谁起标题/写摘要用户手输agent 自动
正文空模板,靠手填agent 据对话写满
代码量~150 行 TS0(一个 .md)
改流程改代码 + /reload改 Markdown + /reload
适合的任务确定性 / 需和系统交互智力在 LLM

小结

判断标准很简单:这个任务的核心是「想」还是「做」? 要是想(归纳、起名、总结、写文档),交给 agent 配一个 Skill 指令;要是做(固定路径、去重、调系统 API),才写扩展。经验沉淀恰好是前者——所以一个 Markdown 文件,比一个插件更合适。