前言

个人学习记录


什么是上下文工程

正如 Andrej Karpathy 所言,LLM 就像一种新型操作系统。LLM 如同 CPU,其上下文窗口如同 RAM,作为模型的工作内存,就像 RAM 一样,上下文窗口的容量有限,无法处理各种来源的上下文,正如操作系统管理 CPU 的 RAM 一样。我们可以将 “LLM 上下文窗口” 看做是操作系统。
使用不同的处理方式,使得上下文窗口的内容更加精准精简。

上下文工程策略

写入上下文

将其保存在上下文窗口之外,以帮助Agent执行任务

  • 临时笔记板
    当人类解决问题时,我们会做笔记并记住未来相关任务的信息。Agent 也在获得这些能力!通过 “临时笔记板” 做笔记是一种在 Agent 执行任务时持久保存信息的方法。其思想是将信息保存在上下文窗口之外,以便 Agent 可用。
    Anthropic 的多 Agent 研究系统展示了这一点的清晰示例:
    首席研究员首先思考方法并将其计划保存到内存中,因为如果上下文窗口超过 200,000 个 token 将被截断,保留计划很重要。
    临时笔记板可以通过几种不同的方式实现。它们可以是一个简单的工具调用,写入文件。它们也可以是会话期间持久的运行时状态对象中的字段。无论哪种情况,临时笔记板都让 Agent 保存有用信息以帮助完成任务。
  • 记忆
    临时笔记板帮助 Agent 在给定会话(或线程)内完成任务,但有时 Agent 会从多个会话中记住事情中受益。
    Reflexion 引入了在每个 Agent 轮次后进行反思并重用这些自生成记忆的想法。Generative Agents 从过去的 Agent 反馈集合中定期合成记忆。

临时笔记本的实现方式

  • 数据库存储:将临时信息存储在专门的数据库(如关系型数据库、NoSQL 数据库等)中。Agent 可以通过数据库接口进行数据的写入和读取操作,利用数据库的持久化和查询能力来管理临时信息。
  • 缓存系统:借助缓存系统(如 Redis 等)来保存临时笔记信息。缓存系统具有快速读写的特点,适合存储需要频繁访问的临时数据,能让 Agent 快速获取和更新临时笔记内容。
  • 消息队列:利用消息队列来传递和暂存临时信息。Agent 可以将临时笔记相关的消息发送到消息队列中,其他组件或后续的 Agent 操作可以从消息队列中获取这些信息,实现信息的临时存储和传递。
  • 分布式文件系统:在分布式环境下,使用分布式文件系统(如 HDFS 等)来存储临时笔记。这样可以利用分布式文件系统的高可用性和可扩展性,确保临时信息在多节点环境下的可靠保存和访问。

选择上下文

将其拉入上下文窗口以帮助Agent执行任务

  • 临时笔记板
    从临时笔记板中选择上下文的机制取决于临时笔记的实现方式。如果是工具,那么 Agent 只需通过工具调用读取它。如果是 Agent 运行时状态的一部分,则开发人员可以选择在每个步骤向 Agent 公开状态的哪些部分。这为在后续轮次向 LLM 公开临时笔记上下文提供了细粒度控制。
  • 记忆
    如果 Agent 有能力保存记忆,它们还需要有能力选择与正在执行任务相关的记忆。这可能出于几个原因很有用。Agent 可能会选择少量示例(情景记忆)作为期望行为的示例,指令(程序记忆)来引导行为,或事实(语义记忆)作为任务相关上下文。
Memory Type What is Stored Human Example Agent Example
Semantic Facts Things I learned in school Facts about a user
Episodic Experiences Things I did Past agent actions
Procedural Instructions Instincts or motor skills Agent system prompt

一个挑战是确保选择相关记忆。一些流行的 Agent 只是使用一组狭窄的文件,这些文件总是被拉入上下文。例如,许多代码 Agent 使用特定文件保存指令(“程序” 记忆),或在某些情况下保存示例(“情景” 记忆)。Claude Code 使用 CLAUDE.md,Cursor 和 Windrush 使用规则文件。
但是,如果 Agent 存储并从大量事实 / 记忆集合中(例如,语义记忆),选择就更难了。ChatGPT 是一个很好的流行产品示例,它存储着大量的用户特定或关系集合数据。
嵌入和 / 或知识图谱用于记忆索引通常用于辅助选择。尽管如此,记忆选择仍然具有挑战性。在 AIEngineer World’s Fair 上,Simon Willison 分享了一个选择出错的例子:ChatGPT 从他的记忆中获取位置信息,并意外地将其注入到请求的图像中。这种意外或不期望的记忆检索可能让一些用户感觉上下文窗口 “不再属于他们”!

  • 工具
    Agent 使用工具,但如果提供太多工具,它们可能会不堪重负。这通常是因为工具描述重叠,导致模型混淆该使用哪个工具。一种方法是对工具描述应用 RAG(检索增强生成),以便只为任务获取最相关的工具。一些最近的论文表明,这可以将工具选择准确性提高 3 倍。
  • 知识
    RAG 是一个丰富的主题,它可能是核心的上下文工程挑战。代码 Agent 是大规模生产中 RAG 的一些最佳示例。Windsurf 的 Varun 很好地捕捉了其中一些挑战:
    索引代码≠上下文检索…[我们正在进行索引和嵌入搜索…[使用] AST 解析代码并沿语义上有意义的边界分块… 随着代码库规模的增大,嵌入搜索作为检索启发式变得不可靠… 我们必须依赖多种技术的组合,如 grep / 文件搜索、基于知识图谱的检索和… 重新排序步骤,其中 [上下文] 按相关性排序。

压缩上下文

仅保留执行任务所需的token

  • 上下文摘要
    Agent 交互可能跨越数百轮并使用占用大量 token 的工具调用。摘要是管理这些挑战的一种常见方式。如果你使用过 Claude Code,你已经看到过这一点。当超过上下文窗口的 95% 后,Claude Code 会运行 “自动压缩”,它将总结用户 - Agent 交互的完整轨迹。这种跨 Agent 轨迹的压缩可以使用各种策略,例如递归或分层摘要。
    在 Agent 设计的特定点添加摘要也很有用。例如,它可以用于后处理某些工具调用(例如,占用大量 token 的搜索工具)。作为第二个例子,Cognition 提到了在 Agent-Agent 边界处进行摘要,以减少知识传递期间的 token。如果需要捕获特定事件或决策,摘要可能是一个挑战。Cognition 为此使用微调模型,这突显了这一步可能需要多少工作。
  • 上下文修剪
    虽然摘要通常使用 LLM 来提取最相关的上下文片段,但修剪通常可以过滤或,正如 Drew Breunig 指出的那样,“修剪” 上下文。这可以使用编码启发式方法,如从列表中删除较旧的消息。Drew 还提到了 Provence,一个用于问答的训练有素的上下文修剪器。

隔离上下文

将其拆分以帮助Agent执行任务
LangGraph&LangSmith


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐