对接智能助手(AI 工具)

奶狗 发表于 4 周前 浏览 48 字数 2035 阅读时长 11分钟

4. 对接智能助手(AI 工具 / Function Calling)

通过声明 AI 工具,让智能助手在自然语言对话中自动调用你的插件。两步搞定,不用改 smart 代码。

4.1 声明工具(meta.aiTools)

meta: {
  aiTools: [
    {
      type: 'function',
      function: {
        name: 'get_weather',          // 全局唯一,勿与内置/其他插件重名
        description: '查询指定城市的实时天气和未来预报。用户问天气时调用。',
        parameters: {
          type: 'object',
          properties: {
            city: { type: 'string', description: '城市名称,如"北京"' },
            days: { type: 'integer', description: '预报天数,默认1' },
          },
          required: ['city'],
        },
      },
    },
  ],
},

4.2 实现处理函数(handleAiTool)

导出名支持 handleAiTool 或别名 executeAiTool。智能助手以 pluginHandlers[name](name, args, ctx) 方式调用,因此 handleAiToolthis 为 undefined,请用模块级函数

async function handleAiTool(name, args, ctx) {
  if (name !== 'get_weather') return `未知工具:${name}`;

  const { city, days = 1 } = args;
  const result = await fetchWeather(city, days);

  // 可直接发给用户
  await ctx.sendText(`${city}天气:${result}`);

  // 返回给 AI 的说明(AI 会用来生成最终自然语言回复)
  return '天气信息已直接发送给用户,请简短告知用户即可,不要重复内容。';
}

module.exports = { meta, onMessage, handleAiTool };

4.3 工作原理

  • smart 每次处理消息前,扫描当前机器人已安装启用插件的 meta.aiTools,合并进传给 AI 的 tools 数组。
  • AI 决定调用某工具时,smart 先在内置工具表查找,未命中则转发到声明该插件的 handleAiTool(name, args, ctx)
  • 最多 5 轮 function calling 循环,工具执行抛错不中断对话。

4.4 动态工具(getAiTools)

如果工具需要运行时确定(如 MCP / 动态注册),可导出 getAiTools(botId) 替代静态 meta.aiTools

async function getAiTools(botId) {
  const tools = await fetchToolsForBot(botId);
  return tools;   // 返回 OpenAI function schema 数组
}

module.exports = { meta, getAiTools, handleAiTool, onMessage };

动态工具受 smart 的 5 秒超时和 tools_max_limit(默认 30)限制。

4.5 扩充 AI 系统提示词(getCombinedPrompt)

function getCombinedPrompt(botId, peerId) {
  return `当前用户偏好:简短的回复风格,不使用表情符号。`;
}

smart 在处理消息前,会扫描所有已启用插件的 getCombinedPrompt(botId, peerId),合并进系统提示词。

4.6 注意事项

  • 工具 name 必须全局唯一,不要与内置工具同名。内置工具含:search_knowledgeset_reminderlist_remindersdelete_reminderget_daily_briefingget_random_imagesave_image_to_knowledgesave_url_to_knowledgewrite_knowledgesearch_noteread_notecreate_notesend_emaillist_recent_emailsread_email
  • 插件必须已安装并启用,其工具才会被收集。
  • handleAiTool 内可直接用 ctx.sendText/sendMedia 发消息,然后 return 告诉 AI "已发,请简短确认"。
  • 保留 onMessage 精确指令入口:用户既能自然语言让 AI 调工具,也能发精确指令直接触发,两条路径复用同一份核心逻辑。

4.7 命令前缀(commandPrefix)

如果智能助手已被触发,某些关键词可能需要让位给指令型插件:

meta: {
  commandPrefix: ['/draw', '/绘图', '/imagine', '/生图'],
  // ↑ 消息以这些前缀开头时,smart 主动让位,不再回复
}

匹配忽略大小写。解析时建议兼容中/英文冒号,如 /绘图:猫/draw 猫 都支持。