4.8 KiB
Compact の改善
背景
Pod::compact() とその周辺機構(CompactInterceptor, CompactState, Controller 統合)は
実装済み。挙動の詳細に未決定事項が残っており、要約品質にも改善余地がある。
1. 要約入力の改善
現状の問題
build_summary_prompt() が全 Item をフラットにテキスト化して LLM に投げている。
- データが多すぎる: ToolResult の content(ファイル内容、grep 結果等)を含めている
- 単一関心事の前提: "Original Task" が1つだけ。タスク切り替わりに対応できない
Phase 1: 入力データの削減
build_summary_prompt で渡すデータを絞る:
fn build_summary_prompt(items: &[Item]) -> String {
for item in items {
match item {
Item::ToolResult { summary, .. } => {
// content を含めない。summary だけ
lines.push(format!("[ToolResult] {summary}"));
}
Item::ToolCall { name, .. } => {
// arguments を含めない。ツール名だけ
lines.push(format!("[ToolCall] {name}"));
}
Item::Reasoning { .. } => {
// skip(内部思考は要約に不要)
}
// User/Assistant のテキストはそのまま
}
}
}
Phase 2: 要約フォーマットの改善
タスク切り替わりを反映する:
## Tasks
### Task 1: (最初のユーザー指示)
- 完了した作業
- 判明した事実
### Task 2: (次のユーザー指示)
- 完了した作業
- 判明した事実
## Current State
- (変更されたファイル、残タスク)
Phase 3: マルチターン要約 Worker
1リクエストで全部読ませるのではなく、要約 Worker にツールを持たせて自律的に要約させる。
要約 Worker:
system: 「セッションログを読んで構造化要約を生成せよ」
ツール: read_session_segment(offset, limit)
利点:
- 巨大セッションでもコンテキストに収まる
- Worker が自分で「重要/不要」を判断できる
- タスク切り替わりを検出し、関心事ごとに要約できる
builtin-tools チケットとの依存あり。
2. 挙動の未決定事項
現在の挙動
トリガー(2段階):
- ターン間 (CompactInterceptor):
input_tokens > turn_threshold→ Yield → compact + resume - run 後 (Controller):
input_tokens > post_run_threshold (×9/8)→ best-effort compact
安全機構:
- サーキットブレーカー: 3回連続失敗で無効化
- Thrash 検出: compact 直後に再び閾値超過 → CompactThrash エラー
- Yield 前の永続化: persist_turn を compact の前に実行
2-1. Yield のタイミング精度
現状: pre_llm_request でチェック = ターンの切れ目でしか発火しない。
1ターン内でツール呼び出しが多く、途中でコンテキストが膨らむケースは次のターンまで待つ。
検討:
- ツール実行後にもチェックする?(
post_tool_callで Yield 相当の処理) - 現状の「ターン切れ目のみ」で十分か?
2-2. 閾値の導出
turn_threshold= マニフェストのcompact_thresholdそのままpost_run_threshold=turn_threshold * 9 / 8(≈ 112.5%)
9/8 の根拠はない(安全マージン)。マニフェストで個別指定可能にする?
2-3. Prune と Compact の相互作用
pre_llm_request:
1. PruneHook(content を除去)
2. CompactInterceptor(トークン数チェック)
Prune はリクエストコンテキストのみ操作し、last_input_tokens は前回の LLM レスポンスの値。
Prune の効果は last_input_tokens に反映されず、Compact の判断には影響しない。
→ Prune で十分に縮んでも Compact が走る可能性がある。保守的で実害は小さい。
2-4. compact 中のクライアント通知
compact は LLM 呼び出しを伴う。この間 Controller は Pod を占有。
AlreadyRunning エラーで弾かれる。Protocol チケットの CompactStart/CompactDone で対応。
2-5. 復元時の挙動
Outcome::Yielded で記録されたセッションを restore した場合:
last_run_interrupted = trueで復元- Pod は resume 可能(通常の interrupted セッションと同じ)
- compact 後の新セッションが存在する場合、どちらを restore するかは呼び出し側の責任
compacted_fromで辿れる
実装順序
- Phase 1(content/arguments/reasoning 除去)→
build_summary_promptの変更のみ - 挙動の未決定事項 → 実運用でのフィードバックを元に判断
- Phase 2(フォーマット改善)→ チューニング
- Phase 3(マルチターン要約)→ builtin-tools 後