从 Pi 系列前五期一路看过来,到家人们应该已经对 Pi 的定位、安装、基础对话、工具调用和项目落地有数了。这期我们把镜头拉到真正让 Pi 从“聊天机器人”变成“能干活的老兵”的那个机制——skills。不管你是刚听说这个概念,还是已经在 Claude Code / Codex / OpenCode 里跳过坑,这篇都值得你读完。我会从 Pi 的 skills 是什么、目录结构怎么摆、怎么写一个能用的 skill、怎么和 MCP 工具配合,再到常见问题排查,全流程拆一遍,争取让零基础的人也能跟着把技能装进 Pi 里。
1. skills 到底解决的是什么问题
1.1 从“到处贴提示词”到“能力模块化”
在没有 skills 之前,用 AI 编程助手大概只有两条路:要么把行业规范、项目背景、代码风格全塞进 system prompt 里,结果上下文被占满,对话一长就“失忆”;要么每次都手动复制一大段专业背景给 agent,写几分钟提示词、干几秒钟活,效率极低。skills 机制就是来终结这种“提示词裸奔”状态的。
你可以把 skills 理解成一组“可插拔的能力插件”。一个 skill 通常是一个单独的文件夹,里面有说明文档,可能还有配套脚本、模板或参考资源。Pi 会在合适的时机把这个 skill 的内容注入到对话上下文里,相当于告诉它“现在有一份专门处理这类任务的专家手册,你按这个来”。这样一来,日常对话的上下文不会被无关规则占满,真到用的时候又能拿到完整、结构化的操作指南。
我在实际使用中体感最强的是:以前让 Pi 按公司前端规范写页面,我得先粘贴一大段规范再描述需求。现在只要在项目里装一个“company-frontend-style”的 skill,然后正常描述“帮我写个列表页”——Pi 自己就会识别任务类型并加载这套规范。省掉的不是几行字,而是那种“每次都要重新教育 agent”的疲惫感。
1.2 Pi 中 skills 的目录结构与加载规则
Pi 的 skills 默认放在两个位置,一个归用户,一个归项目:
# 用户级 skills,所有项目都能用 ~/.pi/skills/<skill-name>/SKILL.md # 项目级 skills,只有当前项目用(会在 Git 里共享) <your-project>/.pi/skills/<skill-name>/SKILL.md每个 skill 文件夹的核心是一个SKILL.md文件,里面通常带一段 YAML frontmatter,用来写元信息。以我本地的frontend-reviewskill 为例,文件头部长这样:
--- name: frontend-review description: 用于前端代码审查,检查组件拆分、状态管理、样式规范、可访问性等问题。 trigger: 审查前端代码|review frontend|前端 review version: 1.0.0 ---Pi 加载 skill 的条件其实并不复杂。当用户输入一条消息时,Pi 会把SKILL.md里的name和description和当前请求做语义匹配,命中之后才把整个 SKILL.md 作为上下文的一部分交给模型。换句话说,description 写得好不好,直接决定 skill 会不会被“召唤”出来。另外,你也可以在对话里显式指定,比如写“使用 @frontend-review 审查这段代码”,或者输入pi --skill frontend-review,这种强制方式用来测试非常方便。
1.3 Pi 和 Claude Code、Codex、OpenCode 的 skills 差异
很多朋友是先从别的 agent 知道 skills 的,难免会拿 Pi 和它们对比。我简单整理了一张表,方便速查:
| 项目 | Pi | Claude Code | Codex (OpenAI) | OpenCode |
|---|---|---|---|---|
| 默认路径 | ~/.pi/skills | ~/.claude/skills | ~/.codex/skills | ~/.config/opencode/skill |
| 入口文件 | SKILL.md | SKILL.md | SKILL.md | SKILL.md |
| frontmatter 字段 | name / description / trigger / version | name / description /允许自定义字段 | name / description | name / description / agent 等 |
| 自动加载 | 语义匹配 | 语义匹配 | 语义匹配 | 语义匹配 |
| 配套脚本 | 支持 bash / python / node 等 | 支持 bash / python / node 等 | 支持执行脚本 | 支持执行脚本 |
| MCP 协同 | 通过工具调用层间接使用 | 支持脚本内调用或工具联动 | 类似 | 类似 |
发现没有?大家的设计思路非常像,都是SKILL.md作为入口,然后用自然语言描述做自动触发。真正的区别在底层 agent 的工具调用链路和沙箱策略。比如 Pi 在运行 skill 里的脚本时,权限控制会比 Claude Code 更“直给”一些,少了一些二次确认弹窗,但也意味着你需要自己注意命令安全。
2. 手写一个自己的 skill 包,从设计到落地
2.1 先别急着写文件,把需求想清楚
很多人一上来就建文件夹、写 markdown,结果写出来的 SKILL.md 跟一本流水账差不多。skill 不是文档,它是一段“可执行的思维流程”。动手之前,我会先回答四个问题:
- 这个 skill 要在什么场景下触发?
- 触发之后,Pi 应该按什么顺序做哪些步骤?
- 哪些步骤需要调用外部脚本或工具?
- 最后要产出什么东西?
举个例子,我写过一个“API 接口文档生成”的 skill。如果只是告诉 Pi “帮我把接口整理成文档”,它也能干,但质量和格式不稳定。我的 skill 里明确要求:先扫描项目路由定义,再对照 controller/service 层方法,提取请求参数和响应字段,最后输出 OpenAPI 3.0 格式的 yaml。这样 Pi 干起活来就有章法,而不是自由发挥。
2.2 SKILL.md 怎么写才不容易被模型瞎理解
SKILL.md的正文部分是给模型读的,不是给人读的。所以要尽量用清晰、短句、步骤化的语言,避免大段抒情。我的习惯是把它分成几个固定区块:
# 任务目标 一句话说明这个 skill 的最终输出是什么。 # 触发条件 列出哪些关键词、语义或文件特征会命中这个 skill。 # 操作步骤 1. 先做什么 2. 再做什么 3. 遇到什么情况怎么办 # 输出格式 要求模型以什么格式给出结果,越具体越好。 # 禁止事项 不该做的事,例如“不要修改 lock 文件”“不要发送网络请求”。使用这种结构之后,Pi 的执行稳定性明显提升。尤其是“禁止事项”,很多小白写 skill 会漏掉,结果模型自由发挥时总爱顺手改一些不该改的东西。比如我写自动化测试生成 skill 时,会在禁止事项里写“不得修改被测源码”“不得删除已有测试用例”,血泪教训。
2.3 装进 Pi 并用调试模式验证
写完之后,把文件夹放到 Pi 的 skills 目录即可,不需要额外编译。然后跑一条命令确认 Pi 能看到它:
pi --list-skills正常情况下会打印出所有已加载的 skill 数量和名称。如果没出现,优先检查目录名字是否合法、文件是否叫SKILL.md(严格区分大小写)、frontmatter 有没有语法错误。
接着做一次真实触发,最好带着关键词让 Pi 主动命中。比如我写完前端审查 skill 后,会在项目里放一段有明显问题的代码,然后输入:
pi "请审查一下 src/components/UserList.tsx 里的前端代码"用--debug模式启动 Pi,可以直接看到它是否加载了 skill、加载了哪个版本。这一步非常关键,因为很多“skill 不生效”的案例,都是模型理解偏差导致根本没有触发。
3. skills 进阶:让技能学会调用 MCP 工具
3.1 为什么 skill 要跟 MCP 扯上关系
MCP(Model Context Protocol,模型上下文协议)解决的是“agent 如何标准化地访问外部数据和工具”的问题。简单理解,MCP 就是一个工具服务器,Pi 可以通过统一的协议去调用文件系统、数据库、浏览器、企业内部 API 等能力。
但 MCP 只是“手”,skills 是“大脑”。一个 skill 定义了任务目标、步骤和约束,而真正执行数据库查询或页面抓取时,需要 MCP 提供对应的工具。没有 skills 时,Pi 虽然有 MCP 工具,但不知道什么时候该用、怎么用;没有 MCP 时,skill 里的脚本再漂亮,也做不了动态数据获取。
打个比方:MCP 是工具箱里的电钻、螺丝刀、水平尺,skills 是一本装修施工手册。手册告诉你“先测水平,再打孔,然后拧螺丝”,你手里还得有工具,才能把活干出来。
3.2 在 SKILL.md 里安排 MCP 工具调用的几种姿势
第一种做法最简单:在 SKILL.md 操作步骤里写清楚“如果要做 X,请使用 MCP 工具 Y”。模型只要理解这句话,就会在对话中主动发起工具调用。比如我写过一个小工具类 skill,用来查天气并生成会议提醒,里面就写着:
1. 先调用 mcp__weather__query 获取目标城市的天气。 2. 如果天气为“下雨”,在会议提醒文档中追加“带伞”。第二种做法是在 skill 里放一个独立脚本,用 Python 或 Node 直接访问 MCP 服务器的接口,再把脚本执行结果返回给模型。这种方式适合那些需要精细处理数据的场景。比如我的“数据库巡检” skill 里,会运行一个inspect.py,通过 MCP 客户端连接数据库,查询慢查询日志,然后把结果整理成 markdown 表格。
3.3 参数传递和错误处理的硬经验
用脚本调用 MCP 工具时,最容易出问题的就是参数格式。不同 MCP 工具对参数的要求不同,有的要 JSON 字符串,有的要 base64,有的要文件路径。我踩过的坑是在 skill 脚本里硬编码了工具名,结果一旦 MCP 服务升级,工具名变了就全部报错。后来我习惯先在 Pi 里用自然语言让 MCP 工具跑一次,把底层请求参数抓出来,再写进脚本里面。
另外,脚本一定要做错误兜底。我的一个习惯是:所有脚本输出都加一个前置标记,比如[SKILL_OK]或[SKILL_ERR]。这样 SKILL.md 里可以指示模型,“如果看到 [SKILL_ERR],就不要继续往下走,直接把错误信息反馈给用户”。否则模型很容易在脚本报错后自行脑补一个假结果,那才是最坑的。
4. 实战:从 GitHub 热门的 skills 仓库里“借”思路</ number>array
4.1 superpower skills 和 baoyu skills 到底值不值得装
目前 GitHub 上最出圈的几套 skills 方案,一个是 superpower skills,一个是 baoyu skills,另外还有各种垂直领域的集合。我两个都实际装过,说点主观感受。
superpower skills 主打“把 agent 变成超人”,里面包含了很多像“问题拆解”“深度思考”“自我反思”这种偏思维层面的技能,更像是一套思维脚手架。它的优点是安装方便、文档详细,适合刚开始接触 skills 机制的人去理解“原来这种任务也能封装”。缺点是部分技能描述比较宽泛,加载后对具体业务帮助有限,有时候还会因为 description 写得太过含糊,导致 Pi 频繁加载一堆无关技能,白白浪费上下文。
baoyu skills 则更偏“实用工具包”,里面有 PPT 生成、学术研究、前端开发、测试用例生成等具体场景。这套我从里面抄了不少灵感,比如它为了让模型生成 PPT 更稳定,会在 SKILL.md 里约定好分页逻辑、页面标题层级、图片占位规则,这些细节非常值得学习。说实话,我不建议直接把整个仓库装进去,更建议按需挑一两个,拆开来改造。
4.2 把别人的 skill 改造成自己的东西
拿一个开源的“前端开发 skills”举例。原始版本是给 Claude Code 用的,但我直接复制到 Pi 里,发现几个问题:路径写的是~/.claude,脚本里用了 Claude Code 特有的工具名,还有一些步骤依赖了另一个 skill。改造它的时候,我做了三件事:
- 把 frontmatter 里的 description 改成更贴合 Pi 任务识别的表达;
- 把脚本里的工具调用改成 Pi 支持的 MCP 工具名,或者干脆改成纯 shell 命令;
- 把原来过于庞杂的步骤拆成两个 skill,一个负责组件生成,一个负责代码审查。
改完之后,再把整个文件夹放到 Pi 的项目级 skills 目录里,用真实需求跑一遍,看哪些步骤顺序不合理。这种“别人包好的 meal kit”虽然方便,但你只有自己下锅调味,才真正符合自己的口味。
4.3 按场景整理一份我觉得值得尝试的 skills 清单
这里我从自己的 skill 库里挑了十几个不同方向,列成表给大家参考。注意,这些不是让你一口气全装,而是告诉大家“哦,原来这个场景也能用 skills”:
| 场景 | skill 名称(自拟) | 核心用途 |
|---|---|---|
| 前端开发 | frontend-gen | 生成符合项目规范的组件和页面 |
| 代码审查 | frontend-review | 检查样式、状态、可访问性、性能隐患 |
| 测试用例 | test-case-writer | 根据接口和需求生成覆盖边界条件的用例 |
| 学术研究 | academic-research | 检索文献、提炼观点、生成综述草稿 |
| 数学建模 | math-model-builder | 拆解建模问题、推荐算法、生成实验代码 |
| 演示文稿 | ppt-slide-craft | 按大纲生成结构合理的 PPT 文案 |
| 结构图 | diagram-skill | 生成架构图、流程图、ER 图的 Mermaid/Graphviz 描述 |
| 安全测试 | security-review | 对代码做漏洞扫描和安全配置检查 |
| API 文档 | openapi-doc-gen | 分析接口并输出 OpenAPI 规范文档 |
看到这些例子你应该能发现,skills 的价值在于把“你脑子里默认的那套工作流”固定下来,让 agent 每次都按最高标准执行,而不是靠运气。
5. 常见问题与排查技巧实录
5.1 skill 不生效,先别怪 Pi
“我明明把 skill 放进去了,为什么它不执行?”这是我在评论区看到最多的疑问。参照我自己的排查顺序:
- 先运行
pi --list-skills,确认 Pi 已经扫描到该 skill; - 再看 SKILL.md 的 frontmatter 是否合法,YAML 缩进错误是最常见的坑;
- 看 description 是否足够明确,太模糊会让模型无法关联;
- 用显式调用方式测试,比如
pi "@your-skill-name 请执行任务";如果显式调用成功,说明问题出在自动触发策略上; - 用
pi --debug再跑一次,看日志里到底有没有加载这个 skill。
很多时候不是 Pi 不加载,而是模型认为当前任务跟这个 skill 没关系。这种问题的解法不是改代码,而是改描述。
5.2 上下文爆炸与记忆混乱
skills 装多了之后,Pi 的上下文会变得很挤。尤其是那些 description 写得“无所不能”的 skill,几乎每次对话都会命中,导致模型注意力分散。我的做法是严格限制 description 长度,越精确越好,并且尽量用“触发条件”而非“能力描述”。举个对比:
不推荐:description: 可以处理所有前端相关任务,包括组件、样式、状态、构建、部署…… 推荐:description: 仅用于审查已有前端组件代码,重点检查状态管理和可访问性。第二种写法让 Pi 只在前端审查场景下才加载,效果立竿见影。
5.3 脚本权限和沙箱问题
skill 里的脚本有时候跑不起来,最常见的原因是权限。Pi 的脚本执行受系统用户权限和目录权限影响,你放到~/.pi/skills下的脚本如果没有执行权限,就需要先chmod +x。另外,如果脚本里要访问非项目目录的文件,Pi 可能会因为沙箱限制直接拒绝。我的习惯是把所有依赖的外部文件都放在 skill 文件夹内部,保持“技能自包含”,这样搬到别的项目时也不会因为路径问题挂掉。
5.4 版本管理和团队共享
skills 本身也是代码,应该纳入版本管理。我在团队里的做法是建一个独立的skillsGit 仓库,用软链把项目里的.pi/skills指到仓库目录,这样大家 pull 之后就能同步。每次更新 skill 时,写清楚 changelog,尤其是 frontmatter 里 version 字段要同步变更。因为 Pi 在加载时可能缓存旧版本,遇到“改了不生效”的情况,重启 Pi 或者清缓存就好了。
在我实际用 pi 的这段时间里,最大的体会就是:skills 的价值不在于你装了多少个,而在于你有没有把真正高频、真正有门槛的任务沉淀成可复用的流程。很多人在到处找“全家桶”式 skill 包,但真正顺手好用的技能,往往是自己根据项目习惯一点一点打磨出来的。你不需要一次写得多完整,从一个很小的场景开始,比如“生成测试数据”或“检查代码格式”,用起来、改起来,等你攒到三五个真正顺手的 skill 之后,再回头看最初用 agent 的方式,会发现完全不是一个效率级别。