第 10 章 · 上下文工程:组装、压缩与记忆
本篇目标:为一轮请求画出预算表,为一次长任务设计压缩策略,为跨会话设计记忆。 上下文工程是 Harness 的一个子集,不是与它并列的学科。
10.1 一次请求是怎么拼出来的
官方 DSH core/system-prompt 负责「prompt-section 与 tool-schema 的组装」。docs/architecture.md 的 turn flow 给出精确顺序:
claim 输入 → 快照 model selection → 组装 prompt sections + step-admitted tool schemas
→ agent/pre-step(可改写/拒绝)→ step/start
→ agent/request → prepareCall(绑定适配器,取消则什么都不提交)
→ 刷新运行时事实 → 协调提示词 → 准入 users → 冻结请求 → 流式调用
要点:组装发生在每 step,不是每 session。这意味着运行时事实(git status、时间、权限变化)可以随 step 更新,也意味着「同一 turn 内前后不一致」往往源于刷新而非模型抽风(第 06 章)。
官方 三条硬约束:
- Model-visible means logged —— 新增模型可见输入必须新增会话事件。
- 新增上下文的正规入口是
agent.inject(),落在下一次被准入的请求。 - 插件若要改动已有消息内容,须注册 pure message projections,不能就地改历史。
判据 14:任何绕过正规入口、直接往 messages 数组里塞东西的插件,都在制造「日志里查不到的模型输入」。这类 bug 极难定位。
10.2 上下文预算表
把一轮输入拆成可管理的格子。下表是模板,数字需你自己测(第 09 章「你好」体检):
| 分区 | 内容 | 是否常驻 | 典型量级 | 可优化手段 |
|---|---|---|---|---|
| A 身份与行为 | 系统提示词核心 | ✅ | 固定 | 精简到不可再减 |
| B 工具 schema | step-admitted tools | ✅ | 与工具数线性相关 | 按需准入、收窄描述、PTC |
| C 项目规则 | AGENTS.md |
✅ | 100–300 行 | 指针化、迁 hook、月度删减 |
| D 运行时事实 | 工作区、时钟、权限、git | ✅ | 小 | 只注入真正会变的 |
| E 会话历史 | 本轮对话 + 工具结果 | 增长 | 最容易失控 | 压缩、PTC、工具结果落盘 |
| F 按需加载 | Skill 全文 / 检索片段 | ❌ | 用时才计入 | 只回传必要片段 |
| G 跨会话记忆 | MEMORY.md / progress file |
部分 | 小 | 只存结论,不存过程 |
预算纪律:给 E 设硬阈值,给 A–D 设上限并定期复审,F/G 默认不常驻。
10.3 压缩策略
社区 生产实践里较通行的阈值与做法(来自 Heym 公开运行时):
| 参数 | 值 | 说明 |
|---|---|---|
| 触发阈值 | 模型窗口 80% | 提前压缩,避免硬截断 |
| 压缩对象 | 会话中段 | 保留 system message、first user message、latest message |
| 记录 | 每次 compression 写进 run trace | 否则压缩本身成为不可观测的黑箱 |
| LLM-as-judge | temperature=0 |
评估需确定性 |
原文 DSH 侧的对应能力:/compact 手动触发,极简模式直接砍掉上下文压缩(为了让跑分环境尽量少变量)。subsystems/compaction 是官方文档中的独立子系统页。
官方 提供了 hook 层的配套:PreCompact 可在压缩前归档完整 transcript,PostCompact 记录生成的摘要。
压缩最危险的地方:把「必须 100% 生效」的约束压没了。所以第 08 章才要求把这类约束迁到 hook / sandbox——它们不依赖留在上下文里。
10.4 记忆:跨会话靠什么
社区 Anthropic 在 Effective harnesses for long-running agents(2025-11-26)给出经典模式:initializer agent 先写好 progress file 与 feature list,之后每个新 session 第一件事是读它们。理由很直白:「each new session begins with no memory of what came before.」
| 记忆类型 | 载体 | 写什么 | 不写什么 |
|---|---|---|---|
| 项目约定 | AGENTS.md / CLAUDE.md |
命令、目录所有权、禁区 | 一次性任务细节 |
| 跨会话结论 | MEMORY.md |
用户偏好、已定技术决策、踩过的坑 | 完整对话 |
| 任务进度 | progress.txt / feature list |
已完成 / 待办 / 阻塞 | 推理过程 |
| 可重建事实 | 会话事件日志 | 全部 durable 事件 | — |
| 外部知识 | 记忆 MCP / 向量库 | 检索得到的片段 | 未经验证的推测 |
官方 DSH 文档站有 /guide/mcp-memory(记忆 MCP)与 /reference/subsystems/persistence、spill、session-telemetry 等页面;架构层则由 append-only 日志 + projection seam 统一承载。
判据 15:记忆写「结论」不写「过程」。过程在日志里,随时可 replay;把过程塞进记忆,等于用高成本常驻上下文复刻一份已经存在的日志。
10.5 信息对等再访:注入的边界
第 03、06 章讲过 information parity。这里补一个反向风险:注入也会污染。
| 症状 | 可能的注入源 | 定位方法 |
|---|---|---|
| 模型提到没给过的文件/人名 | 某插件注入了旧会话片段 | Trajectory 按来源逐个关闭,二分 |
| 长任务后半段规则失效 | 压缩把规则段挤掉 | 比对 PreCompact 归档与压缩后提示词 |
| 同一 turn 行为前后矛盾 | attempt 之间运行时事实刷新 | 查 assistant/attempt 与各 step 的 request/context |
| 极简模式正常、标准模式异常 | 时钟上下文 / Skills / 子 Agent 注入 | 逐项关掉再跑(第 06 章二分法) |
原文 极简模式连时钟上下文都砍掉了——这不是疏漏,是跑分环境的必要净化:任何随墙上时间变化的信息都会破坏可复现性。
10.6 本章产出与验收
核心产出:本项目一份真实上下文预算表(A–G 各格实测 token)+ 一条压缩策略(触发阈值、保留项、记录方式)+ 一份 MEMORY.md 模板。
验收点:
- 能说出「组装发生在每 step」带来的一个好处与一个风险
- 能解释为什么必须走
agent.inject()而不能直接改 messages - 能把一条常驻规则迁到 hook,并说明这对压缩鲁棒性的意义
- 能设计一个不污染可复现性的记忆方案
- 能对着 Trajectory 指出上一次压缩丢掉了什么
延伸阅读
| 来源 | URL | 等级 |
|---|---|---|
| 官方文档 · 系统提示词 | https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/system-prompt | 官方 |
| 官方文档 · 上下文压缩 | https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/compaction | 官方 |
| 官方文档 · 会话投影 / 持久化 / Spill | https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/session-projection | 官方 |
| 官方文档 · 记忆 MCP | https://deepseek-harness.github.io/deepseek-harness/guide/mcp-memory | 官方 |
| DSH 架构 · Turn flow / Session log | https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/architecture.md | 官方 |
| Anthropic, Effective harnesses for long-running agents | https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents | 社区 |
| Claude Code · Memory / Skills / Hooks | https://code.claude.com/docs/en/memory | 官方 |
| Heym, Context engineering | https://heym.run/blog/context-engineering | 社区 |