# Context 管理方案对比分析

> 对比 OpenCode、Codex 和 Gemini-cli 三个项目的 context 管理方案

---

## 一、整体架构对比

| 维度 | **OpenCode** | **Codex** | **Gemini-cli** |
|------|-------------|-----------|---------------|
| **核心数据结构** | 线性 Message List | ContextManager (Vec<ResponseItem>) | Content[] (双版本) |
| **消息历史版本** | 单一版本 | 单一版本 + GhostSnapshot | 精选版本 + 完整版本 |
| **分层设计** | 无 | 无 | **✓ 三层**: Global → Environment → JIT |
| **Plan 管理** | goal.json (计划中) + plan.md (参考) | SQLite + TodoListItem | 无 Plan 机制 |
| **存储格式** | Storage Key-Value | JSONL + SQLite 混合 | JSON + 文本文件 |
| **并发控制** | 未明确 | Arc<Mutex> + 文件锁 | Promise并发限制 |

---

## 二、Token 限制处理策略

### 2.1 Token 估算方法

| 项目 | 估算策略 | 精度 | 实现位置 |
|------|---------|------|---------|
| **OpenCode** | 未详细说明,引用 Prune 阈值 | 中 | - |
| **Codex** | **字节估算**: `bytes / 4` (1 token ≈ 4 bytes) | 低 | `truncate.rs::approx_token_count()` |
| **Gemini-cli** | **启发式**: ASCII (0.25), 非ASCII (1.3), 图片 (3000), PDF (25800) | 高 | `tokenCalculation.ts::estimateTokenCountSync()` |

**关键差异**:
- **Codex**: 简单但快速,适合实时估算
- **Gemini-cli**: 更精确,区分字符类型和媒体,牺牲少量性能

### 2.2 Token 限制阈值

| 项目 | 限制类型 | 阈值定义 |
|------|---------|---------|
| **OpenCode** | 删除阈值 | `PRUNE_MINIMUM = 20,000`, `PRUNE_PROTECT = 40,000` |
| **Codex** | 模型限制 | 依赖模型配置,无固定值 |
| **Gemini-cli** | 压缩阈值 | 默认 **50%** 模型限制 (`DEFAULT_COMPRESSION_TOKEN_THRESHOLD = 0.5`) |

### 2.3 截断策略

```
┌─────────────────┬──────────────────────────┬─────────────────────┐
│    OpenCode     │         Codex            │    Gemini-cli       │
├─────────────────┼──────────────────────────┼─────────────────────┤
│ 删除旧工具输出   │ 前缀+后缀保留,中间截断    │ 反向token预算       │
│ 保护最近2轮turns │ 插入省略标记             │ 最近工具完整保留     │
│ 不删除"skill"工具│ 保证UTF-8边界完整性       │ 旧工具仅保留30行    │
└─────────────────┴──────────────────────────┴─────────────────────┘
```

**Gemini-cli 的反向预算策略** (最独特):
```typescript
// 从最新消息往回遍历,为每条工具输出分配token预算
// 优先保留最近的,旧的按需截断
COMPRESSION_FUNCTION_RESPONSE_TOKEN_BUDGET = 50,000;
COMPRESSION_TRUNCATE_LINES = 30;
```

---

## 三、摘要/压缩机制

### 3.1 压缩触发时机

| 项目 | 触发时机 | 方式 |
|------|---------|------|
| **OpenCode** | 事后 (context满时) | 被动压缩 |
| **Codex** | 超过模型窗口时 | 自动压缩 |
| **Gemini-cli** | **主动** (达到50%阈值) + **手动** (/compress) | 混合方式 |

### 3.2 压缩策略对比

#### OpenCode: 两阶段压缩

```
阶段1: Prune (清理旧工具输出)
  ├─ 从后向前遍历
  ├─ 跳过最后2轮
  ├─ 跳过已有summary的消息
  └─ 删除量 > PRUNE_MINIMUM 时执行

阶段2: Full Compaction (上下文总结)
  ├─ 创建summary=true的assistant消息
  ├─ 调用"compaction"专用agent
  └─ 提示词: "Provide a detailed prompt for continuing..."
```

#### Codex: 内联自动压缩

```
触发: run_inline_auto_compact_task()
  ├─ 生成摘要前缀 (SUMMARY_PREFIX)
  ├─ 使用SUMMARIZATION_PROMPT
  ├─ 保留GhostSnapshot (幽灵快照)
  └─ 替换历史记录为CompactedItem
```

**GhostSnapshot** (Codex独有):
- 保留被压缩部分的"幽灵"引用
- 用户可查看但不会发送给模型
- 在UI中显示为折叠项

#### Gemini-cli: 三相智能压缩

```
Phase 1: 历史分割
  ├─ 保留最后30% (COMPRESSION_PRESERVE_THRESHOLD)
  └─ 压缩前70%

Phase 2: 双重总结验证 ⭐ (独特)
  ├─ 第1次: 生成 <state_snapshot>
  ├─ 第2次: 自我批评 ("Did you omit any...")
  └─ 生成改进版本或确认原版本

Phase 3: 输出验证
  ├─ 检查压缩后token数 < 原token数
  └─ 失败则保持原历史
```

**双重验证的价值**:
```typescript
// 第一次生成
"Generate a state snapshot of the conversation..."

// 第二次自我批评
"Did you omit any specific file content, code snippets,
or context that might be needed later? If yes, provide
an improved version. If no, confirm the original."
```

### 3.3 压缩结果处理

| 项目 | 压缩失败处理 | 结果存储 |
|------|------------|---------|
| **OpenCode** | 标记为已compacted | 替换为summary message |
| **Codex** | 保留GhostSnapshot | CompactedItem + replacement_history |
| **Gemini-cli** | **回退原历史** ⭐ | 成功时替换,失败时保持原状 |

---

## 四、存储和加载方式

### 4.1 存储架构

#### OpenCode (计划中)
```
.trace/{trace_id}/
├── goal.json          # Goal Tree (结构化plan)
├── messages.jsonl     # 消息记录 (含 goal_id)
└── meta.json          # Trace 元数据
```

#### Codex
```
~/.codex/
├── history.jsonl                           # 全局消息历史
├── sessions/
│   ├── rollout-{timestamp}-{uuid}.jsonl    # 会话回滚文件
│   └── ...
└── state.db                                # SQLite状态数据库
```

**关键特性**:
- **原子写入**: 使用 `O_APPEND` 标志
- **并发安全**: Advisory文件锁
- **自动清理**: 超过限制时删除旧条目 (软限制80%)

#### Gemini-cli
```
~/.gemini/
├── GEMINI.md                               # 全局内存
├── tmp/{project_hash}/
│   └── chats/{session-ID}.json             # 会话记录
└── config.json                             # 配置

项目根目录/
├── GEMINI.md                               # 环境内存
└── subdirs/
    └── GEMINI.md                           # JIT内存 (按需加载)
```

**独特的三层内存系统**:
```
Tier 1: Global Memory
  ├─ ~/.gemini/GEMINI.md
  └─ 用户级别,所有会话共享

Tier 2: Environment Memory
  ├─ 项目根目录的GEMINI.md
  ├─ 扩展提供的上下文文件
  └─ MCP客户端指令

Tier 3: JIT Subdirectory Memory ⭐
  ├─ 访问路径时动态发现
  ├─ 向上遍历到项目根
  ├─ 向下BFS搜索 (最多200目录)
  └─ 避免加载不相关上下文
```

### 4.2 加载策略对比

| 项目 | 加载时机 | 策略 | 并发控制 |
|------|---------|------|---------|
| **OpenCode** | 会话启动/恢复 | 按需加载 | 未明确 |
| **Codex** | 启动时 | lookup(log_id, offset) | Arc<Mutex> + 文件锁 |
| **Gemini-cli** | **分层+JIT** ⭐ | 全局(启动) + 环境(会话) + JIT(访问) | Promise并发限制 (10/20) |

---

## 五、Plan/Todo 机制

### 5.1 数据结构对比

#### OpenCode (参考方案)
```typescript
// plan.md (文本)
- [ ] 分析代码
- [x] 实现功能
- [ ] 测试

// Todo.Info (结构化)
{
  id: string,
  content: string,
  status: "pending" | "in_progress" | "completed" | "cancelled",
  priority: "high" | "medium" | "low"
}
```

#### OpenCode (我们的方案 - 计划中)
```python
@dataclass
class Goal:
    id: str                    # "1", "1.1", "2"
    description: str
    status: Status             # pending | in_progress | completed | abandoned
    summary: Optional[str]     # done/abandon 时的总结
    children: List["Goal"]

@dataclass
class GoalTree:
    mission: str
    current_id: Optional[str]
    goals: List[Goal]
```

**关键特性**:
- **goal_id 关联**: 每条 message 记录它属于哪个 goal
- **增量压缩**: goal 完成/放弃时压缩相关 messages
- **精确回溯**: 基于 goal 的状态流转

#### Codex
```rust
// TodoListItem in ResponseItem
pub struct TodoListItem {
    todo_list: Vec<TodoItem>,
}

pub struct TodoItem {
    task: String,
    completed: bool,
}
```

**存储**: 作为 ResponseItem 的一部分,随对话历史一起管理

#### Gemini-cli
**无专门 Plan 机制**,但有:
- **会话记录**: 完整的 `ConversationRecord`
- **目录跟踪**: `directories?: string[]` (会话中添加的目录)

### 5.2 执行与 Plan 的关联

| 项目 | 关联方式 | 可编辑性 | 可视化 |
|------|---------|---------|--------|
| **OpenCode (参考)** | 无结构化关联 | plan.md 可直接编辑 | 基础 |
| **OpenCode (计划)** | message.goal_id | 通过 goal 工具 | 增强 (树形+步骤) |
| **Codex** | TodoItem 在 ResponseItem 中 | 通过模型更新 | 基础 |
| **Gemini-cli** | - | - | - |

---

## 六、Sub-Agent/并行探索

### 6.1 Sub-Agent 支持

#### OpenCode (参考方案)
```typescript
// Agent Mode
- primary: 主代理,执行工具
- subagent: 子代理,独立context

// 内置 Sub-Agents
- general: 通用代理,可并行执行
- explore: 代码探索,仅查询工具
- compaction: 上下文总结
```

**执行流程**:
```
1. 创建 SubtaskPart
2. 子代理独立处理 (独立 message list)
3. 结果汇总: "The following tool was executed by the user"
```

#### OpenCode (我们的方案 - 计划中)
```python
@tool
def explore(
    question: str,           # 探索要回答的问题
    branches: List[str],     # 探索方向 (2-4个)
) -> str:
    """并行探索多个方向,汇总结果"""
```

**执行流程**:
```
1. 为每个探索方向创建独立的 Sub-Trace（完整的 Trace 结构）
2. 并行执行所有 Sub-Traces（使用 asyncio.gather）
3. 收集每个 Sub-Trace 的结论
4. 返回汇总结果给主 Trace
```

#### Codex
**无明确 Sub-Agent 机制**,但有:
- **SessionState**: 管理会话状态
- **Turn Context**: 单轮对话的上下文

#### Gemini-cli
**无 Sub-Agent 机制**,但有:
- **CoreToolScheduler**: 工具执行调度
- **并发工具执行**: 多个工具可并行运行

### 6.2 并行探索对比

| 特性 | OpenCode (参考) | OpenCode (计划) | Codex | Gemini-cli |
|------|---------------|---------------|-------|-----------|
| **并行探索** | Sub-agent 手动管理 | explore 工具自动汇总 ⭐ | 无 | 工具级并发 |
| **Context 隔离** | ✓ (独立 message list) | ✓ (独立 message list) | - | - |
| **结果汇总** | 手动 | 自动 (返回 markdown) | - | - |
| **适用场景** | 大任务隔离 | 多方案评估 | - | 工具执行 |

---

## 七、回溯能力

### 7.1 回溯机制对比

#### OpenCode (参考方案)
```
限制: 有限的回溯能力
- 无精确状态保存
- 依赖压缩后的摘要
```

#### OpenCode (我们的方案 - 计划中)
```python
goal(abandon="方案A需要Redis,环境没有", add="实现方案B")
```

**回溯流程**:
```
Before:
  Messages:
    [分析代码的 20 条 message...]
    [实现方案 A 的 30 条 message...]  ← 这些要压缩
    [测试失败的 message...]

After:
  Messages:
    [分析代码的 20 条 message...]
    [Summary: "尝试方案A,因依赖问题失败"]  ← 压缩为1条
    [开始方案B的 message...]

  Plan:
    [✓] 1. 分析代码
    [✗] 2. 实现方案A (abandoned: 依赖问题)
    [→] 2'. 实现方案B
```

**优势**:
- **精确回溯**: 基于 goal 的状态标记
- **保留失败原因**: summary 包含 abandon 原因
- **压缩旧路径**: 失败尝试不占用大量 context

#### Codex
```rust
// GhostSnapshot: 保留被压缩部分的引用
pub struct CompactedItem {
    message: String,
    replacement_history: Option<Vec<ResponseItem>>,
}
```

**回溯能力**:
- **GhostSnapshot**: 用户可查看历史,但不发送给模型
- **Rollout 记录**: 完整的会话记录保存在 JSONL
- **用户转换检测**: 可定位到特定用户消息

#### Gemini-cli
```typescript
enum CompressionStatus {
  COMPRESSED,
  COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,  // 压缩反而增加
  COMPRESSION_FAILED_EMPTY_SUMMARY,          // 摘要为空
  NOOP,
}
```

**回溯能力**:
- **会话记录**: 完整的 `ConversationRecord` 保存所有消息
- **压缩失败回退**: 自动回退到原历史
- **无结构化回溯**: 缺乏基于任务的回溯机制

### 7.2 回溯对比表

| 项目 | 回溯粒度 | 状态保存 | 失败处理 | 历史查看 |
|------|---------|---------|---------|---------|
| **OpenCode (参考)** | 粗粒度 | 摘要 | 有限 | 基础 |
| **OpenCode (计划)** | **goal级别** ⭐ | goal.summary + abandon原因 | 精确压缩 | goal树 + 步骤 |
| **Codex** | 用户turn级别 | GhostSnapshot | GhostSnapshot引用 | 完整回滚文件 |
| **Gemini-cli** | 消息级别 | ConversationRecord | 自动回退 | 会话记录文件 |

---

## 八、核心差异总结

### 8.1 设计哲学

| 项目 | 核心理念 | 优势场景 |
|------|---------|---------|
| **OpenCode** | **结构化计划驱动** | 复杂任务,需要回溯和探索 |
| **Codex** | **简单高效,成熟稳定** | 通用编码助手,快速响应 |
| **Gemini-cli** | **分层智能,高保真保留** | 多项目管理,长期会话 |

### 8.2 独特创新点

#### OpenCode (我们的方案)
1. **goal 工具**: 结构化 Plan + 执行关联
2. **explore 工具**: 并行探索自动汇总
3. **增量压缩**: goal 完成/放弃时压缩,而非事后被动
4. **精确回溯**: abandon + 状态流转

#### Codex
1. **GhostSnapshot**: 压缩历史仍可查看
2. **原子写入**: O_APPEND + 并发安全
3. **字节估算**: 简单快速 (bytes/4)
4. **历史规范化**: 确保调用-输出对完整性

#### Gemini-cli
1. **三层内存**: Global → Environment → JIT ⭐
2. **双重验证**: 自我批评式压缩
3. **反向token预算**: 优先保留最近工具输出
4. **启发式token估算**: 区分字符类型和媒体
5. **JIT Context发现**: 按需加载相关GEMINI.md

### 8.3 技术选型对比

| 技术点 | OpenCode | Codex | Gemini-cli |
|--------|---------|-------|-----------|
| **语言** | TypeScript | Rust | TypeScript |
| **存储** | Storage KV | JSONL + SQLite | JSON + 文本 |
| **并发** | 未明确 | Arc<Mutex> + 文件锁 | Promise限制 |
| **token估算** | 未详述 | bytes/4 | 启发式 (区分类型) |
| **压缩策略** | 两阶段 | 内联自动 | 三相智能 |

---

## 九、与 OpenCode 方案的详细对比

### 9.1 OpenCode vs Codex

| 方面 | OpenCode (参考) | Codex | 评估 |
|------|---------------|-------|------|
| **Plan格式** | 纯文本 (plan.md) | TodoItem (结构化) | Codex更结构化,但OpenCode计划中的goal.json更强 |
| **Plan与执行关联** | 无 | TodoItem在ResponseItem中 | Codex有关联,但OpenCode计划中的goal_id更精确 |
| **压缩时机** | 事后 (满时) | 事后 (超过窗口) | 相同 (被动) |
| **并行探索** | Sub-agent (手动) | 无 | OpenCode参考方案更强,计划方案的explore更自动化 |
| **回溯能力** | 有限 | GhostSnapshot | Codex的GhostSnapshot有价值,但OpenCode计划的goal-based更精确 |
| **存储可靠性** | 未明确 | 原子写入+并发安全 | **Codex胜** ⭐ |
| **工具复杂度** | todoread/todowrite | 无专门工具 | OpenCode参考方案更复杂,计划的goal/explore更简洁 |

**可借鉴**:
- ✓ Codex的原子写入和并发安全机制
- ✓ GhostSnapshot的用户友好性 (可查看但不发送)
- ✓ 历史规范化 (ensure_call_outputs_present)

### 9.2 OpenCode vs Gemini-cli

| 方面 | OpenCode (参考) | Gemini-cli | 评估 |
|------|---------------|-----------|------|
| **Plan格式** | plan.md + Todo.Info | 无 | **OpenCode胜** |
| **Plan与执行关联** | 无 | 无 | 平局 |
| **压缩时机** | 事后 (满时) | **主动** (50%阈值) | **Gemini-cli胜** ⭐ |
| **并行探索** | Sub-agent (手动) | 工具级并发 | OpenCode的Sub-agent隔离更好 |
| **回溯能力** | 有限 | 自动回退 | OpenCode计划方案的goal-based更强 |
| **Context分层** | 无 | **三层** (Global/Env/JIT) | **Gemini-cli胜** ⭐ |
| **压缩质量** | 单次生成 | **双重验证** (自我批评) | **Gemini-cli胜** ⭐ |
| **工具输出保留** | 删除旧输出 | **反向预算** (保留最近) | **Gemini-cli胜** ⭐ |

**可借鉴**:
- ✓ 三层内存系统 (特别是JIT加载)
- ✓ 双重验证的压缩机制
- ✓ 主动压缩 (50%阈值,而非等到满)
- ✓ 反向token预算 (优先保留最近工具输出)
- ✓ 启发式token估算 (区分字符类型)

---

## 十、OpenCode 计划方案的优势

### 10.1 创新点

1. **结构化 Plan (goal.json)**
   - 比纯文本更精确
   - 支持树形结构 (goal.children)
   - 状态流转清晰

2. **执行与 Plan 的强关联 (goal_id)**
   - 每条 message 知道它属于哪个 goal
   - 支持基于 goal 的压缩和回溯
   - 可视化时能展示 goal + 对应步骤

3. **增量压缩 (goal 完成/放弃时)**
   - 比事后被动压缩更主动
   - 压缩粒度可控 (按 goal)
   - 保留失败原因 (abandon summary)

4. **explore 工具 (并行探索自动汇总)**
   - 比手动管理 Sub-agent 更简单
   - 适合多方案评估场景
   - 自动生成汇总报告

5. **精确回溯 (abandon + 状态流转)**
   - 比 GhostSnapshot 更结构化
   - 支持从失败尝试中学习
   - Plan 树中保留失败路径

### 10.2 待改进点 (可借鉴其他方案)

1. **存储可靠性** (借鉴 Codex)
   - 原子写入
   - 并发安全 (文件锁)
   - 自动清理旧数据

2. **Context 分层** (借鉴 Gemini-cli)
   - 全局 context (用户级别)
   - 项目 context (项目级别)
   - JIT context (按需加载)

3. **压缩质量** (借鉴 Gemini-cli)
   - 双重验证 (自我批评)
   - 压缩失败自动回退
   - 验证压缩后 token 数真的减少

4. **主动压缩** (借鉴 Gemini-cli)
   - 达到阈值 (如 50%) 时主动压缩
   - 而非等到 context 满

5. **工具输出管理** (借鉴 Gemini-cli)
   - 反向 token 预算
   - 优先保留最近工具输出的完整性
   - 旧输出智能截断 (保留最后N行)

6. **Token 估算** (借鉴 Gemini-cli)
   - 启发式估算 (区分 ASCII/非ASCII/媒体)
   - 提高估算精度

7. **用户友好性** (借鉴 Codex)
   - GhostSnapshot 机制 (可查看但不发送)
   - 历史规范化 (保证调用-输出对完整性)

---

## 十一、实现建议

### 11.1 Phase 1: 核心 goal 工具 (保留计划)
- Goal 数据结构
- goal 工具 (add, done, focus)
- Plan 注入到 system prompt
- 基础可视化

### 11.2 Phase 2: 增强存储和压缩 (借鉴)
- **存储增强** (借鉴 Codex):
  - 原子写入和并发安全
  - 自动清理机制
- **压缩增强** (借鉴 Gemini-cli):
  - 双重验证机制
  - 主动压缩 (50%阈值)
  - 反向token预算

### 11.3 Phase 3: 回溯和 Context 分层
- **回溯支持** (计划):
  - abandon 操作
  - Message 关联 goal_id
  - 基于 goal 的 context 压缩
- **Context 分层** (借鉴 Gemini-cli):
  - 全局 context 文件
  - 项目 context 文件
  - JIT 子目录 context 发现

### 11.4 Phase 4: 并行探索和优化
- **explore 工具** (计划):
  - 独立 message list 管理
  - 结果汇总机制
- **优化** (借鉴):
  - GhostSnapshot (用户友好)
  - 启发式 token 估算
  - 历史规范化

---

## 十二、总结

### 12.1 三方案对比矩阵

| 能力维度 | OpenCode (计划) | Codex | Gemini-cli | 最佳方案 |
|---------|---------------|-------|-----------|---------|
| **结构化 Plan** | ⭐⭐⭐ goal.json | ⭐⭐ TodoItem | ⭐ 无 | OpenCode |
| **执行关联** | ⭐⭐⭐ goal_id | ⭐⭐ 弱关联 | ⭐ 无 | OpenCode |
| **压缩策略** | ⭐⭐ 增量 | ⭐⭐ 自动 | ⭐⭐⭐ 三相智能 | Gemini-cli |
| **压缩时机** | ⭐⭐ goal完成时 | ⭐ 被动 | ⭐⭐⭐ 主动50% | Gemini-cli |
| **并行探索** | ⭐⭐⭐ explore工具 | ⭐ 无 | ⭐⭐ 工具级 | OpenCode |
| **回溯能力** | ⭐⭐⭐ goal-based | ⭐⭐ GhostSnapshot | ⭐⭐ 会话记录 | OpenCode |
| **存储可靠性** | ⭐⭐ 未明确 | ⭐⭐⭐ 原子+锁 | ⭐⭐ Promise限制 | Codex |
| **Context分层** | ⭐ 无 | ⭐ 无 | ⭐⭐⭐ 三层JIT | Gemini-cli |
| **工具输出管理** | ⭐ 删除旧的 | ⭐⭐ 截断 | ⭐⭐⭐ 反向预算 | Gemini-cli |
| **Token估算** | ⭐⭐ 基础 | ⭐ bytes/4 | ⭐⭐⭐ 启发式 | Gemini-cli |

**评分说明**: ⭐ 基础, ⭐⭐ 良好, ⭐⭐⭐ 优秀

### 12.2 最终建议

**OpenCode 的核心优势** (保留并强化):
- ✅ 结构化 goal.json
- ✅ goal_id 关联
- ✅ explore 工具
- ✅ 精确回溯

**应借鉴的关键特性**:
1. **Gemini-cli 的压缩机制**: 双重验证 + 主动压缩 + 反向预算
2. **Gemini-cli 的分层 Context**: 特别是 JIT 加载
3. **Codex 的存储可靠性**: 原子写入 + 并发安全
4. **Codex 的 GhostSnapshot**: 提升用户体验

**综合方案** (OpenCode + 借鉴):
```
OpenCode 计划方案
  ├─ 保留: goal.json, explore工具, goal-based回溯
  ├─ 增强压缩: Gemini-cli的双重验证 + 主动压缩
  ├─ 增强存储: Codex的原子写入 + 并发安全
  ├─ 增强Context: Gemini-cli的三层分层 + JIT加载
  └─ 增强UX: Codex的GhostSnapshot
```

这将是一个**结构化驱动 + 智能压缩 + 可靠存储 + 分层Context**的综合方案,集三家之长! 🎯
