# 上下文压缩规则与最佳实践

本文档提供上下文压缩的规则、错误记忆机制和最佳实践指导。

## 概览

本文档定义了两种不同的上下文压缩：

1. **对话历史压缩**：压缩长对话，保留关键决策和错误记忆
2. **上下文块压缩**：减少上下文块的 token 数量，保留最相关的信息

> **注意**：本文档主要针对"对话历史压缩"提供规则指导。对于"上下文块压缩"，请参考项目中的 `ContextCompressor` 实现。

---

## 1. 通用压缩规则

### 1.1 核心原则

- 优先保留代码变更记录和架构决策
- 忽略调试过程中的尝试性命令输出
- 保留错误信息和解决方案
- 省略重复的文件读取结果

### 1.2 压缩内容优先级

当上下文利用率达到 70% 时触发压缩，按以下优先级保留内容：

1. **当前任务目标**（必须保留）
2. **已完成的关键动作**（必须保留）
3. **已修改的文件列表**（必须保留）
4. **关键决策与约束**（必须保留，含错误记忆）
5. **下一步计划**（可选）

### 1.3 关键信息标记

在压缩过程中，以下标记的内容必须保留：

- `@important`：核心业务逻辑讨论
- `@decision`：架构决策记录
- `@warning`：潜在风险和注意事项
- `@todo`：待办事项列表

---

## 2. 错误记忆与主动规避机制

### 2.1 错误记录预算

错误记录固定占用上下文预算的 **10%**。

当错误记录使用率超过 80% 时：
- 合并同类错误
- 移除超过 10 轮未出现的旧错误

### 2.2 错误标识格式

所有错误统一使用以下前缀分类：

| 错误类型 | 标识前缀 | 示例 |
|---------|----------|------|
| TypeScript类型错误 | `ERR_TS_` | `ERR_TS_MissingProperty` |
| Python运行时异常 | `ERR_PY_` | `ERR_PY_KeyError` |
| 工具调用失败 | `ERR_TOOL_` | `ERR_TOOL_FileNotFound` |
| 逻辑/业务错误 | `ERR_LOGIC_` | `ERR_LOGIC_OffByOne` |

### 2.3 错误记录结构

压缩时保留的错误记录格式：

```markdown
## Error Memory (Auto-Compacted)
- [标识] 发生次数: N (轮次列表)
  解决方案: 简要描述
  规避建议: 可执行的检查或代码模式
```

示例：

```markdown
## Error Memory
- ERR_TS_MissingExhaustive: 发生3次 (12,24,35)
  解决: 添加 `never` 类型检查
  规避: 在 `switch` 后增加 `default: exhaustiveCheck()`
- ERR_PY_AsyncWithoutAwait: 发生2次 (18,40)
  解决: 添加 `await` 或改为同步函数
  规避: 使用 `ruff` 规则 `ASYNC101`
```

### 2.4 错误记忆更新规则

每次压缩时扫描历史，识别错误信息：
- 若错误标识不存在 → 新建记录
- 若已存在 → 增加计数，更新最近轮次
- 同一标识发生次数 ≥ 2 时，在标识前增加 `#recurring` 标记

### 2.5 主动规避协议

模型在每次生成代码或回答前必须执行以下步骤：

1. 读取当前上下文中的 `## Error Memory` 块
2. 如果当前任务与任何已有错误标识的场景相似，先输出：
   > ⚠️ 检测到历史错误 `[标识]`，规避建议：`[规避建议]`
3. 若用户要求忽略规避建议，必须记录为 `@decision: ignore_ERR_xxx`

---

## 3. 自动压缩调优

### 3.1 触发条件

- 上下文利用率达到 **70%** 时触发压缩
- 保留最近 **5轮** 完整对话
- 仅对超过 **10轮** 的对话进行压缩

### 3.2 压缩内容优先级

1. 保留当前任务目标
2. 保留已完成的关键动作
3. 保留已修改的文件列表
4. 保留关键决策与约束（含错误记忆）
5. 保留下一步计划

### 3.3 压缩后状态恢复

#### 自动恢复的文件类型
- 最近修改的 5 个核心文件
- 包含未解决问题的文件
- 架构设计文档
- 测试配置文件

#### 恢复优先级
1. 主应用入口文件
2. 路由配置文件
3. 核心业务逻辑文件
4. 数据库模型文件
5. 测试配置文件

#### 恢复时必须输出的内容
- 当前工作目录（显式声明）
- 已打开的文件列表
- 未完成的任务列表
- 已发现的问题和解决方案
- 错误记忆块（完整输出）

---

## 4. Token 预算分配

### 4.1 优化后的预算分配

| 组成部分 | 预算比例 | 说明 |
|----------|----------|------|
| 系统提示词 | 10% | 固定 |
| 对话历史 | 50% | 压缩后的历史对话 |
| 错误记忆 | 10% | 新增，存储错误标识及规避建议 |
| 工具结果 | 20% | 文件读写、命令执行等结果 |
| 输出预留 | 10% | 留给当前回答生成 |

### 4.2 动态调整规则

- 上下文利用率 > 80% 时：工具结果预算降至 10%，错误记忆保持 10%
- 上下文利用率 < 50% 时：输出预留增至 15%，错误记忆可降至 5%（若无近期错误）

---

## 5. 缓存策略

### 5.1 可缓存内容类型

- 静态文件内容
- 编译后的代码
- 文档内容
- 重复的查询结果

### 5.2 缓存失效规则

- 文件修改时自动失效
- 任务变更时自动失效
- 每 24 小时强制刷新缓存

---

## 6. 团队压缩标准

### 6.1 通用压缩模板

```
/compact 总结对话内容，包括：
1. 已完成工作
2. 待完成任务
3. 关键决策
4. 问题与解决方案（含错误记忆摘要）
5. 下一步计划
```

### 6.2 禁止事项

- 压缩时不得删除错误信息
- 压缩时不得删除架构决策
- 压缩时不得删除待办事项
- 压缩时不得清空错误记忆块（除非用户明确要求）

---

## 7. 基于角色的压缩

### 7.1 开发人员

```
/compact 保留代码变更、技术实现细节和错误记忆
/compact 忽略项目管理和沟通内容
```

### 7.2 测试人员

```
/compact 保留测试用例和缺陷记录（错误记忆中的`ERR_LOGIC`类）
/compact 忽略代码实现细节
```

### 7.3 产品经理

```
/compact 保留需求讨论和功能决策
/compact 忽略技术实现细节和错误记忆
```

---

## 8. 压缩故障排除

| 问题 | 解决方案 |
|------|----------|
| 压缩后丢失关键信息 | 增加关键信息标记（@important等），调整压缩策略 |
| 压缩频繁触发影响效率 | 提高压缩触发阈值（如75%），优化上下文使用 |
| 恢复状态不完整 | 完善状态恢复规则，增加文件恢复列表，显式输出错误记忆 |
| 错误标识过多或混乱 | 定期执行错误合并，手动清理超过10轮未出现的标识 |

---

## 9. 性能指标与优化目标

| 指标 | 目标值 |
|------|--------|
| 压缩触发频率 | < 每小时 5 次 |
| 信息丢失率 | < 5% （错误记忆丢失率 < 1%） |
| 恢复时间 | < 2秒 |
| 重复错误率 | 相比无错误记忆降低 ≥ 50% |

---

## 10. 与项目压缩能力的区别

### 10.1 对话历史压缩（本文档）

- **压缩对象**：对话历史
- **目标**：保留关键决策和错误记忆
- **方法**：压缩规则、错误记忆机制
- **适用场景**：长对话管理

### 10.2 上下文块压缩（项目实现）

- **压缩对象**：上下文块
- **目标**：减少 token 数量，保留最相关信息
- **方法**：压缩策略（优先级、相关性、新鲜度）
- **适用场景**：`prepare_context()` 流程

### 10.3 项目压缩策略

项目提供以下压缩策略：

1. **PRIORITY_BASED**：基于优先级的压缩
2. **RELEVANCE_BASED**：基于相关性的压缩
3. **FRESHNESS_BASED**：基于新鲜度的压缩
4. **COMPOSITE**：综合评分（优先级+相关性+新鲜度）
5. **RULE_BASED**：基于规则的压缩

### 10.4 因果链增强压缩

项目支持因果链增强压缩功能，提升压缩质量：

**因果链的价值**：
- 信息密度高：因果链用简洁的方式表达复杂的因果关系
- 逻辑清晰：因果链明确展示"原因→结果"的关系
- 可压缩性强：因果链本身就是一种压缩形式
- 可追溯性强：通过因果链可以追溯决策和行动的来源

**实施方式**：
- 在 metadata 中添加 `causal_chain` 字段
- 基于规则的压缩策略（`RULE_BASED`）检查 `causal_chain` 字段
- 包含因果链的上下文块获得额外权重（+30 ~ +80）

**使用示例**：
```python
metadata = {
    "causal_chain": [
        {"cause": "用户请求", "effect": "生成回复"},
        {"cause": "生成回复", "effect": "调用工具"},
    ],
    "timestamp": "2024-01-01T00:00:00Z",
}

block = ContextBlock(
    source=ContextSource.INSIGHT,
    priority=ContextPriority.HIGH,
    content="...",
    token_count=50,
    metadata=metadata,
)

# 压缩时，包含因果链的块会获得额外权重
result = orchestrator.compress_context(
    blocks=[block, ...],
    compression_ratio=0.7,
    strategy="rule_based",
)
```

**权重计算**：
- 基础权重：+30
- 长度权重：+5/节点，最多 +50
- 总权重：+30 ~ +80

详细使用方法请参考 [SKILL.md](SKILL.md) 的"上下文压缩"章节。
