|
@@ -0,0 +1,659 @@
|
|
|
|
|
+# 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. 为每个 branch 创建独立 message list
|
|
|
|
|
+2. 串行执行每个 branch (各自调用 LLM + 工具)
|
|
|
|
|
+3. 收集每个 branch 的结论
|
|
|
|
|
+4. 返回汇总结果给主会话
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 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**的综合方案,集三家之长! 🎯
|