🤖

Responses APIで会話を記憶するSlack Botを構築する

に公開

モチベーション

弊社ではResponses APIおよび、自作のMCPを用いて社内用Slack Botを作成しています。
Slack Botおよび、Remote MCPの作成に関しては以下の記事を参照して下さい。
https://zenn.dev/bizibl_dev/articles/04954d9a7f8a0e
https://zenn.dev/bizibl_dev/articles/ccaadc7304103d
今回はこの Slack Bot に「記憶」を付与する仕組みを構築しました。これにより、例えば以下のような活用が可能になります。

  • 一度記録した作業手順を保持し、次回の同一作業時に参照できるようにする
  • 毎日の Slack 上での情報をまとめて記憶させ、それをもとに応答させる

アプローチ

Responses API では、ツールとしてOpenAI Vector Storeを指定し、そこに紐づけられたファイルを回答時に参照させることができます。

const resp = await openai.responses.create({
  model: OPENAI_MODEL,
  input,
  tools: [
    { type: 'file_search', vector_store_ids: ['vs_vector_store_id'] },
  ],
});

この仕組みを応用しSlack Botに記憶を持たせるためのフローを以下の手順で構築しました。

  1. 記憶させたい内容を格納したファイルを作成し、それを vector_storeに紐づけるためのツールをRemote MCP側で用意する
  2. Responses API において「記憶して」と入力された際、上記のツールを呼び出すように設計する
  3. あらかじめ vector_store を Responses API に紐づけておくことで、保存されたファイルが次回の回答時に自動的に参照される

構築

インフラ


詳細に関しては以下の記事も参照してください
https://zenn.dev/bizibl_dev/articles/04954d9a7f8a0e

コード

Remote MCP側

export const updateMemory = async (args, extra) => {
  const openAiApiKey = "sk-proj-" + extra.requestInfo.headers['memory-token'];
  const client = new OpenAI({ apiKey: openAiApiKey });

  const file = await client.files.create({
    file: await toFile(Buffer.from(args.content, "utf-8"), `${args.title}.md`),
    purpose: "assistants",
  });
  await client.vectorStores.files.create(
    "vs_vectore_store_id",
    {
      file_id: file.id,
    }
  );

  return {
    content: [{ type: "text", text: args.title }]
  };
}

server.tool(
  "update-memory",
  "会話記録を更新する",
  {
    title: z.string().describe("会話記録のタイトル(英語で記録)"),
    content: z.string().describe("会話記録の内容"),
  },
  updateMemory
);

Responses API側

const resp = await openai.responses.create({
  model: OPENAI_MODEL,
  input,
  tools: [
    { type: 'file_search', vector_store_ids: ['vs_memory_vector_store'] },
    {  
      "type": "mcp",
      "server_url": "remote-mcp-url",
      "server_label": "bizibl-mcp",
      "require_approval": "never",
      "headers": {
        "mcp-access-token": biziblRemoteMcpAccessToken,
        "memory-token": openAIAPIKey.replace(/^sk-proj-/, "")
      }  
    }  
  ],
});

基本的な作り方は以下の記事と同じです
https://zenn.dev/bizibl_dev/articles/04954d9a7f8a0e
今回問題となったのは、Responses API がsk-proj-を接頭辞に持つ OpenAI API Key を自動的に弾いてしまう点です。
そのため、次のように処理を工夫しています。

  1. リクエスト送信時はsk-proj-を取り除いた状態でヘッダーに渡す
  2. Remote MCP 側では受け取ったkey にsk-proj-を付け直し、有効な API Key として利用する
    この手順により、Responses API を経由しても Vector Store への安全なアクセスが可能となりました。

まとめ

今回の仕組みにより、Slack Bot に記憶機能を持たせることができました。これにより、日々の会話や作業手順を保存し、必要に応じて呼び出して活用できます。
今後は、記録を整理して体系化し、人間が直接参照できる形にすることで、さらに実用性を高めていく予定です。


Bizibl では開発エンジニアを絶賛採用しています!カジュアル面談に興味がある方はこちらから!
https://open.talentio.com/r/1/c/bizibl/pages/99945

株式会社Bizibl Technologies テックブログ

Discussion