# Context Engine 深度分析 - 对标 Claude Code

## 📊 一、当前实现状态分析

### 1.1 已实现的功能

✅ **基础缓存机制**
- FileContext 存储文件内容
- HashMap 基础缓存（50个文件上限）
- 基本的增删改查操作

✅ **元数据追踪**
- relevanceScore（相关性分数）
- tokenCount（token估算）
- lineCount（行数）
- accessCount（访问次数）
- lastAccessed（访问时间）
- lastModified（修改时间）
- symbols（符号列表 - 但未填充）
- imports（依赖列表 - 但未填充）

✅ **相关性评分**
- 简化的TF-IDF（关键词匹配）
- 访问频率权重
- 时间衰减权重
- rankFilesByRelevance() 排序

✅ **智能压缩**
- 三级压缩策略（空行/注释/声明）
- autoCompress() 自动选择级别
- truncateToTokens() 截断

✅ **多因素LRU淘汰**
- 时间 + 频率 + 相关性综合评分
- markAsImportant() 手动标记

---

## ❌ 二、存在的核心问题

### 问题 1：Token 估算严重不准确 🔴

**当前实现**：
```cangjie
private static func estimateTokens(text: String): Int64 {
    let words = text.split(" ").size
    let tokens = words / 4
    return if (tokens > 0) { tokens } else { 1 }
}
```

**问题分析**：
1. ❌ 按空格分隔单词过于简单，不适用于代码
2. ❌ 不考虑标点符号、括号、运算符
3. ❌ 不考虑多语言特性（中文、日文等）
4. ❌ 除以4的经验值不适用于代码token

**Claude Code 的做法**：
- 使用 cl100k_base tokenizer（GPT系列标准）
- 精确计算每个token
- 考虑特殊字符和代码结构

**影响**：
- 压缩决策不准确
- 缓存大小估算错误
- 可能导致token超限

---

### 问题 2：symbols 和 imports 字段未被填充 🔴

**当前实现**：
```cangjie
this.symbols = ArrayList<String>().toArray()   // 总是空的！
this.imports = ArrayList<String>().toArray()   // 总是空的！
```

**问题分析**：
1. ❌ symbols 字段定义了但从不填充
2. ❌ imports 字段定义了但从不使用
3. ❌ DependencyAnalyzer 没有与 ContextEngine 集成
4. ❌ 无法利用符号信息进行精确引用

**Claude Code 的做法**：
- 自动提取文件中的所有符号（函数、类、变量）
- 自动解析 import/依赖关系
- 符号级别的上下文引用
- 基于符号的智能推荐

**影响**：
- 无法实现符号级别的引用
- DependencyAnalyzer 的功能浪费
- 推荐系统不够智能

---

### 问题 3：缺少文件内容的增量更新机制 🟡

**当前实现**：
```cangjie
public func addFile(path: Path, content: String): Unit {
    // 总是完整替换整个文件内容
    let context = FileContext(path, content)
    this.fileCache[pathKey] = context
}
```

**问题分析**：
1. ❌ 每次更新都重新创建 FileContext
2. ❌ 丢失历史访问统计信息
3. ❌ 无法感知文件的实际变更范围
4. ❌ 不能只更新变更的部分

**Claude Code 的做法**：
- 增量更新机制（只更新变更行）
- 保留元数据（relevanceScore, accessCount等）
- 使用 diff 算法最小化更新
- 缓存未变更的部分

**影响**：
- 性能浪费（每次全量更新）
- 丢失有价值的元数据
- 与 FileWatcher 集成不够智能

---

### 问题 4：关键词匹配过于简单，缺少语义理解 🟡

**当前实现**：
```cangjie
private func keywordMatch(content: String, query: String): Float64 {
    let queryWords = query.split(" ")
    // 简单的字符串包含检查
    if (content.contains(word)) {
        matchCount += 1
    }
}
```

**问题分析**：
1. ❌ 纯字符串匹配，无法理解语义
2. ❌ 不考虑词的重要性（TF-IDF 简化过度）
3. ❌ 不能识别同义词、变体
4. ❌ 缺少大小写不敏感（仓颉限制）

**Claude Code 的做法**：
- 使用 embedding 进行语义相似度计算
- BM25 算法（优于简单TF-IDF）
- 考虑词频、逆文档频率
- 模糊匹配和拼写纠正

**影响**：
- 相关性评分不准确
- 推荐结果质量低
- 用户体验不佳

---

### 问题 5：缺少 Token 预算管理 🟡

**当前实现**：
```cangjie
// 只有 autoCompress() 考虑了 token 限制
public func autoCompress(file: FileContext, maxTokens: Int64): String
```

**问题分析**：
1. ❌ 没有全局 token 预算概念
2. ❌ 不能自动平衡多个文件的 token 分配
3. ❌ 压缩决策孤立（每个文件独立）
4. ❌ 无法优先保留重要文件的完整性

**Claude Code 的做法**：
- 全局 token 预算管理
- 根据相关性动态分配 token
- 重要文件优先完整保留
- 次要文件激进压缩
- 实时调整策略

**影响**：
- 可能浪费 token（不重要文件占用过多）
- 可能丢失关键信息（重要文件被过度压缩）
- 不能充分利用模型的上下文窗口

---

### 问题 6：压缩策略过于粗暴 🟡

**当前实现**：
```cangjie
private func compressLevel3(content: String): String {
    // 只保留包声明和函数/类签名
    if (trimmed.startsWith("public func ") || ...) {
        result.add(trimmed)
    }
}
```

**问题分析**：
1. ❌ Level 3 丢失了函数体（可能包含关键逻辑）
2. ❌ 不保留重要的注释（如文档字符串）
3. ❌ 丢失了函数间的调用关系
4. ❌ 不考虑代码的语义重要性

**Claude Code 的做法**：
- 保留关键注释（文档字符串、TODO）
- 保留重要的常量定义
- 保留异常处理逻辑
- 使用 AST 分析识别重要代码块
- 渐进式压缩（先压缩次要部分）

**影响**：
- 压缩后代码不可读
- AI 理解不完整
- 可能无法完成任务

---

### 问题 7：缺少上下文优先级管理 🟡

**当前实现**：
- 只有 relevanceScore 一个维度
- 没有区分"必需"、"有用"、"可选"

**问题分析**：
1. ❌ 所有文件平等对待
2. ❌ 没有"pin"机制（固定重要文件）
3. ❌ 不能标记"必需依赖"
4. ❌ evictOldest() 可能误删重要文件

**Claude Code 的做法**：
- 文件优先级系统（P0/P1/P2/P3）
- 用户可手动 pin 文件
- 自动识别"必需依赖"
- 保护机制防止误删

**影响**：
- 重要文件可能被淘汰
- 用户无法控制上下文
- 缓存策略不够智能

---

### 问题 8：缺少与其他模块的深度集成 🟡

**当前实现**：
- ContextEngine 相对孤立
- DependencyAnalyzer 单独工作
- FileWatcher 信号未充分利用

**问题分析**：
1. ❌ ContextEngine 不感知文件的依赖关系
2. ❌ FileWatcher 的变更信号没有触发缓存更新
3. ❌ MentionParser 的符号引用不能直接定位
4. ❌ 各模块数据不共享，重复计算

**Claude Code 的做法**：
- ContextEngine 是中心枢纽
- 自动感知文件变更
- 自动更新依赖文件
- 模块间数据共享
- 事件驱动架构

**影响**：
- 功能割裂
- 性能浪费
- 用户体验不流畅

---

### 问题 9：缺少智能的上下文窗口管理 🔴

**当前实现**：
- 固定 50 文件上限
- 没有根据文件大小动态调整
- 没有根据任务类型优化上下文

**问题分析**：
1. ❌ 50文件上限是硬编码，不灵活
2. ❌ 不考虑文件的实际大小
3. ❌ 大文件和小文件同等对待
4. ❌ 不能根据任务动态调整策略

**Claude Code 的做法**：
- 基于 token 而非文件数管理上下文
- 动态调整缓存策略
- 任务感知（编码 vs 阅读 vs 重构）
- 自适应压缩级别

**影响**：
- 缓存利用率低
- 可能缓存大量小文件却放不下重要大文件
- 不能应对不同场景

---

### 问题 10：缺少统计和可视化功能 🟡

**当前实现**：
```cangjie
public func getStats(): String {
    return "ContextEngine: ${this.fileCache.size} files cached (max: ${this.maxCacheSize})"
}
```

**问题分析**：
1. ❌ 统计信息过于简单
2. ❌ 不显示 token 使用情况
3. ❌ 不显示缓存命中率
4. ❌ 不显示压缩效果

**Claude Code 的做法**：
- 详细的统计面板
- Token 使用率可视化
- 缓存命中率、压缩率统计
- 文件优先级分布
- 实时性能监控

**影响**：
- 用户不了解上下文状态
- 无法优化使用方式
- 调试困难

---

## 🎯 三、修复优先级

### P0 - 关键问题（必须修复）

1. **Token 估算不准确** 🔴
   - 集成 cl100k_base tokenizer
   - 改动量：~100 行
   - 工作量：2-3 小时

2. **symbols 和 imports 未填充** 🔴
   - 集成 DependencyAnalyzer 和 LSP
   - 改动量：~150 行
   - 工作量：3-4 小时

3. **缺少智能上下文窗口管理** 🔴
   - 基于 token 的管理策略
   - 改动量：~80 行
   - 工作量：2 小时

### P1 - 重要问题（应该修复）

4. **缺少文件增量更新**
   - 保留元数据的更新逻辑
   - 改动量：~60 行
   - 工作量：1-2 小时

5. **Token 预算管理**
   - 全局 token 预算和分配
   - 改动量：~100 行
   - 工作量：2-3 小时

6. **上下文优先级管理**
   - Pin/Priority 系统
   - 改动量：~80 行
   - 工作量：2 小时

### P2 - 改进问题（可以优化）

7. **关键词匹配优化**
   - BM25 算法
   - 改动量：~120 行
   - 工作量：3-4 小时

8. **压缩策略优化**
   - 基于 AST 的智能压缩
   - 改动量：~150 行
   - 工作量：4-5 小时

9. **模块深度集成**
   - 事件驱动架构
   - 改动量：~200 行
   - 工作量：5-6 小时

10. **统计和可视化**
    - 详细统计面板
    - 改动量：~60 行
    - 工作量：1-2 小时

---

## 📝 四、修复计划

### 阶段一：核心问题修复（P0，6-9小时）

**目标**：修复致命问题，让 Context Engine 可用

#### 1.1 Token 估算器升级
```cangjie
// 使用 cl100k_base_tiktoken.cj 中的实现
private static func estimateTokens(text: String): Int64 {
    return Tiktoken.encode(text).size
}
```

#### 1.2 符号和依赖自动提取
```cangjie
public init(path: Path, content: String) {
    // ... 原有初始化 ...
    
    // 🆕 自动提取符号
    this.symbols = SymbolExtractor.extract(content, path)
    
    // 🆕 自动提取依赖
    this.imports = DependencyExtractor.extract(content)
}
```

#### 1.3 Token-based 上下文管理
```cangjie
private let maxTotalTokens: Int64  // 替代 maxCacheSize
private var currentTokenCount: Int64

public func addFile(path: Path, content: String): Unit {
    let newFileTokens = FileContext.estimateTokens(content)
    
    // 如果超过 token 限制，智能淘汰
    while (this.currentTokenCount + newFileTokens > this.maxTotalTokens) {
        this.evictLeastImportant()
    }
    
    // ... 添加文件 ...
    this.currentTokenCount += newFileTokens
}
```

---

### 阶段二：功能增强（P1，5-7小时）

#### 2.1 文件更新优化
```cangjie
public func updateFile(path: Path, newContent: String): Unit {
    let pathKey = path.toString()
    
    if (let Some(existing) <- this.fileCache.get(pathKey)) {
        // 保留元数据
        let oldTokens = existing.tokenCount
        existing.content = newContent
        existing.tokenCount = FileContext.estimateTokens(newContent)
        existing.lastModified = getCurrentTimestamp()
        
        // 更新全局 token 计数
        this.currentTokenCount = this.currentTokenCount - oldTokens + existing.tokenCount
    } else {
        this.addFile(path, newContent)
    }
}
```

#### 2.2 全局 Token 预算管理
```cangjie
public class TokenBudgetManager {
    private let totalBudget: Int64
    private var allocated: HashMap<String, Int64>
    
    public func allocate(query: String, files: Array<FileContext>): HashMap<String, Int64> {
        // 根据相关性分配 token
        // 重要文件分配更多 token
    }
}
```

#### 2.3 优先级系统
```cangjie
public enum FilePriority {
    case P0  // 必需（pin的文件）
    case P1  // 非常重要
    case P2  // 重要
    case P3  // 一般
}

public class FileContext {
    public var priority: FilePriority = FilePriority.P3
    
    public func pin(): Unit {
        this.priority = FilePriority.P0
    }
}
```

---

### 阶段三：智能优化（P2，12-15小时）

#### 3.1 BM25 相关性算法
#### 3.2 AST-based 压缩
#### 3.3 事件驱动集成
#### 3.4 详细统计面板

---

## 🎯 五、预期效果

修复后的 Context Engine 将实现：

✅ **准确的 Token 管理**
- 精确估算，避免超限
- 充分利用上下文窗口

✅ **智能的上下文选择**
- 基于符号和依赖的推荐
- 自动包含相关文件

✅ **高效的缓存策略**
- Token-based 管理
- 智能淘汰和压缩

✅ **更好的用户体验**
- Pin 重要文件
- 可视化上下文状态
- 灵活的控制

---

**与 Claude Code 的差距**：
- 修复前：~40% 功能完整度
- 修复后：~75% 功能完整度

**改动规模**：
- P0：~330 行
- P1：~240 行
- P2：~530 行
- **总计：~1100 行**

**工作量估算**：
- P0：6-9 小时
- P1：5-7 小时
- P2：12-15 小时
- **总计：23-31 小时**（约 3-4 天）

