Skip to content

自動トリミング戦略の詳細

学習後にできること

  • 3つの自動トリミング戦略の動作原理を理解する
  • 各戦略を有効化/無効化する状況を判断できる
  • 設定を通じて戦略の効果を最適化できる

抱えている課題

会話が長くなるにつれて、コンテキスト内のツール呼び出しが山積みになります。

  • AIが同じファイルを繰り返し読み込み、毎回完全な内容をコンテキストに詰め込む
  • ファイルへの書き込み後に読み込みを行うと、元の書き込み内容がコンテキスト内で「無駄に」残る
  • ツール呼び出しに失敗しても、巨大な入力パラメータがそのままの位置を占拠し続ける

これらの問題により、トークン請求は雪だるま式に増大し、コンテキストを「汚染」してAIの判断に影響を与える可能性があります。

中核となる考え方

DCPは毎回のリクエスト送信前に自動トリミング戦略を3つ提供し、LLMコストゼロで自動実行されます。

戦略デフォルト機能
重複除去✅ 有効重複したツール呼び出しを検出し、最新の1つだけを保持
上書き書き込み❌ 無効読み込みで上書きされた書き込み操作の入力を削除
エラー削除✅ 有効Nターン後にエラーツール入力を削除

すべての戦略は以下のルールに従います。

  • 保護ツールをスキップ: task、write、edit などの重要なツールはトリミングされません
  • 保護ファイルをスキップ: 設定されたglobパターンで保護されたファイルパス
  • エラーメッセージを保持: エラー削除戦略は入力パラメータのみを削除し、エラー情報は保持されます

重複除去戦略

動作原理

重複除去戦略は同じツール名とパラメータの重複呼び出しを検出し、最新の1つだけを保持します。

署名マッチング機構

DCPは「署名」を通じて重複を判定します。

  • ツール名が同じ
  • パラメータ値が同じ(null/undefinedは無視、キー順序は影響なし)

例えば:

json
// 1回目の呼び出し
{ "tool": "read", "path": "src/config.ts" }

// 2回目の呼び出し(署名が同じ)
{ "tool": "read", "path": "src/config.ts" }

// 3回目の呼び出し(署名が異なる)
{ "tool": "read", "path": "src/utils.ts" }

適用シナリオ

有効を推奨(デフォルトで有効):

  • AIがコード分析のために同じファイルを頻繁に読み込む
  • 複数ターンにわたり同じ設定を繰り返し照会する
  • 最新の状態を維持する必要があり、履歴出力を破棄できるシナリオ

無効化したい場合

  • 各ツール呼び出しのコンテキストを保持する必要がある(ツール出力のデバッグなど)

設定方法

json
// ~/.config/opencode/dcp.jsonc
{
  "$schema": "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/main/dcp.schema.json",
  "strategies": {
    "deduplication": {
      "enabled": true  // true で有効、false で無効
    }
  }
}

保護ツール(デフォルトでトリミングされない):

  • task、write、edit、batch、plan_enter、plan_exit
  • todowrite、todoread(タスクリストツール)
  • discard、extract(DCP自身のツール)

これらのツールは設定であっても重複除去のトリミング対象にはなりません(ハードコードされた保護)。


上書き書き込み戦略

動作原理

上書き書き込み戦略は後続の読み込みで上書きされた書き込み操作の入力を削除します。

例:書き込み後の読み込み
text
ステップ1:ファイルへの書き込み
AIが write("config.json", {...}) を呼び出す

ステップ2:ファイルの読み込みで確認
AIが read("config.json") を呼び出す → 最新の内容を返す

上書き書き込み戦略が認識
write の入力(大きい可能性がある)が冗長になる
read がファイルの現在の状態をすでに取得しているため

トリミング
read の出力のみを保持し、write の入力を削除

適用シナリオ

有効を推奨

  • 頻繁な「書き込み→検証→修正」のイテレーション開発シナリオ
  • 書き込み操作に大量のテンプレートまたは完全なファイル内容が含まれる

デフォルトで無効の理由

  • 一部のワークフローはコンテキストとして「履歴書き込み記録」に依存する
  • 一部のバージョン管理関連のツール呼び出しに影響する可能性がある

手動で有効化するタイミング

json
{
  "strategies": {
    "supersedeWrites": {
      "enabled": true
    }
  }
}

注意事項

この戦略はwriteツールの入力のみをトリミングし、出力はトリミングしません。なぜなら:

  • write の出力は通常確認メッセージ(小さい)
  • write の入力には完全なファイル内容が含まれる可能性がある(大きい)

エラー削除戦略

動作原理

エラー削除戦略は、ツール呼び出しが失敗した後、Nターン待ってから入力パラメータを削除します(エラーメッセージは保持)。

ターン(turn)とは?

OpenCodeの対話では:

  • ユーザーがメッセージを送信 → AIが返信 = 1ターン
  • ツール呼び出しはターンにカウントされない

デフォルトの閾値は4ターンであり、これはエラーツールの入力が4ターン後に自動的に削除されることを意味します。

適用シナリオ

有効を推奨(デフォルトで有効):

  • ツール呼び出しが失敗し、入力が大きい(超大容量ファイルの読み込み失敗など)
  • エラー情報は保持する必要があるが、入力パラメータは価値がない

無効化したい場合

  • デバッグのために失敗したツールの完全な入力を保持する必要がある
  • 頻繁に「断続的な」エラーに遭遇し、履歴を保持したい

設定方法

json
{
  "strategies": {
    "purgeErrors": {
      "enabled": true,   // 有効化スイッチ
      "turns": 4        // 削除閾値(ターン数)
    }
  }
}

保護ツール(デフォルトでトリミングされない):

  • 重複除去戦略と同じ保護ツールリスト

戦略の実行順序

3つの戦略は固定順序で実行されます。

mermaid
graph LR
    A["メッセージリスト"] --> B["ツールキャッシュを同期"]
    B --> C["重複除去戦略"]
    C --> D["上書き書き込み戦略"]
    D --> E["エラー削除戦略"]
    E --> F["トリミング内容を置換"]

これは以下を意味します。

  1. 先に重複除去(冗長性を削減)
  2. 次に上書き書き込み(無効になった書き込みを削除)
  3. 最後にエラー削除(期限切れのエラー入力を削除)

各戦略は前の戦略の結果に基づいており、同じツールを繰り返しトリミングすることはありません。


よくある落とし穴

❌ 誤解 1:すべてのツールが自動的にトリミングされると思っている

問題:task、writeなどのツールがトリミングされないのはなぜか?

原因:これらのツールは保護ツールリストにあり、ハードコードされた保護されています。

解決策

  • writeをトリミングする必要がある場合は、上書き書き込み戦略を有効化することを検討してください
  • taskをトリミングする必要がある場合は、保護ファイルパスを設定して間接的に制御できます

❌ 誤解 2:上書き書き込み戦略がコンテキストを不完全にする

問題:上書き書き込みを有効化すると、AIが以前の書き込み内容を見つけられない。

原因:戦略は「読み込みで上書きされた」書き込みのみを削除しますが、書き込み後に読み込みがない場合はトリミングされません。

解決策

  • ファイルが実際に読み込まれたか確認してください(/dcp context で確認可能)
  • 書き込み記録を保持する必要がある場合は、この戦略を無効化してください

❌ 誤解 3:エラー削除戦略が早すぎる

問題:エラー入力がトリミングされた直後に、AIが同じエラーに遭遇する。

原因turns 閾値が小さすぎる。

解決策

json
{
  "strategies": {
    "purgeErrors": {
      "turns": 8  // デフォルトの4から8に増やす
    }
  }
}

このテクニックを使うタイミング

シナリオ推奨戦略組み合わせ
日常開発(読み込み多め、書き込み少なめ)重複除去 + エラー削除(デフォルト設定)
頻繁な書き込み検証すべて有効(手動で上書き書き込みを有効化)
ツール失敗のデバッグ重複除去のみ(エラー削除を無効化)
完全なコンテキスト履歴が必要すべて無効

本レッスンのまとめ

  • 重複除去戦略:重複したツール呼び出しを検出し、最新の1つを保持(デフォルトで有効)
  • 上書き書き込み戦略:読み込みで上書きされた書き込み操作の入力を削除(デフォルトで無効)
  • エラー削除戦略:Nターン後にエラーツール入力を削除(デフォルトで有効、閾値4)
  • すべての戦略は保護ツールと保護ファイルパスをスキップする
  • 戦略は固定順序で実行される:重複除去 → 上書き書き込み → エラー削除

次のレッスンの予告

次のレッスンでは LLM駆動トリミングツール を学習します。

学習内容:

  • AIがどのように discard と extract ツールを自律的に呼び出すか
  • セマンティックレベルのコンテキスト最適化の実現方法
  • 重要な発見を抽出するベストプラクティス

付録:ソースコード参照

クリックしてソースコードの場所を表示

更新日時:2026-01-23

機能ファイルパス行番号
重複除去戦略の実装lib/strategies/deduplication.ts13-83
上書き書き込み戦略の実装lib/strategies/supersede-writes.ts16-105
エラー削除戦略の実装lib/strategies/purge-errors.ts16-80
戦略のエントリーエクスポートlib/strategies/index.ts1-5
デフォルト設定lib/config.ts423-464
保護ツールリストlib/config.ts68-79

主要関数

  • deduplicate() - 重複除去戦略のメイン関数
  • supersedeWrites() - 上書き書き込み戦略のメイン関数
  • purgeErrors() - エラー削除戦略のメイン関数
  • createToolSignature() - 重複除去マッチング用のツール署名を作成
  • normalizeParameters() - パラメータ正規化(null/undefinedを除去)
  • sortObjectKeys() - パラメータキーのソート(署名の一貫性を確保)

デフォルト設定値

  • strategies.deduplication.enabled = true
  • strategies.supersedeWrites.enabled = false
  • strategies.purgeErrors.enabled = true
  • strategies.purgeErrors.turns = 4

保護ツール(デフォルトでトリミングされない)

  • task、todowrite、todoread、discard、extract、batch、write、edit、plan_enter、plan_exit