Files
inkreach-agent/docs/plugins/02-tools-and-commands.md
T

3.0 KiB
Raw Blame History

L1 · 工具与命令

前置:L0。api.pi 就是 pi 的原生 ExtensionAPI——pi CLI 扩展能做的这里都能做,语义一致。

1. 注册一个带参数的工具

工具是 Agent 的「手」:注册后自动进入系统提示词与工具列表,受审批拦截管理。

export default function definePlugin(api) {
  api.pi.registerTool({
    name: 'dice_roll',
    description: '掷一个 N 面骰子,返回点数',
    parameters: {
      type: 'object',
      properties: {
        sides: { type: 'number', description: '面数,默认 6' }
      }
    },
    async execute(_id, params) {
      const sides = Number(params.sides) || 6
      const value = 1 + Math.floor(Math.random() * sides)
      api.log.info('dice rolled', { sides, value })
      return { output: String(value), metadata: { sides, value } }
    }
  })
}

要点:

  • description 会注入系统提示词,写清楚「什么时候该用这个工具」,Agent 的调用准确率取决于它
  • execute 返回 { output: string }——output 是喂回模型的内容,保持精炼
  • 工具名全局唯一,用 <插件名>_<动作> 前缀避免撞名

2. 注册斜杠命令

命令是用户的「入口」:聊天框输入 / 出现,回车触发。

export default function definePlugin(api) {
  api.pi.registerCommand({
    name: 'dice',
    description: '掷骰子',
    handler: async (ctx, args) => {
      const sides = Number(args) || 6
      ctx.notify(`🎲 ${1 + Math.floor(Math.random() * sides)} / ${sides}`)
    }
  })
}

3. 订阅事件

在 Agent 生命周期钩子上挂逻辑(发消息前注入、工具调用前后处理等):

export default function definePlugin(api) {
  const off = api.pi.on('before_agent_start', (event) => {
    api.log.debug('agent starting', { prompt: event.prompt?.slice(0, 50) })
  })
  // 返回的取消函数放进 dispose,宿主在禁用/重载时调用
  return () => off()
}

常用事件:before_agent_start / agent_start / tool_call / tool_result / before_provider_request / agent_end。全集见 pi 的 ExtensionAPI 类型(@earendil-works/pi-coding-agent)。

4. 与插件私有存储配合

需要跨回合记住状态时用 api.storage(按插件隔离,落盘 aso-plugin-storage.json):

let count = api.storage.get('count') ?? 0
api.storage.set('count', ++count)

5. 验证

  1. 重载插件(开关切换或重启)
  2. 日志确认 plugin activated
  3. 聊天框输入 /dice 回车 → 收到点数;对 Agent 说「掷个 20 面骰」→ 观察它调用 dice_roll
  4. 日志中应出现 dice rolled sides=20 value=…

排障

  • 工具没出现在 Agent 里:日志搜 plugin activated 确认激活成功;registerTool 抛错会记为 plugin activation failed
  • 命令没出现在 / 面板:命令名冲突(重名被去重),换名再试

上一篇 L0 · 下一篇:L2 设置表单——让用户能配置你的插件。