zudo-doc
GitHub リポジトリ

検索したい単語を入力

いつでも検索バーを開ける

AI Assistant API

作成 2026年5月10日更新 2026年6月11日Takeshi Takatsudo
タグ:#ai

AIアシスタントのチャットエンドポイントのAPI仕様です。

エンドポイント

POST /api/ai-chat
Content-Type: application/json

リクエストボディ

interface AiChatRequest {
  message: string;
  history?: ChatMessage[];
}

interface ChatMessage {
  role: "user" | "assistant";
  content: string;
}
フィールド必須説明
messagestringはいユーザーの現在のメッセージ。空でないこと。
historyChatMessage[]いいえ過去の会話メッセージ。不正な形式(非配列、50件超、コンテンツが8192文字超、またはインジェクション一致)の場合はHTTP 400で拒否。

成功レスポンス (200)

interface AiChatResponse {
  response: string;
}

responseフィールドはアシスタントの返答をマークダウン文字列として含みます。

例:

// Request
{
  "message": "How do I add a new page?",
  "history": []
}

// Response
{
  "response": "Create an MDX file in `src/content/docs/`:\n\n1. Add frontmatter with `title`\n2. Write your content in MDX\n3. The page appears in the sidebar automatically"
}

エラーレスポンス (400 / 500)

interface AiChatErrorResponse {
  error: string;
}
ステータス条件
400無効なJSONボディ
400messageが空でない文字列ではない
400messageが4000文字の制限を超えている
400入力スクリーニング(プロンプトインジェクションガード)で拒否された
400historyの形式が不正(フィールド説明を参照)
405リクエストメソッドがPOSTでもOPTIONSでもない
415Content-Typeがapplication/jsonではない
429レート制限超過(Retry-Afterヘッダーを含む)
500Anthropic APIコール失敗

このエンドポイントはPOST(チャット)とOPTIONS(CORSプリフライト)のみを受け付けます。それ以外のメソッドはすべて{ "error": "Method not allowed" }とともに405を返します。

CORS

このエンドポイントはオリジンごとの許可リストを使用します。aiChatDemoModefalseの場合、Access-Control-Allow-OriginaiChatAllowedOrigins設定にリストされたリクエストオリジンに対してのみエコーされます。それ以外のオリジンにはallow-originヘッダーが返されず、ブラウザによってブロックされます。(デモモードでは後方互換性のため常に*が返されます。)これはワイルドカードCORS(*)を使用するSearch Workerよりも意図的に厳格です。各コールに実際のAnthropic APIコストが伴うAIチャットエンドポイントはオリジンでゲートしますが、検索はメーター課金のないオプトインサービスだからです。2つのエンドポイントが同じCORSポリシーを共有していると仮定しないでください。

CF環境バインディング

バインディング種別必須説明
ANTHROPIC_API_KEYsecretはいAnthropic APIキー
DOCS_SITE_URLvarはいデプロイ済みのドキュメントサイトURL(llms-full.txtの取得に使用)
RATE_LIMITKV namespaceはいレート制限のカウンタと監査ログを保存
RATE_LIMIT_PER_MINUTEvarいいえIPあたりの1分間の最大リクエスト数(デフォルト10
RATE_LIMIT_PER_DAYvarいいえIPあたりの1日の最大リクエスト数(デフォルト100
PUBLIC_ENABLE_MOCKSvarいいえ"true"に設定するとMSWのモックレスポンスが有効になる(開発モードのみ)

設定

以下のsrc/config/settings.tsフィールドがエンドポイントの動作を制御します(上記のCF環境変数とは 別のもので、こちらはCloudflare側のランタイム設定です)。

設定デフォルト説明
aiChatDemoModebooleantrueエンドポイントを固定返答でショートサーキット。APIキーやKVにアクセスしない
aiChatAllowedOriginsstring[][]CORSオリジン許可リスト(非デモ時のみ有効)。空配列 = 全クロスオリジンリクエストをブロック
aiChatGlobalDailyLimitnumber | falsefalse全IPを合算した1日のリクエスト上限。false = 上限なし

セキュリティ

このエンドポイントは、レガシーのスタンドアロンWorkerから移植された多層的な防御を備えています:

  • ハードニングされたシステムプロンプト — XMLタグでコンテキストを区切り、明示的なガードレールによってモデルが設定情報を漏洩したり、トピック外の指示に従ったりすることを防ぎます。さらに、過去の会話ターンはすべてクライアント由来の信頼できない入力として扱うようモデルに指示します(下記の チャット履歴の信頼モデル を参照)

  • 入力スクリーニング — 一般的なプロンプトインジェクションパターンを正規表現の事前フィルタで弾き、Claude APIに到達する前に拒否します。スクリーニングはレート制限チェックのに実行されるため、インジェクションガードで拒否されたリクエストでも呼び出し元のレート制限の枠は消費します(リミッターはKV書き込みの増幅を防ぐため先に実行する必要があります)

  • レート制限RATE_LIMIT KVを使ったIPごとの制限。aiChatDemoModefalse の場合は フェイルクローズ(KV障害時 → HTTP 429)。デモモードではフェイルオープン(デモのショートサーキットが先に実行されるため、実際にはレートリミッターには到達しない)

  • CORSオリジン許可リスト — 非デモ時、Access-Control-Allow-OriginaiChatAllowedOrigins に含まれるオリジンにのみエコーされます。リスト外のオリジンからのクロスオリジンリクエストはブラウザでブロックされます。デモモードは後方互換性のため常に * を送信します

  • グローバル1日上限 — IPローテーションやボットネットへの対策として aiChatGlobalDailyLimit でオプションのバックストップを設定できます。デフォルトは無効

  • 監査ログ — すべてのインタラクションをaudit:プレフィックスでRATE_LIMIT KVに記録(7日のTTL、ファイア・アンド・フォーゲット)

  • メッセージ長制限 — 4000文字を超えるメッセージはAPIに到達する前に拒否されます

  • cf-connecting-ipの注意点 — IPごとのレート制限にはこのヘッダーを使用しており、WorkerがCloudflareのネットワーク経由でデプロイされている場合にのみ信頼できます

チャット履歴の信頼モデル

history配列はクライアント由来かつステートレスです。サーバーはセッション記録を一切保持しないため、assistantロールのターンが実際に過去のモデル応答によって生成されたものかを検証できません。各エントリは依然としてハードニングされています。すなわち、user/assistantへの厳格なロールホワイトリスト、上記のエントリ件数および1エントリあたりの長さ制限、そして紛れ込んだ余分なフィールドを取り除く{ role, content }への再構築です。userロールのターンはインジェクションスクリーニングされますが、assistantロールのターンはされません(本物のアシスタント応答はインジェクションのような文面を正当に引用しうるためです)。

ロールが検証不可能であるため、呼び出し元は敵対的な指示を含むassistantターンを偽造してユーザーターンのスクリーニングを回避できます。この残存リスクは意図的に受容しています。本チャットはブラスト半径の小さいドキュメントアシスタントであり、システムプロンプトはすべての過去ターンを、自身のルールを上書きできない信頼できない入力として扱うようモデルに指示しているためです。堅牢な対策(サーバー発行の署名付き履歴)はシークレットのプロビジョニングとクライアント/サーバー間ペイロード契約の変更を必要とし、この機能には見合いません。決定の全記録はissue #2036を参照してください。

ドキュメントコンテキスト

このエンドポイントは、llms.txtインテグレーションで生成されたllms-full.txtDOCS_SITE_URLから取得し、CF Workersのアイソレートが生きている間メモリにキャッシュします(ベストエフォート、約1時間)。取得したコンテンツはシステムプロンプトに<documentation>XMLコンテキストとして含められます。

Revision History

Takeshi Takatsudo作成: 2026-05-10T21:56:58+09:00更新: 2026-06-11T13:14:41+09:00

AI Assistant

Ask a question about the documentation.