mirror of
https://github.com/shareAI-lab/analysis_claude_code.git
synced 2026-09-20 12:13:38 +08:00
feat: consolidate course into 21 lessons
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
|
||||
|
||||
s01 → s02 → s03 → s04 → s05 → s06 → s07 → `s08` → [s09](../s09_memory/) → s10 → ... → s20 → s21 → s22
|
||||
s01 → s02 → s03 → s04 → s05 → s06 → s07 → `s08` → [s09](../s09_memory/) → s10 → ... → s20 → s21
|
||||
> *"上下文总会满, 要有办法腾地方"* — 四层压缩策略, 便宜的先跑贵的后跑。
|
||||
>
|
||||
> **Harness 层**: 压缩 — 干净的记忆, 无限的会话。
|
||||
@@ -120,9 +120,9 @@ def tool_result_budget(messages, max_bytes=200_000):
|
||||
|
||||
三步流程:
|
||||
|
||||
1. **保存 transcript**:完整对话写入 `.transcripts/`,JSONL 格式。transcript 保留了可恢复记录,但模型的活跃上下文里只剩摘要。对模型当下推理来说,细节已经不在上下文中了。教学代码没有提供 transcript 检索工具。
|
||||
1. **保存 transcript**:完整对话写入 `.transcripts/`,JSONL 格式。transcript 保留完整记录;消息列表只保留摘要,原始细节不再进入后续模型调用。
|
||||
2. **LLM 生成摘要**:把对话历史发给 LLM,要求保留当前目标、重要发现、已改文件、剩余工作、用户约束等关键信息。
|
||||
3. **替换消息列表**:所有旧消息被替换为一条摘要。教学版只保留摘要;真实 Claude Code 会在 compact 后重新附加部分最近文件、计划、agent/skill/tool 等上下文。
|
||||
3. **替换消息列表**:所有旧消息被替换为一条摘要。
|
||||
|
||||
```python
|
||||
def compact_history(messages):
|
||||
@@ -189,7 +189,7 @@ def agent_loop(messages):
|
||||
break # 结束当前 turn,用压缩后的上下文开始新一轮
|
||||
```
|
||||
|
||||
**顺序不能换。** L3(budget)在 L2(micro)前面,因为 micro 会把旧的大 tool_result 替换成一行占位符,budget 必须在那之前把完整内容落盘。这也是为什么 CC 源码把 `applyToolResultBudget` 放在最前面。
|
||||
**顺序不能换。** L3(budget)在 L2(micro)前面,因为 micro 会把旧的大 `tool_result` 替换成一行占位符,budget 必须在那之前保存完整内容。
|
||||
|
||||
---
|
||||
|
||||
@@ -228,85 +228,5 @@ python s08_context_compact/code.py
|
||||
|
||||
s09 Memory → 三个子系统:选择记什么、提取关键信息、整理巩固。跨压缩、跨会话。
|
||||
|
||||
<details>
|
||||
<summary>深入 CC 源码</summary>
|
||||
|
||||
> 以下基于 CC 源码 `compact.ts`、`autoCompact.ts`、`microCompact.ts`、`query.ts` 的分析。
|
||||
|
||||
### 执行顺序对照
|
||||
|
||||
教学版为了讲解方便按 L1/L2/L3/L4 编号,但实际执行顺序和编号不完全对应:
|
||||
|
||||
| 维度 | 教学版 | Claude Code |
|
||||
|------|--------|-------------|
|
||||
| 执行顺序 | budget → snip → micro → auto | budget → snip → micro → collapse → auto(`query.ts:379-468`) |
|
||||
| snip_compact | 保留头 3 + 尾 47 | CC 仅主线程启用;实现不在开源仓库中(`HISTORY_SNIP` feature gate),但接口可见:`snipCompactIfNeeded(messages)` → `{ messages, tokensFreed, boundaryMessage? }`,还暴露了 `SnipTool` 工具让模型主动调用。教学版的 3/47 是简化参数 |
|
||||
| micro_compact | 文本占位符替换 | 两条路径:time-based 直接清内容,cached 走 API `cache_edits`(legacy path 已移除) |
|
||||
| micro_compact 白名单 | 按位置(最近 3 条) | time-based 按时间阈值触发;cached 按计数触发(`microCompact.ts`) |
|
||||
| tool_result_budget | 200KB 字符 | 200,000 字符(`toolLimits.ts:49`) |
|
||||
| compact_history 阈值 | 字符数估算 | 精确 token:`contextWindow - maxOutputTokens - 13_000` |
|
||||
| 摘要要求 | 5 类信息 | 9 个部分 + `<analysis>`/`<summary>` 双标签 |
|
||||
| 压缩 prompt | 简单 prompt | 首尾双重防呆禁止调工具 |
|
||||
| PTL retry | 有(简化) | `truncateHeadForPTLRetry()` 按消息组回退(`compact.ts:243-290`) |
|
||||
| 后压缩恢复 | 无(教学版只保留摘要) | 自动重新读取最近文件、计划、agent/skill/tool 等 |
|
||||
| 熔断器 | 3 次 | 3 次(`autoCompact.ts:70`) |
|
||||
| reactive 重试 | 1 次 | CC 有更精细的分级重试 |
|
||||
|
||||
### 执行顺序详解
|
||||
|
||||
CC 源码 `query.ts` 中的真实顺序:
|
||||
|
||||
1. `applyToolResultBudget`(L379):先处理大结果,确保完整内容落盘
|
||||
2. `snipCompact`(L403):裁中间消息
|
||||
3. `microcompact`(L414):旧结果占位
|
||||
4. `contextCollapse`(L441):独立的上下文管理系统(教学版无)
|
||||
5. `autoCompact`(L454):LLM 全量摘要
|
||||
|
||||
教学版的 budget → snip → micro 顺序与此一致。教学版没有 contextCollapse 机制。
|
||||
|
||||
### read_file 的取舍
|
||||
|
||||
教学版的 `micro_compact` 会把旧 `tool_result` 统一替换成占位符,包括 `read_file`。这通常不影响功能正确性:如果后续还需要文件内容,模型可以重新读一次。代价是可能多一次工具调用,也可能降低 prompt cache 命中率。
|
||||
|
||||
Claude Code 没有用教学版这种简单规则解决这个问题。它把 `Read` 也放进可 microcompact 的工具集合,但同时维护 `readFileState`:重复读取未变化文件时返回 `FILE_UNCHANGED_STUB`,compact 后再按预算恢复最近读过的文件内容(例如最多 5 个文件、每个 5K token、总预算 50K token)。这是生产级实现里的缓存和恢复机制,教学版不展开,保留“压缩旧结果,必要时重新读取”的简单 trade-off。
|
||||
|
||||
### 完整常量参考
|
||||
|
||||
| 常量 | 值 | 源文件 |
|
||||
|------|-----|--------|
|
||||
| `AUTOCOMPACT_BUFFER_TOKENS` | 13,000 | `autoCompact.ts:62` |
|
||||
| `MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES` | 3 | `autoCompact.ts:70` |
|
||||
| `MAX_OUTPUT_TOKENS_FOR_SUMMARY` | 20,000 | `autoCompact.ts:30` |
|
||||
| `POST_COMPACT_TOKEN_BUDGET` | 50,000 | `compact.ts:123` |
|
||||
| `POST_COMPACT_MAX_FILES_TO_RESTORE` | 5 | `compact.ts:122` |
|
||||
| `POST_COMPACT_MAX_TOKENS_PER_FILE` | 5,000 | `compact.ts:124` |
|
||||
| 时间 micro_compact 间隔 | 60 分钟 | `timeBasedMCConfig.ts` |
|
||||
| `MAX_COMPACT_STREAMING_RETRIES` | 2 | `compact.ts:131` |
|
||||
|
||||
### contextCollapse 和 sessionMemoryCompact
|
||||
|
||||
CC 源码中还有两个机制本教学版没有展开:
|
||||
|
||||
- **contextCollapse**:独立的上下文管理系统,启用时抑制 proactive autocompact(`autoCompact.ts:215-222`),由 collapse 的 commit/blocking 流程接管上下文管理。但 manual `/compact` 和 reactive fallback 仍是独立路径,不受 contextCollapse 影响。
|
||||
- **sessionMemoryCompact**:compact_history 之前,CC 会先尝试用已有的 session memory(s09 会讲到)做轻量摘要,不调 LLM。这个机制等学完 s09 之后回头看会更清楚。
|
||||
|
||||
### 压缩 prompt 长什么样?
|
||||
|
||||
CC 的压缩 prompt 有两个硬性要求:
|
||||
|
||||
1. **绝对禁止调用工具**:开头就是 `CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.`,末尾还会再 REMINDER 一次
|
||||
2. **先分析再总结**:模型需要先在 `<analysis>` 标签里理清思路,然后在 `<summary>` 标签里输出正式摘要。analysis 在格式化时被剥离
|
||||
|
||||
### 教学版的简化是刻意的
|
||||
|
||||
- micro_compact 用文本占位 → 我们没有 API 层的 `cache_edits` 权限
|
||||
- read_file 不特殊处理 → 教学版接受必要时重新读取,避免引入 readFileState 和后压缩恢复机制
|
||||
- token 用字符数估算 → 精确 tokenizer 不在教学范围内
|
||||
- 后压缩恢复省略 → 教学版只保留摘要,不自动重新附加文件
|
||||
- 两个辅助机制不展开 → 属于 10% 的细节
|
||||
|
||||
核心设计思想,便宜的先跑贵的后跑,完整保留。
|
||||
|
||||
</details>
|
||||
|
||||
<!-- translation-sync: zh@v2, en@v2, ja@v2 -->
|
||||
|
||||
Reference in New Issue
Block a user