Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

履歴管理

ランタイムは各エージェントセッションの会話履歴を保持し、プロバイダー向けの作業履歴をモデルに送信します。2つの補完的な制限が、異なる表現に対して機能します。

  1. トークンバジェットのトリミングは、プロバイダー向けの ChatMessage 作業履歴に作用し、推定コンテキストがトークンバジェットに収まるまで、最も古いターンを丸ごと削除します。
  2. 構造化メッセージ数トリミングは、構造化エージェントの有効メッセージ上限を超えた場合に、RPC、ゲートウェイ、およびACP の Agent ターンが使用する Agent::historyConversationMessage)を変更します。レガシー agent::run パスを呼び出すデーモンチャンネルループは、以下で説明する別個のrawメッセージ上限を使用します。

トークンバジェットのトリミングと構造化されたメッセージ数の上限は、ターンをアトミックに保持します。ターンは実際のユーザーメッセージから始まり、アシスタントの応答と、次のユーザーメッセージまでのすべてのツール呼び出しおよびツール結果を含みます。したがって、トリミングによってツール呼び出しとその結果が分割されることはありません。

ターン全体の保持

history_trim::trim_to_recent_turns はトークン予算を適用し、history_trim::trim_conversation_to_recent_turns は構造化されたメッセージ数の上限を適用します。どちらも、最新の完全なターンがそれぞれの制限を超える場合でも、その最新の完全なターンを保持します。これは意図的な設計です。最新のメッセージを削除したり、ツール交換を途中で分断して数値上の上限を満たすよりも、現在の完全なターンを保持する方が安全なためです。

先頭のシステムメッセージは保持されます。トリミングが不要な場合、メッセージの順序と形状は変更されません。

トークン予算

トークン予算は ResolvedRuntime::effective_context_budget() から取得されます:

  • history_pruning.enabled が正の history_pruning.max_tokens とともに設定されている場合、予算にはその値と max_context_tokens のうち小さい方が使用されます。
  • それ以外の場合、上限は max_context_tokens です。

トークン数は history::estimate_history_tokens によって推定されます: 1 トークンあたりおよそ 4 文字に、1 メッセージあたり 4 個のフレーミングトークンを加えます。これはヒューリスティックであり、プロバイダーのトークナイザーではありません。

トークンバジェットのトリミングは、履歴が有効バジェットをすでに超えている場合にターンの最初のプロバイダー呼び出しの前、およびツールループの反復間のプロバイダー呼び出し境界で実行されます。これには、プロバイダーがコンテキストウィンドウが超過したと報告した場合の反応的な実行も含まれます。ターン全体を保持するため、ツール交換を分割することはありません。

構造化メッセージ数の上限

max_history_messages は、エージェントのランタイムプロファイルで構成された値です。明示的に構成された値は、0 を含め、レガシーの raw パスと構造化されたエージェント履歴の両方に対して正式な値として扱われます。構造化トリミングでは常に最新の完全なターンが保持されるため、値が 0 の場合、古いターンは削除されますが、現在のターンは消去されません。

max_history_messages が省略された場合、従来の raw cap は 50 のままです。structured agent の実効上限は、tool-loop の許容量から導出されます:

max(50, 2 * max_tool_iterations + 2)

各ツールイテレーションでは、ツール呼び出しとツール結果を追加できます。追加の 2 つのスロットは、ユーザーメッセージと最終的なアシスタント応答をカバーします。デフォルトの max_tool_iterations = 10 では、算出される上限は 50 のままです。

表示のトリミング

トークン予算のトリミングまたは構造化メッセージ数の上限により古いターンが削除されるたびに、ランタイムは:

  1. モデルが以前のコンテキストが省略されたことを認識できるよう、最初の保持されたターンの前にパンくずリストを挿入します。
  2. ドロップされたメッセージ数、保持されたターン数、およびトークンバジェットまたはメッセージ制限を示す理由とともに HistoryTrimmed を発行します。

イベントは、アクティブなクライアントトランスポートを通じて、およびダッシュボードやイベントサブスクライバーが使用するオブザーバーパスを通じて表面化されます。したがって、トリミングはログのみに限定されず、モデルにも接続されたクライアントにも通知されないわけではありません。

レガシーの agent::run パス(loop_.rs)は変更されない例外です。history::trim_history における生の ChatMessage 上限はメッセージレベルのままであり、トリミングはブレッドクラムや HistoryTrimmed イベントを使用せずログのみで報告されます。このパスは、インタラクティブな使用に加え、ワンショット、非インタラクティブなデーモン、cron、サブエージェント、およびSOPの呼び出し元にも対応しています。

ペアリングの安全性

ターン全体の保持は、ツールのペアリングに関する主要な保証です。ツール呼び出しとその結果は同じターンに属し、一緒に保持されるか破棄されます。孤立要素のスイープは、復元されたセッションや外部で変更されたセッションなど、すでに不整合だった履歴に対する最後のセーフティネットとして残ります。

ツール結果の長さ制限は別途扱われます。max_tool_result_chars は個々の結果が記録される際にそのサイズを制限しますが、会話履歴をトリミングするものではありません。プロバイダー側のコンテキスト制限も別途扱われますが、プロバイダーのオーバーフローによってランタイムの事後的なトークンバジェットのトリミングがトリガーされる場合があります。