Skip to content

编码 Agent 的上下文工程(Context Engineering)

Birgitta 是 Thoughtworks 的杰出工程师(Distinguished Engineer)和 AI 辅助交付专家。她拥有超过 20 年的软件开发人员、架构师和技术领导者经验。

本文是”探索生成式 AI(Exploring Gen AI)“系列的一部分。该系列记录了 Thoughtworks 技术专家探索将生成式 AI(gen ai)技术用于软件开发的过程。

2026 年 2 月 5 日

在过去的几个月里,我们可以用来配置和丰富编码 agent 上下文的选项数量呈爆炸式增长。Claude Code 在这一领域引领潮流,但其他编码助手也在迅速跟进。强大的上下文工程正成为这些工具开发者体验的重要组成部分。

当然,上下文工程适用于所有类型的 agent 和 LLM 使用场景。我的同事 Bharani Subramaniam 给出的简单定义是:“上下文工程(Context engineering)就是精心策划模型所见的内容,以便获得更好的结果。”

对于编码 agent 而言,正在形成一套上下文工程方法和术语。其基础是工具提供的配置功能(例如”rules”、“skills”),然后是我们如何在概念上使用这些功能(“specs”、各种工作流)。

本文是一份关于当前上下文配置功能状态的入门指南,最后以 Claude Code 为例进行说明。

“一切都是上下文”——然而,这些是我认为在编码 agent 中属于上下文配置的主要类别。

几乎所有形式的 AI 编码上下文工程最终都涉及一堆带有提示(prompts)的 markdown 文件。我在这里使用最广义的”提示(prompt)“概念,就像 2023 年那样:提示是我们发送给 LLM 以获取响应的文本。对我来说,这些提示背后有两种主要的意图类别,我将它们称为:

  • 指令(Instructions):告诉 agent 执行某项操作的提示,例如”按以下方式编写 E2E 测试:……”

  • 指导(Guidance):(也称为 rules、guardrails)agent 应遵循的通用约定,例如”始终编写彼此独立的测试。”

这两个类别经常相互融合,但我发现区分它们仍然很有用。

我找不到一个公认的术语来描述我所说的上下文接口(context interfaces):即向 LLM 描述它如何可以在需要时获取更多上下文。

  • 工具(Tools):内置功能,如调用 bash 命令、搜索文件等

  • MCP 服务器(MCP Servers):在你的机器(或服务器)上运行的自定义程序或脚本,为 agent 提供对数据源和其他操作的访问权限

  • 技能(Skills):这些是编码上下文工程中最新的成员,它们是额外资源、指令、文档、脚本等的描述,LLM 可以在认为与当前任务相关时按需加载

你配置的这些内容越多,它们在上下文中占用的空间就越大。因此,明智地思考哪些上下文接口对于特定任务是必要的,是很谨慎的做法。

编码 agent 中最基本且强大的上下文接口是文件读取和搜索,以了解你当前的代码库,所以我在这里特别提及它们。值得反思的是,你现有的代码作为上下文的表现如何,基本上就是你是否有 AI 友好的代码库设计(AI-friendly codebase design)。

是否以及何时:谁决定加载上下文?

Section titled “是否以及何时:谁决定加载上下文?”
  • LLM:允许 LLM 自行决定何时加载上下文是以无人监督方式运行 agent 的先决条件。但始终存在一些不确定性(我敢说就是非确定性),即 LLM 是否会在我们期望的时候实际加载上下文。示例:技能(Skills)

  • 人类(Human):人类主动调用上下文给了我们控制权,但会降低整体自动化水平。示例:斜杠命令(Slash commands)

  • Agent 软件:某些上下文功能由 agent 软件本身在确定的时间点触发。示例:Claude Code 钩子(hooks)

上下文工程的目标之一是平衡所给上下文的数量——既不能太少,也不能太多。尽管上下文窗口(context windows)在技术上已经变得非常大,但这并不意味着可以不加选择地将信息倾倒其中。当 agent 获得过多上下文时,其有效性会下降,而且过多的上下文当然也是一个成本因素。

其中一些大小管理取决于开发者:我们创建多少上下文配置,以及在其中放入多少文本。我的建议是逐步构建如 rules 文件之类的上下文,而不是一开始就塞入太多内容。模型已经变得相当强大,所以半年前你可能需要放入上下文中的内容现在可能已经不再必要了。

关于上下文有多满以及什么内容占用了多少空间的透明度,是工具中帮助我们驾驭这种平衡的关键功能。

但这并不完全取决于我们,一些编码 agent 工具在底层优化上下文方面也做得更好。它们会定期压缩对话历史,或优化工具的表示方式(如 Claude Code 的工具搜索工具(Tool Search Tool))。

以下是截至 2026 年 1 月 Claude Code 的上下文配置功能概述,以及它们在上述维度中的分类:

内容: 指导(Guidance)

谁决定加载: Claude Code - 在会话开始时始终使用

何时使用: 适用于整个项目的最常见重复的通用约定

示例用例:

  • “我们使用 yarn,而不是 npm”
  • “运行任何内容之前别忘了激活虚拟环境”
  • “当我们重构时,我们不关心向后兼容性”

其他编码助手: 基本上所有编码助手都有这个主”rules 文件”功能;有人尝试将其标准化为 AGENTS.md

内容: 指导(Guidance)

谁决定加载: Claude Code,当配置路径下的文件被加载时

何时使用: 有助于组织和模块化指导,从而限制始终加载的 CLAUDE.md 的大小。Rules 可以限定到文件(例如 *.ts 对应所有 TypeScript 文件),这意味着它们只会在相关时加载。

示例用例: “编写 bash 脚本时,变量应引用为 ${var} 而不是 $var。” paths: **/*.sh

其他编码助手: 越来越多的编码助手允许这种基于路径的 rules 配置,例如 GH Copilot 和 Cursor

内容: 指令(Instructions)

谁决定加载: 人类(Human)

何时使用: 你有特定较长提示的常见任务(review、commit、test 等),并且你想在主上下文中手动触发这些任务。在 Claude Code 中已弃用(DEPRECATED),被 Skills 取代

示例用例: /code-review · /e2e-test · /prep-commit

其他编码助手: 常见功能,例如 GH Copilot 和 Cursor

内容: 指导(Guidance)、指令、文档、脚本等

谁决定加载: LLM(基于技能描述)或人类(Human)

何时使用: 在最简单的形式中,这适用于你只想在与当前任务相关时”懒加载(lazy load)“的指导或指令。但你可以将任何额外的资源和脚本放入技能的文件夹中,并从主 SKILL.md 中引用它们以便加载。

示例用例:

  • JIRA 访问(技能例如描述 agent 如何使用 CLI 访问 JIRA)
  • “React 组件应遵循的约定”
  • “如何集成 XYZ API”

其他编码助手: Cursor 的”智能应用(Apply intelligently)“rules 一直有点类似这样,但它们现在也切换到 Claude Code 风格的 Skills

内容: 指令 + 模型配置和可用工具集;将在其自己的上下文窗口中运行,可并行化

谁决定加载: LLM 或人类(Human)

何时使用:

  • 适合且值得在自己上下文中运行的常见大型任务,以提高效率(通过更有针对性的上下文改善结果,或降低成本)
  • 你通常希望使用与默认模型不同的模型的任务
  • 需要特定工具/MCP 服务器的任务,而你不想让这些工具/MCP 服务器始终在默认上下文中可用
  • 可编排的工作流

示例用例:

  • 为刚刚构建的所有内容创建 E2E 测试
  • 由单独的上下文和不同的模型进行的代码审查,为你提供”第二意见”,而不带原始会话的包袱
  • 子 agent 是 swarm 实验(如 claude-flow 或 Gas Town)的基础

其他编码助手: Roo Code 拥有子 agent 已经相当长一段时间了,他们称之为”模式(modes)“;Cursor 刚刚获得此功能;GH Copilot 允许 agent 配置,但目前只能由人类触发

内容: 在你的机器(或服务器)上运行的程序,通过模型上下文协议(Model Context Protocol)为 agent 提供对数据源和其他操作的访问权限

谁决定加载: LLM

何时使用: 当你想为 agent 提供对 API 的访问权限,或对你机器上运行的工具的访问权限时使用。可以把它想象成你机器上的一个脚本,有很多选项,这些选项以结构化的方式暴露给 agent。一旦 LLM 决定调用它,工具调用本身通常是一个确定性的事情。现在有一种趋势是用描述如何使用脚本和 CLI 的 skills 来取代一些 MCP 服务器功能。

示例用例: JIRA 访问(可以执行对 Atlassian 的 API 调用的 MCP 服务器)· 浏览器导航(例如 Playwright MCP)· 访问机器上的知识库

其他编码助手: 此时所有常见的编码助手都支持 MCP 服务器

内容: 脚本

谁决定加载: Claude Code 生命周期事件

何时使用: 当你希望每次编辑文件、执行命令、调用 MCP 服务器等时都确定性地发生某事

示例用例:

  • 自定义通知
  • 每次文件编辑后,检查是否是 JS 文件,如果是,则在其上运行 prettier
  • Claude Code 可观察性用例,如将所有执行的命令记录到某处

其他编码助手: Hooks 仍然是一个相当罕见的功能。Cursor 刚刚开始支持它们。

内容: 分发所有或任何这些内容的一种方式

示例用例: 向组织中的团队分发一组通用的命令、技能和钩子

这是一个相当长的列表!然而,我们目前正处于”风暴(storming)“阶段,肯定会收敛到一组更简单的功能。我预计例如 Skills 不仅会吸收斜杠命令,还会吸收 rules,这将使此列表减少两个条目。

正如我在开头所说,这些功能只是人类进行实际工作并用合理的上下文填充它们的基础。建立一个好的设置需要相当多的时间,因为你必须使用一个配置一段时间才能说它是否工作良好——上下文工程没有单元测试。因此,人们热衷于相互分享好的设置。

共享的挑战:

  • 分享者和接收者的上下文必须尽可能相似——在团队内部比在互联网上的陌生人之间效果更好得多
  • 有一种倾向是一开始就用不必要的、复制粘贴的指令过度工程化上下文,根据我的经验,最好是迭代式地构建
  • 不同的经验水平可能需要不同的 rules 和指令
  • 如果你因为从陌生人那里复制了很多而对自己的上下文中有什么内容意识较低,你可能会无意中重复指令或与现有指令矛盾,或者当编码 agent 只是遵循你的指令时,错误地责怪它没用

尽管有这个名称,但这最终并不是真正的工程(engineering)……一旦 agent 获得所有这些指令和指导,执行仍然取决于 LLM 如何解释它们!上下文工程肯定可以使编码 agent 更有效,并大大增加有用结果的概率。然而,有时人们用”确保它执行 X”或”防止幻觉(hallucinations)“这样的短语来谈论这些功能。但只要涉及 LLM,我们就永远无法确定任何事情,我们仍然需要用概率思维,并为工作选择合适级别的人类监督。

最新文章(3 月 4 日):

软件工程循环中的人类与 agent(Humans and Agents in Software Engineering Loops)

上一篇文章:

使用 agent 编码时评估内部质量(Assessing internal quality while coding with an agent)

下一篇文章:

Harness 工程(Harness Engineering)