主题
Pi 的 Skill 与技能包
我的 Pi 环境里装了 100 多个 Skill,但真正参与每次对话的只有 7 个。剩下的不是没用,而是按需启用:Pi 在启动时只把技能的名字、描述和路径放进系统提示,等任务真的匹配时才读取完整的 SKILL.md。如果把所有技能都打开,光路由信息就会占掉大量上下文,模型反而更容易选错。
这篇记录截至 2026 年 10 月 27 日、Pi 1.4.0 的实际配置:哪些 Skill 生效、它们从哪来、各自解决什么问题,以及 5 个常驻技能包分别补上了哪块能力。
Skill 的加载机制
一个 Skill 就是一个带 SKILL.md 的目录,遵循 Agent Skills 规范。目录里可以放脚本、参考资料和模板,SKILL.md 负责说明「什么时候用、怎么用」。
Pi 启动时做三件事:
- 扫描用户级、项目级和包内的技能目录;
- 把每个技能的
name、description、filePath写进系统提示; - 等任务匹配时,由模型自己用
read打开SKILL.md,或者由我用/skill:name强制加载。
常用位置:
| 位置 | 作用 |
|---|---|
~/.agents/skills/ | 跨工具共享的 Agent Skills,Claude Code 等也能读 |
~/.pi/agent/skills/ | Pi 私有技能 |
.agents/skills/ | 项目级技能,随仓库走 |
包内 skills/ | 由 Pi 包声明并随包分发 |
Pi 还支持通过 settings.json 的 skills 数组增删技能。我当前的写法是「先全部关掉,再精确放行」:
json
{
"skills": [
"!*",
"+/home/mhwy/.agents/skills/reverse-engineer-anything/SKILL.md",
"+/home/mhwy/.agents/skills/ub-mode/SKILL.md"
]
}!* 关掉自动发现的技能,+ 再逐个放行。实际效果是:~/.agents/skills/ 下的 111 个技能(其中 35 个通过软链接出现在 ~/.pi/agent/skills/)除显式放行的两个外都处于「已安装、未启用」状态,而 nowledge-mem-pi 包自带的 5 个技能仍由包加载器提供。最终系统提示里只有 7 个技能。
什么时候用 /skill:name
模型偶尔会漏掉相关技能。明确知道要用某个流程时,直接输入 /skill:reverse-engineer-anything 分析这个安装包,比等它自己判断更稳。技能加载后,命令后面的文字会作为附加要求一起交给模型。
当前启用的 7 个 Skill
| Skill | 来源 | 解决什么问题 |
|---|---|---|
reverse-engineer-anything | ~/.agents/skills | 对二进制、Electron、固件、浏览器目标做逆向与行为取证 |
ub-mode | ~/.agents/skills | 用「先跑通、再写对、后成习惯」的约束收紧代码改动 |
read-working-memory | nowledge-mem-pi | 会话开始时加载当日工作记忆与关注点 |
search-memory | nowledge-mem-pi | 检索过往决策、偏好和操作流程 |
distill-memory | nowledge-mem-pi | 把值得长期保留的信息沉淀成记忆 |
save-thread | nowledge-mem-pi | 在明确要求时生成结构化交接摘要 |
status | nowledge-mem-pi | 检查 Nowledge Mem 服务连通性与配置 |
REA:依赖证据的逆向分析
reverse-engineer-anything(REA)解决的问题不是「读源码」,而是「手上只有成品」。它覆盖原生程序、托管程序、Electron/JavaScript 应用、打包产物、固件和浏览器目标,强调用实际发布物或运行时证据来回答功能、版本差异和实现方式的问题。
它和普通的仓库分析有一道明确分界:如果源码完整、问题只涉及代码结构,直接用常规仓库工具即可,不必启用 REA。只有当结论必须落在二进制、反编译结果或运行时行为上时,才值得走这套流程。
REA 的完整能力依赖一个独立的 MCP 服务。我的 ~/.pi/agent/mcp.json 里注册了:
json
{
"mcpServers": {
"rea": {
"type": "stdio",
"command": "npx",
"args": ["-y", "rea-agents@6.5.0", "mcp"]
}
}
}技能本身只提供指令,不负责安装引擎或注册服务。技能元数据标注的是 v42、207 项工具能力,但实际可用工具以当前 MCP 服务返回的列表为准;版本不一致时,以服务端为准,不照搬技能里的描述。
没有 MCP 或引擎不可用时,REA 也给了 CLI 兜底。例如分析一个 JavaScript 应用目录:
bash
npx -y rea-agents@6.5.0 analyze-javascript-application /path/to/app --json这种方式不需要 MCP 注册,适合临时排查。需要原生引擎的任务仍然要单独准备 Hopper、Ghidra 等环境,REA 不会替你装。
ub-mode:给改动套上纪律
ub-mode 是一份很克制的工程约束,核心顺序是:
- First Make it Work:先让最小的改动跑通;
- Then Make it Right:再修根因、补测试、拆函数;
- Follow Practice:最后固化成日志、提交和清理习惯。
里面几条规则对我特别有用:
- 一个决策只放在一个地方,能删的复杂度先删;
- 先定数据形状,再写逻辑;
- 测试从用户视角调用代码,若所有函数返回空值测试仍能通过,这个测试就是假的;
- 两个共享同一前提的修复都失败时,停下来把前提写成一句话,而不是继续打补丁;
- 改动要能重复执行,崩溃后重跑也落到同一状态。
它不会自动触发,通常在输入 /ub-mode 或明确要求「按精简原则改」时加载。
记忆五件套
nowledge-mem-pi 带来的 5 个技能围绕同一套跨工具记忆:
| 技能 | 触发场景 | 行为 |
|---|---|---|
read-working-memory | 会话开始 | 读取当日简报:关注领域、优先级、最近变更 |
search-memory | 任务涉及旧决策或偏好 | 用 nmem 检索记忆与历史会话 |
distill-memory | 对话产生可复用结论 | 主动沉淀为记忆,不用等人开口 |
save-thread | 明确要求做检查点 | 生成一份简短的续接摘要 |
status | 记忆命令报错或要查配置 | 检查服务地址、密钥与连通性 |
这套技能的价值在于「跨会话、跨工具」。Pi 原生会话恢复只解决单次对话,记忆层解决的是几周后换一个工具还能不能找回当时的判断依据。
常驻的 5 个技能包
技能包(Pi Package)可以同时分发扩展、技能、提示词和主题。当前 settings.json 里的 packages 有 5 项:
| 包 | 版本 | 提供的能力 |
|---|---|---|
pi-hud-footer | 0.5.1 | 仿 Claude HUD 的底部状态栏 |
nowledge-mem-pi | 0.8.12 | 跨工具记忆扩展 + 5 个技能 |
@yukikisaku/pi-tmux-status | 0.2.0 | tmux 窗口状态、完成提醒与自动标题 |
@juicesharp/rpiv-btw | 2.13.9 | /btw 旁问面板,不污染主对话 |
pi-friends | 0.2.0 | 异步小伙伴:并行派活、面板跟踪、统一验收 |
pi-hud-footer:把运行状态摊开
它把模型、思考等级、项目名、Git 分支、上下文占用、词元用量、输出速率、缓存读写、费用和工具调用统计集中显示在 TUI 底部,省得反复敲命令查状态。
两套样式:
classic:传统三行 footer,信息集中在输入框下方;border:把稳定信息嵌进输入框上下边框,动态工具统计留在 footer,高度更稳。
用 /hud-footer-theme 切换,配置写入 ~/.pi/agent/hud-footer.json,项目里存在 .pi/hud-footer.json 时优先用项目级配置。
nowledge-mem-pi:记忆层
除了 5 个技能,这个包还带一个原生扩展:
- 完成的 Pi 会话自动同步为可搜索的 Mem Thread;
- 启动时注入 Context Bundle 或 Working Memory;
- 通过
~/.nowledge-mem/config.json或NMEM_API_URL、NMEM_API_KEY连接远程服务。
记忆检索和写入最终都落到 nmem CLI 上,所以服务端没跑或配置不对时,技能会先引导去查 nmem status,而不是让模型凭空回忆。
pi-tmux-status:只在 tmux 里干活
这个包只在 $TMUX 存在时激活,其他终端里完全静默,适合常驻安装。
- 运行中在 tmux 窗口名上转 spinner;
- 完成后打 🔔,切到该窗口自动清除;
- 不在当前窗口时播放提示音,依赖
mpv,没装也只是没声音; - 用模型根据对话生成窗口标题,
bash会变成Fix OAuth callback。
命令有 /rename(重新生成或指定窗口名)和 /pi-tmux(设置菜单),配置存在 ~/.pi/agent/pi-tmux.json。
rpiv-btw:旁问不留在正文里
/btw <问题> 会用当前主模型、基于对话的只读副本回答,答案显示在底部面板,不写进 transcript,也不落盘。适合问「刚才为什么不用 SSE」这类不影响主线的追问。
面板支持 ↑ / ↓ 滚动、x 清空本会话旁问历史、Esc 关闭并取消请求。它复用当前会话的模型和凭据,不需要额外选模型。
pi-friends:把活分出去
pi-friends 从 Git 安装,给 Pi 加了一套异步协作机制:
- 一次派出多个有名字的成员,各自开独立会话、改不同文件;
- 输入框上方常驻面板,显示谁在做什么、多久没汇报;
- 成员完成后进入待验收,主 Agent 实际检查后才算通过;
- 支持追加任务、调整方向、停止和遣散。
它解决的是单线程对话的吞吐问题:查资料、改文档、跑验证可以并行,主线程继续做手上的事,最后统一收口。
自建扩展与 MCP
除了包,~/.pi/agent/extensions/terminal-progress.ts 是我自己放进去的本地扩展,负责向终端上报 OSC 9;4 进度:
- 运行中每 250ms 更新一次百分比,按耗时逐步爬升,封顶 92%;
- 完成发送 100%,出错发送错误态,中止立即清除;
- 每 2 秒重发结束态,避免 kitty 自动清掉。
它要求 terminal.showTerminalProgress 设为 false,否则 Pi 内置的不确定态进度会不断覆盖百分比。调试命令是 /progress-demo,加 error 或 clear 可以看错误态和复位。
MCP 侧目前只注册了 REA 一个服务,不再往常驻工具列表里堆其他服务。
配置与维护
当前的技能相关配置可以精简成:
json
{
"skills": [
"!*",
"+/home/mhwy/.agents/skills/reverse-engineer-anything/SKILL.md",
"+/home/mhwy/.agents/skills/ub-mode/SKILL.md"
],
"packages": [
"npm:pi-hud-footer",
"npm:nowledge-mem-pi",
"npm:@yukikisaku/pi-tmux-status",
"npm:@juicesharp/rpiv-btw",
"https://github.com/whoamihappyhacking/pi-friends"
]
}日常操作:
bash
pi list # 查看已配置的包
pi install npm:包名 # 安装
pi remove npm:包名 # 移除
pi update --extensions # 同步包更新
pi config # 交互式开关扩展、技能等资源新增一个技能后,如果仍保留 !*,记得在 skills 里补一条 +绝对路径;改完 SKILL.md 用 /reload 重新加载,不用退出会话。
为什么只开 7 个
技能不是越多越好,原因有三个:
- 路由成本:每个技能的名字和描述都进系统提示,技能越多,模型越容易在相似描述之间摇摆;
- 上下文预算:技能正文只在加载时占用上下文,但路由信息是常驻的;
- 行为冲突:不同技能可能给出相反的流程要求,同时启用会让模型两头讨好。
所以现在的策略是「少量常驻 + 大量备用」:REA 和 ub-mode 是明确的工作模式,记忆五件套是基础设施,其余技能留在磁盘上,需要时再放行。技能包则相反,它们提供的是界面、状态和协作能力,不参与任务路由,常驻成本低,可以一直开着。