# 機能設計書 5-Compaction エージェント

## 概要

本ドキュメントは、OpenCodeシステムにおけるCompaction エージェントの機能設計を記述する。Compaction エージェントは、コンテキスト圧縮用の内部エージェントであり、会話履歴を要約してトークン使用量を削減する。

### 本機能の処理概要

Compaction エージェントは、セッションのトークン使用量がモデルのコンテキスト制限に近づいた際に自動的に起動され、会話履歴を要約してコンテキストを圧縮する。これにより、長時間のセッションでも継続的な対話が可能となる。

**業務上の目的・背景**：LLMにはコンテキストウィンドウの制限があり、長時間の会話セッションでは制限を超過する可能性がある。Compaction エージェントは、この問題を解決するため、重要な情報を保持しながら会話履歴を圧縮し、セッションの継続性を確保する。

**機能の利用シーン**：コンテキスト使用量がオーバーフロー閾値（モデルのコンテキスト制限 - 出力トークン上限 - バッファ）を超えた際に自動起動される。ユーザーが明示的にコンパクションを要求することも可能。

**主要な処理内容**：
1. トークンオーバーフロー検出
2. 古いツール呼び出し結果のプルーニング
3. 会話履歴の要約生成
4. 要約メッセージとしてセッションに保存
5. 自動継続メッセージの挿入（オプション）

**関連システム・外部連携**：設定ファイルによりコンパクションの有効/無効、自動継続の設定が可能。プラグインによるコンパクションプロンプトのカスタマイズも対応。

**権限による制御**：Compaction エージェントは、内部エージェントとして全ツール使用が禁止（*: deny）されている。テキスト生成のみを行い、ファイル操作等は一切行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | 内部機能 | UI表示なし（バックグラウンド処理） |

## 機能種別

コンテキスト管理 / 自動圧縮

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | Yes | エージェント名（"compaction"固定） | 文字列型 |
| mode | "primary" | Yes | エージェントのモード | enum値 |
| native | boolean | Yes | ネイティブエージェントかどうか（true） | boolean型 |
| hidden | boolean | Yes | 非表示フラグ（true） | boolean型 |
| prompt | string | Yes | 要約用システムプロンプト（PROMPT_COMPACTION） | 任意の文字列 |
| permission | PermissionNext.Ruleset | Yes | 権限ルールセット（全ツールdeny） | 有効なルールセット配列 |

### 入力データソース

- セッションメッセージ履歴
- トークン使用量情報
- モデルのコンテキスト制限

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| summaryMessage | MessageV2.Assistant | 要約を含むアシスタントメッセージ |
| prunedParts | number | プルーニングされたツール結果の数 |

### 出力先

- セッションデータベース（summary: trueフラグ付きメッセージ）

## 処理フロー

### 処理シーケンス

```
1. オーバーフロー検出
   └─ SessionCompaction.isOverflow()でトークン超過判定
2. プルーニング実行
   └─ SessionCompaction.prune()で古いツール結果を削除
3. 要約生成
   └─ Compactionエージェントによる会話要約
4. 要約メッセージ保存
   └─ summary: trueフラグ付きでメッセージ保存
5. 自動継続（オプション）
   └─ 継続用ユーザーメッセージの挿入
```

### フローチャート

```mermaid
flowchart TD
    A[ステップ完了] --> B{トークンオーバーフロー?}
    B -->|No| C[通常継続]
    B -->|Yes| D[Compaction開始]
    D --> E[プルーニング実行]
    E --> F{PRUNE_MINIMUM超過?}
    F -->|Yes| G[古いツール結果を圧縮]
    F -->|No| H[プルーニングスキップ]
    G --> I[要約生成]
    H --> I
    I --> J[Compactionエージェント実行]
    J --> K[要約メッセージ保存]
    K --> L{自動継続設定?}
    L -->|Yes| M[継続メッセージ挿入]
    L -->|No| N[Compaction完了]
    M --> N
    N --> C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 自動圧縮 | config.compaction.auto !== falseの場合に自動実行 | トークンオーバーフロー時 |
| BR-02 | プルーニング閾値 | PRUNE_MINIMUM（20,000トークン）以上でプルーニング実行 | プルーニング判定時 |
| BR-03 | 保護閾値 | PRUNE_PROTECT（40,000トークン）以内のツール結果は保護 | プルーニング実行時 |
| BR-04 | 要約フラグ | summary: trueの要約メッセージ以降はプルーニング対象外 | プルーニング実行時 |
| BR-05 | ツール禁止 | 全ツールがdenyで要約テキスト生成のみ | 常時 |
| BR-06 | スキルツール保護 | "skill"ツールの結果はプルーニング対象外 | プルーニング実行時 |

### 計算ロジック

- **オーバーフロー判定**：
  - usable = model.limit.input ? (input_limit - reserved) : (context - maxOutputTokens)
  - overflow = tokens.total >= usable
- **プルーニング対象**：
  - 直近40,000トークン分は保護
  - それ以前のツール結果をcompacted状態に

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 要約メッセージ作成 | message | INSERT | summary: trueのメッセージ作成 |
| パーツ圧縮 | message_part | UPDATE | compacted: timestampを設定 |
| 継続メッセージ作成 | message | INSERT | 自動継続用ユーザーメッセージ |

### テーブル別操作詳細

#### message

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | summary | true | 要約メッセージフラグ |
| INSERT | agent | "compaction" | Compactionエージェント |
| INSERT | mode | "compaction" | 圧縮モード |

#### message_part

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | state.time.compacted | Date.now() | 圧縮タイムスタンプ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 要約生成失敗 | LLM APIエラー | エラー状態でセッション継続 |

### リトライ仕様

要約生成時のAPIエラーは通常のリトライ処理に従う。

## トランザクション仕様

プルーニングと要約保存は別々のトランザクションで実行。

## パフォーマンス要件

- プルーニングはバックグラウンドで効率的に実行
- 要約生成は通常のLLMストリーミングと同等の速度

## セキュリティ考慮事項

- 全ツールが禁止されており、ファイル操作等の副作用なし
- 要約はセッション内部に保持され、外部出力なし

## 備考

Compaction エージェントは、hiddenフラグがtrueに設定されており、ユーザーが直接選択することはできない。内部処理専用のエージェントである。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

Compactionエージェントの設定とコンパクション処理の構造を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | agent.ts | `packages/opencode/src/agent/agent.ts` | compactionエージェント定義（157-171行目） |
| 1-2 | compaction.ts | `packages/opencode/src/session/compaction.ts` | SessionCompaction名前空間の構造 |

**読解のコツ**: hidden: trueフラグにより、このエージェントはUIに表示されない内部専用エージェントであることを理解。

#### Step 2: オーバーフロー検出を理解する

トークンオーバーフローの判定ロジックを把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | compaction.ts | `packages/opencode/src/session/compaction.ts` | isOverflow()関数（32-48行目） |

**主要処理フロー**:
1. **32-34行目**: config.compaction.auto === falseで無効化可能
2. **35-36行目**: context === 0の場合は判定スキップ
3. **38-40行目**: トークン合計計算
4. **42-46行目**: usable計算とオーバーフロー判定

#### Step 3: プルーニング処理を理解する

古いツール結果の圧縮処理を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | compaction.ts | `packages/opencode/src/session/compaction.ts` | prune()関数（58-99行目） |

**主要処理フロー**:
- **50-51行目**: PRUNE_MINIMUM = 20,000、PRUNE_PROTECT = 40,000定数
- **53行目**: PRUNE_PROTECTED_TOOLS = ["skill"]
- **68-88行目**: メッセージをスキャンしてプルーニング対象を特定
- **90-98行目**: 閾値超過時にcompacted状態を設定

#### Step 4: 要約生成処理を理解する

Compactionエージェントによる要約生成を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | compaction.ts | `packages/opencode/src/session/compaction.ts` | process()関数（101-229行目） |

**主要処理フロー**:
- **109行目**: Agent.get("compaction")でエージェント取得
- **113-138行目**: 要約メッセージの作成（summary: true）
- **151-177行目**: デフォルトの要約プロンプトテンプレート
- **202-224行目**: 自動継続メッセージの挿入

### プログラム呼び出し階層図

```
processor.process() [processor.ts]
    │
    ├─ finish-step イベント
    │      └─ SessionCompaction.isOverflow()
    │               │
    │               └─ "compact" 返却
    │
    └─ Session.chat() [index.ts]
           │
           └─ SessionCompaction.process()
                  │
                  ├─ SessionCompaction.prune()
                  │      └─ 古いツール結果を圧縮
                  │
                  ├─ Agent.get("compaction")
                  │
                  ├─ SessionProcessor.create()
                  │
                  └─ processor.process()
                         │
                         └─ 要約テキスト生成
```

### データフロー図

```
[入力]                    [処理]                         [出力]

セッション履歴 ───▶ isOverflow()
    │                     │
    └─ トークン使用量     ├──▶ オーバーフロー判定
                          │
                          └──▶ prune()
                                    │
                                    ├──▶ PRUNE_PROTECT以前を圧縮
                                    │
                                    └──▶ compacted状態設定
                                              │
                                              ▼
                                    Compactionエージェント
                                              │
                                              ├──▶ 要約テキスト生成
                                              │
                                              └──▶ summary: true メッセージ
                                                        │
                                                        └──▶ セッションDB
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| agent.ts | `packages/opencode/src/agent/agent.ts` | ソース | Compactionエージェント定義（157-171行目） |
| compaction.ts | `packages/opencode/src/session/compaction.ts` | ソース | コンパクション処理ロジック |
| compaction.txt | `packages/opencode/src/agent/prompt/compaction.txt` | テンプレート | 要約用システムプロンプト |
| processor.ts | `packages/opencode/src/session/processor.ts` | ソース | オーバーフロー検出トリガー |
| config.ts | `packages/opencode/src/config/config.ts` | ソース | compaction設定 |
