外观
π(pi)概念解读:极简编程智能体的 Skills、MCP 与 Extensions
在 2025 年的 AI 编程工具浪潮里,pi(开源仓库 badlogic/pi-mono)是一个很有辨识度的编程智能体(coding agent)。它不像很多同类产品那样追求"大而全",而是把核心做得极小,再把能力交给三个可组合的机制——Skill(技能)、**Extension(扩展)**和 MCP(Model Context Protocol,模型上下文协议)。理解了这三样东西,基本就理解了 pi 的设计哲学与用法边界。本文假设 pi 指的就是这个开源编程智能体;该项目迭代较快,个别细节请以官方 README 与文档为准。
一、pi 是什么:一个"反复杂"的编程智能体
pi 的作者 Mario Zechner(libGDX 的作者之一)对 agent 的理解非常朴素:agent 的本质就是一个循环——把对话发给大模型,模型决定调用什么工具,工具执行后把结果喂回去,如此往复。围绕这个循环,pi 的核心只保留了最必要的东西:
- 统一的 LLM 接入层:一套 API 适配 Anthropic、OpenAI、Google 等主流模型,自带 API Key 即可使用(BYOK);
- 最小工具集:读写文件、执行命令、检索代码等基础工具;
- 轻量终端界面(TUI):保持命令行体验的克制与高效。
除此之外的一切——新工具、新命令、新知识、外部服务——都不写死在核心里,而是通过下面三种机制按需挂载。
二、三个概念一览
| 概念 | 形态 | 本质 | 触发方式 | 典型用途 |
|---|---|---|---|---|
| Skill | Markdown 文档(SKILL.md) | 写给模型看的"操作手册" | 模型按语义自主决定何时读取 | 教会模型某类任务的标准做法 |
| Extension | TypeScript/JavaScript 模块 | 写给程序执行的"代码插件" | 加载时注册,运行时被调用 | 新增工具、自定义命令、拦截流程 |
| MCP | 开放协议(JSON-RPC) | 连接外部工具/数据的标准总线 | 客户端—服务器握手后发现能力 | 复用现成的外部服务生态 |
一句话记住三者:Skill 是"知识",Extension 是"代码",MCP 是"协议"。
三、Skill:写给模型看的"操作手册"
Skill 是 pi 中最轻量的扩展方式,借鉴自 Claude Code 的 Agent Skills 规范:把某类任务的专业知识写成结构化 Markdown 文档,让模型在需要时自己去找、自己去读。它不执行任何代码,纯粹是"注入知识"。
1. Skill 的结构
一个 skill 是一个目录,里面必须有一个 SKILL.md,用 YAML frontmatter 声明元数据,正文写操作指引:
---
name: react-component
description: 编写符合团队规范的 React 组件
---
# React 组件规范
## 步骤
1. 使用函数组件 + hooks,不使用 class 组件;
2. 组件文件放 src/components/,测试文件同名 .test.tsx;
3. 样式一律用 Tailwind,不写内联 style;
4. 提交前跑 pnpm lint 与 pnpm test。只有 name 和 description 是必须的,但 description 是关键——模型主要根据这段描述判断"当前任务是否需要这个技能",所以它必须具体、带触发词,而不是空泛的"帮助写代码"。
2. Skill 的加载逻辑
- 声明式发现:pi 启动时扫描两类位置——用户全局目录(
~/.pi/skills/)与项目级目录(.pi/skills/),以及各 skill 目录下的 SKILL.md; - 渐进式加载:只有 name + description 会进入系统提示,正文不会全部塞进上下文。模型判断某任务相关时,再用 read 工具读取完整内容。这样即便装了几十个技能,也不会撑爆上下文窗口,这正是这套机制可以堆料的原因;
- 可引用文件:skill 目录里可以放其他文件(脚本、模板、数据表),SKILL.md 里写明相对路径,模型会在需要时去读。
3. Skill 的三级来源
| 来源 | 位置 | 生效范围 | 适用场景 |
|---|---|---|---|
| 个人技能 | ~/.pi/skills/ | 该用户所有项目 | 个人偏好:提交信息风格、文档写作习惯 |
| 项目技能 | .pi/skills/ | 当前项目,可随仓库分享 | 团队规范:构建流程、部署步骤、代码风格 |
| 已安装包 | npm 包随包分发 | 安装即用 | 通用技能:前端框架、测试框架的官方技能 |
团队最有价值的用法是第二种:把工程规范沉淀成 .pi/skills/ 下的技能并提交进仓库,新人 clone 代码后,pi 就自动带着团队的隐性知识干活。
4. 写好 Skill 的要点
- description 要像"检索关键词"一样写:包含技术栈、动作、场景(如"何时需要编写数据库迁移脚本时使用");
- 正文直接写步骤与规则,指令式语气,不写背景故事;
- 一个技能只管一类任务,宁可拆成多个小技能,不要做成大杂烩;
- 需要的脚本、模板随目录分发,并在文档里注明路径。
四、Extension:写给程序执行的"代码插件"
Skill 解决"模型知道什么",Extension 解决"程序能做什么"。它是一个 TypeScript/JavaScript 模块,在 pi 启动时加载,通过事件与 API 直接介入 agent 的运行时,能做的事比 skill 重得多:
- 注册自定义工具:给模型增加新的能力,比如查数据库、调内部 API、操作 CI;
- 自定义斜杠命令:把常用操作封装成
/deploy、/review这类命令; - 拦截与修改事件流:在消息发出前改写、在工具调用前审计、在响应后做后处理;
- 定制 UI:注入自定义组件、快捷键、状态栏信息。
Extension 与核心的关系是事件驱动的:核心在关键节点(启动、每轮对话、工具调用前后等)发出事件,扩展订阅事件并做出反应。这也意味着扩展的能力边界很大——理论上能把 pi 改造成另一个产品。
// 一个极简 extension:注册一个查询数据库的工具
export default function (pi) {
pi.registerTool("query_db", {
description: "在只读副本上执行 SQL 查询并返回结果",
parameters: {
sql: { type: "string", description: "要执行的 SQL 语句" }
},
async execute({ sql }) {
const rows = await db.query(sql); // 连接与白名单校验由扩展自己实现
return JSON.stringify(rows);
}
});
}几个需要留意的设计点:
- 加载范围与 skill 类似:支持全局、项目级、npm 包三种来源,项目级同样适合团队共建;
- 运行在 Node 进程里、有完整权限:扩展不是沙箱。它执行任意代码、访问文件系统与网络,所以只装可信来源的扩展,项目级扩展随仓库进来时同样要审一遍代码;
- 是 TypeScript 优先:与 pi 的核心同构,调试、类型提示体验好,这也是它区别于 MCP 的一个特征。
五、MCP:连接外部世界的"标准总线"
前两者都在 pi 进程内,而 MCP(Model Context Protocol)是 Anthropic 发起的开放协议,用于把外部工具和数据源标准化地接入 agent。它的模型很简单:
- MCP 服务器:一个独立进程,对外暴露三类能力——tools(可调用的操作)、resources(可读取的数据)、prompts(预设提示模板);
- MCP 客户端:pi 内置客户端,负责启动或连接服务器,并把对方的能力自动转换成模型可调用的工具;
- 传输方式:本地服务器走 stdio,远程服务器走 HTTP(SSE / streamable HTTP);
- 能力发现:握手后客户端自动获取服务器的能力清单,无需手工注册任何工具。
对 pi 来说,MCP 的价值在于复用生态:社区已有大量现成服务器——GitHub、Slack、Postgres、Playwright、文件系统……接上就能用,不需要自己写一行扩展代码。接入方式通常是配置文件里声明服务器列表,例如:
{
"mcpServers": {
"github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "..." } },
"docs": { "type": "http", "url": "https://mcp.example.com/sse" }
}
}需要注意的现实问题:
- 每个服务器是一个独立进程,数量多了启动慢、内存占用高,工具数量过多也会稀释模型对工具的选择准确度,按需启用即可;
- 安全模型:服务器拿到的是你配置给它的凭据,等于把对应系统的权限交了出去,敏感系统要最小化授权;
- 调用有开销:跨进程 JSON-RPC 通信比进程内函数调用慢,高频、低延迟的本地操作更适合用 Extension 实现。
六、三者怎么选:一张决策表
| 你的需求 | 选择 | 理由 |
|---|---|---|
| 教模型团队规范、任务流程 | Skill | 零代码,写 Markdown 即可,按需加载不占上下文 |
| 给模型加新能力、新命令、拦截流程 | Extension | 进程内、全权限、可深度定制 UI 与运行时 |
| 接入现成的外部服务(GitHub、数据库、浏览器) | MCP | 社区已有大量现成服务器,接上即用,无需写代码 |
| 性能敏感的本地高频操作 | Extension | 省去 MCP 跨进程通信的开销 |
| 想让能力随仓库共享给团队 | 项目级 Skill / Extension | 配置进 .pi/ 目录,clone 即生效 |
| 多个 agent 平台通用、避免厂商锁定 | MCP | 开放协议,一次对接,处处可用 |
经验法则:先问"这是知识还是能力"。知识用 Skill;能力优先 Extension;只有当能力来自外部系统、且社区已有现成 MCP 服务器时,才走 MCP。
七、三者如何协作:一个完整例子
三种机制并不互斥,真实项目里往往同时用。假设团队要做一个"自动化运维"场景:
- MCP 接入基础设施:挂一个 Kubernetes MCP 服务器,模型获得查看 Pod、查看日志、滚动重启等工具;
- Extension 注册内部工具:写一个扩展封装公司内部的告警查询 API 和审批流程,注册成工具与
/oncall命令; - Skill 沉淀操作手册:把"线上告警排查 SOP"写成技能,描述中包含"告警、p0、重启、回滚"等触发词;
- 协作流程:值班人员输入告警信息 → pi 匹配到 SOP 技能 → 按手册步骤调用 K8s 工具与内部工具 → 每一步都遵循团队规范执行与汇报。
这个例子里:Skill 提供了怎么做的知识,Extension 与 MCP 提供了能做什么的能力,三者共同把一个通用 agent 变成了团队专属的运维助手。
八、常见误区
- "Skill 就是提示词模板"——不只是。它有发现、按需加载、目录化分发的机制,是可工程化的知识库;
- "MCP 比 Extension 更高级"——不是优劣关系。MCP 强在跨进程的标准化与生态复用,Extension 强在进程内的深度与性能;
- "扩展装得越多越好"——工具越多,模型选择越容易出错,上下文消耗也越大,按需启用、及时清理;
- "项目级扩展可以直接信任"——扩展是任意代码,clone 别人的仓库后先审查 .pi/ 目录再启动 pi;
- "三者只能选一个"——实践中最佳组合是:通用外部服务用 MCP,团队内部能力用 Extension,规范与 SOP 用 Skill。
九、小结
pi 的设计哲学可以用一句话概括:核心极小,能力外置,组合优先。Skill 用 Markdown 传递知识,Extension 用代码注入能力,MCP 用协议连接世界——三者分别覆盖"知识、能力、生态"三个维度,又都遵循"按需加载、随项目分发"的原则。理解了这套分工,无论之后 pi 怎么迭代,你都能快速判断"我该把需求放进哪一层"。