驯服上下文窗口:记忆与重置
驯服上下文窗口:内存与重置
Section titled “驯服上下文窗口:内存与重置”设想一下,你正在管理一个由顶尖工程师组成的庞大软件项目,但这里有一个致命的问题:他们每轮班结束时都会彻底失忆。每次他们打卡上班时,你都必须手忙脚乱地向他们解释项目是什么、昨天完成了什么、今天需要做什么。如果你的解释太长,他们会感到不知所措,记不住中间的指令;如果解释太短,他们会因为缺乏背景信息而破坏现有的功能。这正是构建缺乏合理内存管理的长期运行 AI Agent(智能体)时的真实感受。
当 Agent 运行数小时甚至数天,不断读取文件、编写代码并调试错误时,它们的上下文窗口(Context Window)会被填满。这会导致一种被称为**上下文焦虑(Context Anxiety)**或健忘的现象。在本章中,我们将探讨 AI Harness Engineering(AI 工具链工程)如何通过上下文压缩(Context Compaction)、上下文重置(Context Resets)以及结构化交接工件(Structured Handoff Artifacts)来解决这一问题。
上下文焦虑的威胁
Section titled “上下文焦虑的威胁”大语言模型(LLM)本质上是无状态的(Stateless)。为了维持“对话”或“智能体回话(Agentic session)”,Harness 必须不断地将新的操作和响应附加到运行中的记录中,并在每一步都将完整的记录发回给模型。这带来了三个严重的问题:
- “迷失在中间”效应(The ‘Lost in the Middle’ Effect): 模型非常擅长记住提示词(System Instructions)的开头和结尾(最近的错误消息),但众所周知,它们会忽略或忘记埋藏在庞大上下文窗口中间的细节。
- 成本与延迟: 为每个微小的动作来回发送 100,000 个 Token 不仅速度极慢,而且在经济上也非常昂贵。
- 幻觉与漂移: 随着记录中充满了失败的尝试、死胡同式的调试轨迹和临时日志,Agent 会被自己混乱的历史记录搞糊涂,从而偏离最初的目标。
上下文压缩 vs. 上下文重置
Section titled “上下文压缩 vs. 上下文重置”为了防止 Agent 淹没在自己的历史记录中,Harness 必须主动管理上下文窗口。实现这一目标有两种主要技术:上下文压缩(Context Compaction)和上下文重置(Context Resets)。
| 技术 | 工作原理 | 最佳适用场景 |
|---|---|---|
| 上下文压缩 | 定期使用 LLM 读取冗长的记录并撰写简明摘要。随后,原始的长记录将被摘要替换。 | 需要记住对话“梗概”而非精确按键操作的持续性子任务。 |
| 上下文重置 | 彻底清除对话历史,仅携带必要的关键状态工件启动一个全新的 Agent 实例。 | 在主要阶段之间转换(例如从规划到实施)或从卡死状态中恢复。 |
上下文压缩:挤压海绵
Section titled “上下文压缩:挤压海绵”上下文压缩就像挤掉湿海绵里的水,以便它能吸收更多水分。当上下文达到一定阈值(例如 Token 限制的 80%)时,Harness 会拦截执行过程,并要求一个辅助的、更廉价的 LLM 对目前为止的进程进行总结。这将数千个 Token 浓缩为几段文字。
[压缩前:25,000 Tokens]System: 你是一名编程 Agent...Agent: 我将检查文件。Tool: Cat src/main.py -> (10,000 行代码)Agent: 我发现了 Bug,我将编写一个测试。Tool: 运行测试 -> (5,000 行堆栈跟踪)...
[压缩后:500 Tokens]System: 你是一名编程 Agent...Summary: Agent 检查了 src/main.py,在认证逻辑中定位到一个 NullPointerException,并运行了一套测试用例,在第 42 行失败。Agent: 接下来,我需要修复第 42 行。上下文重置与结构化交接工件
Section titled “上下文重置与结构化交接工件”虽然压缩很有用,但它本质上是有损的。最终,Agent 的“大脑”还是会变得过于混乱。管理长期运行 Agent 最稳健的方法是彻底的上下文重置。你需要终止当前的 Agent 进程,并启动一个全新的、高度专注的实例。
然而,为了避免前面提到的“健忘”问题,即将离任的 Agent 必须为即将上任的 Agent 准备一份结构化的简报。可以将其想象为护士在换班时的临床交接。我们将这些称为结构化交接工件(Structured Handoff Artifacts)。
- 进度日志(“做什么与为什么”): 由 Agent 维护的一个 Markdown 文件,详细说明总体目标、已完成的工作、失败的原因以及接下来的具体步骤。
- Git 提交历史(“证据”): 终极系统记录。通过强制 Agent 在重置前提交工作状态,新 Agent 只需运行
git log -n 3和git diff即可瞬间了解代码库的当前状态。 - 架构状态文件: JSON 或 YAML 文件,用于跟踪变量、数据库模式或 API 端点的当前状态,新 Agent 无需重新发现即可直接引用。
实现交接机制
Section titled “实现交接机制”让我们看看如何使用 Python 伪代码在 Harness 中编排这一过程。Harness 会监控 Token 数量或步数。当需要重置时,它会强制 Agent 生成交接工件,保存工作区,然后重启。
# 用于管理上下文重置的 Harness 伪代码
def run_agent_session(task_description, previous_handoff=None): # 初始化一个干净的上下文环境 context = [{"role": "system", "content": "你是一名软件工程师。"}]
# 如果存在上一轮的内存,则注入其中 if previous_handoff: context.append({ "role": "user", "content": f"上一轮交接内容:\n{previous_handoff}" }) else: context.append({"role": "user", "content": f"新任务: {task_description}"})
# Agent 执行循环 for step in range(MAX_STEPS_PER_SHIFT): action = llm.generate(context) result = execute_tool(action) context.extend([action, result])
# 检查任务是否完成 if is_task_complete(result): return "COMPLETED"
# 如果接近上下文限制,触发重置 if estimate_tokens(context) > TOKEN_WARNING_LIMIT: print("即将达到上下文限制。正在发起换班...") break
# 轮次结束。强制 Agent 编写交接工件。 handoff_prompt = { "role": "user", "content": "你的轮次即将结束。请为下一个 Agent 编写一份简明的进度日志(PROGRESS LOG)。包括你做了什么、什么失败了,以及接下来确切的步骤。将你的代码提交到 git。" } context.append(handoff_prompt)
# 生成并返回工件给 Harness handoff_artifact = llm.generate(context) return handoff_artifact
# 主 Harness 循环current_task = "将数据库从 SQLite 迁移到 PostgreSQL"handoff = None
while True: status_or_handoff = run_agent_session(current_task, handoff) if status_or_handoff == "COMPLETED": print("任务圆满完成!") break else: # 保存工件并使用全新的实例重新开始循环 handoff = status_or_handoff print("正在重置上下文... 正在将接力棒传给新的 Agent 实例。")驯服上下文窗口是 AI 工具链工程的一项基础技能。通过将思维方式从“一次长对话”转变为一系列由 Git 历史和进度日志等结构化交接工件连接的、离散且记录完备的“轮次”,你可以确保你的 Agent 始终保持敏锐、成本效益高且功能强大,无论项目持续多久。