编程代理的上下文配置指南
过去几个月,我们配置和丰富编程agent上下文的选项呈爆发式增长。Claude Code 在这一领域引领创新,但其他编程助手也在迅速跟进。强大的上下文工程已成为这些工具开发者体验的重要组成部分。
当然,上下文工程与所有类型的agent和 LLM 使用场景都相关。我有一个简单的定义:“上下文工程就是筛选模型看到的内容,以便获得更好的结果。”
对于编程agent来说,出现了一系列上下文工程方法和术语。其基础是工具提供的配置功能(例如“规则”、“技能”),然后是我们如何在概念上使用这些功能(“规范”、各种工作流)。
本文是关于当前上下文配置功能状态的入门指南,以 Claude Code 为例进行说明。
什么是编程代理中的上下文?
“一切皆为上下文”——不过,以下是我认为的编程代理中上下文配置的主要类别。
可复用的提示
几乎所有形式的 AI 编程上下文工程最终都涉及大量包含提示的 markdown 文件。我在这里 broadest 意义上使用“提示”一词,就像 2023 年那样:提示是我们发送给 LLM 以获取响应的文本。在我看来,这些提示背后有两种主要的意图类别,我称之为:
指令:告诉代理执行某操作的提示,例如“用以下方式编写 E2E 测试:……”
指导:(也称为规则、护栏)代理应遵循的一般约定,例如“始终编写相互独立的测试。”
这两个类别经常相互融合,但我仍然认为区分它们很有用。
上下文接口
我实在找不到一个既定的术语来形容我所说的上下文接口:向 LLM 描述如何在需要时获取更多上下文的描述。
工具:内置功能,如调用 bash 命令、搜索文件等。
MCP 服务器:在您本地机器(或服务器)上运行的定制程序或脚本,使代理能够访问数据源和其他操作。
技能:这些是编程上下文工程中的最新成员,是描述代理可以在需要时按需加载的额外资源、指令、文档、脚本等的描述。
配置的这些接口越多,它们在上下文中占用的空间就越多。因此,对于特定任务需要哪些上下文接口,进行战略性思考是明智的。
工作区中的文件
编程代理中最基本且最强大的上下文接口是文件读取和搜索,以了解您当前的代码库,所以我在这里特别提及。值得反思您现有的代码作为上下文的效果如何,基本上就是您是否拥有AI 友好的代码库设计。
如果以及何时:谁决定加载上下文?
LLM:允许 LLM 决定何时加载上下文是以无人监督方式运行代理的前提条件。但始终存在一些不确定性(不妨说是非确定性)——即 LLM 是否会在我们期望时加载上下文。例如:Skills
人类:人类调用上下文让我们能够控制,但会降低整体自动化程度。例如:通过斜杠命令 /skill_name
agent软件:某些上下文功能由agent软件本身在确定性时间点触发。示例:Claude Code hooks
多少:尽可能保持上下文精简
上下文工程的目标之一是平衡给出的上下文量——不要太少,也不要太多。尽管上下文窗口实际上已经变得非常大,但这并不意味着可以随意将信息倾倒进去。当代理获得过多上下文时,其效率会下降,当然,过多的上下文也是成本因素。
其中一些大小管理取决于开发者:我们创建多少上下文配置,以及我们在其中放入多少文本。我的建议是逐步构建规则文件等上下文,而不是从一开始就塞入太多内容。模型已经变得相当强大,所以您可能在半年前必须放入上下文的内容现在可能不再必要了。
关于上下文有多满、什么占用了多少空间的透明度,是帮助我们平衡这一点的工具中的关键功能。
但这并不完全取决于我们,有些编程agent工具在底层优化上下文方面也做得更好。它们会定期压缩对话历史,或优化工具的表示方式(如 Claude Code 的Tool Search Tool)。
以Claude Code为例
以下是Claude Code 的上下文配置功能概览,以及它们在上述维度中的位置:
1.CLAUDE.md
是什么:指导
谁决定加载:Claude Code - 会话开始时始终使用
何时使用:对于适用于整个项目的最常重复的一般约定
内容样例:
“我们使用 yarn,不用 npm”
“运行任何东西前别忘了激活虚拟环境”
“我们重构时不关心向后兼容性”
其他编程助手:基本上所有编程助手都有这个主“规则文件”功能,例如OpenClaw等;目前正在尝试将其标准化为AGENTS.md
2.Rules
是什么:指导
谁决定加载:Claude Code,当配置路径中的文件已被加载时
何时使用:有助于组织和模块化指导,从而限制始终加载的 CLAUDE.md 的大小。规则可以限定到文件(例如 *.ts 适用于所有 TypeScript 文件),这意味着它们只在相关时才会加载。
内容样例:“编写 bash 脚本时,变量应引用为 ${var} 而不是 $var。”路径:**/*.sh
其他编程助手:越来越多的编程助手允许这种基于路径的规则配置,例如 GH Copilot 和 Cursor
3.斜杠命令 /
是什么:指令
谁决定加载:人类
何时使用:您有特定较长提示的常见任务(审查、提交、测试……),您希望在主上下文内自行触发这些任务。在 Claude Code 中已弃用,被技能取代
内容样例:/code-review·/e2e-test·/prep-commit
其他编程助手:常见功能,例如 GH Copilot 和 Cursor
4.技能 skills
是什么:指导、指令、文档、脚本……
谁决定加载:LLM(基于技能描述)或人类
何时使用:在最简单的情况下,这是用于您只想在任务相关时“延迟加载”的指导或指令。但您可以将任何额外资源和脚本放入技能的文件夹中,并从主SKILL.md中引用它们以供加载。
内容样例:
- JIRA 访问(技能例如描述代理如何使用 CLI 访问 JIRA)
- “React 组件应遵循的约定”
- “如何集成 XYZ API”
其他编程助手:Cursor 的“智能应用”规则一直有点类似,但现在他们也在转向 Claude Code 风格的技能
5.子代理sub agent
是什么:指令 + 模型配置和可用工具集;将在其自己的上下文窗口中运行,可以并行化
谁决定加载:LLM 或人类
何时使用:
适合并值得在它们自己的上下文中运行以提高效率(通过更多有意的上下文来改善结果)或降低成本的大型常见任务。
您通常希望使用与默认模型不同的模型的任务
需要特定工具/MCP 任务的任务,而这些工具您不希望始终在默认上下文中可用
可编排的工作流
内容样例:
为刚构建的所有内容创建 E2E 测试
由单独的上下文和不同模型完成的代码审查,为您提供“第二种意见”,而不带有原始会话的包袱
子代理是 claude-flow 或 Gas Town 等 swarm 实验的基础
其他编程助手:Roo Code 已经有子代理有一段时间了,他们称之为“模式”;Cursor 刚刚获得它们;GH Copilot 允许代理配置,但目前只能由人类触发
6.MCP 服务器
是什么:在您的机器上(或服务器上)运行的程序,通过模型上下文协议使代理能够访问数据源和其他操作
谁决定加载:LLM
何时使用:当您希望赋予代理访问 API 或在您机器上运行的工具时使用。将其想象为您机器上具有大量选项的脚本,这些选项以结构化方式暴露给代理。一旦 LLM 决定调用此工具,工具调用本身通常是一个确定性的事情。现在有一种趋势,用描述如何使用脚本和 CLI 的技能来取代某些 MCP 服务器功能。
示例用例:
- JIRA 访问(可以执行 Atlassian API 调用的 MCP 服务器)
- 浏览器导航(例如 Playwright MCP)
- 访问您机器上的知识库
其他编程助手:此时所有常见的编程助手都支持 MCP 服务器
7.钩子Hooks
是什么:脚本
谁决定加载:Claude Code 生命周期事件
何时使用:当您希望每次编辑文件、执行命令、调用 MCP 服务器等时都确定性发生某些事情时
示例用例:
自定义通知
每次文件编辑后,检查它是否是 JS 文件,如果是,则在其上运行 prettier
Claude Code 可观测性用例,例如将所有执行的命令记录到某处
其他编程助手:Hooks 仍然是一项相当罕见的功能。Cursor 刚开始支持它们。
8.插件plugins
是什么:分发所有或任何这些内容的方式
示例用例:在组织内分发一组通用的命令、技能和 hooks 给团队