← レッスンに戻る
第8章 · 実践プロジェクト

シンプルなチャットボット

Simple Chatbot · 約 14 分

重要キーワード

English日本語説明
Stateless API ステートレスAPI サーバーが履歴を保持しない設計。クライアントが履歴を持つ
Streaming ストリーミング 応答を逐次返す方式
Sliding Window スライディングウィンドウ 履歴の古い部分を切る or 要約する技法
Compaction 圧縮 長い会話を要約して短くする処理

シンプルなチャットボット

最小構成のチャットボットを Flask で作ります。

設計

サーバー側

import voyageai
vo = voyageai.Client()  # 環境変数 VOYAGE_API_KEY

result = vo.embed(
    texts=["猫が好きです", "犬が好きです", "天気がいいです"],
    model="voyage-3-large",
    input_type="document",   # or "query"
)
vectors = result.embeddings  # list[list[float]]

クライアント側 (擬似)

system=[
    {"type": "text", "text": SYSTEM_BASE},
    {"type": "text", "text": LONG_GUIDELINES, "cache_control": {"type": "ephemeral"}},
]

履歴の長期化対策: Sliding Window + Summary

会話が長くなると input が肥大化します。次の戦略を組み合わせます:

wzxhzdk:2

summarize() も Claude で実装すれば自然な要約に。

ベストプラクティス

Cache をかける

長い system は cache_control: ephemeral で。 ユーザーが多いほどヒット率が上がる。

system=[
    {"type": "text", "text": SYSTEM_BASE},
    {"type": "text", "text": LONG_GUIDELINES, "cache_control": {"type": "ephemeral"}},
]

Tip: ユーザーごとのカスタム system

「このユーザーは英語で答える」「あのユーザーは詳細な技術解説を好む」など、 ユーザー設定 + 共通システム のハイブリッドが理想。

この academy アプリも参考に

本講座の Playground は同じパターンで実装されています (app.pyapi_playground)。

演習問題

演習 1: ミニ Flask チャットを書く

150 行以内で、次の機能を持つ Flask チャットを書いてください。

  • / で簡単な HTML (チャット UI)
  • /chat POST: 履歴を受け取り、Streaming で応答を返す
  • 履歴 30 ターン超なら古いターンを要約に置換
  • system は cache_control 付き
スタータープロンプト:
Python + Flask で 150 行以内のミニチャットアプリを書いてください。要件:
1. anthropic SDK でストリーミング応答
2. /chat POST 履歴を JSON で受け取る (stateless)
3. 履歴 30 ターン超なら古いターンを Claude で要約して 1 メッセージに圧縮
4. system プロンプトに cache_control: ephemeral
5. /clear ボタン (フロントで履歴をクリアするだけ)
シングルファイル app.py で完結。
ヒントを見る

本講座アプリ (app.py) のコードが良い参考になります。SSE のフォーマットも同じパターンを流用できます。

理解度チェック

  1. サーバー側で会話履歴を保持しなくてもよい理由は?
    1. Claude API が stateless だから
    2. ブラウザは記憶力が良いから
    3. 禁止されているから
    4. 履歴は不要だから
  2. 履歴が長くなったときの一般的対策は?
    1. 古いターンを要約して圧縮
    2. ランダムに削除
    3. 暗号化して送る
    4. max_tokens を増やすだけ
  3. ストリーミング応答を返すレスポンスの mimetype として一般的なのは?
    1. text/plain or text/event-stream
    2. application/zip
    3. image/png
    4. audio/mp3
解答と解説を見る
  1. A — stateless API なので履歴はクライアントが管理する設計が自然です。
  2. A — コンテキスト溢れを避けるため、要約による圧縮が基本です。
  3. A — プレーン or SSE (text/event-stream) で送るのが一般的です。