Dev Study
← AIを部品として組み込む仕組み
レッスン 3 / 12·約 9 分·第20期 AIを部品として組み込む仕組み

モデルは会話を覚えていない — 毎回送り直す有限の窓

リクエストがアプリケーションに届くまで
  1. ブラウザURL入力
  2. DNS名前→IP
  3. ルータ経路選択
  4. ロードバランサ振り分け
  5. Nginx受け口
  6. アプリ処理今ここ
  7. DB保存

前回「スキーマが縛るのは形まで」では、1回の応答の形を部品の外で確かめました。今回は、会話の続きを部品の外の誰が持っているのかを見ます。

まず結論

2026-09 時点の Anthropic の公式文書は、Messages API を stateless と書き、会話の履歴は毎回全部送るとしています。会話を持っているのはモデルではなく、呼ぶ側のアプリです。

だから何を残し、何を捨て、過去の応答をどう書き換えるかもアプリが決めます。送れる量には上限(コンテキストウィンドウ)があり、その量は文字数では決まりません。

? 読む前に予測

Anthropic の Messages API で、3往復目の質問を送るとき、アプリは要求に何を入れる必要があるでしょうか。

当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。

抽象原理

続きを持っているのは、呼ぶ側

チャット画面で話していると、相手が前の発言を覚えているように見えます。しかし API の文書は、そうは書いていません。

The Messages API is stateless, which means that you always send the full conversational history to the API. You can use this pattern to build up a conversation over time.

stateless、つまり要求をまたいで会話を持たない。続きに見えるのは、アプリが毎回、最初からの履歴を全部送り直しているからです。

同じ段落は続けます。

Earlier conversational turns don't necessarily need to actually originate from Claude. You can use synthetic assistant messages.

過去の応答が、本当にモデルの出力である必要はない。履歴はアプリの持ち物なので、残すのも、削るのも、書き換えるのもアプリです。

往復ごとに、アプリは履歴を全部送り直す
1往復目の要求質問1
応答1をアプリが保存
2往復目の要求質問1・応答1・質問2
応答2をアプリが保存
3往復目の要求質問1・応答1・質問2・応答2・質問3
  • ・会話の記録はアプリの側にある。何を入れて送るかはアプリが決める
  • ・毎回送り直すので、1回の要求は往復のたびに大きくなる
具体実物

文書の例に、アプリが書いた「応答」がある

文書が示す要求の本体です(cURL の例から messages の部分だけを抜粋)。

Using the Messages API の例(抜粋)設定ファイル
"messages": [
{"role": "user", "content": "Hello, Claude"},
{"role": "assistant", "content": "Hello!"},
{"role": "user", "content": "Can you describe LLMs to me?"}
]

assistant の行は、この要求の前にモデルが返したものかもしれませんし、アプリが書いたものかもしれません。要求の中では区別がありません。

ただし、書き換えてよい範囲には限りがあります。同じ文書は、最後の位置に assistant を置いて続きを書かせる使い方(prefill)について、2026-09 時点で Prefilling is not supported on Claude 4.6 and later models と書き、400 エラーを返すとしています。合成してよいと書かれているのは過去のターンです。

✓ ここまでの確認

アプリが、2往復目のモデルの応答を短い要約に書き換えてから、3往復目の要求の履歴に入れて送りました。文書に照らして、どう扱われると言えますか。

抽象原理

送れる量には上限があり、数え方は文字ではない

毎回全部送るなら、会話はいつか送りきれなくなります。その上限がコンテキストウィンドウです。

The "context window" refers to all the text a language model can reference when generating a response, including the response itself.

応答自身も含みます。 同じ文書は、システムプロンプト、ツールの定義、ツールの結果、そして出力が全部この枠に数えられると書きます。覚えておける量ではなく、1回の要求で見渡せる量です。

上限を超えたらどうなるか。2026-09 時点の文書では、入力だけで超えた要求には全モデルで 400 を返します。古い発言が黙って消えるのではありません。古いものから落とすやり方は、claude.ai のようなチャット画面について can also manage the context window on a rolling "first in, first out" basis と書かれた、画面の側の管理です。

同じ文書は、長い会話への主な対処として server-side compaction(2026-09 時点でベータ)を挙げます。サーバが古い部分を要約しますが、使うかどうかはアプリが選び、要約を含む履歴を送り直すのも引き続きアプリです。

上限の内側でも安心はできません。文書は As token count grows, accuracy and recall degrade, a phenomenon known as context rot. と書きます。これは量の話です。別に、位置の話もあります。Liu らは、関連情報が入力の中ほどにあると成績が大きく落ちることがあると報告しました(2023年のモデルでの測定)。窓に入れたことは、読まれることを約束しません。

具体実物

同じ意味の文を、2つの数え方で数える

同じ意味の英文と和文を、2つのモデルのトークナイザで数えました。Docker 上で版を固定して2回走らせ、2回とも同じ出力です(分割結果の列は省略)。

英文 57字 / 和文 26字 を数える(gpt2・Qwen2.5-0.5B-Instruct)コマンド出力
transformers 5.17.0 tokenizers 0.23.2
openai-community/gpt2 en: chars= 57 tokens= 11
openai-community/gpt2 ja: chars= 26 tokens= 31
Qwen/Qwen2.5-0.5B-Instruct en: chars= 57 tokens= 11
Qwen/Qwen2.5-0.5B-Instruct ja: chars= 26 tokens= 17

英文は "The deployment did not succeed because the disk was full."、和文は「ディスクが満杯だったため、デプロイは成功しなかった。」です。

英文はどちらも11。和文は文字数が半分以下なのに31と17で、同じ和文でも数え方によって2倍近く違います。

省略した分割結果を見ると、gpt2 は「満」1文字を 'æ', 'º', 'Ģ' の3片に、Qwen2.5 も 'æº', 'Ģ' の2片に割っています。これは UTF-8 の各バイトを見える文字に写した表記で、1片が1文字とは限らず、1文字の途中で切れることもあります。 なお Sennrich らの方式は文字を併合するもので、バイトに割れるのはこの2つのトークナイザで観察された性質です。

✓ ここまでの確認

compaction などの文脈管理の機能を有効にせず、Messages API を直接呼ぶチャット機能で、長い会話の序盤の発言が回答に反映されなくなりました。序盤を送らないと決めたのは誰だと考えるべきですか。

⇄ 2つを見比べる
具体例 A

Messages API に会話を送る

運ぶのは会話そのものです。履歴は毎回全部送られ、記録はアプリの側にあります。何を残し、削り、書き換えるかをアプリが決められ、その量には上限があります。

何を運び、記録はどこにあるか表
毎回運ぶもの 会話の履歴すべて
記録の置き場 アプリ
具体例 B

HTTP で Cookie を送る(別コース「状態を持たないHTTPとCookie/セッション」)

RFC 9110 は HTTP を stateless と定め、各要求の意味が単独で理解できることとします。続きを表すには、クライアントが合言葉(セッション ID)を毎回運びます。状態そのものはサーバの表に置けるので、運ぶのは鍵だけで済みます。

何を運び、記録はどこにあるか表
毎回運ぶもの 合言葉(セッション ID)
記録の置き場 サーバの表(に置ける)

どちらも stateless と呼ばれます。では、なぜ HTTP は鍵だけで済み、Messages API は会話を全部送るのでしょうか。

「鍵を渡されたとき、それで引ける表がどちらの側にあるか」を考えてください。

この章のまとめ

  • Messages API は stateless。会話の履歴は毎回全部送る(2026-09 時点の公式文書)。
  • 履歴はアプリの持ち物。過去の応答は 合成してよい と文書が書く。ただし最後の位置の prefill は新しいモデルで 400。
  • コンテキストウィンドウは 応答自身も含む。覚えておける量ではなく、1回の要求で見渡せる量。
  • 入力だけで超えれば 400。既定では、古い発言を落とすのは API ではなく送る側の管理(compaction を有効にした場合は、サーバが要約を作り、それで古い部分を置き換える)。
  • 窓の内側でも、量が増えると落ち(context rot)、位置でも変わりうる(Liu ら、2023年のモデル)。
  • 消費量は文字数でも意味でもなく 分割の仕方 で決まる。同じ和文が31と17。

自分の現場で確かめる

読んだだけでは身につきません。手元の環境で実際に見てみてください。

理解度チェック

読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。

問題 1 / 3正解: 0

2026-09 時点の Anthropic の文書で、入力だけでコンテキストウィンドウを超えた要求を送ると、どうなるとされていますか。

用語集(4語)
stateless(Messages API)
API が要求をまたいで会話を保持しないこと。文書は、会話の履歴を毎回全部送ると書く。
コンテキストウィンドウ
Anthropic の文書の定義では、応答を生成するときにモデルが参照できるテキストの全体で、応答自身を含む。学習に使ったデータとは別物。
トークン
モデルが扱う文字列の単位。1片が1文字とは限らず、1文字の途中で割れることもある。数え方はトークナイザごとに違う。
context rot
Anthropic の文書の語。窓に入れる量が増えると正確さと想起が落ちる現象。