Simple Chatbot
シンプルなチャットボット
約 14 分
·
クイズ 3 問
·
演習 1 問
重要キーワード (4 語)
Stateless API
(ステートレスAPI)
— サーバーが履歴を保持しない設計。クライアントが履歴を持つ
Streaming
(ストリーミング)
— 応答を逐次返す方式
Sliding Window
(スライディングウィンドウ)
— 履歴の古い部分を切る or 要約する技法
Compaction
(圧縮)
— 長い会話を要約して短くする処理
シンプルなチャットボット
最小構成のチャットボットを Flask で作ります。
設計
- 状態は クライアント (ブラウザ) が持つ。
- サーバーは履歴を受け取って Claude に転送するだけ。
- Streaming で応答を逐次返す。
サーバー側
from flask import Flask, request, Response, jsonify
from anthropic import Anthropic
app = Flask(__name__)
client = Anthropic()
SYSTEM = "あなたは丁寧な日本語アシスタントです。"
@app.post("/chat")
def chat():
history = request.json["history"] # [{role, content}, ...]
def gen():
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
system=SYSTEM,
messages=history,
) as s:
for t in s.text_stream:
yield t
return Response(gen(), mimetype="text/plain")
クライアント側 (擬似)
async function send(userMsg) {
history.push({role: "user", content: userMsg});
const res = await fetch("/chat", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({history}),
});
const reader = res.body.getReader();
let assistant = "";
for (;;) {
const {value, done} = await reader.read();
if (done) break;
assistant += new TextDecoder().decode(value);
render(assistant);
}
history.push({role: "assistant", content: assistant});
}
履歴の長期化対策: Sliding Window + Summary
会話が長くなると input が肥大化します。次の戦略を組み合わせます:
MAX_TURNS = 20
def trim(history: list[dict]) -> list[dict]:
if len(history) <= MAX_TURNS:
return history
# 古いターンを要約
old, recent = history[:-MAX_TURNS], history[-MAX_TURNS:]
summary = summarize(old)
return [{"role": "user", "content": f"<会話の要約>\n{summary}"}] + recent
summarize() も Claude で実装すれば自然な要約に。
ベストプラクティス
- システムプロンプトはキャッシュ対象に。
- 入力検証: 極端に長い入力 / 連投 を制限。
- ユーザー識別はハッシュ化して
metadata.user_idに。 - 失敗時は 古い応答に戻す or 再試行 UI を提供。
- レート制限はサーバー側でクオータ実装。
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.py の api_playground)。