
说实话把 Pi 系列的第六篇写到 skills 机制上我内心是有点兴奋的。前面几篇我们分别聊过 Pi 的环境搭建、基础对话、文件操作能力和多步任务拆解但那些都还是“把 Pi 当做一个聪明的对话工具”的范畴。到了 skills 这一步才算真正意义上把 Pi 从一个“偶尔帮得上忙的助手”变成了一个“个人专属的工程团队”。我用它跑了快两个月的项目最大的体会是不会写 skills 的人和会写 skills 的人用的是两种完全不同的工具。这篇就把我踩过的坑、验证过的方法、以及这套机制背后的设计逻辑一次性讲清楚全程从零讲起哪怕你前五篇都没看过也能直接上手。先说清楚这篇文章要解决什么问题。Pi 的 skills 机制简单说就是允许你把“一套完整的、有步骤的、带规则的工作方式”打包成一个文件让 Pi 在遇到对应场景时自动调用。它解决的是三个非常实际的痛点第一你不用每次对话都重新把方法论输入一遍第二Pi 不用在上下文里加载大量无关的提示词反应更快、错误更少第三团队里沉淀的经验可以从个人大脑里转移到统一技能文件里新成员接手就能有一致的行为底线。这篇文章适合三类人正在用 Pi 做正经项目、希望输出质量更稳的开发者还没入门但听说 skills 很强大、想搞明白原理的观望者以及用过一点 skills、但描述写不好所以效果不理想的困惑选手。1. 为什么 coding agent 必须有一套 skills 机制1.1 从“每次重新教”到“教一次复用”agent 协作的真实困境我先讲一个真实的场景。早期我用 Pi 做前端项目时频繁需要它帮我为新写的组件补测试。一开始我的做法是把测试框架的配置、过往组件的测试写法、当前组件的上下文全部贴在对话里然后让 Pi 照着写。听起来可行但实际上每次都要花十几分钟整理上下文而且 Pi 写出来的测试风格飘忽不定——今天喜欢用describe/it明天变成test今天我要求 mock 掉网络请求下次它忘了直接发真实请求。这个问题的本质是对话上下文是易失的。模型每轮都在根据当前 token 做预测昨天的指令不会自动变成今天的偏好。Skills 机制的出现就是要把这些“容易被遗忘的规则”从对话里抽出来固化成一个可命名的、可匹配的、按需加载的独立模块。打个比方不带 skills 的 agent 像一个记忆力时好时坏的临时工你每天都要重新交代工作标准带上 skills 的 agent 像一位带着操作手册上岗的资深工程师手册没翻到对应章节之前不废话翻到了就严格按照规程执行。这套“手册”存在哪里、长什么样、什么时候被翻出来就是这个机制要解决的全部问题。1.2 上下文预算不是省 token是防止 agent 变笨很多人第一次听说 skills 机制时第一反应是“这不过就是省点 token 钱嘛”。这个理解有偏差。上下文窗口确实是一种成本但更重要的是上下文越长模型对关键指令的注意力就越容易被稀释。我做过一个粗略的对照实验在同一段代码上分别让 Pi 在“附带 6000 token 杂项规则”和“只附带 2000 token 核心规则”两种状态下补一个功能后者不仅完成速度更快而且对函数命名、边界处理这类细节的遵循度明显更高。而 skills 机制恰好是“按需加载”的它不会把几十个技能文件全部塞进上下文。Pi 平时只会在记忆里维护一份技能索引一般就是每个技能的名称加一句描述这个开销可以忽略不计。只有当你当前的任务与某个技能描述高度匹配时Pi 才会去读取对应的完整技能内容。这个设计逻辑跟人脑的运作方式很像你不会每次写代码时都把整本编程规范从头到尾默背一遍而是遇到“这段代码要提交了”才想起“哦我应该跑一遍 lint”。上下文不是无限膨胀的仓库而是一张桌面——skills 机制保证了桌面上只放当下要用的工具其余的全部收在抽屉里。1.3 团队与社区的技能沉淀载体第三个视角是协作。一个人的经验沉淀成技能文件带来的效率提升可能是两三倍但一个团队的经验沉淀成一套统一技能库带来的效率提升是指数级的。拿代码审查来举例公司内部通常有自己的一套规范——不要写超过 100 行的函数、提交信息必须带需求单号、所有对外接口都要有 JSDoc。这些规范如果只存在于某个负责人的大脑里那每个人审代码时标准都不一样如果把它固化成一份代码审查.skills文件那么团队里任何人让 Pi 做 reviews拉出来的规则都是同一套。这也是为什么 GitHub、各个 agent 社区里会有大量共享的 skills 仓库例如热搜里频繁出现的“claude code skills”“opencode skills”本质上都是经验的模块化流通。而且从社区热词也能看到skills 已经覆盖到了“前任.skills下载”“测试用例skills”“数学建模skills”“渗透测试skills”这类细分领域。这说明它已经不是极客自嗨的小玩具了而是正在变成 agent 世界里的“app store”。所以理解 skills 机制的底层逻辑比单纯会装一两个技能文件要重要得多——前者让你永远跟上生态后者只让你会用某个具体工具。2. skills 的最小可行骨架一个 skill 文件到底装了什么2.1 最简目录结构与必备字段第一次拆解 skills 机制时我最关心的问题是“最小可用的 skill 长什么样”。经过多次实验我把最核心的结构压缩成了一个目录加一个文件my-skill/ └── SKILL.md对你没有看错它不需要代码不需要脚本只需要一个 Markdown 文件。这也是 skills 机制最聪明的地方——它把“技能定义”与“具体执行”解耦了你可以在 SKILL.md 里写纯文本规则也可以在里面引用脚本、调用工具甚至直接让 Pi 执行一段 Python。真正的门槛不在格式而在内容组织。SKILL.md 内部最通用的、我看下来各个实现都认可的必备字段有三个字段作用写作难度name技能的唯一标识加载索引时靠它区分简单description一句话描述这个技能适用于什么场景agent 靠它决定是否调用难正文内容具体的规则、步骤、示例是 Pi 被加载后实际遵循的指令体最难为什么说description很难因为它是 Pi 判断“当前要不要用这个技能”的唯一依据但它又不像算法里的标签一样可以精准匹配。模型是在做语义匹配description写得太平凡任务来了它意识不到这里有个技能可用写得太过宽泛它又会在不该用的场景里强行拉出来。后面第 6 节我会用实例专门讲怎么校准描述这里先记住一个总原则description 是对“触发场景”的描述不是对“技能功能”的赞美。2.2 描述字段为什么是灵魂我要把这一节单独拎出来强调是因为我见过太多人栽在这个字段上。比如有个人写了一个“前端开发 skills”描述是“这是一个帮助前端开发的强大技能覆盖各种前端场景”。这种描述在 Pi 的索引里几乎等于没有因为它跟任何普通的前端提问都能沾上边但没有一个场景能精准命中。结果是 Pi 经常在只是“帮忙改一下这个按钮的颜色”时也加载一个几百行的大技能浪费上下文还容易用错规则。我后来总结了一个好用的公式描述 “当用户需要 [具体任务类型]尤其是 [更细的场景特征] 时使用此技能。”举例来说与其写“前端开发技能”不如写“用户需要为 React 组件编写单元测试或调整测试配置时使用包括 jest、testing-library 相关的依赖安装和 mock 策略”。这样 Pi 在做 Vue 项目时基本不会误用但一旦识别出“React”“测试”这两个关键词组合就会准确地把这个技能拉出来。这里多说一句description的措辞不是写给人看的是写给模型看的。人类看“为 React 组件编写测试”觉得很清楚模型也清楚但如果你在前面加上“这是一个……的技能”这类空话反而会稀释语义。我实测下来用祈使句或条件句写 description模型命中率最高例如“When the user asks to generate tests for React components, use this skill”。这个规律在多个 agent 上都成立。2.3 一个开箱能用的例子代码审查 skill说再多理论不如直接给一份可复制的模板。以下是我目前正在用的一个代码审查 skill删掉了内部业务敏感信息保留了所有关键结构--- name: code-review description: 用户要求审查代码、检查 PR、找 bug 或提出代码改进意见时使用。尤其适合 JavaScript/TypeScript 项目 --- # Code Review 规则 ## 第一遍通读全局 1. 先了解项目的目录结构和技术栈 2. 识别本次审查的文件范围及其依赖关系 ## 第二遍逐文件审查按优先级检查以下项目 - 正确性逻辑错误、边界条件、空值处理 - 安全性用户输入校验、敏感信息泄漏、依赖漏洞 - 性能循环内不必要的计算、重复请求、可缓存的数据 - 可维护性函数长度、命名一致性、重复代码 - 测试覆盖关键路径是否有对应测试 ## 输出格式 按“问题位置 - 问题的严重程度 - 问题说明 - 修改建议”的方式列出。 严重程度分为 blocker / major / minor其中 blocker 是必须修复的问题。 给出总体结论是否建议合并以及合并前必须完成的事。 ## 红线 - 不要在没有证据时凭感觉报问题每个问题必须对应具体代码位置 - 不要修改代码只做审查与建议 - 如果审查内容超过 1000 行先列出文件清单确认范围再继续这个模板我用了很久它体现了一个好的 skill 应该有的几个特征有步骤、有优先级的边界、有固定的输出格式、有红线规则。其中“输出格式”特别关键它保证每次审出来的结果长一个样这样团队 review 的时候扫一眼就能定位信息而不是翻来翻去。3. 手写实战把一个前端开发工作流做成可调用 skill3.1 先拆流程再写配置我选的工作流理论部分过了现在来做一次完整的实战。我选的场景是“为新功能补齐测试并跑通覆盖率检查”这是我在前端项目里最常做、又最希望标准化的流程。先说明白我为什么要挑这个场景它包含明确的判断条件什么时候要补测试、标准的工具调用vitest、c8、istanbul、以及清晰的产出物覆盖率报告。这种带有规则和步骤的场景最适合作成 skill——如果场景本身是一句话就能回完的那做成 skill 反而是负担。动手之前我先在纸上画出流程需求输入 - 分析改动点 - 定位受影响的测试文件 - 写测试用例 - 跑单测 - 检查覆盖率 - 低于阈值则补充用例 - 输出测试摘要这七步就是这个 skill 的主干。写 skill 的一个核心经验是先把流程拆出来再考虑怎么写描述、怎么组织正文。很多人在电脑前打开编辑器就对着空白 SKILL.md 发呆就是因为脑子里只有“做一个测试 skill”这个模糊目标没有具体到步骤级。3.2 逐行编写 skill 定义与提示词流程确定后我开始写文件。首先是name和description--- name: frontend-test-coverage description: 用户要求为新增或修改的前端功能补齐测试并确保测试覆盖率达标时使用。涉及 vitest、jest、react testing library 的项目优先使用 ---这个 description 跟第 2 节里被批评的“前端开发技能”相比差别在于它锚定了三个信息具体动作是“补齐测试”判断标准是“覆盖率达标”适用技术栈是“vitest、jest、RTL”。Pi 看到这个描述后即使不是 100% 确定也会先加载再说而一个泛泛的描述它根本不知道什么时候该用。接着是关键的正文本体。我按流程章节组织并在每个步骤旁注明了原因# 前端测试补齐流程 ## 第一步定位改动点 1. 查看用户描述的改动内容结合 git diff 获取变更文件列表 2. 标注新增/修改的函数和组件的 props、状态、异步逻辑 ## 第二步识别测试缺口 - 对每个改动点判断现有测试是否覆盖 - 正常路径 - 错误/边界条件 - 异步加载与 loading 状态 - 给出缺口清单格式为文件 - 函数/组件 - 缺失场景 ## 第三步编写测试 1. 优先补充与改动逻辑紧密相关的测试不要大范围重构旧测试 2. 测试命名遵循 should do something when condition 格式 3. 涉及网络请求时一律使用 mock禁止发出真实请求 4. 断言优先使用 behavior 语义比如 testing-library 的 getByRole而不是测试实现细节 ## 第四步运行与校准 1. 运行测试命令npx vitest run 2. 如有失败先看是断言问题还是被测代码问题是断言问题就直接修是被测代码问题则报告不要擅自改业务代码 3. 运行覆盖率命令npx vitest run --coverage 4. 若覆盖率低于 80%继续补测试直到达标如果存在无法覆盖的分支如环境判断在摘要中说明原因 ## 第五步输出摘要 按以下格式返回 - 改动点清单 - 新增测试文件/用例数量 - 覆盖率数据行、函数、分支 - 遗留的未覆盖项及原因可以看到这套指令里我刻意写了“不要擅自改业务代码”“禁止真实请求”这样的硬边界。是因为经验告诉我不给 agent 画红线它就会根据自己的“自由意志”做出不可控的操作。好的 skill 不是让模型完全自由发挥而是把自由限制在安全的笼子里让它在这个范围内做最优决策。3.3 加载与验证让 agent 真的带上这个技能文件写好之后还需要把它放到 Pi 能扫描到的目录并验证加载。不同的 agent 实现默认目录通常不同有的放在~/.pi/skills/有的支持项目内.pi/skills/。我当时的操作是在项目根目录建了.pi/skills/frontend-test-coverage/目录把 SKILL.md 复制进去重启会话让 Pi 重新加载技能索引输入一句“帮我给这个新加的 DatePicker 补一下测试跑下覆盖率”观察反馈验证有没有被正确加载最直观的办法是先执行一次/skills之类的内置命令确认列表里有frontend-test-coverage这个名字。然后我故意把请求说得模糊一点——“测试一下日期选择器那个功能”看 Pi 是否能自己识别出应该调用这个 skill。如果它没识别出来我会检查 description 是否有问题而不是怪模型笨。这个“先确认加载、再验证命中、最后评估执行质量”的三步流程是我每次写完一个新 skill 之后必做的自检建议你也养成习惯。实测下来这个 skill 的命中率非常高。而且比手动教 Pi 更省心的是它不止省了指令还省了我反复强调“mock 网络请求”“命名格式”这些规则的时间——因为这些已经在文件里了所以输出一次比一次接近我想要的样子。4. 加载与调用链路agent 怎么决定用哪个 skill4.1 从用户请求到 skill 匹配的完整链路前面两节都是在讲“写”这节讲讲“用”。很多人写完 skill 后会好奇我什么都没告诉 Pi 今天要用这个技能它是怎么在需要的时候把它翻出来的如果你拆开看内部的匹配链路大概是下面这样的我以 Pi 和一些主流 agent 的通用架构为例细节可能不同但大方向一致第一层是索引扫描。会话启动时Pi 会加载所有可用 skill 的元信息也就是上文说的name和description把它们作为一个轻量列表注入到上下文中。这个过程几乎不占空间但效用极大——它让模型在每次收到用户消息时都能“看到”自己有哪些弹药可用。第二层是语义匹配。当用户发来一条请求比如“帮我看下这段代码有没有问题”Pi 会将请求与索引里的每一条 description 做语义相似度计算。这里的实现不一定是数学意义上的向量检索有些 agent 直接靠模型推理完成判断但效果是一样的找到最贴近的那个描述。第三层是内容加载。pi 判断某个 skill 可能适用后才会去读取 SKILL.md 的完整内容注入当前上下文。如果判断“不适用”就完全不加载正文这也是性能优化的关键所在。第四层是执行约束。注入的 skill 内容会充当系统层指令对后续几轮对话形成约束直到任务完成或出现明显更优先的新指令。这里要注意skill 一旦被触发它的规则会持续“在线”直到 Pi 判断当前上下文已经不属于这个技能范围。所以如果你的 skill 里写着“按以下格式输出”那这段格式会在本次整个任务中反复生效。4.2 上下文注入方式与适用场景既然说到“注入”就不得不提一个关键问题skill 注入的上下文是以什么形式存在的我理解它本质上是在用户请求之外、系统提示之内插入了一段临时的指令块。这个位置很重要因为系统提示对模型的约束力远大于普通对话内容。这也是为什么在 skill 里写的规则比你在对话框里说的“你记得要……”要好用得多的原因——它不是商量是设置。但这带来一个副作用不恰当的注入会污染其他任务。举个我踩过的例子。我给 Pi 写了一个“会议纪要整理”的 skill里面规定了输出格式是“结论-依据-行动项”。有一次我让它分析一段代码日志它居然也用类似格式输出了。原因就是那个 skill 的 description 写得有点宽系统认为日志分析也算某种“整理总结”所以把整份规则加载了进来。这件事给我的教训是触发条件必须足够“窄”宁可让 skill 偶尔漏触发也不能让它频繁误触发。围绕注入方式我通常把 skill 分成两类来设计Skill 类型适用场景常见写法风险流程型多步骤、有固定顺序的工作流步骤清单、判断条件、输出格式步骤过于僵化不适合开放任务偏好型希望输出风格或质量标准一致正负面示例、红线规则描述过宽容易误触发实际项目中一个 skill 往往是两者混合。比如代码审查技能既有流程步骤先看全局再看细节也有偏好约束不修改代码只提建议。关键是要清楚每个字段在注入后扮演什么角色这样才能在写的时候有意识地控制边界。4.3 多 skill 依赖与执行顺序控制再进阶一点的话题当一个任务同时涉及两个技能时Pi 是怎么处理的我测试过不少场景最典型的是“前端开发”和“代码审查”同时被触发——比如用户说“帮我开发一个新页面然后验证一下代码质量”。理论上这需要两个 skill 配合但很多 agent 的实现会让两个 skill 的内容同时注入如果没有明确顺序就会导致指令互相干扰。我的解决策略很简单在一个 skill 中去显式调用另一个 skill。举例来说我在“前端开发”skill 的最后一步写了“如果任务包含代码审查需求请在开发完成后调用 code-review 技能执行第二轮检查”。这样 Pi 就会先按“前端开发”的步骤走完再切换成“代码审查”的规则来审视自己的产出。这种显式的依赖声明比让模型自己猜顺序要可靠得多。另外我也遇到过 skill 之间指令冲突的情况。比如两个 skill 都定义了“输出格式”后者注入后覆盖了前者。遇到这种情况我的建议是在写 skill 时统一一个约定每个 skill 只对自己负责的领域定义输出格式不要试图规定总体的交流风格。比如代码审查 skill 只管“审查结果的格式”不要去规定“所有回复都要用中文”。因为前者是局部约束后者是全局行为全局行为应该放在 agent 的基础配置里而不是塞进某个 skill。5. skills、MCP 工具和内置 tools 的分工边界5.1 三者本质差异与协作方式聊到 skills 就绕不开一个热门问题skills 跟 MCPModel Context Protocol工具、以及 agent 内置 tools 到底有什么区别这三个概念经常出现在同一篇文章里但它们的定位完全不同。用一张表说清楚机制本质解决什么问题类比内置 tools预置能力如执行 shell、打开文件、搜索项目agent 的基本生存技能手脚MCP 工具外部服务的标准化接口如 GitHub API、数据库查询与外部世界通信电话线Skills一套提示词与规则集合决定“怎么做”而不是“能做什么”操作手册这里最容易被混淆的是 MCP 和 skills。MCP 解决的是“连接”问题——让 agent 能调外部服务skills 解决的是“行为”问题——让 agent 按特定流程工作。连接用的工具不会告诉你该不该用而行为规则则决定了你用连接工具的方式。比如一个“数学建模 skills”可能会定义“在建模前先分析问题类型、选用模型、写代码求解、验证结果”这四个步骤而模型求解过程中要联网获取数据那才轮到 MCP 工具上场。5.2 在 skill 中调 MCP 的合法姿势既然两者要协作那“skills 如何调用 MCP 工具”就成了一个实际的操作问题。我在 Pi 上的做法是这样的skill 正文里直接写“当需要获取 XX 数据时调用名称为 XX 的 MCP 工具”然后描述清楚使用它的前提和参数要求。因为 MCP 工具本身已经暴露成 agent 可调用的函数skill 的任务只是告诉模型“在哪个环节、出于什么目的去调用它”。举个实际例子。我在写“学术研究 skills”时需要 Pi 在调研阶段实时搜索论文。我在技能文件的第二步写了“使用 search-paper 这个 MCP 工具搜索与主题相关的论文搜索关键词不少于三个维度再调用 fetch-paper 获取摘要”。这样当技能被触发时Pi 就会在正确的节点主动发起工具调用而不是空想内容。这就实现了“流程规则 外部数据”的组合。但是这里有个重要细节skill 不能强制 MCP 工具存在。如果当前 Pi 环境里没有配置 search-paper 这个工具那 skill 加载后调用就会报错执行流程也会中断。所以我在写带工具依赖的 skill 时都会在文件开头加一段“前置条件”明确该技能需要哪些 MCP 工具方便自己在新环境里快速检查。这也是团队分享 skill 时比较容易忽略的坑——你本地跑得好好的朋友 clone 过去却发现一堆调用失败多半就是前置工具没有配齐。5.3 选型判断这里应该用 skills 还是 MCP最后一个实操问题当我有一个新的需求时我该怎么判断“这应该做成 skill 还是做成 MCP 工具”我自己的判断标准有两条第一条是看“有没有外部交互”。如果任务的核心动作是请求外部服务——读数据库、操作 GitHub、发消息——那必须用 MCP 工具因为它涉及认证、协议、数据格式。skill 永远取代不了 MCP 的连接能力。第二条是看“规则复杂度”。如果任务本身很简单一句指令就能完成做成 MCP 工具更合适如果任务需要多步判断、有规则约束、有固定的输出模板那就算涉及外部调用也应该在 skill 里编排工具的使用方式。你也可以反过来理解MCP 是“原子能力”skills 是“工作流”原子能力可以被多个工作流复用工作流则把原子能力串成有意义的产出。最理想的项目结构是项目里既有少量复用度极高的 MCP 工具又有按场景划分的多份 skill 文件。前者回答“能调什么”后者回答“怎么调才对”。拿一个热搜词里的“渗透测试 skills”来说说这类安全测试技能与 MCP 的关系就特别典型。渗透测试需要扫描端口、解析响应、分析漏洞这些“连接”动作走 MCP但测试步骤、漏洞分级、报告格式、合规红线这些“行为”就必须靠 skill 来约束。一个只接 MCP 没有 skill 的 agent像是一个有能力但没受过训练的新人有了 skill 之后才像是拿了 SOP 上岗的正式员工。两者缺一不可。6. 我踩过的 skills 坑维护性比“能做出来”更重要6.1 描述写得太泛agent 在多个场景里反复横跳前面已经反复提过 description 的重要性但我要用一个真实翻车案例来收尾。有一段时间我给 Pi 配置了一个“通用代码优化”技能描述是“用户需要对代码进行优化时使用包括性能优化、可读性优化、架构优化”。听起来没问题对吧实际用起来完全不是那么回事——每次用户只是问“这个函数为什么这么慢”Pi 都会把这个大而全的技能加载进来然后按照技能里规定的步骤又是分析调用栈、又是画复杂度表格一个原本可以几句话回答的问题被拖成了长篇报告。我后来把技能拆成了三个独立的小技能“性能热点排查”“代码可读性重构”“依赖与架构梳理”。每个描述都限定了触发场景和推断依据。拆完之后误触发率下降得极其明显。这个教训被我总结成一句话一个技能只解决一个场景描述里出现“各种”“所有”“通用”这类词时要警惕它是不是写大了。6.2 把 skill 写成死板脚本参数化失败另一个翻车点是内容设计。我第一次写“部署流程 skills”时在步骤里写死了“执行npm run build然后把 dist 目录上传到服务器”。听起来没毛病但等到项目里换了包管理器从 npm 换到 pnpm这个 skill 就立刻过时了。后来我重新整理把所有工具命令抽成了“参数化指令”- 使用该项目配置的包管理器执行构建命令判断依据项目根目录存在 pnpm-lock.yaml 时使用 pnpm存在 yarn.lock 时使用 yarn否则使用 npm这样技能就不再绑定具体工具而是绑定“判断逻辑”。这看着是小事但在维护上差别巨大——我不用每次项目改配置就去改技能文件了。类似的还有别在技能里写死目录路径除非这个 skill 就是为某个固定项目服务的也别写死版本号除非你确实需要锁版本。好的 skill 是告诉你“如何根据当前情况做决策”而不是告诉你“执行这五条命令”。6.3 skill 的版本管理它也是团队代码资产最后一个不建议大家忽略的点skill 文件本身要纳入版本管理。我见过很多团队代码放在 Git 仓库里管理得井井有条但 Pi 技能文件散落在各个成员的本地目录里互相之间不同步。这样做的后果不用多说同一个人在不同机器上得到的行为不一致团队里两个人调出同一个技能结果规则却不一样。我的建议是把项目相关的 skill 放在项目代码仓库里跟代码一起走比如.pi/skills/目录。这样做有三个好处第一新成员 clone 代码时自动获得技能不需要额外安装第二code review 时附带的 skill 变更可以被审到避免有人悄悄改了规则第三技能会随着项目演进同步迭代不会出现“代码已经改了技能还是旧版”的错位。个人通用的、跟具体项目无关的那些技能我建议放在用户级别的技能目录里区分开“个人能力”和“项目规则”两层避免混在一起后出现不该触发的跨项目污染。这一路从初识 skills 机制的兴奋到写废好几个文件的挫败再到摸清规律之后的顺手中间最大的感悟是skills 本身不神秘它就是一个“把你脑子里的工作方法外置”的过程。写它的难度不在于语法而在于你有没有把流程想明白、把边界划清楚。如果你现在正准备给 Pi 写第一个 skill我建议你从最小的场景开始先写一个只有三步的流程技能跑通一次完整的“写-加载-命中-执行”链路再慢慢加复杂度。用不了几次你就能体会到“agent 开始按你习惯的方式干活”是一种多么上瘾的感觉。