当前位置: 首页 > news >正文

Claude Code是如何做上下文工程的?

Claude Code是如何做上下文工程的?

从提示词工程到上下文工程,一个新的名词的出现往往是思维范式上的转变,一个工程的出现往往是为了解决某些问题产生的一种方法论。
最近的很多实践里都发现Agent能不能有满意的交付的关键就在于能不能理解上下文,这考验模型的能力,以及Agent系统提供准确充足上下文的能力
不可否认,Claude Code的强大源于Claude系列模型的强大,但有力的上下文支持也是Claude Code成功的关键。
接下来让我们以Claude Code逆向工程仓库为基础一点一点探索Claude Code是如何做上下文工程的?

1.上下文,一种支撑prompt的语境

上下文这个词还是太过于技术表达,咱们换个更接地气的表达——语境。

如果咱们把prompt当成一种指令,一次对话,那么上下文就是为每次对话提供足够的语境支持。就像两个人聊天,如果对方不知道你刚才在做什么、在想什么、有什么背景,就很难理解你的话。

比如你说"帮我看看这个",如果对方不知道你正在写代码、不知道你遇到了什么错误、不知道你的项目结构,他就无法给出真正有用的帮助。


2.Claude Code的上下文的难题

最近上下文工程这个词很火,很多朋友可能会问不就把上下文信息塞到prompt里吗,为什么还需要一个新的上下文工程?

在回答这个问题之前,咱们先来看上一篇提到的Claude Code逆向工程研究仓库,仓库里有一段对ClaudeCode运行log的分析。

一次重构任务ClaudeCode需要给出系统提示,运行大量工具调用,从而产生了执行结果、错误信息、状态反馈等海量的细节。从运行日志来看一轮Agent loop 产生了84247字节的上下文,这还只是一轮Agent Loop,一次重构任务经常面临着多轮AgentLoop,如此庞杂的上下文信息该如何管理呢?

除此之外ClaudeCode还有分层多Agent架构(主Agent + SubAgent),每个Agent有自己的上下文信息,如何传递协调不同Agent之间的上下文也是个大问题


3.上下文的四大痛点

Drew Breunig把这些上下文难题总结成四大痛点:

1.上下文中毒

比如当一次模型虚构了工具调用状态信息,被写入上下文时,在多轮循环中,模型可能会把错误信息误认为是事实反复引用,并执着于实现不可能或无关的目标,以至于后续每一步决策都在错误基础上前行,越走越偏。

2.上下文过长,情境干扰

当上下文过长,会导致模型注意力资源被稀释,过度关注上下文,忽略了原本通过训练获得的内容,输出质量下降。
虽然现在的大模型都已经支持百万级别的 token 上下文输入,但是 Gemini 2.5 的一份技术报告中指出,随着上下文超过 10 万个 token,大模型倾向于多步骤生成推理的长上下文,而非用于检索的长上下文。

3.多余信息过多,语境混淆

上下文中多余的内容也会干扰大模型的响应。以MCP工具调用为例,用过的朋友都知道,如果配置了数十个五花八门的MCP函数给大模型,每次调用时大模型要对数十个MCP做判断,调用工具决策的准确性会大幅下降

伯克利今年6月发布的报告,显示大模型在引入函数调用或使用工具的时候,几乎所有大语言模型的性能都会比原始文本生成任务中有所下降,在多函数调用场景中,准确率显著低于单函数调用。

4.多个信息源,语境冲突

语境冲突常出现在多个Agent协作时,比如导航subAgentA说中山路往东,导航subAgentB说中山路要往西,大模型做决策时到底听谁的?


4.ClaudeCode的上下文结构六大模块

为了解决这些痛点,在工程上,咱们就需要解决上下文结构是什么样的?什么时候增减?什么时候压缩?如何压缩?是否需要隔离?谁来写?谁来拼接?
解答这些问题这需要一套系统的工程方法论,这就是上下文工程的由来。

咱们还是从Claude Code逆向工程研究仓库的这份context_dump.log来看,这个690行的日志文件包含了一次逆向分析ClaudeCode代码会话的完整上下文信息,按照日志原文结构分为以下六个部分:

1. 系统信息内容

  • 包含系统身份定位,安全策略,交互规范,代码风格,工具使用指南,任务管理,工作流程以及示例展示的系统提示词。
  • 第二部分包含工作目录路径,近期git状态,文件列表

2. 会话延续上下文

  • 主要记录之前的会话完整历史,包含初始背景,主要请求,关键行动,用户反馈,修正措施,最终任务,最新请求

  • 第二块是会话中断的原因,中断状态,当时的工作进度

  • 这块是之前提到过的八段式压缩上下文,将超过阈值的上下文总结成:

    • 用户的主要请求和意图、关键技术概念、相关的文件位置、出现的问题及其解决方案、问题解决的思路方法结果、所有用户消息的完整记录和时间线、 待完成的任务(包含挂起的任务)和当前工作及下一步的结构化摘要。
    • 日志里面发现其实九段,其中对挂起的任务做了单独的总结,这在压缩提示词模板里是可选项。

3. 会话中的工具的调用和反馈

  • 这块包含工具的调用参数,反馈。需要注意的是,Claude Code的subAgent,todo也是一种工具,所以你在这里也会看到TaskAgent相关的信息和todolist的任务状态

4. 已验证的关键任务节点

  • 基于工具调用,日志等信息汇总而成的关键任务结论

5. 用户请求

  • 这块主要按时间顺序,结构化用户最新请求

6. 系统信息

  • 包含用户近期操作,打开或点击文件,有意思的是ClaudeCode在备注用户操作文件时给出提示词不要告诉用户,不需要因为状态变化而重读文件。

【注】提示词里会用标记system-reminder 用户消息,工具调用信息 ,用于与其他信息区分,并用ismeta是用户消息,用于与系统消息区分。


5.Claude Code的上下文更新流程图

从上下文的结构上,咱们就能大致猜测出什么时机注入什么上下文,接下来咱们拆解一下,Claude Code的上下文更新机制:

上下文管理
压缩子系统
需要压缩
无需压缩
ga0身份声明
Ie1上下文注入
yj行为准则
va0安全策略
tG5文件安全
VE Token计算
qH1压缩执行
Re1上下文分析
AU2模板生成
TW5文件恢复
BU2摘要格式化
用户操作/系统事件
事件分类器
WD5事件分发器
K2消息工厂
消息队列
nO主循环
wU2压缩判断
wu API调用
响应处理
结果输出

6.Claude Code的上下文更新流程

从前面流程图不难看出来,整个机制就是以事件触发为起点,经过消息队列,上下文处理等流程到最后API调用响应为终点

整个流程大体可以总结为的

  • 用户操作/系统事件 → 事件分类 → WD5分发处理
    → K2创建消息 → 消息队列 → nO主循环 → wU2压缩
    → Ie1上下文注入 → wu API调用 → 响应处理

Claude Code的上下文更新机制咱们可以总结成三个原则

  • 事件驱动
  • 实时响应
  • 按需注入

7.Claude Code上下文更新的三个原则

1).事件驱动

  • Claude Code上下文更新触发机制,采用事件驱动架构,当产生文件操作,工具执行,用户输入,目录变更时等操作时就会触发事件,由WD5函数作为事件分发中心。

  • 每一个事件对应着相应的提示词模板,比如plan模式激活会触发创建限制写文件操作的提示词,打开文件触发提示用户打开文件的提示词。

  • 除此之外比较特别的是,ClaudeCode将对内存的访问事件,也会触发事件处理机制,比如内存紧张时触发紧张压缩机制,传递提示词给压缩大模型进行紧急压缩。

2).实时响应

  • 当这些事件触发之后,K2函数会创建对应的提示词,事件提示词会立马被塞到一个消息队列里

  • 每次调用API前,如果消息队列里有新的内容,都会对其重新做上下文的注入,过期之前的会话的用户信息和工具信息,从而保证上下文的时效性。

  • 第二层实时响应,是在主循环多个yield _处设置中断点,支持用户实时的进行交互

3).按需注入

  • 由于在触发事件时,才生成提示词,这种机制能够让ClaudeCode,每次只注入需要的提示词,比如只需要某些工具的调用,就只注入某些工具调用的提示词,减少多工具调用的语境混淆,避免多余的信息干扰。
  • 消息队列会将带有前文提到的system-reminder用户消息,工具调用信息总是放在消息队列最前面,确保AI最先看到最新的状态信息。
  • 以及对ismate用户消息特殊处理,确保用户信息不丢失。
  • Ie1函数通过条件检查机制,只有在存在相关事件队列时才进行注入,从而才做API调用,避免了无效上下文注入和不必要的API的调用。
  • 可以通过多种方式触发,对上下文内容进行结构化压缩。

8.Claude Code的上下文压缩触发节点

Claude Code上下文压缩机制的核心是qH1函数,有三种触发方式:

  • 1.自动触发通过主循环调用wU2压缩判断达到token使用阈值之后自动触发qH1函数执行压缩。
  • 2.通过用户输入/compact 命令手段执行压缩
    • 用户可以通过输入"/compact"命令跳过是否压缩判断,自主选择时机压缩上下文。
    • 用户还可以通过输入"/compact 请重点关注TypeScript代码变更",传递给压缩提示词模板,要求他除了原有八段式要点之外增加"请重点关注TypeScript代码变更"当作压缩要点。
  • 3.系统检测到内存压力时触发,系统会持续监控内存和性能指标,当指标超过阈值时,也会触发事件生成提示词,通过提示词传递给qH1函数执行更为激进的紧急压缩策略。

9.上下文压缩流程图:

重建阶段
执行阶段
分析阶段
文件状态恢复
TW5重要文件恢复
Agent状态恢复
PW5 Agent状态恢复
摘要格式化
BU2压缩摘要格式化
消息重建
K2压缩摘要消息创建
8段式模板生成
AU2压缩模板生成
压缩提示消息
K2压缩提示消息创建
专用压缩模型
wu压缩模型调用
当前Token使用量
VE Token精确计算
消息类型分析
Re1多维度上下文分析
性能指标生成
HU2性能度量收集
qH1压缩函数启动
消息数组验证
E1遥测数据上报
QU2工具权限设置
流式响应处理
setMessages状态更新
setMessageHistory历史保存

10.ClaudeCode的上下文压缩流程:

ClaudeCode压缩流程里,最核心的无疑就是调用专用压缩大模型进行总结抽象式压缩,当然前期消息准备,和后期上下文重建也起到重要作用。整个压缩流程可以总结为三个阶段:分析,执行,上下文重建

  • 1.分析阶段

    • 主要做消息的分类整理,工具消息,用户消息,以及其他类型的区分处理
    • 第二层是从多维度对上下文进行分析包含:消息类型的统计,工具使用情况的统计,时间序列分析,文件操作的报告,以及内容复杂度分析
    • 第三是对token的计算分析,token用量,各消息token使用占比等,从而计算可能压缩的空间,生成一份分析报告。
  • 2.执行阶段

    • 生成压缩提示词,如果有外部传递过来的压缩要点提示,这个阶段也会进行整合。
    • 将压缩提示词,上下文,分析报告向特定上下压缩大模型上报等待响应
  • 3.上下文重建阶段

    • 在这个阶段会将在token预算内,根据时间频次等指标尽可能的恢复重要文件,写回上下文
    • 此外Agent的状态进行恢复,比如todo工具信息,会话延续上下文,任务进度等
    • 为了避免核心提示词被压缩,还会重新注入系统提示词,与压缩后的上下文一起组成新的上下文
    • 另外这个阶段还会对UI状态做恢复,对存储的信息进行更新。

11.Claude Code的如何协调多Agent结构

我们在上篇文章中提到过Claude Code采用Task工具作为一种子Agent协作模式,整体运行流程是这样的:

多Agent运行流程图


12.多Agent避免上下文冲突的机制

在Agent的运行方式上,通常可以划分为串行的,并行的,有上下文共享的,上下文不共享的。如果说todo+Agent Loop的回调算一种串行的,有上下文共享的Agent。那么Task工具可以说实现一种并行的,上下文不共享的Agent

Task Agent在避免上下文冲突和混乱上做了许多工作:

1. 隔离机制

  • 完全隔离的执行环境:独立会话ID、空消息历史
  • 选择性上下文继承:只继承必要环境信息,不继承对话历史
  • 工具权限白名单:由于TaskAgent是通过工具实现的,所以限制可用工具,不继承Task等工具,防止递归调用,不允许再次拆分任务
  • 关键任务注入:将拆解后的任务注入到不同的TaskAgent里

2. 状态管理

  • 无状态设计:每次调用完全独立
  • 单向通信:TaskAgent只向主Agent传递工具调用报告,不传递上下文信息
  • 并发协调:UH1函数管理多Agent并发

3. 结果处理

  • 独立结果收集:每个Agent结果独立存储
  • 智能排序:由于TaskAgent是并发执行的,但任务拆解时之间本身可能有顺序关系,在整合结果的时候按Agent索引确保结果顺序一致
  • 智能结果合成:KN5函数本质上是一个新的TaskAgent专门用于合并多Agent结果,合成结果时会按照以下要求大模型来合成结果:
    1. 阅读所有Agent的响应
    2. 识别每个响应的核心观点
    3. 检测观点之间的冲突
    4. 基于任务目标进行优先级排序
    5. 生成能够协调所有观点的统一方案
    6. 保留重要的技术细节和代码示例
    7. 组织成结构化的输出格式
  • 错误隔离:由于单个Agent是独立环境运行的,单个Agent的错误不影响其他Agent
http://www.lryc.cn/news/598600.html

相关文章:

  • Maven Scope标签:解锁Java项目依赖管理的秘密武器
  • [嵌入式embed]ST官网-根据指定固件名下载固件库-STSWSTM32054[STM32F10x_StdPeriph_Lib_V3.5.0]
  • 使用maven-shade-plugin解决依赖版本冲突
  • RCLAMP0504S.TCT 升特半导体TVS二极管 无损传输+军工防护+纳米护甲 ESD防护芯片
  • 陕西地区特种作业操作证考试题库及答案(登高架设作业)
  • Product Hunt 每日热榜 | 2025-07-24
  • 2025年人形机器人动捕技术研讨会于7月31日在京召开
  • 火语言 RPA 在日常运维中的实践
  • ESP32使用 vscode IDF 创建项目到烧录运行全过程
  • 优选算法:移动零
  • 使用ffmpeg转码h265后mac默认播放器不支持问题
  • Mac电脑使用IDEA启动服务后,报service异常
  • 从零构建 Node20+pnpm+pm2 环境镜像:基于 Dockerfile 的两种方案及持久化配置指南
  • 开源Qwen凌晨暴击闭源Claude!刷新AI编程SOTA,支持1M上下文
  • Vue3实现视频播放弹窗组件,支持全屏播放,音量控制,进度条自定义样式,适配浏览器小窗播放,视频大小自适配,缓冲loading,代码复制即用
  • 合泰单片机怎么样
  • idea监控本地堆栈
  • Linux系统监控模块之Zabbix7添加监控主机
  • 生成式人工智能展望报告-欧盟-03-经济影响
  • 第一二章笔记
  • 同步时钟系统提升仓库自动化水平
  • Opentrons 模块化平台与AI技术助力智能移液创新,赋能AAW™自动化工作站
  • 爬虫逆向--Day12--DrissionPage案例分析【小某书评价数据某东评价数据】
  • 2025年区块链安全威胁全景:新兴漏洞、攻击向量与防护策略深度解析
  • 常见半导体的介电常数
  • gitlab使用 备份恢复 全量迁移
  • 期货交易系统界面功能与操作流程解析
  • C++ <多态>详解:从概念到底层实现
  • Java 实现 B/S 架构详解:从基础到实战,彻底掌握浏览器/服务器编程
  • 深入理解 ThreadLocal:从原理到最佳实践