ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

上下文工程深度解析:从 KV Cache 到 Agent Skills 的技术原理与工程实践

上下文工程深度解析:从 KV Cache 到 Agent Skills 的技术原理与工程实践 上下文工程深度解析从 KV Cache 到 Agent Skills 的技术原理与工程实践本文基于开源技术书《深入理解 AI Agent》第二章系统解析上下文工程的技术体系。该章是全书最关键的一章从 API 消息结构出发深入 KV Cache 底层原理再依次展开提示工程、Agent Skills、Agent 状态栏和上下文压缩等核心技术。上下文工程是 Harness 中上下文与工具层面的核心实现决定了 Agent 在每个决策点能看到什么信息、以什么结构看到这些信息。上下文为什么是决定性因素该章开篇即指出大语言模型在标准测试中成绩亮眼但到了实际业务场景中却常常让人失望。原因是模型执行具体任务时需要的背景信息产品架构、业务规则、内部约定根本不在通用模型的训练数据中。一个中等能力的模型配上精心组织的上下文往往能胜过一个顶级模型在信息匮乏下的盲目摸索。上下文工程因此成为利用现有模型开发高效 Agent 的关键所在。OpenAI 研究员翁家翌的观点被引用“人和模型一样最重要的是 Context。”API 消息结构上下文的工程骨架理解上下文工程的基础是理解大模型 API 的消息结构。以 OpenAI Chat Completions API 为例核心是一个消息列表每条消息有一个角色标识system系统提示词定义 Agent 身份和行为规则user用户输入assistant模型之前的回复包括文本和工具调用tool工具执行结果通过tool_call_id关联到对应的工具调用此外工具定义tools作为请求的独立字段告诉模型有哪些工具可用。这意味着四种消息角色 tools 字段恰好覆盖了第一章所说的五个上下文组成部分。Agent 核心循环的实现Agent 框架的核心工作就是管理这个 messages 列表在合适的时机往里追加消息然后把整个列表送给模型。核心逻辑只有一个 while 循环模型返回了 tool_calls 就执行工具并继续循环没有就输出结果并退出。上下文由两部分组成上半部分System Prompt Tool Definitions在整个对话过程中保持不变是静态前缀下半部分对话历史即轨迹随交互不断增长。这个静态前缀 轨迹的结构是后续讨论 KV Cache 优化、上下文压缩等技术的基础。KV Cache前缀稳定性背后的底层原理KV Cache 是该章技术密度最高的部分其核心直觉是模型每生成一个 token都要回头看一遍前文所有 token 的中间计算结果。KV Cache 把前文的中间计算结果缓存下来下一轮只需要计算新增 token 的部分。前提是要复用的上下文 token 前缀保持不变。注意力机制与 QKV理解 KV Cache 需要先理解注意力机制。每个新词生成自己的 Query查询向量与所有已有词的 Key键向量做点积计算匹配度再用所有词的 Value值向量加权求和。如果每次都从头计算所有 K 和 V计算量会随上下文长度不断增长。KV Cache 把已算过的 K 和 V 缓存起来让新词直接复用。一个关键发现是注意力储存池现象序列第一个 token 往往吸收了异常高的注意力权重有时超过 70%因为 softmax 约束要求所有权重必须分配到某个地方模型学会把剩余权重倾倒到固定位置。另一个重要模式是位置偏好模型对上下文开头和结尾的信息分配更高注意力中间部分更容易被忽视。三条核心实践结论该章提炼了三条即使跳过原理细节也必须记住的核心结论系统提示词和工具定义一旦确定就不要改。任何改动哪怕多一个空格都可能改变 token 序列使首个不同 token 及其后的缓存无法复用。动态信息永远追加到末尾——时间戳、用户状态等变化的内容作为新消息追加到对话末尾而不是修改系统提示词。使用标准 API 格式不要自行拼接消息——结构化消息会被 Chat Template 翻译成模型训练时见过的固定 token 序列。缓存失效的工程代价一个真实案例说明了这些原则的工程意义某团队客服 Agent 每天处理 10 万次对话工程师在系统提示词里加了一行实时时间戳。第二天监控告警所有对话的首 token 延迟从 0.5 秒涨到 3-5 秒月度推理账单几乎翻倍。原因是那一行时间戳使每次请求的 token 序列从时间戳位置开始不同该位置及之后的 KV 状态无法复用。Chat Template 的作用Chat Template 把 API 的结构化 JSON 消息转换为模型能理解的线性 token 流。用特殊标记如|im_start|system划分每条消息的边界和角色。理解它的存在有两个实用价值第一解释了为什么必须使用标准 API 格式——自行拼接消息会破坏模型训练时建立的优先级体系导致思维链保留机制失效。第二解释了 KV Cache 为什么对前缀敏感——Chat Template 将 system 消息和工具定义转换为固定 token 序列放在最前面这些 token 的 KV 被缓存后可跨请求复用但前缀中任何位置的变化都会导致后续缓存失效。缓存作为架构约束在生产级 Agent 系统中缓存不仅是性能优化手段更是一个架构约束。Claude Code 的实践揭示了几个体现这种约束的设计决策提示词结构由缓存边界决定动态元素必须放到边界之后子 Agent 必须与父 Agent 字节级对齐以命中 Prompt Cache工具结果的替换字符串在首次出现时就被冻结核心启示是在设计 Agent 架构时缓存经济性不是事后优化而是前置约束。提示工程系统提示词的设计方法提示工程的核心对象是系统提示词——Agent 的员工手册。该章从多个维度讨论其优化方法。结构化与流程驱动现代大语言模型对结构化输入展现出显著敏感性。XML 标签提供机器可解析的精确语义Markdown 提供人机共读的组织逻辑。两者配合可以形成双层结构。更关键的是流程驱动优于规则堆砌。流程驱动的提示词让模型在任何时刻都能清楚知道自己处于哪个阶段、当前步骤的目标是什么、完成后该进入哪个步骤。该章的消融实验证实打乱信息组织结构、去除标题层次后任务成功率下降超过 30%。业务规则细化该章强调业务规则细化不是技术问题而是产品设计问题。以一个帮用户打电话处理账单的 Agent 为例计费系统设计涉及三种模式的精确区分。模糊的规则会导致 Agent 行为极不稳定——“帮我取消 Netflix 订阅到底算省钱还是取回本属于用户的钱”核心设计哲学是大语言模型的优势在于遵循复杂指令和从长上下文中提取信息但不应该在业务规则制定上被赋予过多自由裁量权。在优秀的 Agent 公司里提示词一般由产品经理来设计。工具定义设计工具定义的质量直接决定 Agent 使用工具的准确性。从 Claude Code 的工具定义可以观察到每个描述都精心设计了使用边界、具体示例、性能提示和工具间协作关系。该章还揭示了工具定义正在向渐进式披露演进的趋势OpenAI Responses API 提供tool_search和defer_loading标记Anthropic 提供 Tool Search 机制Codex CLI 默认开启 BM25 检索的tool_search——这些机制都遵循名称和简述常驻、完整 schema 按需追加到末尾的设计原则。提示注入防御提示注入是 Agent 安全的核心威胁之一攻击者通过 Agent 处理的外部内容网页、邮件、文档将伪装成系统指令的文本混入上下文。在 Agent 系统中这比普通聊天机器人更危险因为 Agent 拥有工具调用能力被注入的指令可能导致不可逆操作。上下文层防御的核心是帮模型分清指令与数据来源标记用 XML 标签包裹并标注来源、结构化角色严格利用 Chat Template 的角色体系传递信息和输入清洗。但该章清醒地指出上下文层只能降低攻击成功率无法做到万无一失。Agent Skills渐进式披露的工程实现随着 Agent 覆盖的业务场景越来越多把所有知识塞进一个系统提示词会带来两个问题浪费 token 和注意力被稀释。Agent Skills 采用渐进式披露的设计哲学——先给 Agent 看一份目录摘要需要时再加载完整内容。三层结构每个 Skill 包含三个层次第一层元数据SKILL.md开头的 YAML frontmatter包含name和description。目录在完整正文加载前对 Agent 可见使其能判断当前任务是否需要某项能力。第二层核心流程当 Agent 判断需要某个 Skill 时运行时才加载完整的SKILL.md。第三层细则通过文件引用深入到更详细的子文档。description字段是路由决策的关键写法应像路由条件而非功能介绍——何时该用我比我能做什么重要得多。Skills 与 KV Cache 的关系Skills 机制对 KV Cache 极为友好。完整 Skill 正文在被选中后追加到上下文末尾而不是插回前缀。因果注意力决定了每个 token 的 KV 只依赖它之前的 token因此在末尾追加新内容不会改变任何已缓存 token 的 K/V。新增的工具 schema 只需在首次出现时计算一次此后就并入不断增长的前缀在后续所有轮次持续命中。该章揭示了一个重要的工程原则选择 Agent 交互模式时应与模型厂商的训练方法保持一致。基础模型公司推行的 Agent 用法本质上是它们专门训练过的模式。Agent 状态栏元信息注入机制Agent 状态栏解决的是另一个独立问题如何让 Agent 随时看到任务进度、环境变化和工具调用计数等运行时状态。状态栏的理论基础是一个深刻洞察上下文学习更像检索而非推理。模型擅长从已有内容中查找信息但不擅长主动归纳和总结。上下文窗口是一台只有一半的检索引擎——检索这一半非常强但没有提炼层。关于已经打了几次电话的知识没有被自动提炼出来而是以原始通话记录的形式分散在 KV Cache 中模型每次都要从原始信息中现算一遍。状态栏的本质是把分散在上下文各处的隐式状态提炼为可直接使用的显式知识。实验表明为模型提供一条提前算好的状态栏后较小开源模型的准确率可以接近前沿大模型且思考效率大幅提升——不带状态栏时思考量随上下文变长持续增长带上状态栏后变得基本恒定。状态栏的位置与缓存代价Agent 状态栏在 API 层面是作为一条 user 角色的消息插入到上下文末尾的——而不是修改开头的 system 消息。原因正是 KV Cache 约束修改 system 消息会破坏整个前缀的缓存。状态更新有两种实现方式每轮替换移除旧状态、追加新状态会使上次注入后的短后缀缓存失效和持久追加旧状态永久保留对缓存完全友好但会累积陈旧状态。选择取决于状态大小、更新频率和轨迹长度的权衡。上下文压缩策略随着多轮交互深入上下文不断膨胀。该章指出压缩有三个截然不同的动机解决长度和成本约束窗口有限token 越多成本越高提升思考质量总结后的知识比原始形式更利于模型使用缓解上下文焦虑模型认为窗口即将耗尽时可能提前收尾上下文腐化隐蔽的质量衰减该章引入了一个重要概念——上下文腐化Context Rot。这与上下文溢出是不同的问题溢出是装不下了腐化是装得下但找不到了。无关的内容一旦占到上下文的大头Agent 的决策质量就会明显下滑但表面上还在正常工作只是决策质量悄然下降。压缩的设计原则是与其期望模型从冗长上下文中自动学习不如主动地、显式地进行知识提炼。压缩与 KV Cache 的关系压缩和 KV Cache 看似矛盾——前者要求修改上下文后者要求前缀不变。关键在于理解压缩发生的时机和位置压缩不是在单次 API 调用中修改上下文而是在两次 API 调用之间由 Agent 框架对消息列表进行预处理。System Prompt 和 Tool Definitions 永远不动压缩对象是对话历史中的 tool results替换位置之后的缓存会失效但之前的仍然有效。该章的实验对比了六种压缩策略从无压缩到自适应窗口化。上下文感知压缩将 token 使用量减少了 75% 以上而自适应窗口化策略通过阈值触发和批量压缩在初期保持完整原始信息的同时控制了上下文增长。子 Agent 上下文隔离隔离优于压缩一个更釜底抽薪的思路是让大体积的中间信息根本不进入主上下文。主 Agent 把会产生海量中间内容的任务委派给子 Agent子 Agent 在自己的上下文中完成探索只把结论性摘要回传。这本质上是用隔离代替压缩压缩是有损的事后补救隔离让噪声从一开始就与主上下文绝缘主 Agent 的 KV Cache 前缀完全不受影响。小结上下文工程的主线是显式管理信息API 消息结构定义骨架稳定前缀提高 KV Cache 命中率Prompt、Skills 和状态栏分别承载规则、按需知识与当前状态压缩则在保留决策、约束、失败和来源的前提下提高历史信息密度。这些技术共同回答了一个核心问题怎样以更低成本向模型提供一个信息充分的上下文让 Agent 的通用思考能力得以在具体任务中充分发挥。本文内容整理自开源技术书《深入理解 AI Agent》(bojieli/ai-agent-book)采用 Apache 2.0 许可证
返回列表