午後一杯でAIミーティングノートテイカーを構築する

LLazare Rossillon

すべてのAIミーティングアシスタントの裏側にあるアーキテクチャ:bot がミーティングを録画し、webhook がトランスクリプトを配信し、LLM がサマリーを生成します。コード付きでパイプライン全体を解説します。

午後一杯でAIミーティングノートテイカーを構築する
August 13, 2026

すべてのAIミーティングアシスタント — ノートテイカー、営業通話分析ツール、コンプライアンス録画システム — は同じ3段階のパイプラインで構築されています:

  1. キャプチャ: bot がミーティングに参加して録画する
  2. 文字起こし: 音声が話者付きのテキストに変換される
  3. 推論: LLM がトランスクリプトをサマリー、アクションアイテム、CRM更新へと変換する

ステージ1と2はインフラです。ステージ3があなたのプロダクトです。このガイドでは、ステージ1と2をAPI1回の呼び出しで完結させ、ステージ3に集中できるようにする方法を紹介します。

キャプチャレイヤーが最も難しい部分です — Zoom、Google Meet、Microsoft Teams にわたる待機室、レイアウト変更、4時間に及ぶ通話を乗り越えられる bot が必要です。これは自前で構築すべきではなく、購入すべき部分です。

キャプチャレイヤー:1回のPOSTリクエスト

import { createBaasClient } from "@meeting-baas/sdk";

const client = createBaasClient({
  api_key: process.env.MEETING_BAAS_API_KEY,
  api_version: "v2"
});

const { success, data, error } = await client.createBot({
  bot_name: "Acme Notetaker",
  meeting_url: meetingUrl // Zoom, Google Meet or Microsoft Teams
});

同じリクエストで3つのプラットフォームすべてに対応できます。カレンダー連携を有効にすれば、このステップも不要です — ユーザーの今後のミーティングに合わせて bot が自動的にスケジュールされます。

webhook でトランスクリプトが届く

ミーティングが終了すると、webhook に話者分離付きのトランスクリプト、参加者リスト、録画URLが送信されます。最小限のハンドラー例:

export async function POST(req: Request) {
  const rawBody = await req.text();

  // Verify the webhook signature over the raw body before parsing —
  // see the webhooks documentation for the signing scheme
  if (!verifySignature(req.headers, rawBody)) {
    return new Response("invalid signature", { status: 401 });
  }

  const event = JSON.parse(rawBody);

  if (event.event === "complete") {
    const { bot_id, transcript, participants } = event.data;
    // Deduplicate on bot_id so replayed deliveries don't re-run the LLM
    if (await alreadyProcessed(bot_id)) return new Response("ok");
    await summarize(bot_id, transcript, participants);
  }

  return new Response("ok");
}

話者分離はすべての録画に含まれており、セグメントは実際の参加者名と紐付けられます — LLMへのプロンプトには「スピーカー2:金曜日に出荷します」ではなく「Sarah:金曜日に出荷します」という形式で渡されます。この違いがアクションアイテム抽出を実際に機能させる鍵です。

推論レイヤー:あなたのプロダクト

クリーンな話者分離済みトランスクリプトがあれば、LLMのステップはプロジェクトではなく、プロンプト1つで済みます:

async function summarize(botId: string, transcript: Segment[], participants: Participant[]) {
  const text = transcript
    .map((segment) => `${segment.speaker}: ${segment.text}`)
    .join("\n");

  const summary = await llm.complete({
    prompt: `Summarize this meeting. Extract decisions and action items with owners.\n\n${text}`
  });

  await saveNotes(botId, summary);
}

ここからの差別化はプロダクト開発です:参加者ごとのフォローアップメール、CRMエンリッチメント、定例ミーティング全体にわたるトピック追跡、またはリアルタイムで質問に答えるスピーキング bot — 最後の機能については speaking bots API で対応しています。

運用コスト

録画は話者分離込みで1時間あたり1トークン、文字起こしは1時間あたり0.25トークンが加算されます。トークンパックは1トークンあたり$0.35〜0.50で、完全に文字起こしされたミーティング1時間のコストは$0.44〜0.63です(LLMコストは別途、1時間のミーティングのトランスクリプトでは通常1〜2セント程度)。

次のステップ

関連ブログtutorial