Skip to content

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 启动时做三件事:

  1. 扫描用户级、项目级和包内的技能目录;
  2. 把每个技能的 name、description、filePath 写进系统提示;
  3. 等任务匹配时,由模型自己用 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-memorynowledge-mem-pi会话开始时加载当日工作记忆与关注点
search-memorynowledge-mem-pi检索过往决策、偏好和操作流程
distill-memorynowledge-mem-pi把值得长期保留的信息沉淀成记忆
save-threadnowledge-mem-pi在明确要求时生成结构化交接摘要
statusnowledge-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 是一份很克制的工程约束,核心顺序是:

  1. First Make it Work:先让最小的改动跑通;
  2. Then Make it Right:再修根因、补测试、拆函数;
  3. 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-footer0.5.1仿 Claude HUD 的底部状态栏
nowledge-mem-pi0.8.12跨工具记忆扩展 + 5 个技能
@yukikisaku/pi-tmux-status0.2.0tmux 窗口状态、完成提醒与自动标题
@juicesharp/rpiv-btw2.13.9/btw 旁问面板,不污染主对话
pi-friends0.2.0异步小伙伴:并行派活、面板跟踪、统一验收

它把模型、思考等级、项目名、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 个 ​

技能不是越多越好,原因有三个:

  1. 路由成本:每个技能的名字和描述都进系统提示,技能越多,模型越容易在相似描述之间摇摆;
  2. 上下文预算:技能正文只在加载时占用上下文,但路由信息是常驻的;
  3. 行为冲突:不同技能可能给出相反的流程要求,同时启用会让模型两头讨好。

所以现在的策略是「少量常驻 + 大量备用」:REA 和 ub-mode 是明确的工作模式,记忆五件套是基础设施,其余技能留在磁盘上,需要时再放行。技能包则相反,它们提供的是界面、状态和协作能力,不参与任务路由,常驻成本低,可以一直开着。