# Context Engineering：从 Prompt 到上下文的系统工程

## 概述

当 agent 从单次对话走向多步骤、长时间运行的复杂任务时，prompt engineering 已经不够用了。行业正在经历一个范式转变：从"如何写好 prompt"到"如何系统性地管理 agent 在整个生命周期中看到的所有信息"。这就是 context engineering。本文综合 Anthropic、Manus、Fowler/Thoughtworks、HumanLayer 和 OpenHands 等多方视角，深入探讨 context engineering 的定义演变、经济学模型、核心技术策略，以及实践者必须面对的根本性限制。

## 从 Prompt Engineering 到 Context Engineering

Anthropic 给出了最权威的定义：context engineering 是"在 LLM 推理过程中策划和维护最优 token 集合的艺术"[^9]。这超越了单纯的 prompt 编写，包含了运行时的动态 context 管理——system instructions、tools、外部数据和消息历史都是 context 的组成部分。

Fowler/Thoughtworks 则提供了一个更朴素但同样精准的表述："context engineering 是策划模型所看到的内容以获得更好结果"[^11]。对于 coding agent，这意味着系统性地配置提供给 AI 工具的信息和指令。

这种定义的演变反映了实践的深化。早期的 prompt engineering 关注的是**一次性输入的优化**——如何写出更好的指令。而 context engineering 关注的是**整个信息环境的持续管理**——不仅包括初始 prompt，还包括工具输出、对话历史、外部数据检索、跨 session 的记忆，以及这些信息随时间的动态增减。

根本原则也相应转变。Anthropic 将其总结为："找到最小的高信号 token 集合来最大化期望结果"[^9]。这意味着 **context 不是越多越好，而是需要精心策划**。

## Context 作为有限资源的经济学

### Context Rot：性能的递减回报

多篇文章从不同角度描述了同一现象：随着 context 增长，agent 性能不是线性提升，而是在某个点后开始下降。Anthropic 从 transformer 架构的底层原理解释了原因：LLM 需要处理 n² 的 pairwise token 关系，context 增长带来的是注意力的稀释[^9]。LangChain 将这一现象命名为 **"context rot"**——信息过载导致的注意力分散和连贯性下降[^9]。Anthropic 还观察到一个更具体的症状：**"context anxiety"**——模型在接近感知到的 context 限制时过早结束工作[^9]。

HumanLayer 提供了一个实用的量化框架：**"Smart Zone"**——模型在约 75,000 token 以内时保持最佳推理性能，超出后进入"Dumb Zone"，性能显著下降[^13]。这个数字为实践者提供了具体的操作基准。

### KV-Cache 优化：生产环境的首要指标

Manus 的贡献在于将 context 管理从"语义层"下沉到"基础设施层"。在真实生产环境中（数百万用户），agent 系统通常有约 100:1 的输入/输出 token 比率，创造了巨大的缓存机会[^10]。Claude Sonnet 的缓存 token 成本为 $0.30/M，未缓存则为 $3/M——**10倍成本差异**[^10]。

为最大化 KV-cache 命中率，Manus 提出三个策略：维护稳定的 prompt 前缀、使用 **append-only** 的 context 设计（只追加不修改）、以及确定性序列化[^10]。这些策略看似与"精心策划 context"的直觉相矛盾——但它们解决的是"在保证语义质量的前提下，如何让推理引擎更高效"这个工程问题。

一个精巧的工程方案是用 **logits masking 替代动态工具移除**。动态移除工具会改变 prompt 内容使 KV-cache 失效；Manus 改用"context-aware state machine"在解码阶段通过 logits masking 约束行动选择——既实现了动态工具可用性控制，又保护了缓存[^10]。

### 二次方到线性的扩展

OpenHands 定量展示了 context 管理的经济效益：没有 condensation 时，context 管理开销随时间呈二次方增长；使用 condensation 后，通过战略性摘要和缓存优化，实现了线性增长[^14]。在 SWE-bench Verified 基准测试中，condensation 方案达到了 54% 的解题率（baseline 为 53%），同时 API 成本降低最多 2 倍[^14]。这个数据说明一个重要事实：**适当的信息压缩不仅不会伤害性能，反而可能因为减少噪音而略微提升表现**。

## 三种信息类型：指令、规范与上下文接口

Fowler/Thoughtworks 提供了最清晰的 context 配置分类法[^11]：

**Instructions（指令）**：特定任务的指令，如"按此模式编写 E2E 测试"。它们是 context 中的"行动命令"，直接告诉 agent 做什么。

**Guidance（规范）**：通用惯例和标准，如"保持测试独立性"。它们是 context 中的"通用原则"，影响 agent 的所有行为而非特定任务。OpenAI 的 `ARCHITECTURE.md` 和 `PLANS.md` 属于这一类[^11]。

**Context Interfaces（上下文接口）**：agent 获取额外信息的"管道"——Tools（内置能力）、MCP Servers（外部数据源）、Skills（按需加载的资源包）[^11]。它们不是 context 本身，而是 context 的获取渠道。

这个分类的实用价值在于：它帮助团队清晰地组织和管理大量的 context 配置，避免将不同性质的信息混杂在一起。Instructions 需要精确，Guidance 需要灵活，Context Interfaces 需要高效——三者的优化方向不同。

## 压缩与精炼技术

context 管理的核心挑战是：agent 需要足够的信息来完成任务，但 context window 是有限的。多篇文章从不同角度提出了解决方案，形成了一个从"事前控制"到"事后压缩"的完整策略谱。

### Backpressure：事前控制输入

HumanLayer 将系统工程中的 **backpressure（背压）** 概念引入 agent 设计[^13]。核心哲学极为简洁：**成功 = ✓，失败 = 完整输出**。通过 bash wrapper 函数，静默捕获 test/build 输出，成功时只显示一个勾号，失败时才输出完整错误信息。这可以把 200+ 行的测试通过输出压缩为几个 token。

关键洞察是：**确定性优于非确定性**。当我们已经知道哪些信息是重要的，就不应该把解析数千行无用 token 的决策权交给模型[^13]。作者观察到，RL 训练让模型学会了"节约 context"的行为模式（如 pipe 到 `/dev/null`），但这些模式本身反而可能浪费更多资源——因为 agent 可能不得不重新运行整个命令来获取丢失的信息。

### Condensation：事后压缩历史

OpenHands 提供了事后压缩的方案[^14]：在对话达到特定大小阈值时触发 condenser，对旧的交互进行策略性摘要，同时保持最近的对话完整。压缩器会编码保留关键信息：用户目标、agent 进度和剩余任务。对于软件开发任务，还会特别保留关键文件路径和失败的测试信息。

一个重要的工程细节是：**condensation 与 prompt caching 之间存在权衡**。触发 condensation 会使缓存失效，因此需要选择合适的触发阈值来平衡两者[^14]。

### Frequent Intentional Compaction：工作流级别的压缩

HumanLayer 将 compaction 从"技术手段"提升为"工作流设计原则"[^12]。其 **Frequent Intentional Compaction** 工作流的核心目标是保持 **40-60% 的 context 利用率**——为新信息和推理留出充分的空间。工作流分为三个阶段：Research（理解问题空间）→ Planning（制定实施计划）→ Implementation（增量执行，每步验证后将状态压缩回规划文档）。

最深刻的洞察是关于 **人类杠杆效应的层级结构**：研究阶段的错误会产生数千行问题代码；规划阶段的错误会产生数百行；编码阶段的错误仅影响个别行[^12]。因此，**将人类审查集中在研究和规划阶段能获得最大的投资回报**。

### 复述操控注意力

Manus 提出了一个独特的策略：让 agent 维护 `todo.md` 文件并持续更新，将关键目标"复述"到 context 末尾[^10]。这利用了模型的 recency bias 来对抗 **"lost-in-the-middle"** 效应——在平均约50次工具调用的长任务中，这是维持长期目标一致性的关键机制。

## CLAUDE.md 最佳实践

`CLAUDE.md`（或 `AGENTS.md`）是 agent harness 中**杠杆率最高的单一配置点**，因为它出现在每一个 agent 会话中[^15]。

### 指令预算

HumanLayer 揭示了一个关键约束：前沿 LLM 能可靠遵循的指令数量约为 **150-200 条**，而 Claude Code 的系统提示已经占用了约50条[^15]。这意味着 `CLAUDE.md` 不是可以无限堆砌指令的地方，而是需要精心分配的稀缺"指令预算"。

实践标准是：根文件控制在 **300 行以内**，核心内容不超过 60 行[^15]。HumanLayer 自己的根文件不到 60 行，只包含普遍适用的内容。

### 渐进披露

解决"指令预算有限"和"信息需求丰富"之间矛盾的核心策略是 **Progressive Disclosure（渐进式披露）**[^15][^11]。不在启动时加载所有工具和知识，而是在需要时才激活。具体做法是创建 `agent_docs/` 目录下的专题文件（building、testing、conventions、architecture、schema），在 `CLAUDE.md` 中用指针引用。

Fowler 将这一策略映射到 Claude Code 的功能集：CLAUDE.md（始终加载的全局 guidance）→ Rules（路径范围的精细控制）→ Skills（延迟加载的资源包）→ Subagents（独立 context window 的专门任务 agent）[^11]。

### 关键反模式

**不要自动生成**：ETH Zurich 的研究证明，LLM 生成的 agent 配置文件反而会损害性能，同时多消耗20%的 token[^7]。手动精心策划每一行内容，因为坏指令会在规划和实现阶段产生指数级的错误放大。

**不要放代码风格指南**：使用 linter 的 auto-fix 功能处理格式问题，而非浪费 LLM 的 token 和推理能力[^15]。确定性工具能处理的事情，不要交给概率性的 LLM。

**警惕外部复制**：直接复制他人的 context 配置可能与现有规则矛盾[^11]。迭代式开发优于批量复制。

## 外部化记忆策略

当 context window 不够用时，文件系统成为天然的扩展。Manus 将文件系统视为 **"无限、持久"的外化记忆**[^10]，关键设计是"压缩是可逆的"——在 context 中存储 URL 而非页面内容，存文件路径而非文档内容。需要时可以通过工具调用恢复完整信息。

Anthropic 推荐 **Structured Note-Taking**：agent 维护外部记忆文件（如 `NOTES.md`、to-do 列表），使多小时任务能跨 context 重置保持连贯[^9]。这种策略配合 **Just-in-Time Context Retrieval** 使用效果最佳：预加载索引信息，将详细数据的获取延迟到需要时通过工具检索[^9]。

Manus 还提出了 **保留失败证据** 的策略——不隐藏错误，而是让模型"隐式更新内部信念"[^10]。失败轨迹帮助模型建立"什么不管用"的知识，避免重复犯同样的错误。

这些外部化记忆策略共同构成了一个类比：**agent 的 context 管理类似于操作系统的虚拟内存管理**——有限的"物理内存"（context window）通过"页面置换"（compaction/offloading）和"页面文件"（文件系统）来支持远超物理容量的"虚拟地址空间"（任务所需的全部信息）[^12]。

## 控制幻觉：概率性本质与根本限制

在 context engineering 的乐观氛围中，Fowler/Thoughtworks 提出了一个重要的认知校准：**"Illusion of Control"（控制幻觉）**[^11]。Context engineering 提供的是概率上的改进，而非确定性的控制。LLM 行为仍然是概率性的——你可以通过精心策划 context 来显著提高获得期望结果的概率，但无法保证。

这一洞察有深远的实践含义。首先，它意味着 **context engineering 的价值应该用概率提升来衡量**，而非用"是否每次都能得到正确结果"来衡量。其次，它意味着关键任务仍然需要人类监督——context engineering 不是消除人类参与的手段，而是让人类参与更高效的手段[^12]。

Fowler 进一步提出了一个关键决策框架：**谁控制 context 的加载？**[^11] 三种模式各有权衡：
- **LLM-driven**：agent 自主判断加载什么 context，支持无监督运行但引入不确定性
- **Human-triggered**：用户显式触发 context 加载，有控制力但降低自动化
- **Agent software**：系统在确定性节点自动触发 context 加载

选择哪种模式取决于任务的关键性和组织对风险的容忍度。这个决策直接影响了 agent 的自主性和可预测性之间的平衡。

## 跨文章洞见

**事前 vs 事后的互补**：Backpressure[^13] 和 Condensation[^14] 分别解决了 context 管理的两端——源头控制和事后压缩。理想的 agent 系统应该同时采用两种策略：用 backpressure 减少输入噪音，用 condensation 管理累积历史。

**语义层 vs 基础设施层**：大多数文章在"语义层"讨论 context（如何写更好的 prompt、如何组织信息），Manus 则将讨论下沉到"基础设施层"（KV-cache 命中率、logits masking）[^10]。这两个层次的优化是正交的——你可以同时优化 prompt 的语义质量和推理引擎的缓存效率。

**一个隐含的悖论**：context engineering 的核心技术（compaction、note-taking、sub-agent）本身也消耗 context 和计算资源。Condensation 会使 prompt cache 失效[^14]，Manus 的 todo.md 更新占用了额外的工具调用[^10]。context 管理本身的成本需要纳入整体的 ROI 计算。

**未解决的张力**：保留失败证据[^10]与积极压缩 context[^12][^14]之间存在矛盾。保留多少错误轨迹、何时压缩掉它们，目前没有统一的最佳实践。此外，KV-cache 优化要求 append-only 设计[^10]，而 condensation 本质上需要重写历史[^14]——这两种策略在实现层面存在冲突，需要精心的工程权衡。

## 对技术管理者的建议

1. **将 context 视为工程预算来管理**：像管理内存预算一样管理 context window。建立 40-60% 利用率的团队标准[^12]，监控哪些信息在消耗 context 空间。

2. **同时投资事前和事后策略**：为 test/build/lint 命令编写 backpressure wrapper[^13]，同时配置 condensation 机制管理长任务的历史累积[^14]。两者互补，缺一不可。

3. **精心策划 CLAUDE.md，视为团队资产**：手动编写，控制在 60 行核心内容以内，覆盖 WHAT/WHY/HOW 三个维度[^15]。使用 progressive disclosure 将详细文档外部化。不要自动生成，不要放代码风格指南。

4. **在生产环境中优先优化 KV-cache 命中率**：采用 append-only 的 context 设计，维护稳定的 prompt 前缀，使用确定性序列化[^10]。这是成本优化的最大杠杆。

5. **将人类审查集中在高杠杆阶段**：研究和规划阶段的每分钟投入可以节省实施阶段的数小时[^12]。不要在编码细节上花费人类注意力，而是在问题定义和方案规划上投入。

6. **对 context engineering 的效力保持清醒认识**：它是概率改进而非确定性保证[^11]。根据任务关键性配置适当的人类监督级别，而非盲目信任 agent 自主运行。

## 引用来源

- [^7]: [HumanLayer: Skill Issue — Harness Engineering for Coding Agents](../notes/07-humanlayer-skill-issue.md)
- [^9]: [Anthropic: Effective Context Engineering for AI Agents](../notes/09-anthropic-context-engineering.md)
- [^10]: [Manus: Context Engineering for AI Agents](../notes/10-manus-context-engineering.md)
- [^11]: [Fowler/Thoughtworks: Context Engineering for Coding Agents](../notes/11-fowler-context-engineering-coding.md)
- [^12]: [HumanLayer: Advanced Context Engineering](../notes/12-humanlayer-advanced-context.md)
- [^13]: [HumanLayer: Context-Efficient Backpressure for Coding Agents](../notes/13-humanlayer-backpressure.md)
- [^14]: [OpenHands: Context Condensation for More Efficient AI Agents](../notes/14-openhands-context-condensation.md)
- [^15]: [HumanLayer: Writing a Good CLAUDE.md](../notes/15-humanlayer-writing-claude-md.md)
