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

Agent 原理(十四):Agent 跑得越久,为什么反而越容易变笨?真正要解决的,是“怎么忘”

做 Agent 做到一定阶段,你迟早会撞上一堵墙。

而且这堵墙很容易被误判。

刚开始,我们写的 Agent 非常自然:

用户说一句话。

模型思考。

调用工具。

工具返回结果。

再把结果塞回 Context。

模型继续思考。

再调用工具。

再塞回 Context。

于是整个系统一直沿着一个非常简单的逻辑运行:

发生过什么,就继续记住什么。

任务只有十几轮的时候,这种设计几乎完美。

可一旦 Agent 真正开始工作半小时、一个小时,甚至跨天运行,问题马上就来了。

它读过几十份文件。

调用过上百次 Tool。

查过网页。

运行过代码。

遇到过报错。

修改过 Plan。

调用过 Subagent。

做过 Verification。

等待过人工审批。

用户中间又修改过几次要求。

如果所有这些东西都继续放进 Context,那么你很快会发现一个很反直觉的现象:

Agent 明明掌握的信息越来越多,表现却可能越来越差。

很多人看到这里,第一反应是:

“Context Window 不够大。”

然后开始寻找 128K、200K、1M Context 的模型。

但真正理解 Agent 以后,你会发现:

这不是问题的本质。

因为哪怕明天模型拥有 1000 万 Token 的 Context,你依然不应该把过去发生的一切全部塞给它。

真正的问题是:

一个 Agent 到底应该记住什么,又应该忘掉什么?

这就是 Context Compression。

原来的课程设计把这一课概括成“Agent 工作几十分钟为什么不会爆 Context”,对应实验就是实现一个 Conversation Compressor。

但这一课如果只是教你“聊天太长就总结一下”,其实远远不够。

我们真正要解决的是一个更底层的问题:

一个长期运行的 Agent,怎样在丢掉大量历史细节以后,仍然知道自己是谁、正在做什么、已经做到哪里,以及下一步应该干什么。

这才是第十四课。


先别想 Agent,想象你自己工作了一整天

假设今天老板给你一个任务:

分析 20 家供应商报价,最后选出综合条件最优的一家。

上午九点,你开始工作。

第一家报美元。

第二家报人民币。

第三家按一打报价。

第四家按件报价。

有人 FOB。

有人 CIF。

有人没写运费。

有人 MOQ 不满足。

有人包装是一箱 24 件,有人是一箱 30 件。

于是你开始整理 Excel、发邮件、查汇率、统一计价单位、计算运费。

中间还发现一个公式写错了。

修正。

重新计算。

Supplier H 不满足 MOQ,排除。

Supplier C 少了 Freight,等待回复。

Supplier B 和 Supplier D 最接近,又继续比较付款条件。

下午三点,老板过来问:

“现在做到哪里了?”

你会怎么回答?

正常人绝对不会说:

“早上 9:02,我打开了第一个 Excel。”

“9:04,我点击了 Sheet2。”

“9:06,我发现 D17 是空值。”

“9:08,我第一次运行公式失败。”

“9:09,我重新运行。”

……

这些事情确实都发生过。

但它们已经没有资格继续占据你现在的工作记忆。

你真正会说的大概是:

已经完成 18 家供应商的标准化。

Supplier H 因 MOQ 不满足已经排除。

Supplier C 还缺运费数据。

目前 Supplier B 综合成本最低,Supplier D 第二。

但由于 Supplier C 数据还没补齐,现在还不能做最终推荐。

注意这里发生了什么。

过去六个小时,也许发生了几百个动作。

你没有全部忘记。

原始 Excel 还在。

邮件还在。

计算表还在。

但你的大脑已经把它们压缩成了几个真正影响下一步工作的状态。

这就是 Context Compression 最自然的理解。

不是“把字数变少”。

而是:

把已经发生的大量过程,重新表达成现在做下一步决定真正需要的信息。


一个非常关键的误区:Context 不是 Agent 的数据库

我们在前面的课程里已经把几个东西拆开了。

Context 是:

这一轮模型现在能够看到什么。

State 是:

当前任务已经进行到哪里。

Memory 是:

过去发生过什么,或者过去知道什么。

Skill 是:

遇到这类问题时,已经总结出来应该怎么做。

这几个概念原本就是课程中必须刻意区分的核心。

到了第十四课,还要再加一个东西:

Evidence。

也就是:

这个结论的原始证据到底在哪里。

比如采购案例中:

Supplier C Freight = 0.48 USD / piece。

这是一个事实。

这个事实可能进入 State。

但它的 Evidence 是:

Supplier C 发来的原始邮件。

现在模型不一定每一轮都要重新读取那封完整邮件。

可如果之后有人问:

“0.48 是从哪里来的?”

系统必须能够找回来。

这就是为什么:

“模型现在看不到”与“系统已经丢失”完全不是一回事。

这是理解长期 Agent 的第一道分水岭。


最原始的 Agent 为什么迟早会出问题?

我们最开始写 Agent Loop 时,通常会有一个messages

每发生一件事情,就往里面 append。

概念上大概是:

messages = [] while True: response = llm(messages, tools) if response.tool_calls: for call in response.tool_calls: result = execute_tool(call) messages.append({ "role": "tool", "content": result }) else: return response.text

这段代码没有错。

事实上,理解 Agent 最好的方式之一,就是先亲手写出这样一个 Loop。

问题出现在:

我们把messages同时当成了运行历史、任务状态、记忆系统和模型 Context。

刚开始它们看起来是一回事。

运行久以后,就完全不是了。

比如 Agent 工作一小时以后,messages里面可能已经有:

用户原始要求。

第一次 Plan。

第二次 Plan。

一个已经被推翻的旧 Plan。

20 个文件的原始内容。

12 个搜索结果。

3 次失败搜索。

6 个 Python Error。

几十次 Tool Call。

几百 KB 的日志。

两个 Subagent 的完整报告。

用户中途修改过的要求。

已经解决的问题。

已经失效的假设。

等待审批的 Action。

Verification 结果。

然后下一轮模型调用时,你把这一切重新发送给模型。

表面上:

“模型什么都知道。”

实际上:

你正在让模型重新阅读一大堆已经失去决策价值的信息。

这不是记忆力强。

这是没有信息管理。


Context Window 越大,为什么还是解决不了这个问题?

这里特别容易走错方向。

假设今天模型可以处理 128K Token。

有人说:

“那我换一个 1M Context 模型不就行了?”

当然会缓解容量问题。

但只解决了最浅的一层。

因为 Context 的真正成本不只是:

“装不装得下”。

还有另外一个更重要的问题:

哪些信息值得模型重新关注?

假设你现在真正需要解决的问题只有:

Supplier C 的运费数据什么时候回来。

结果模型同时看到:

70 轮以前已经修好的 Python Error。

Supplier A 的完整报价。

Supplier D 的完整报价。

十几个已经失效的搜索结果。

第一次 Plan。

第二次 Plan。

第三次 Plan。

五千字 Subagent 报告。

已经通过 Verification 的旧步骤。

这些内容都是真的。

但它们此时已经是噪声。

这就是 Context Engineering 最反直觉的地方:

给模型更多信息,有时候不是在帮助模型,而是在降低信噪比。

所以一个好的 Context 系统追求的从来不是:

“我能不能把所有东西都塞进去。”

而是:

这一轮决定,到底必须让模型看到什么?

课程最早在讲 Context Engineering 时其实已经留下了这个问题:哪些内容应该 permanent,哪些应该 retrieved,哪些应该 summarize,哪些应该直接丢弃。

第十四课就是开始真正给这个问题一个工程答案。


真正的转折:Context 应该是“临时构造”的

这一点如果想通,你对 Agent 的理解会发生一次明显升级。

早期 Agent 很容易这样理解:

Context = Conversation History

但成熟 Agent 应该是:

Context = Runtime 为当前这一轮决策临时构造出来的工作视图。

注意“临时构造”。

真实系统里可能保存着非常多东西:

用户 Goal。

当前 Task State。

完整 Session History。

Memory。

Skills。

原始文件。

Tool Results。

Subagent Results。

Audit Log。

Approval State。

环境状态。

但它们没有任何理由全部进入同一次 LLM Call。

Runtime 应该根据:

“现在准备做什么”

来选择:

“现在应该给模型看什么”。

所以到了这里,Context 已经不应该被理解成一个永远增长的数组。

更准确地说:

Context 是一个函数。

CONTEXT 的工程化理解

真实系统状态→Runtime 按当前任务选择信息→Working Set→LLM 做下一步决定

它接收当前系统状态,

然后生成:

这一轮模型需要看到的 Working Set。


Working Set:这是理解 Context Compression 最值得掌握的词

操作系统不会要求所有数据永远待在 CPU Cache。

数据库也不会为了执行一个查询,把整个数据库加载进内存。

Agent 同样不应该把所有历史永远放在 Context。

它真正需要的是:

Working Set。

也就是:

当前完成下一步工作真正需要的信息集合。

比如采购任务现在做到:

Supplier C 的 Freight 还没有拿到。

此时 Working Set 可能只需要:

用户最终目标。

“数据不完整不能推荐”的约束。

当前 Plan。

其他 19 家供应商已经完成标准化的事实。

Supplier C 的结构化报价。

缺失字段:Freight。

当前 Next Action:获取 Freight。

这时候需要把另外 19 家完整 PDF 再读一次吗?

不需要。

需要把两个小时前那个已经解决的 Python Stack Trace 放进来吗?

不需要。

需要把第一次失败的 Search Result 放进来吗?

也不需要。

这就是 Working Set。

而真正优秀的 Context Manager,本质上一直在回答:

什么应该进入当前 Working Set?


然后很多人会犯第二个错误:让 LLM “总结一下全部历史”

这是最常见的 Context Compression 实现。

历史太长。

于是:

“请总结以上聊天,保留重要内容。”

得到一段 Summary。

然后删掉前面的消息。

Demo 里看起来特别漂亮。

生产环境却隐藏着一个很大的风险。

因为:

Summary 是有损压缩。

比如原始资料是:

Supplier B 单价 8.42 USD / piece。

Freight 0.36。

MOQ 12,000。

Payment 60 days。

Supplier D 单价 8.31。

Freight 0.61。

MOQ 10,000。

Payment 30 days。

Compressor 最后总结成:

“Supplier B 和 Supplier D 报价接近,目前 Supplier B 综合条件略好。”

这句话完全没有错。

但半小时以后如果 Agent 需要重新分析:

为什么 B 比 D 好?

运费到底差多少?

Payment Terms 是否参与过判断?

你会突然发现:

Summary 已经不够了。

于是这一课必须建立第二个极其重要的概念:

Summary 不是 Evidence。

Summary 是为了帮助模型继续思考。

Evidence 是为了让系统能够重新证明:

“这个结论为什么成立。”

这两个东西不能混。


真正成熟的 Compression,第一步甚至不是“总结”

而是:

分层。

我们把 Agent 运行过程中产生的信息重新分一下。

第一类:

不能轻易丢掉的任务状态。

例如:

Goal。

Constraint。

当前 Plan。

Completed。

Pending。

关键 Decision。

Approval State。

Verification State。

这些东西如果消失,Agent 很可能直接改变行为。

第二类:

可以压缩的执行历史。

例如:

打开过哪些文件。

中间跑过哪些命令。

已经解决的报错。

旧的搜索过程。

已经结束的局部讨论。

这些东西不需要永远逐条占据 Context。

第三类:

原始 Evidence。

PDF。

Excel。

邮件。

数据库结果。

完整 Tool Output。

它们不需要每轮可见,但必须能够重新 Retrieve。

第四类:

长期知识。

Memory。

Skill。

这些甚至不一定属于当前任务,要按需加载。

所以一个成熟 Agent 的 Context,最后往往更接近:

Pinned Information + Current State + Compressed History + Recent Turns + Retrieved Evidence

CURRENT CONTEXT

Pinned Information + Current State + Compressed History + Recent Turns + Retrieved Evidence

而不是:

Everything That Ever Happened

这已经不是一个 Summary 技巧。

这是信息架构。


什么信息最不能被压错?

真正做 Agent 时,我会特别盯下面几类。

第一类是 Goal 和 Constraint。

比如用户说:

“数据不完整之前不要做最终推荐。”

如果 Compressor 最后只留下:

“目标是找出最优供应商,目前 Supplier B 最便宜。”

Agent 很可能下一步直接推荐 Supplier B。

程序不会报错。

模型也不会觉得自己做错了。

但原任务已经被 Compression 改写。

这类错误非常危险。

因为它不是 Crash。

它会继续正常运行。

第二类是已经确定的关键 Decision。

比如前面已经决定:

所有价格统一成USD / piece

结果压缩以后只剩:

“已经完成价格标准化。”

过一会 Agent 重新处理一份数据时改成USD / dozen

前半段一个标准。

后半段一个标准。

每一步单独看似乎都合理。

最终结果却已经不可比。

第三类是 Pending。

假设:

Supplier C 缺 Freight。

Supplier F 的 Packaging Basis 待确认。

如果 Summary 写成:

“报价标准化基本完成。”

这个“基本完成”特别危险。

Agent 很可能直接进入下一阶段。

所以长期 Agent 里一个非常重要的原则是:

Completed 和 Pending 必须结构化分开。

不要让一句“差不多完成了”承担系统状态。

第四类是失败产生的新约束。

比如某个数据源已经证实过期。

某个接口权限不足。

某条路径已经尝试并证明不可行。

Stack Trace 可以不留。

但:

这条路已经验证不能走

这件事情可能必须保留。

否则 Agent 过 30 轮以后又重新踩一次。

第五类是 Governance。

上一课最核心的变化,就是 Planning 得出的动作不再天然拥有执行权。Agent 只是提出“我认为应该做什么”,系统还需要检查权限和风险,再决定允许、审批还是禁止。

所以如果当前 Action 正在:

等待采购负责人审批,

Compression 以后千万不能只剩:

“采购流程正在进行。”

系统至少应该知道:

审批的是哪个 Action。

哪张 PO。

什么金额。

为什么需要审批。

当前状态。

谁批准了没有。

否则 Context Compression 可能直接把上一课建立的安全边界压没。


到这里,就该引入真正比 Summary 更重要的东西:Checkpoint

我觉得理解 Checkpoint 最简单的方法,不是想 Agent。

想游戏。

你玩一个 RPG 玩了六个小时。

存档时,游戏会保存什么?

不会保存过去六小时屏幕上出现过的每一帧。

它保存的是:

你现在在哪里。

多少级。

有什么装备。

哪些任务完成了。

哪些任务还没完成。

哪些门已经打开。

哪个 Boss 已经打死。

当前世界状态是什么。

下一次重新打开游戏,

系统加载这些状态。

你就能继续玩。

Agent 一样。

如果它工作了两个小时,

真正值得保存的不是:

两小时完整聊天。

而是一个能够继续任务的 Checkpoint。

例如:

checkpoint = { "goal": ..., "constraints": ..., "plan": ..., "completed": ..., "pending": ..., "decisions": ..., "critical_facts": ..., "evidence_refs": ..., "approval_state": ..., "verification_state": ..., "next_action": ... }

看到这里,你应该会有一个很明显的恍然大悟:

长期 Agent 真正依赖的不是“更长的聊天记录”,而是“可恢复的任务状态”。


更关键的是:这些东西很多根本不应该交给 LLM 总结

这是从 Demo 走向工程系统特别重要的一步。

假设系统明明已经知道:

amount = 184300

为什么还要把整个对话交给 LLM,再让它总结成:

“这是一笔比较大的订单。”

系统明明知道:

approval_state = waiting_for_procurement_director

为什么还要让模型总结成:

“目前还在等待审批。”

系统明明已经拿到:

Supplier C Freight = 0.48 USD / piece。

为什么让它依赖一段自然语言 Summary 保存?

能结构化保存的东西,

就直接结构化保存。

这条原则我会写得非常重:

能 deterministic 保存的事实,不要交给 LLM 猜回来。

金额。

日期。

ID。

数量。

版本。

状态。

审批结果。

计算结果。

关键字段。

这些都应该属于 Structured State。

LLM Compressor 更适合做什么?

它更适合处理:

“前面这几十轮到底发生了什么?”

“为什么最后选择这种做法?”

“哪些尝试失败过,不值得重复?”

“还有什么异常值得后面注意?”

也就是说:

Structured State 保存事实。

Summary 保存语义。

Evidence 保存依据。

Compression 的三层分工

Structured State保存事实
Summary保存语义
Evidence保存依据

这三层一分开,Context Compression 才真正开始可靠。


现在我们可以真正设计一个 Compressor 了

假设这次继续沿用整门课的风格,不上 LangChain,不上 LangGraph。

直接自己写。

原课程本身也是这样安排的:一路从01_llm.py演进到14_context_compression.py,最终再去理解完整 Agent Harness。

先把 State 从 messages 中独立出来:

from dataclasses import dataclass, field @dataclass class TaskState: goal: str constraints: list[str] = field(default_factory=list) plan: list[str] = field(default_factory=list) completed: list[str] = field(default_factory=list) pending: list[str] = field(default_factory=list) decisions: list[str] = field(default_factory=list) evidence_refs: list[str] = field(default_factory=list) approval_state: str = "not_required" verification_state: str = "not_started"

这段代码并不复杂。

但它做了一件特别重要的事情:

以前 Agent 想知道自己做到哪里,

只能回头翻聊天记录。

现在:

Runtime 自己知道。

接下来生成 Checkpoint:

def build_checkpoint(state: TaskState): return { "goal": state.goal, "constraints": list(state.constraints), "plan": list(state.plan), "completed": list(state.completed), "pending": list(state.pending), "decisions": list(state.decisions), "evidence_refs": list(state.evidence_refs), "approval_state": state.approval_state, "verification_state": state.verification_state, }

然后才轮到 LLM。

而且它只负责压缩真正非结构化的旧历史:

def compress_history(llm, old_messages): prompt = """ Compress the old execution history. Preserve: - important conclusions - unresolved issues - reasons behind key decisions - failed approaches that should not be repeated Do not invent facts. Do not replace structured task state. """ return llm(prompt, old_messages)

这时候系统的逻辑已经完全变了。

不是:

“让 LLM 帮我记住整个世界。”

而是:

“Runtime 保存确定状态,LLM 只帮我压缩难以结构化的语义。”


旧历史是不是全部压掉?

也不是。

这里还有一个很容易忽略的细节:

Recent Turns 通常应该暂时保留原文。

例如刚刚发生:

Agent:

Supplier C 一箱 24 件,对吗?

用户:

不是,最新版改成 30 件。

Agent:

收到,我重新计算。

这三句刚刚发生。

它们具有非常强的局部相关性。

如果马上压成:

“Packaging Basis 已更新。”

大意虽然对,

但原始纠正关系已经弱了一层。

因此比较成熟的 Context 通常会保留:

Pinned Context。

Checkpoint。

Compressed Old History。

Recent Turns。

Retrieved Evidence。

比如可以简单切:

def split_history(messages, recent_count=8): if len(messages) <= recent_count: return [], messages return messages[:-recent_count], messages[-recent_count:]

旧的压。

新的暂时不压。

这就非常接近人类工作记忆的方式。


然后最核心的函数,不再是messages.append()

而是:

build_context()

例如:

def build_context( system_prompt, checkpoint, compressed_history, recent_messages, retrieved_evidence, ): context = [] context.append({ "role": "system", "content": system_prompt, }) context.append({ "role": "system", "content": f"CURRENT TASK STATE:\n{checkpoint}", }) context.append({ "role": "system", "content": f"OLD HISTORY SUMMARY:\n{compressed_history}", }) context.extend(retrieved_evidence) context.extend(recent_messages) return context

这里是第十四课真正值得记住的代码变化。

前十三课你可能一直在:

messages.append(...)

到了第十四课,真正应该开始思考的是:

这一轮到底怎样 Build Context。

Agent 的历史第一次和 Agent 的当前 Context 正式分家。


但这还不够:Compression 本身也要 Verification

这一点非常容易被忽略。

大家对 Compressor 有一种莫名其妙的信任:

“它只是总结而已,能有什么问题?”

当然会有问题。

它也是模型。

模型就可能:

漏掉。

误解。

改写。

把不确定写成确定。

把 0.48 写成 0.84。

把 Pending 写成 Completed。

把“不能执行”压成“暂未执行”。

所以我们前面学过的 Verification,在这里又回来了。

假设压缩前系统知道:

Goal。

Constraint。

Pending。

Approval State。

压缩以后应该检查:

这些关键语义还在不在。

最朴素的版本甚至可以这样:

def verify_checkpoint(before, after): assert before["goal"] == after["goal"] assert set(before["constraints"]).issubset( set(after["constraints"]) ) assert set(before["pending"]).issubset( set(after["pending"]) ) assert ( before["approval_state"] == after["approval_state"] )

真实系统当然会比这个复杂。

但真正重要的是这个思想:

Compressor 不是天然可信模块。

它也应该接受检查。

这就是为什么前面的课不是一节一节孤立存在。

Planning。

Verification。

Memory。

Skill。

Learning。

Governance。

到了长期 Agent 以后,它们开始互相咬合。


再往深一点:Context Compression 其实很像“编译”

这个比喻特别好用。

假设 Agent 原始历史是:

打开 Excel。

读取 Sheet1。

D 列解析失败。

发现是百分号格式。

标准化。

重新计算。

结果异常。

检查公式。

重新运行。

Verification Passed。

这是一串非常低层的执行 Trace。

未来 Agent 真正需要知道的可能只是:

Supplier A 已完成 GM 计算。

GM = 31.4%。

原始百分比字段已标准化。

Verification Passed。

Evidence = calculation_run_17。

也就是说:

几十个低层事件,

被“编译”成一个高层状态。

这就是优秀 Compression 真正做的事情。

不是单纯:

短一点。

而是:

表达层级更高。

原始操作留在底层。

当前决策只看抽象后的结果。

需要检查时,再下钻到 Evidence。

这和成熟软件系统的思想其实非常接近。


信息其实应该有自己的生命周期

一份数据进入 Agent 后,不应该永远以同一种形态存在。

比如一份 80 页 PDF。

刚开始处理时:

可能需要全文。

接着找到相关章节以后:

只需要几个关键段落。

结构化提取以后:

只需要字段。

形成结论以后:

只需要 Summary。

再往后:

甚至 Context 里面只需要一个 Evidence Reference。

于是它可能经历:

Raw → Relevant Extract → Structured Fact → Summary → Reference Only。

Context Lifecycle

Raw→Relevant Extract→Structured Fact→Summary→Reference Only

需要核查时,再 Retrieve 原始 Evidence。

后来如果需要核查:

再 Retrieve 原始 Evidence。

这就是 Context Lifecycle。

一旦开始这样理解 Agent,

你就不会再问:

“这份文件要不要一直留在 Prompt?”

你会问:

它现在处于哪个生命周期阶段?

这个问题高级得多。


Compression 应该什么时候发生?

最简单的方法是:

Token 快满了再压。

例如:

used_tokens > budget * 0.75

第一版完全可以这么写。

但生产系统最好不要只看 Token。

因为还有一种非常自然的 Compression 时机:

任务阶段结束。

比如:

20 份文件全部提取完成。

一个 Subagent 已经返回。

某一个 Plan 阶段完成。

一次 Verification 通过。

系统准备等待人工审批。

当前任务准备暂停。

这些时刻天然形成一个语义完整的边界。

在这里创建 Checkpoint,比做到半截突然因为 Token 不够而硬压,通常可靠得多。

所以真正好的 Compression Trigger 往往有两种:

一种是:

Resource Boundary

Context 快超预算了。

另一种是:

Semantic Boundary

一个完整工作阶段刚刚结束。

RESOURCE BOUNDARY

Context 快超预算了

典型触发:Token 使用接近预算上限。

SEMANTIC BOUNDARY

一个完整工作阶段刚刚结束

例如提取完成、Subagent 返回、Verification 通过或准备等待审批。

两种一起用,才像真正的 Runtime。


这时候,你会发现 Compression 和 Retrieval 根本分不开

如果一段历史离开 Context,

下一句话一定应该问:

“那以后需要的时候怎么找回来?”

如果回答是:

“找不回来了。”

那不叫 Compression。

那只是删除。

成熟系统会把信息从:

Always Visible

变成:

Available When Needed

原始文件可以进 Artifact Store。

Tool Result 可以进 Session Store。

结构化状态进 Task State。

审批信息进 Audit / Governance State。

长期事实以后可能进入 Memory。

可复用做法经过 Learning Loop 后可能进入 Skill。

然后当前 Context 只拿真正相关的一小部分。

所以:

Compression 回答:

什么应该暂时离开 Context?

Retrieval 回答:

什么现在应该重新回来?

Compression回答:什么应该暂时离开 Context?

Retrieval回答:什么现在应该重新回来?

只有这两件事同时存在,才叫 Context Management。


现在重新跑一次完整采购案例

用户要求:

分析 20 家报价。

统一币种、单位、MOQ、贸易条款、运费、税费、Packaging Basis。

数据不完整之前不能最终推荐。

Agent 开始读取。

Supplier 1。

Supplier 2。

Supplier 3。

……

做到第 12 家。

已经产生大量 Tool Calls。

这时候做一次 Checkpoint:

Goal:

比较 20 家供应商并形成采购建议。

Constraint:

数据完整前不能最终推荐。

Completed:

12 / 20。

Normalization:

USD / piece。

Excluded:

Supplier H,因为 MOQ 不满足。

Pending:

Supplier C Freight Missing。

Evidence:

supplier_table_v2,以及 12 份原始报价引用。

然后:

前面那些打开文件、解析字段、修复格式、重新读取的过程,

可以退出 Active Context。

Agent继续处理 13 到 20。

第二个阶段结束。

再次 Checkpoint:

Completed:

20 / 20。

Pending:

Supplier C Freight。

Current Best Candidate:

Supplier B。

Final Recommendation:

Not Allowed Yet。

最后一句特别重要。

因为它不是“信息”。

它是:

当前行动边界。

Supplier C 数据回来。

系统 Retrieve Supplier C Record。

更新 Freight。

重新计算。

Supplier B 最优。

Verification 通过。

然后进入上一课 Governance。

订单金额超过阈值。

需要采购负责人审批。

Agent 停下来。

人批准。

执行。

再 Verification ERP 状态。

完成。

整个任务可能经历 200 次 Tool Call。

但最后一轮模型根本没有必要重新看那 200 次过程。

它只需要看到:

Goal。

Constraint。

当前 State。

最终计算结果。

关键 Evidence。

Approval State。

这就是一个真正可以长期工作的 Agent。


现在我们终于能回答:Context Compression 到底解决了什么?

表面上:

它解决 Token。

实际上:

它解决的是长期 Agent 的连续性。

如果 Agent 的全部“自我”都存在聊天记录里面,

那每运行一轮,

过去就越来越重。

而当我们把:

State 独立出来。

Evidence 独立出来。

Memory 独立出来。

Skill 独立出来。

Audit 独立出来。

Conversation History 可以 Compression。

Context 每一轮重新 Build。

Agent 才终于从:

一直拖着整个过去往前走

变成:

保存过去,但只携带现在需要的部分。

这已经是两个完全不同的系统。


更深的一层:Context Compression 其实是 Persistence 的前置条件

假设 Agent 今天运行了两小时。

已经完成:

数据收集。

清洗。

分析。

现在等待采购负责人批准。

你关掉程序。

第二天再打开。

如果系统只能保存 Conversation History,

恢复任务意味着:

重新塞入昨天两小时的聊天。

很笨。

真正成熟的系统应该:

Load Checkpoint。

恢复 Goal。

恢复 Plan。

恢复 Completed / Pending。

恢复 Decision。

恢复 Approval State。

重新 Retrieve 当前需要的 Evidence。

Build 一个新的 Context。

继续执行。

这时候 Agent 才真正拥有:

Resume。

而 Resume 一旦成立,

后台任务。

跨 Session。

Scheduler。

长时间运行。

甚至跨天 Agent,

才真正有了基础。

所以 Context Compression 并不是一个 Prompt 小技巧。

它实际上已经开始进入:

Agent Runtime Design。


最后再说一个特别容易混淆的问题:Compression 不是 Memory

比如这次任务里:

Supplier B 当前报价最低。

这是当前 Task State。

一个月以后价格变了。

如果你因为这句话出现在 Compression Summary 里面,就写进长期 Memory:

“Supplier B 是最便宜供应商。”

那未来一定出问题。

再比如:

“比较供应商报价之前,需要统一 Packaging Basis。”

这更接近 Skill。

而:

“Supplier C 当前 Freight 是 0.48”

只是这一次任务的事实。

所以永远不要把:

Compression Summary、

Memory、

Skill

看成同一个东西。

它们解决的是三个不同时间尺度的问题。

Compression:

当前任务继续跑,哪些历史可以变薄。

Memory:

未来任务可能重新需要哪些过去信息。

Skill:

以后遇到这类任务,应该怎样做得更好。

把时间尺度想清楚,很多 Agent 架构自然就不会乱。


如果这一课你真正学懂,脑子里应该发生一个变化

以前看到 Agent,你可能想:

“它有一个很长的 Messages 数组。”

以后应该变成:

系统拥有一个很大的真实状态世界。

里面有:

State。

Memory。

Skills。

Evidence。

Artifacts。

History。

Governance。

Audit。

Environment。

但每一轮 LLM Call 前,Runtime 都会问一句:

“为了现在这个决定,我到底应该让模型看到什么?”

然后才构造 Context。

这就是 Context Engineering 从:

“Prompt 怎么写”

真正走向:

“Runtime 怎么设计”。


第十四课真正值得带走的,不是“总结历史”

我会把这一课最后压成三个判断。

第一个:

Context 不是历史。

历史可以非常长。

Context 只是现在的工作视图。

第二个:

Compression 不是删除。

信息可以离开 Context,但重要状态和 Evidence 必须仍然存在,而且能找回来。

第三个:

长期 Agent 的核心能力不是永远记住,而是知道什么现在必须记住,什么可以暂时忘掉,以及什么时候重新想起来。

最早的 Agent 是这样工作的:

发生什么,

append。

再发生什么,

再 append。

一直把整个过去背在身上。

而真正成熟的 Agent 会逐渐变成:

真实世界不断产生事件。

Runtime 更新 State。

Evidence 被保存。

旧历史被压缩。

当前相关信息被 Retrieve。

Context 被重新构造。

LLM 做下一步决定。

再进入下一轮。

长期 Agent 的运行闭环

真实世界不断产生事件 → Runtime 更新 State → Evidence 被保存 → 旧历史被压缩 → 当前相关信息被 Retrieve → Context 被重新构造 → LLM 做下一步决定 → 再进入下一轮

所以第十四课表面上讲的是:

Context Compression。

但它真正教的是另一件更重要的事情:

一个 Agent 只有学会“正确地忘记”,才有资格开始长期工作。

因为智能从来不只是:

记得越多越好。

真正的智能,是到了这一刻,

你仍然知道:

什么最重要。

http://www.jsqmd.com/news/1401116/

相关文章:

  • cheetah python:别让模板引擎拖后腿,快得像在飙车
  • 30 分钟告别风扇噪音:Windows 风扇控制开源软件 FanControl 上手实战
  • 鸿蒙系统禁用全局搜索与服务中心:ADB命令安全操作指南
  • Windows 11 LTSC 安装微软商店实战指南:一个免费脚本,几分钟补齐缺失的应用生态
  • 第8讲:分布式锁与选主——分布式协调服务
  • ACG和防火墙透明模式端口联动配置
  • Grok 4.6 1.5万亿参数升级:SFT与RLHF技术栈深度解析与实践指南
  • 珠海专业配电柜回收公司推荐:五星回收公司认准资质与技术三强对比 - 广东再生资源回收
  • 2026年华北地区大型连锁餐饮GEO优化靠谱服务商推荐:聚焦本地生活AI场景适配,附选型避坑指南 - U渠道
  • 伊春除甲醛公司甲醛治理公司剖析:金耀环境除甲醛 - CMA甲醛检测中心
  • AI自主编排IT服务治理:从可观测性到策略即代码的实践指南
  • 2026甄选:深圳水利水电总包资质代办公司的专业实力与高效服务双优之选 - 卓企推荐
  • 基于向量数据库与RAG技术构建AI长期记忆系统:从原理到工程实践
  • Power BI 权限那些事儿:一个例子带你理清全部门道
  • AI如何成为调试伙伴:从日志分析到嵌入式开发的脑力延伸实践
  • 特种合金供应链韧性观察:17-4PH现货格局与价值服务商的进阶之路 - 2027品牌AI展
  • 中山电缆回收哪家靠谱?五星履约三大品牌深度对比 - 广东再生资源回收
  • 肇庆发电机回收哪家好?2026年真实测评**五星拆除推荐 - 广东再生资源回收
  • 微信聊天记录如何永久保存?一个开源小工具WeChatMsg的全套用法
  • 珠海机房拆除回收哪家好?2026年真实测评**五星施工推荐 - 广东再生资源回收
  • 阳泉除甲醛公司甲醛治理公司剖析:金耀环境除甲醛 - CMA甲醛检测中心
  • Redis缓存三大难题:击穿、雪崩、穿透
  • 开会突然被点名却答不上来?这款免费离线语音转文字工具让我告别走神焦虑
  • 深圳思科光模块供应商推荐:5家优质企业深度评测与选型指南(2026) - poly-sz
  • Cesium三维可视化动态特效开发:Geo-Effect-Kit核心功能与实战应用
  • 内存故障全解析:从开机报警到蓝屏崩溃的诊断与修复指南
  • 重组代谢酶实验为什么总不稳定?从Supersomes孵育体系看ADME数据质量控制
  • GhostSplice攻击实战教程:恶意MCP服务器拆分指令窃取SSH密钥溯源、复现与防御
  • 2026年中山发电机回收五星门店品牌推荐:上门服务全域覆盖 - 广东再生资源回收
  • QML入门到精通:声明式UI开发与Qt Quick实战指南