Claude Code源码解构:压缩提示工程(二)
Claude Code源码解构:压缩提示工程(二):深度摘要与状态保留
接上篇(一),我们继续深入深度摘要的防幻觉策略和状态保留机制。
三、深度摘要的防幻觉策略

当令牌预算触发压缩后,系统会调用 streamCompactSummary 函数,向模型发送一个精心设计的 System Prompt,要求其生成结构化的对话摘要。
3.1 摘要 Prompt 模板
Please generate a detailed summary of the conversation so far.
Format your response with <analysis> and <summary> tags.
<analysis>
First, think through the key points, user intent, technical decisions, and pending tasks.
</analysis>
<summary>
1. Primary Request and Intent:
[详细描述]
2. Key Technical Concepts:
- [概念 1]
- [概念 2]
3. Files and Code Sections:
- [文件名 1]
- [总结为什么这个文件很重要]
- [对此文件所做更改的摘要]
- [重要的代码片段]
4. Errors and fixes:
- [错误 1 的详细描述]:
- [你如何修复错误]
- [用户对错误的反馈,如果有]
5. Problem Solving:
[解决的问题和正在进行的故障排除的描述]
6. All user messages:
- [详细的非工具调用的用户消息]
7. Pending Tasks:
- [任务 1]
- [任务 2]
8. Current Work:
[当前工作的精确描述]
9. Optional Next Step:
[要采取的可选下一步]
</summary>
请根据迄今为止的对话提供你的摘要,遵循此结构并确保你的回复精确和彻底。
该 Prompt 强制要求模型以 <analysis>(思考逻辑)和 <summary>(正式摘要)格式输出,确保涵盖用户意图、技术决策、修改的文件列表及下一步待办事项。
3.2 <analysis> 与 <summary> 的实战意义
在源码的实现中,这两个模块承载了截然不同的工程使命:
-
• <analysis>(思考暂存区):这是模型的Chain of Thought(思维链)。系统强制要求模型在输出摘要前,先在<analysis>标签内把事情”过一遍脑子”。这能大幅降低幻觉(Hallucination)。但关键在于,这个模块对用户和未来的上下文是不可见的。源码中的formatCompactSummary函数会通过正则/<analysis>[\s\S]*?<\/analysis>/将其直接删除。 -
• <summary>(浓缩上下文):这是真正保留给下一轮对话的正式摘要。
3.3 代码层面的实战回复示例
假设你让 Claude 帮忙重构登录组件,期间读取了文件并修复了报错,触发 /compact 后,模型实际返回的 XML 结构如下:
<analysis>
好的,梳理一下。
1. 用户让我把 src/components/Login.tsx 的状态管理改成 Zustand。
2. 我用 Read 读了文件,用 Edit 修改了 useAuth 为 useAuthStore。
3. 修改后报错:Property 'token' does not exist。
4. 我在 store/authStore.ts 补上了 token 的类型。目前已修复。
</analysis>
<summary>
1. Primary Request and Intent:
将 Login.tsx 的状态管理重构为 Zustand。
2. Key Technical Concepts:
- Zustand (状态管理) / TypeScript
3. Files and Code Sections:
- src/components/Login.tsx:替换了 useContext 为 Zustand hook。
- src/store/authStore.ts:在 AuthState 接口补充了 token?: string。
4. Errors and fixes:
- 报错 Property 'token' does not exist:
- 修复:在 store/authStore.ts 添加了类型定义。
5. Pending Tasks:
- 为 Login.tsx 添加单元测试。
6. Current Work:
准备编写测试用例。
</summary>
关键点:<analysis> 被系统删除,只保留 <summary> 作为新对话的起点。
四、状态保留与场景复现
这是 Claude Code 压缩机制中最容易被忽视、但也是最核心的”防失忆”设计。
4.1 为什么需要状态重注入?
如果压缩只是简单地”清空历史 + 插入摘要”,模型会立刻陷入”我知道我做过什么,但我不知道我手里有什么”的尴尬境地。
问题:摘要里说”已修复 auth.ts”,但模型手里没有 auth.ts 的最新代码。它怎么继续写 session.ts?
答案:在清空历史后,系统会立即重新读取关键文件,并将它们作为”附件”(Attachment)注入新对话的首轮。
4.2 状态重注入的三大支柱
|
|
|
|
|---|---|---|
| 文件内容重读 | createPostCompactFileAttachments |
|
| 计划进度恢复 | createPlanModeAttachmentIfNeeded |
/plan 任务树的执行状态 |
| Skill 规则激活 | createSkillAttachmentIfNeeded |
|
4.3 对话状态转换实例
步骤一:压缩前(Before Compact)
[
{ "role": "user", "content": "帮我重构 auth.ts..." },
{ "role": "assistant", "tool_calls": [{"name": "Read", "args": {"file": "auth.ts"}}] },
{ "role": "user", "content": "[File: auth.ts ... 500 lines]", "type": "tool_result" },
// ... 经过 50 轮对话,Token 达到 195k ...
{ "role": "assistant", "content": "下一步处理 session.ts" }
]
步骤二:压缩中(During Compact)
系统执行 messages = [],清空所有历史消息。
步骤三:压缩后(After Compact)
系统立即将”脱水”后的精华重新注入 messages 数组,作为后续对话的新起点:
[
// A. 插入边界标记 (System Message)
{
"type": "system",
"subtype": "compact_boundary",
"content": "Conversation compacted",
"compactMetadata": { "trigger": "auto", "preTokens": 190000 }
},
// B. 注入深度摘要 (User Message)
{
"role": "user",
"content": "This session is being continued... [Summary: 已完成 auth.ts 重构,修复了 JWT 漏洞。下一步:session.ts...]"
},
// C. 状态重注入 (Attachment Messages)
{
"role": "user",
"content": "[File Attachment: auth.ts(最新磁盘内容)]",
"isAttachment":true
},
{
"role": "user",
"content": "[Plan Attachment: 当前重构计划进度表]",
"isAttachment":true
}
]
这就是”不受上下文限制”的真相:不是真的有无限空间,而是通过**”摘要 + 关键文件内容重读 + 进度计划重注入”**,在清空历史后,瞬间为模型搭建了一个”案发现场”,让它能够无缝衔接。
下一篇(三):三层压缩策略 + 实战排障指南 + 完整场景复现
参考文献:
-
1. Claude Code源码:compact.ts -
2. Anthropic Claude API Documentation
夜雨聆风