ストリーミング & マルチターン会話
API 上でチャットのような体験を構築する際の、2 つの実務的な現実: ユーザーが出力をすぐ見られるようストリーミングすること、そして API がステートレスなので履歴を自分で管理することです。
ストリーミング
ストリーミングがないと、ユーザーは返信全体を待ちます。ストリーミングがあれば、トークンは生成されるそばから届きます — 体感速度がはるかに良くなります。SDK のストリーミングヘルパーを使いましょう:
- Python
- TypeScript
with client.messages.stream(
model="claude-sonnet-4-6", max_tokens=1024,
messages=[{"role": "user", "content": "Explain RAG in two sentences."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
const stream = client.messages.stream({
model: "claude-sonnet-4-6", max_tokens: 1024,
messages: [{ role: "user", content: "Explain RAG in two sentences." }],
});
for await (const event of stream) {
if (event.type === "content_block_delta") process.stdout.write(event.delta.text ?? "");
}
マルチターン: 履歴はあなたが保持する
API は呼び出しの間にメモリを持ちません(理由)。会話を継続するには、毎回それまでのやり取り全体を送り返します:
messages = [{"role": "user", "content": "Hi, I'm planning a trip."}]
# ... get assistant reply, then append both turns:
messages.append({"role": "assistant", "content": assistant_text})
messages.append({"role": "user", "content": "Make it 3 days."})
# send the full `messages` list again
長い会話はウィンドウを埋めていく
履歴が増えるとコンテキストウィンドウを消費し、コストも上がります。対策:
- 古いターンを、引き継いでいく短いまとめへと要約/圧縮する。
- 関係のない以前のターンをトリミングする。
- プロンプトキャッシュ と組み合わせて、安定した先頭部分への再支払いを避ける。