全部课程
亲手改一个 Agent/ 番外 · pi 怎么让你改它/ 改它的脾气,不用动一行源码 番外
番外 · pi 怎么让你改它

改它的脾气,不用动一行源码

用着 agent,你迟早会冒出个念头——"它 rm -rf 之前能不能先问我一句?""能不能让它说话正经点?"传统答案是改源码。但 pi 给了你另一条路:它在自己运转的每个关节都留了一个钩子,你在旁边挂一个小文件接住,就能插手——不碰一行源码。这条路,它叫 extension。

你已经学完《亲手写一个 Agent》,手里有一个看得懂的 agent 了。用着用着,你迟早冒出这类念头:

  • “它 rm -rf 之前,能不能先问我一句?”
  • “我想让它某些时候说话像海盗,玩一下。”
  • “这个项目我想给它加条规矩,但不想写进主系统提示。”

传统的答案只有一个:改源码。 翻进 pi 的代码,找到执行工具那一段,插进去几行——然后每次 pi 升级,你的补丁就得重打一遍。又累,又脆。

pi 不让你这么干。它给了你另一条路。

每个关节都留了钩子——一头完整的机关木牛(agent),各关节露出小挂钩;阿澄踮脚往其中一个挂上小灯,不拆开机器,只是挂上去。


pi 在每个关节都留了一个钩子

回想主课那六件:Session 存、Loop 转、Context 装、ToolUse 动手、Provider 接模型、人设。pi 运转时,会一件一件地走过这些关节。

关键在于:每走到一个关节,pi 都会”喊一嗓子”。

  • 准备调一个工具了 → 喊一声 tool_call
  • 要开始一轮了、系统提示刚拼好 → 喊一声 before_agent_start
  • 要压缩上下文了 → 喊一声 session_before_compact
  • 一个新会话起来了 → 喊一声 session_start

平时没人接这些嗓子,pi 自顾自往下走。但只要你写个小函数接住某一嗓子,就能在那个关节插手——拦下它、改一改、加点东西。

这个”挂在旁边、接住某个关节”的小文件,就是 extension。

出门的叫法。 别的产品——比如 Claude Code——管这类”给主程序外挂能力”的东西叫 plugin(插件)。pi 不用这个词,它叫 extension(扩展)。意思是一码事:不改主程序,往上加能力。本课统一用 pi 的原生词 extension,你跟别人对话时知道它约等于”插件”就行。


它到底长什么样:十几行

先给你看一眼,破除”扩展一定很复杂”的错觉。下面这个 extension 让 agent 能切换到”海盗模式”(源码 examples/extensions/pirate.ts),去掉注释就十几行:

export default function (pi) {
  let pirateMode = false;

  // 加一个 /pirate 命令,用来开关
  pi.registerCommand("pirate", {
    handler: async (_args, ctx) => {
      pirateMode = !pirateMode;
      ctx.ui.notify(pirateMode ? "海盗模式开!" : "海盗模式关");
    },
  });

  // 接住"系统提示刚拼好"这一嗓子——开着就往后面加一段
  pi.on("before_agent_start", async (event) => {
    if (pirateMode) {
      return { systemPrompt: event.systemPrompt + "\n\n从现在起,像海盗一样说话。" };
    }
  });
}

你不用全看懂。只要抓住这个形状:

  • pi.on("某个关节", 函数) —— 接住 pi 喊的那一嗓子。
  • 想改,就在函数里 return 一个改动(这里是”给系统提示加一段”)。
  • pi.registerCommand —— 顺手加一个 /命令。

就这么点东西,你改动了 agent 的人设——而 pi 的源码,一行没动。


你能改的,是你已经认识的那六件

extension 最妙的地方:它开的口子,正好挂在你主课学过的每个大件上。所以这门番外不是新知识,是回到那六件,看它们各自留的门:

你想改的挂在哪个大件pi 喊的那一嗓子
危险命令先问一句ToolUse 的准备关tool_call
换个系统提示 / 加条规矩人设before_agent_start
自己决定怎么压缩Contextsession_before_compact
会话一起来就做点事Sessionsession_start

看懂这张表,你就懂了这门课的走法:每一节,回到一个大件,学它那道门怎么开。


带走这一句

pi 不用改源码就能改行为——因为它在运转的每个关节都”喊一嗓子”(触发一个事件),你写个小文件(extension,别人叫 plugin)接住那一嗓子,return 一个改动就行。而这些关节,正是你主课学过的那六件:改工具、改人设、改压缩、改会话,都是回到老地方开一道门。十几行,一行源码不碰。

下一课

这一节你看到了形状。下一课把形状拆开:一个 extension 其实只有三样东西——接事件(pi.on)、加命令(registerCommand)、跟界面说话(ctx.ui)。三样认全,你就能读懂任何一个 extension,也能开始写自己的。