◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/API & SDK
⬡ API & SDK/2026-04-25上級

Claude API × Convex でリアクティブな AI アプリを本番構築する — データフロー設計とエージェントパターン

Convex のリアクティブデータベースと Claude API を組み合わせて、本番運用に耐えるチャット・エージェント系アプリを構築する方法をまとめました。スキーマ設計、Action/Mutation/Query の境界、ストリーミング、ツール状態管理、冷え始めの落とし穴まで、開発現場の判断軸を共有します。

Claude API128ConvexAgent SDK5TypeScript24RealtimeProduction

✦ プレミアム記事

Convex と Claude API を組み合わせたチャットアプリや業務エージェントを作り始めた方から、ここ数週間で似たような相談が続けて届きました。「マルチプレイヤーのチャットは気持ち良く動くのに、Claude を呼ぶと突然レイテンシが倍になる」「Action のタイムアウトで長時間処理が落ちる」「リロードすると途中まで届いたツール実行結果が消える」。いずれも、Convex のリアクティブな世界観と、Claude の非同期・ストリーミング前提のリクエストを無理に1層で混ぜてしまったときに起きる症状です。

私自身も、まったく同じ順番でつまずきました。最初の実装では Claude の呼び出しを mutation の中へ押し込もうとして、型は通るのに実行時だけ落ちる画面を半日ほど眺めていた覚えがあります。原因は自分の書き方ではなく、層の置き方でした。action に移した瞬間、あれほど粘っていたエラーが嘘のように消えました。

以下では、その設計を土台に、層の切り分け方、スキーマ設計、ストリーミング同期、ツール状態管理、そして見落とされがちな冷え始めレイテンシ対策までを順に整理してまいります。コードは TypeScript、@anthropic-ai/sdk と convex の安定版(2026 年4月時点)を前提にしていますが、バージョンが動いても残る設計原則の方に重心を置いています。

Convex を AI アプリの基盤に選ぶときの判断軸

Convex は「リアクティブなクエリを中心に据えた、ドキュメントベースのサーバーレスプラットフォーム」です。単なるデータベースではなく、クエリが自動で subscribe され、書き込みによる影響範囲が差分で配信される点が特徴です。この性質は、AI との対話 UI と驚くほど相性が良く、新しいメッセージが追加されるたびに UI を更新する処理を自前で書く必要がありません。

ただし、Convex にはサーバーレス特有の制約もあります。mutation と query には CPU 時間の上限があり、外部 API を呼ぶのは原則として action 経由です。Claude API のように応答に 5〜60 秒かかる呼び出しは、常に action の層で扱い、結果を mutation で書き戻すパターンが基本になります。「Mutation から fetch したい」という欲求は早めに諦めてください。この境界を曖昧にすると、後から巨大なリファクタが必要になります。

私は Convex を選ぶかどうかを、以下の観点で判断しています。クライアント側でリアルタイム同期が必要で、かつユーザー同士の協調が発生する(共同編集・マルチプレイヤーなど)なら Convex が強力です。一方、単純な単一ユーザーのチャット UI で、既に Postgres と GraphQL が動いているなら、Convex を追加する必然性は高くありません。Claude API の ストリーミング配信 を SSE でダイレクトに送る方が、レイテンシは低く保てます。

スキーマ設計 — スレッド・メッセージ・ツールコールの3層モデル

私が本番で使っているスキーマは、チャット UI とエージェント実行を両方想定しています。最小構成でも、スレッド、メッセージ、ツール実行の3テーブルに分離するのがおすすめです。これは後述する「進行中の処理を別レコードで追う」パターンに直結します。

// convex/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
 
export default defineSchema({
  threads: defineTable({
    userId: v.string(),
    title: v.string(),
    model: v.string(), // "claude-sonnet-4-6" など
    systemPrompt: v.optional(v.string()),
    totalInputTokens: v.number(),
    totalOutputTokens: v.number(),
    archivedAt: v.optional(v.number()),
  }).index("byUser", ["userId", "archivedAt"]),
 
  messages: defineTable({
    threadId: v.id("threads"),
    role: v.union(v.literal("user"), v.literal("assistant"), v.literal("tool")),
    // ストリーミング中は contentDraft を更新し続け、確定後に content に移す
    content: v.optional(v.string()),
    contentDraft: v.optional(v.string()),
    status: v.union(
      v.literal("pending"),
      v.literal("streaming"),
      v.literal("complete"),
      v.literal("error"),
    ),
    errorMessage: v.optional(v.string()),
    inputTokens: v.optional(v.number()),
    outputTokens: v.optional(v.number()),
  }).index("byThread", ["threadId"]),
 
  toolCalls: defineTable({
    messageId: v.id("messages"),
    name: v.string(),
    input: v.any(),
    output: v.optional(v.any()),
    status: v.union(
      v.literal("pending"),
      v.literal("running"),
      v.literal("success"),
      v.literal("failure"),
    ),
    startedAt: v.number(),
    completedAt: v.optional(v.number()),
  }).index("byMessage", ["messageId"]),
});

contentDraft と content を分けるのは、「完了前の下書き」と「確定結果」を同じフィールドで管理しないためです。クライアントが content だけを購読するようにすれば、ストリーミング中の細かい再描画で UI がちらつく問題を回避できます。逆に「タイピング中のカーソル」を表示したい場合は、別コンポーネントで contentDraft を購読させれば良い、という分離が効きます。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦Convex + Claude API でチャット・エージェントを作り始めた人が、Action と Mutation の境界で詰まる問題を最初に解決できる
✦長時間実行するエージェントをサーバーレスで安定稼働させるスケジュール型ジョブと進行状況同期の実装を習得できる
✦コスト追跡・レート制限・スキーマ進化を含む本番運用の設計をそのままコピーして使える形で手に入る
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

⬡ API & SDK2026-05-04
Bun × Claude API で本番運用するエッジAIサービス — Node.js移行の判断軸と落とし穴を回避する実装パターン
Claude APIをBun上で本番運用するための実装ガイド。Node.jsからの移行判断軸・組み込みSQLite/WebSocketの活用・ストリーミング最適化・典型的な落とし穴の回避策まで、動作するコードと実測値で解説します。
⬡ API & SDK2026-04-17
Claude API で作る GitHub PR レビューボット — Webhook統合からセキュリティスキャン・品質スコアリングまで実装
Claude API × GitHub Webhook で PR レビューボットを実装します。Tool Use で構造化スコアリングとセキュリティ検査を自動化し、署名検証が手元でだけ通る落とし穴、202 応答が失敗を隠す挙動、デバウンスとコスト管理まで実測を添えてお伝えします。
⬡ API & SDK2026-10-16
Make から Claude API に 40 行流すと 14 行目で止まる — 429 を待ち時間の計算で避ける
表計算の行を1件ずつ Claude API に渡すノーコード自動化が、途中で 429 になる理由と直し方です。模擬バケットで7通りの間隔を比べ、Sleep の秒数を 60÷上限−応答時間 で決める式と、失敗行を落とさない設定を示します。