AI英会話で「さっき言ったことを覚えていない」と感じるとき、そこで効いていないのは文脈保持という仕組みだ。
文脈保持とは、前の発言を次の発言の材料として持ち回る処理のことだ。
ここで最初に押さえておくべき前提がある。
OpenAI の Conversation state のガイドは「各テキスト生成リクエストは独立しており、ステートレスである」と書いている。
つまり、何もしなければAIは前のターンを持っていない。
覚えているように見えるのは、アプリ側が毎回それを渡し直しているからだ。
この記事では、AIの部品を売っている会社の開発者向け公式ドキュメントの記述だけを材料にして、文脈保持の仕組みと、どこで切れるのかを分解していく。
【結論】文脈保持は「毎回渡し直している」だけで、上限は文字数ではなくトークン
先に答えを置く。
公式ガイドは、文脈保持のやり方を大きく3つ示している。
| やり方 | 公式での呼ばれ方 | 要点 |
|---|---|---|
| ① | Manually manage conversation state | 過去のやりとりを毎回まるごと入力に足す |
| ② | Conversations API | 会話を持続する1つのオブジェクトとして保存する |
| ③ | previous_response_id | 前の応答のIDを渡して連結する |
どのやり方でも、最終的にモデルに入るのは1回のリクエストに収まるトークンの列だ。
公式の定義はこうだ。「コンテキストウィンドウとは、1回のリクエストで使えるトークンの最大数である。この最大トークン数には入力・出力・推論のトークンが含まれる」。
⇒ 文脈保持の限界は「何ターン前まで」ではなく「合計トークンがいくつまで」で決まっている。
文脈保持のやり方①|過去の会話を毎回まるごと渡し直す
いちばん素朴で、いちばん中身が見える方法がこれだ。
公式ガイドは「各テキスト生成リクエストは独立してステートレスだが、追加のメッセージをパラメータとして渡すことでマルチターンの会話を実装できる」と書いている。
載っている例は、ノックノックジョークのやりとりだ。
ユーザーの「Knock knock.」、アシスタントの「Who’s there?」、ユーザーの「Orange.」を、役割つきの配列として入力に並べる。
AIが「覚えている」のではなく、こちらが毎回もう一度読ませている、というのがこの方式の姿だ。
公式は続けて、手動で文脈を共有するには「モデルの前回の応答の出力を入力として含め、それを次のリクエストに追加する」と書いている。
さらに注意書きもある。推論モデルをステートレスに使う場合は応答の output 配列のすべてのアイテムを保持せよ、というものだ。
公式は「Responses API は既定で暗号化された推論アイテムを返す。出力すべてをそのまま再生することで、推論アイテムとアシスタントの phase の値が保たれる」とも書いている。
文脈保持のやり方②|Conversations APIは会話を器として残す
2つめは、会話そのものを保存対象の物体として扱う方法だ。
公式の説明はこうだ。「Conversations API は Responses API と連携し、会話状態を独自の永続的な識別子を持つ長寿命のオブジェクトとして保持する」。
そして「会話オブジェクトを作ったあとは、セッション・デバイス・ジョブをまたいで使い続けられる」と書かれている。
中に入るものも明記されている。
- メッセージ。
- ツール呼び出し(tool calls)。
- ツールの出力(tool outputs)。
- その他のデータ。
公式は利点も書いている。マルチターンのやりとりでは、後続の応答に conversation を渡すことで状態を保持でき、複数の応答アイテムを連結し続ける必要がなくなる。
⇒ 別の端末で続きから話せるタイプのAI英会話は、この器の側に会話が積まれている作りだと考えると筋が通る。
文脈保持のやり方③|previous_response_idで数珠つなぎにする
3つめは、前の応答のIDだけを渡す方法だ。
公式は「previous_response_id パラメータで生成された応答間の文脈を共有できる。このパラメータは応答を連鎖させ、スレッド化された会話を作る」と書いている。
一見すると、渡す量が減るので軽そうに見える。
だが公式ははっきり釘を刺している。
「previous_response_id を使っている場合でも、その連鎖に含まれるすべての過去の入力トークンが、APIでは入力トークンとして課金される」。
⇒ IDで指しても、中身は毎回モデルに入っている。
WebSocket モードについても記述がある。「接続ローカルのキャッシュが、低遅延の継続のために最近の応答をメモリに保持する」。
そして「キャッシュされていないIDが解決できない場合は、previous_response_id を null にした新しいターンを送り、完全な入力文脈を渡せ」と書かれている。
文脈保持の上限|コンテキストウィンドウが溢れると何が起きるか
文脈保持がどこで切れるかは、この節にはっきり書かれている。
公式は2種類の上限を区別している。どちらもモデルごとに値が違うので、公式はモデルの詳細ページを見るよう案内している。
| 名前 | 公式の定義 | 公式が挙げている例 |
|---|---|---|
| 出力トークン | プロンプトへの応答としてモデルが生成するトークン | gpt-4o-2024-08-06 は最大 16,384 出力トークン |
| コンテキストウィンドウ | 入力と出力(モデルによっては推論トークンも)に使える合計トークン | gpt-4o-2024-08-06 は合計 128k トークン |
溢れたときの挙動も書かれている。
「大きなプロンプトを作ると、モデルに割り当てられたコンテキストウィンドウを超える危険があり、出力が切り詰められる(truncated)結果になりうる」。
さらに「コンテキストウィンドウの上限を超えて生成されたトークンは、APIの応答で切り詰められることがある」とも書かれている。
⇒ 長い会話でAIの返事が尻切れになるのは、感覚の問題ではなく上限の話として説明できる。
なお公式は、トークン数の見積もりに tokenizer ツールを使えと案内している。このツールは tiktoken ライブラリで作られている、とも書かれている。
文脈保持を長持ちさせる仕組み|コンパクションという逃げ道
上限に当たったとき用の仕組みも、公式ガイドに名前が出ている。
Compaction(コンパクション)だ。
Conversation state のガイドは、詳しい案内は Compaction のページに移ったとしたうえで、2つの入口を挙げている。
/responsesのcontext_managementとcompact_threshold(サーバー側のコンパクション)。/responses/compactエンドポイント(明示的にコンパクションを制御する)。
⇒ 長い会話の文脈保持は、そのまま積み上げるのではなく、途中で圧縮する前提で設計されている。
圧縮が入るということは、細部が同じ形で残り続けるとは限らないということでもある。
文脈保持と保存期間|30日で消えるものと消えないもの
文脈保持の話には、データがどれだけ残るかという別の軸がある。
公式の記述は具体的だ。
| 対象 | 公式の記述 |
|---|---|
| Response オブジェクト | 既定で30日間保存される。store を false にすると無効にできる |
| Conversation オブジェクトとその中のアイテム | 30日のTTLの対象外。会話に紐づいた応答のアイテムはTTLなしで保持される |
同じ箇所には「OpenAI は明示的な同意なしに、API経由で送られたデータをモデルの学習に使わない」とも書かれている。
⇒ 文脈保持の器を使うかどうかは、会話が残る期間の設計とセットになっている。
音声の文脈保持は別の箱|Realtimeセッションは60分で終わる
音声でのAI英会話には、テキストとは別の入れ物がある。
Realtime conversations は「Realtime Session はモデルと接続されたクライアントとのステートフルなやりとりである」と書いている。
構成要素は3つだと明記されている。
- Session=モデルや音声などやりとりのパラメータを制御するオブジェクト。
- Conversation=現在のセッション中に生成されたユーザー入力アイテムとモデル出力アイテム。
- Responses=会話に追加される、モデルが生成した音声またはテキストのアイテム。
ここに強い制約が1つ書かれている。「Realtime セッションの最大継続時間は60分である」。
⇒ 音声の文脈保持は、少なくともこのセッションという箱の外側までは自動では伸びない。
もう1つ、セッション中に変えられないものも明記されている。モデルが一度音声で応答したあとは、出力に使う voice を更新できない。
文脈保持がわざと切られる場面|会話に足されない応答がある
文脈保持は「常に入れる」ものではなく、切る手段も用意されている。
Realtime conversations には、既定の会話の外側で応答を作る方法が書かれている。
公式の説明では、既定ではセッション中に生成されたすべての応答が会話状態に追加されるが、response.conversation を none にすると会話状態に追加されない応答を作れる。
公式はこれを out-of-band(帯域外)の応答と呼んでいる。
用途の例として挙がっているのは、これまでの会話を分析して「support」か「sales」かを出力させるといった分類の処理だ。
文脈の与え方にも段階がある。
- カスタムの文脈=
response.createのinput配列で、新しい入力を使うか、会話内の既存アイテムをIDで参照する。 - 文脈なし=
inputを空の配列にすると、他のすべての指示と文脈を無視した応答を会話に挿入できる。
⇒ AI英会話で「前の話を引きずらない返事」が返ってくる設計は、仕様として存在している。
加えて、割り込みが起きたときにも文脈は書き換わる。Interruption and Truncation の節によると、conversation.item.truncate はモデルの最後の応答のうち再生されなかった部分を会話から取り除く。
文脈保持に関するよくある質問
Q. 文脈保持は何ターン前まで効くのか。 A. ターン数ではなくトークンの合計で決まる。公式の定義は「1回のリクエストで使えるトークンの最大数」で、入力・出力・推論のトークンが含まれる。何ターンかは1ターンの長さ次第で変わる。
Q. 会話が長くなると返事が途中で終わるのはなぜか。 A. 公式は、コンテキストウィンドウを超えると出力が切り詰められる結果になりうると書いている。上限を超えて生成されたトークンはAPIの応答で切り詰められることがある、とも書かれている。
Q. 別の日に続きから話せるサービスと、毎回リセットされるサービスがあるのはなぜか。 A. 公式には、会話を永続的な識別子を持つ長寿命オブジェクトとして保持する Conversations API がある。「セッション・デバイス・ジョブをまたいで使い続けられる」と書かれており、これを使うかどうかは作り手の設計次第だ。
Q. 音声のAI英会話はどれくらい連続して話せるのか。 A. Realtime セッションについては「最大継続時間は60分」と明記されている。セッションをまたいで文脈を持ち回るかどうかは、その外側の設計の話になる。
Q. 会話の内容はどれくらい残るのか。 A. Response オブジェクトは既定で30日間保存され、store を false にすると無効にできる。Conversation オブジェクトとその中のアイテムは30日のTTLの対象外だと書かれている。
まとめ|文脈保持は「毎回渡し直す作業」で、上限はトークンで決まる
もう一度整理する。
- テキスト生成のリクエストは独立してステートレスだと公式が書いている。文脈保持は、アプリ側が過去を渡し直すことで成立している。
- やり方は3つ=手動で渡す/Conversations API の器に入れる/
previous_response_idで連結する。 - IDで連結しても「連鎖に含まれるすべての過去の入力トークンが入力トークンとして課金される」。中身は毎回入っている。
- 上限はコンテキストウィンドウ=入力・出力・推論を合わせたトークン数。超えると出力が切り詰められることがある。
gpt-4o-2024-08-06の例では合計 128k トークン、出力は最大 16,384 トークンと公式に書かれている。 - 音声側は別の箱で、Realtime セッションの最大継続時間は60分。割り込みが起きると未再生分は会話から取り除かれる。
⇒ AI英会話が前の話を落とすのは、記憶力の優劣ではなく1回のリクエストに何を詰めたかの結果だ。
だから覚えていてほしい内容は、長く話すよりも短く言い直したほうが残りやすい、という読み方ができる。
※本記事の一次ソースはすべて2026-09-16に各公式ドキュメントで確認した。仕様は更新されるため、最新は各公式ドキュメントで確認してほしい。
Comments