我的 Agent 跑着跑着就开始胡言乱语、还动不动报上下文超限,最后发现是每一步的工具结果都被原样塞进了上下文、把窗口活活撑爆的深度复盘

我做了个多步 Agent,每步都把工具返回结果追加进上下文再喂给模型,自以为"信息越全决策越好"。可步骤一多它就出问题:跑十几步后开始胡言乱语、忘了最初目标,还动不动报"上下文超出最大长度"直接崩,token 账单也高得离谱。打印完整上下文才惊觉它臃肿不堪——塞满了前面每步原始的工具结果(大坨 JSON、整页文档),滚雪球般撑爆了窗口。深究才懂上下文是 Agent 最稀缺的资源,有三重约束:长度有上限(超了报错)、有成本(每步重发整个上下文计费)、注意力会被稀释(噪声淹没目标导致失焦)。这篇从上下文是稀缺资源讲起,到提炼精华/历史压缩/外部记忆的正解、上下文工程方法,以及那句最戳心的——信息不是越多越好,稀缺资源要主动管理别无节制累积。

我的 Agent 跑着跑着就开始胡言乱语、还动不动报上下文超限,最后发现是每一步的工具结果都被原样塞进了上下文、把窗口活活撑爆的深度复盘

这是一个让我对"上下文是 Agent 的稀缺资源"刻骨铭心的故事。我做了一个多步骤的 AI Agent:它会一步步地调用工具(查数据、读文档、调接口),每一步,我都把工具返回的结果,追加进对话历史(上下文)里,再喂给大模型,让它基于完整的历史,思考下一步。在我朴素的认知里,这天经地义——把所有信息都给模型,它掌握的越全,决策不就越好嘛;我甚至有点得意,觉得"保留完整上下文",是个负责任的设计。

可这个 Agent,在步骤一多之后,就开始出各种问题:第一,它会"胡言乱语"——跑了十几步之后,它仿佛"忘了"最初的目标,开始做一些偏离任务、答非所问的事,甚至重复或自相矛盾。第二,更直接的,是报错:跑着跑着,就抛出"上下文超出最大长度(context length exceeded)"的错误,整个 Agent 直接挂掉。第三,我的 token 账单,高得离谱我一开始以为是模型能力不行、或者 Prompt 没写好。可当我把某一步实际发给模型的完整上下文打印出来一看,才惊觉问题所在:那个上下文,已经臃肿得不成样子了!里面塞满了前面每一步工具返回的、完整的、原始的结果——某次查询返回的一大坨 JSON、某次读文档返回的好几页全文、某次调接口返回的一长串数据……这些原始的、未经处理的工具结果,被我一字不漏地、全部累积在了上下文里;随着步骤增加,上下文就像滚雪球一样,越滚越大,最终把模型那个有限的"上下文窗口",活活撑爆了我这才痛彻地明白:问题的核心,是我错把"上下文"当成了一个"无限的、免费的"信息容器,无节制地往里塞东西;可上下文,其实是 Agent 最稀缺、最宝贵的资源——它有三重约束。第一,有长度上限:模型的上下文窗口是有限的,塞超了,就直接报错(我的"超限"崩溃)。第二,有成本:每一步,都要把整个(越来越长的)上下文,重新发给模型计费,所以上下文越长,每一步都越贵(我的天价账单)。第三,也是最微妙的——会稀释注意力:当上下文里塞满了大量无关的、原始的噪声时,模型真正重要的信息(比如最初的目标),就被淹没了,模型的"注意力"被分散,于是它就开始抓不住重点、忘记目标、胡言乱语(我的"失忆"和"胡说")。我那个自以为"负责任"的"保留完整上下文",实际上,是在用大量的噪声,污染、撑爆这个稀缺的资源——信息给得越多,反而越糟。

故障现场:上下文被原始工具结果撑成了滚雪球

我把这个"上下文撑爆"的现场,用过程摊开给你看:

# ✗ 灾难: 每一步都把"完整的、原始的"工具结果, 塞进上下文

messages = [{"role": "user", "content": goal}]
for step in range(MAX_STEPS):
    response = llm.chat(messages)          # 每步都把"整个 messages"发给模型!
    tool_call = response.tool_call
    result = call_tool(tool_call)          # 工具返回, 可能是一大坨原始数据

    # ✗ 把"完整的原始结果", 一字不漏地追加进上下文
    messages.append({"role": "tool", "content": result})
    #                                          ↑ result 可能是:
    #   - 一大坨 JSON(几千 token)
    #   - 一篇文档的全文(几页)
    #   - 接口返回的一长串列表
    # → 每步都往 messages 里堆这种东西, messages 越来越大!

# 滚雪球的后果:
#   step 1: messages ~ 2k token
#   step 5: messages ~ 15k token
#   step 12: messages ~ 50k token → 超出模型上下文窗口 → 报错崩溃!
#   (即使没崩, 也越来越贵、越来越"失焦")

# 三重恶果:
#   1. 长度超限: 上下文窗口有上限, 堆超了直接报错。
#   2. 成本爆炸: 每步都把"整个"(越来越长的)上下文重新发去计费 → 越来越贵。
#   3. 注意力稀释: 海量无关的原始数据, 淹没了"目标"等关键信息
#      → 模型抓不住重点、忘目标、胡言乱语。

# 根因: 把"上下文"当成无限免费的容器, 无节制地堆原始工具结果。
#   而上下文是"稀缺资源"(有长度上限 + 有成本 + 注意力会被稀释)。
#   → 堆得越多, 越容易撑爆、越贵、模型越"失焦"。

看着那个臃肿不堪的上下文,我才算真正理解了这个"撑爆"的根源。问题的核心,是我错把"上下文",当成了一个"无限的、免费的"信息容器,于是无节制地,把每一步的、完整的、原始的工具结果,全都往里塞。看那个滚雪球的过程就一目了然:第 1 步,上下文还只有 2k token;到第 5 步,因为堆了几次工具结果,涨到了 15k;到第 12 步,涨到了 50k,直接超出了模型的上下文窗口、报错崩溃而这,带来了三重恶果:第一,长度超限——模型的上下文窗口是有上限的,你堆超了,就直接报错(我那个"context length exceeded"崩溃)。第二,成本爆炸——大模型是无状态的,每一步,你都要把整个(越来越长的)上下文,重新发给它计费;所以,上下文越长,每一步就越贵,而且是越往后越贵(我那张天价账单)。第三,也是最微妙、最容易被忽略的——注意力稀释:当上下文里,塞满了大量无关的、原始的噪声时,那些真正重要的信息(比如最初的任务目标),就被淹没在了茫茫的噪声里;模型的"注意力"被严重分散,于是,它就开始抓不住重点、忘记目标、答非所问、胡言乱语(我那个 Agent 跑着跑着就"失忆"和"胡说"的根源)。归根结底,我领悟到一个深刻的道理:上下文,不是一个无限免费的容器,而是 Agent 最稀缺、最宝贵的资源——它有长度上限、有成本、且注意力会被稀释。我那个自以为"负责任"的"保留完整上下文",实际上,是在用大量的、未经处理的噪声,去污染、并撑爆这个稀缺的资源。信息,并不是给模型越多越好;给它一堆未经提炼的原始噪声,反而会让它更糟——这,是和我"信息越全决策越好"的朴素直觉,完全相反的、一个关于 Agent 的反直觉真相。

第一件事:搞懂上下文是 Agent 的稀缺资源

定位到根源,我必须把"上下文为什么是稀缺资源"这件事,彻底想清楚:

上下文(Context)是 Agent 最稀缺的资源, 不是无限免费的容器

# 大模型的上下文, 有三重"硬约束":
# 1. 长度有限(上下文窗口): 模型一次能"看"的 token 是有上限的。
#    - 堆超了 → 直接报错(context length exceeded), Agent 崩溃。
# 2. 有成本: 模型无状态, 每次调用都要把"整个上下文"重新发去处理、计费。
#    - 上下文越长, 每一步越贵; 多步累积下来, 成本指数级上升。
# 3. 注意力会被稀释: 上下文里噪声越多, 关键信息(目标/约束)越容易被淹没。
#    - 模型在长而杂的上下文里, 容易"失焦"、忘记目标、抓不住重点。
#    (即所谓 "lost in the middle"——长上下文中间的信息容易被忽略)

# 所以, 一个反直觉的真相:
#   "把所有信息都塞给模型" ≠ "模型决策更好"。
#   塞一堆未经提炼的原始噪声, 反而会: 撑爆窗口 + 烧钱 + 让模型失焦。
#   → 信息要"精", 不要"多"。给模型"它当前这步真正需要的", 而非"全部历史原文"。

# Agent 多步运行的特殊性:
#   - 它是个"循环", 上下文会随步数"累积增长"。
#   - 如果不加管理, 必然滚雪球, 迟早撑爆/失焦/烧钱。
#   → 所以 Agent 必须"主动管理上下文"(压缩、摘要、取舍), 不能无脑累积。

# 核心: 上下文是稀缺资源(有限+有成本+注意力稀释)。
#   要像管理"内存/预算"一样, 精打细算地管理它——
#   只放"当前需要的精华", 而不是"堆砌所有原始历史"。

想清楚之后,我对"Agent 的上下文",有了一个根本性的、清醒的认识。大模型的上下文,有三重"硬约束":第一,长度有限(上下文窗口)——模型一次能"看"的 token 是有上限的,堆超了就直接报错、Agent 崩溃。第二,有成本——大模型是无状态的,每一次调用,都要把"整个上下文"重新发去处理和计费;所以上下文越长,每一步就越贵,多步累积下来,成本是指数级上升的。第三,注意力会被稀释——上下文里的噪声越多,那些关键信息(目标、约束)就越容易被淹没;模型在又长又杂的上下文里,容易"失焦"、忘记目标、抓不住重点(这就是所谓的 "lost in the middle"——长上下文中间的信息,容易被模型忽略)。由此,我领悟到一个反直觉的真相:"把所有信息都塞给模型",并不等于"模型决策更好";相反,塞一堆未经提炼的原始噪声,反而会同时撑爆窗口、烧钱、并让模型失焦。所以,信息要"精",不要"多"——要给模型的,是"它当前这一步,真正需要的精华",而不是"全部的历史原文"。而 Agent 多步运行,又有它的特殊性:它是一个"循环",上下文会随着步数累积增长;如果不加管理,就必然会滚雪球,迟早撑爆、失焦、或烧穿预算。所以,Agent 必须"主动管理上下文"(压缩、摘要、取舍),而不能无脑地累积归根结底:上下文,是 Agent 最稀缺的资源(有限 + 有成本 + 注意力会被稀释);你必须像管理"内存"或"预算"一样,精打细算地去管理它——只往里放"当前真正需要的精华",而不是"堆砌所有的原始历史"。我那次的崩溃,正是源于我把这个稀缺资源,当成了无限免费的容器——这,是我用一次"撑爆 + 失焦 + 烧钱"的事故,补上的、关于 Agent 工程最重要的一课。

第二件事:正解——压缩、摘要、只留精华,主动管理上下文

搞懂了根因——"原始工具结果无节制累积、撑爆稀缺的上下文"——正解就清晰了:不要把工具的完整原始结果塞进上下文,而要先提炼/摘要出"对完成任务真正有用的精华",只把精华放进去;并主动管理整个上下文(裁剪历史、压缩旧步骤),让它始终控制在一个合理的规模。

# 正解1: 工具结果, 先"提炼精华"再入上下文, 别塞原始全文
result = call_tool(tool_call)        # 原始结果可能很大
# ✗ messages.append({"role":"tool", "content": result})  # 别塞原文!
# ✓ 提炼出"任务相关的精华", 只放精华:
summary = extract_relevant(result, goal)   # 如: 从一大坨JSON里只取需要的几个字段;
                                           #     从全文里只摘和任务相关的几句
messages.append({"role": "tool", "content": summary})   # 上下文只增加一点点

# 提炼的几种方式:
#   - 程序裁剪: 只取需要的字段/行(最省, 适合结构化结果)。
#   - 截断: 太长就截断 + 标注"(已截断)"。
#   - 用 LLM 摘要: 让一个便宜的模型, 把长结果"压缩成要点"。

# 正解2: 主动管理"对话历史", 别让它无限增长
def manage_context(messages):
    # 策略a: 保留"目标 + 最近 N 步", 把更早的步骤"压缩成一段摘要"
    if len(messages) > THRESHOLD:
        old = messages[1:-KEEP_RECENT]               # 较早的历史
        digest = llm_summarize(old)                  # 压缩成一段"中间过程摘要"
        messages = [messages[0],                     # 保留最初的目标
                    {"role":"system","content":"前面步骤摘要: "+digest},
                    *messages[-KEEP_RECENT:]]         # 保留最近几步原文
    return messages

# 正解3: 把"大块数据"放到上下文"之外", 上下文里只留引用
#   - 工具返回的大文档 → 存到外部(文件/向量库/变量), 上下文只放"它的ID/摘要"。
#   - 需要细节时, 再用另一个工具按需去取那一小部分。
#   → 上下文里是"索引/指针", 而非"全部内容"。

# 核心: 工具结果"提炼精华再入上下文"; 历史"压缩/裁剪"别无限涨;
#   大数据"放外部, 上下文只留引用"。让上下文始终"精简且聚焦"。

这套正解,核心就一句话:把上下文,当成稀缺的资源去精打细算地经营——只放精华,主动裁剪。正解1(工具结果提炼精华再入上下文):工具返回的原始结果可能很大,不要把它一字不漏地塞进去;而要先提炼出"对完成任务真正有用的那部分精华",只把精华放进上下文。提炼有几种方式:程序裁剪(从一大坨 JSON 里,只取你需要的那几个字段——最省、适合结构化结果)、截断(太长就截断并标注)、用 LLM 摘要(让一个便宜的模型,把长结果压缩成要点)。正解2(主动管理对话历史):别让对话历史无限增长——一个常用策略是,保留"最初的目标" + "最近的 N 步原文",把更早的那些步骤,压缩成一段"中间过程摘要";这样,上下文里既有目标、又有最近的细节、还有早期的概要,但总长度被控制住了。正解3(大数据放外部,上下文只留引用):对于工具返回的大块数据(如一整篇文档),把它存到上下文之外(文件、向量库、或一个变量里),上下文里,只放它的ID 或摘要;需要细节时,再用另一个工具,按需地去取那一小部分——这样,上下文里装的是"索引/指针",而不是"全部内容"。归根结底:工具结果要"提炼精华再入上下文";历史要"压缩/裁剪",别无限涨;大数据要"放外部,上下文只留引用"。三管齐下,让上下文,始终保持"精简,且聚焦"。我那次的错误,正是把原始结果无脑全塞;而正解,是对每一份要进上下文的信息,都精挑细选

下面这张图,对比了"无脑累积原始结果"和"提炼+管理上下文"两条路径:

这张图的对比很清楚:左边红色那条,原样塞完整的工具结果,上下文随步数滚雪球,最终超长报错、烧钱、注意力被稀释,Agent 崩溃或失焦胡说;右边绿色那条,提炼出任务相关的精华再放、历史定期压缩成摘要、大数据放外部只留引用,上下文始终精简聚焦、稳定运行。两条路的根本分野,在于你有没有把上下文当稀缺资源去主动经营,而不是无脑堆砌。

第三件事:上下文管理的其它手段

填平了"原始结果撑爆"这个坑,我系统梳理了一遍 Agent 上下文管理的完整手段:

Agent 上下文管理的完整手段:

# 1. 工具结果精炼(本文核心): 入上下文前提炼/截断/摘要, 别塞原文。

# 2. 历史压缩(对话摘要): 较早的步骤压缩成摘要, 保留目标 + 最近几步。
#    (很多 Agent 框架有自动的 conversation summarization)

# 3. 外部记忆(memory): 把信息存到上下文之外, 按需取回。
#    - 短期: 把中间产物存变量/文件, 上下文只留引用。
#    - 长期: 存向量库, 需要时检索相关片段进上下文(RAG 式记忆)。

# 4. 滑动窗口: 只保留最近 N 轮, 丢弃过老的(简单, 但会丢早期信息)。

# 5. 结构化状态(scratchpad): 用一个结构化的"状态对象"记录关键进展,
#    而不是靠"翻聊天记录"。每步更新它, 上下文里带"当前状态"即可。

# 6. 子任务/子 Agent: 把大任务拆成子任务, 每个子任务用"独立的、干净的上下文",
#    只把"子任务的结论"返回给主流程 → 避免一个上下文背负全部细节。

# 7. 选择性纳入: 不是每个历史都要带, 只带"和当前步骤相关"的。

# 8. 监控上下文用量: 记录每步的 token 数, 接近上限就告警/触发压缩。

# 选择: 简单任务用"精炼+历史压缩"够了; 复杂/长任务上"外部记忆+子Agent+结构化状态"。

# 核心: 上下文管理, 是 Agent 工程的核心能力之一。
#   目标: 让上下文始终"装着完成当前步骤所需的、最精炼的信息", 不多不少。

这一梳理,让我对 Agent 上下文管理,有了体系化的认识。除了工具结果精炼(本文核心),还有一整套手段:历史压缩(把较早的步骤压缩成摘要,保留目标和最近几步,很多框架有自动的对话摘要);外部记忆(把信息存到上下文之外、按需取回——短期把中间产物存变量/文件、上下文只留引用,长期存向量库、需要时检索相关片段进来,即 RAG 式记忆);滑动窗口(只保留最近 N 轮,简单但会丢早期信息);结构化状态(scratchpad)(用一个结构化的"状态对象",记录关键进展,每步更新它,上下文里带"当前状态"即可,而不是靠翻聊天记录);子任务/子 Agent(把大任务拆成子任务,每个子任务用独立的、干净的上下文,只把"子任务的结论"返回给主流程,避免一个上下文背负全部细节);选择性纳入(只带和当前步骤相关的历史);监控上下文用量(记录每步 token 数,接近上限就告警或触发压缩)。选择上,简单任务用"精炼 + 历史压缩"就够了;复杂、长任务,则要上"外部记忆 + 子 Agent + 结构化状态"。归根结底:上下文管理,是 Agent 工程的核心能力之一;它的目标,是让上下文,始终"装着完成当前这一步所需的、最精炼的信息,不多不少"。一个好的 Agent,不只是会调工具、会循环,更要会聪明地管理自己那有限的"注意力"和"记忆"

第四件事:把上下文当"工作内存"来经营

这次踩坑,让我对"上下文工程(context engineering)"这个概念,有了切身的理解。我把它整理成了一套"经营上下文"的方法:

把上下文当"工作内存"来经营(context engineering)

# 一个好的类比: 上下文 ≈ 模型的"工作内存(working memory)"
#   - 它容量有限(像 CPU 的寄存器/L1 缓存, 很宝贵)。
#   - 你要决定"此刻把什么放进去", 让模型能高效地完成当前这步。
#   - 放对了(精华) → 决策准; 放错了(噪声) → 失焦、浪费、撑爆。

# 经营上下文的几个原则:
# 1. 相关性: 只放"和当前步骤相关"的信息(无关的别占地方)。
# 2. 精炼性: 信息要提炼过, 别放原始冗余(一份摘要 > 十页原文)。
# 3. 结构性: 重要的(目标/约束/当前状态)放在显眼、稳定的位置, 别被淹没。
# 4. 时效性: 过时的、已完成的, 可压缩/移除; 保留最新最相关的。
# 5. 分层: 热数据(常用)放上下文; 冷数据(偶尔用)放外部, 按需取。

# 上下文里应该常驻的"核心"(别被噪声挤掉):
#   - 任务目标(最重要! 防止失焦)
#   - 关键约束/规则
#   - 当前进展/状态(scratchpad)
#   - 最近几步的关键信息
# 上下文里要警惕的"噪声":
#   - 原始的、未提炼的工具大结果
#   - 早就用完、不再需要的中间数据
#   - 重复的、冗余的内容

# 一个心态: 像"给一个人做简报"——你不会把所有原始资料都甩给他,
#   而是提炼出"他此刻做决策需要的关键信息"。对模型也一样。

# 核心: 上下文工程 = 主动决定"在每一步, 把什么精华放进模型的工作内存"。
#   它和 Prompt 工程一样, 是用好 LLM/Agent 的一项核心功夫。

这一思考,让我对"上下文工程(context engineering)"有了切身的理解。一个很好的类比是:上下文,约等于模型的"工作内存(working memory)"——它容量有限(就像 CPU 的寄存器、L1 缓存,非常宝贵);你要决定"此刻该把什么放进去",好让模型能高效地完成当前这一步;放对了(精华),决策就准;放错了(噪声),就会失焦、浪费、甚至撑爆经营上下文,有几个原则:相关性(只放和当前步骤相关的,无关的别占地方)、精炼性(信息要提炼过,一份摘要胜过十页原文)、结构性(重要的——目标、约束、当前状态——放在显眼、稳定的位置,别被淹没)、时效性(过时的、已完成的可压缩/移除,保留最新最相关的)、分层(热数据放上下文,冷数据放外部、按需取)。具体来说,上下文里应该常驻的"核心"(别被噪声挤掉)是:任务目标(最重要,防失焦!)、关键约束/规则、当前进展/状态、最近几步的关键信息;而要警惕的"噪声"是:原始的、未提炼的工具大结果,早就用完、不再需要的中间数据,以及重复冗余的内容我特别喜欢一个心态:经营上下文,就像"给一个人做简报"——你不会把所有的原始资料,一股脑全甩给他;而是会提炼出"他此刻做决策,真正需要的那些关键信息"。对模型,也是完全一样的。归根结底:上下文工程,就是主动地决定"在每一步,把什么精华,放进模型的工作内存";它和 Prompt 工程一样,是这个时代,用好 LLM 和 Agent 的一项核心功夫把"堆砌上下文"和"经营上下文"对比成一张表:

维度 堆砌上下文(踩坑) 经营上下文(成熟)
放什么 所有原始历史全塞 只放当前需要的精华
工具结果 原文一字不漏 提炼/摘要后再放
对目标 被噪声淹没 常驻显眼位置
大数据 全塞进上下文 放外部,只留引用
类比 甩给人全部原始资料 给人提炼好的简报

第五件事:稀缺资源要主动管理,别无节制累积

这次踩坑,在认知层面给了我最大的纠偏——它让我重拾了"管理稀缺资源"这个根本的工程意识。我把这层反思,沉淀了下来:

认知纠偏: 凡是"稀缺资源", 都要主动管理, 不能无节制累积

# 我的误解(错误的):
#   我把上下文当"无限免费"的, 无节制地往里堆——还自以为"信息越全越好"。
#   → 我没意识到它是"稀缺资源", 也就没想过要"管理"它。

# 真相: 上下文是稀缺资源, 而"稀缺资源无节制累积", 必然出事
#   - 这其实是个老道理: 内存、连接、文件句柄、线程、磁盘、预算……
#     凡是"有限的资源", 你只申请不释放/只累积不清理, 迟早耗尽。
#   - 上下文也一样: 只往里加、不提炼不清理 → 撑爆。
#   - 我对"传统资源"有管理意识(会关连接、会释放内存),
#     却对"上下文"这个新资源, 丢掉了这份意识。

# 普遍原则: 对一切"有限/稀缺"的资源, 都要"有借有还、精打细算"
#   - 内存: 申请了要释放(别泄漏)。
#   - 连接/句柄: 用完要关。
#   - 上下文: 加进去的要提炼, 过时的要清理。
#   - 注意力/认知: 人也一样——别让无关信息淹没了重点。
#   → 资源管理的本质: 在"有限"的约束下, 把资源用在"最有价值"的地方。

# 而且"加进去的东西", 不只占空间, 还有"副作用"(噪声稀释注意力):
#   - 所以不是"用完释放"那么简单, 还要"控制加进去的质量"——只加精华。

核心: 上下文是稀缺资源。凡稀缺资源, 都要主动管理、精打细算,
  别无节制累积。把"管理传统资源"的工程意识, 用到上下文这个新资源上。

这层反思,是这次踩坑给我最高维度的收获。复盘我的误解,根源是:我把上下文,当成了"无限免费"的,无节制地往里堆,还自以为"信息越全越好";我根本没意识到它是一个"稀缺资源",也就从没想过要去"管理"它。可真相是:上下文是稀缺资源,而"稀缺资源无节制累积",必然出事而这,其实是一个古老的工程道理:内存、连接、文件句柄、线程、磁盘、预算……凡是"有限的资源",你只申请不释放、只累积不清理,迟早会耗尽。上下文也一样:只往里加、不提炼不清理,就会撑爆。讽刺的是,我对那些"传统资源"是有管理意识的(我会记得关连接、会注意释放内存),却唯独对"上下文"这个新资源,丢掉了这份意识由此,我重拾了一个普遍的原则:对一切"有限/稀缺"的资源,都要"有借有还、精打细算"——内存申请了要释放(别泄漏)、连接句柄用完要关、上下文加进去的要提炼/过时的要清理;就连人的注意力和认知也一样,别让无关信息淹没了重点。资源管理的本质,是在"有限"的约束下,把资源,用在"最有价值"的地方而上下文,还有一个比传统资源更微妙的地方:"加进去的东西",不只占空间,还有"副作用"(噪声会稀释模型的注意力);所以,管理它,不只是"用完释放"那么简单,还要控制"加进去的质量"——只加精华归根结底:上下文,是稀缺资源;凡是稀缺资源,都要主动管理、精打细算,别无节制累积。要把"管理传统资源"的那份工程意识,郑重地,用到"上下文"这个 AI 时代的新资源上。我那次的撑爆,正是因为对一个新资源,丢掉了一份本该有的老意识。把"无节制累积"和"主动管理"两种心态对比成一张表:

维度 无节制累积(踩坑) 主动管理(成熟)
对上下文 当无限免费容器 当稀缺资源经营
加信息 原始全塞 只加精华
清理 从不清理 过时的压缩/移除
资源意识 对新资源丢了 老意识用到新资源
结果 撑爆/烧钱/失焦 精简聚焦稳定

一套"工具结果该怎么进上下文"的决策流程

把这次踩坑的全部教训,我浓缩成了一张"Agent 拿到工具结果、该怎么放进上下文"的决策图,贴在了团队做 Agent 的文档里:

这张图,把我"血泪换来"的整套方法论,串成了一条可执行的路径:Agent 拿到工具结果,先看结果大不大——小且全相关的可直接放;大或含大量无关的,再看后续还要不要细节:只要结论/几个字段的就提炼精华/裁剪后放,可能要细节的就把原文放外部、上下文只留摘要+引用。同时,每隔几步检查上下文长度,一旦接近窗口上限,就把早期历史压缩成摘要、保留目标和最近几步这条"入context前先提炼、定期压缩历史"的决策链,现在是我们团队设计每一个 Agent 上下文流转时的准则。

我立下的几条 Agent 上下文管理规矩

这次"上下文撑爆"的踩坑,让我把 Agent 上下文管理的注意事项,认真地立成了几条规矩:

  1. 工具结果别原样塞上下文。先提炼/裁剪/摘要出任务相关的精华,再放;大结果尤其要处理。
  2. 主动管理对话历史。早期步骤压缩成摘要,保留目标 + 最近几步,别让上下文无限滚雪球。
  3. 大数据放外部,上下文只留引用。文件/向量库存原文,上下文放 ID/摘要,按需取细节。
  4. 目标等核心信息要常驻。放显眼稳定的位置,别被噪声淹没导致失焦。
  5. 监控上下文用量。记录每步 token,接近上限就告警/触发压缩,别等崩了才知道。
  6. 复杂任务用子 Agent/结构化状态。子任务用独立干净上下文,只回传结论;用状态对象记进展。
  7. 把上下文当稀缺资源经营。有限+有成本+注意力会稀释;只放精华,别无节制累积。

写在最后

这次"我的 Agent 跑着跑着就胡言乱语、还报上下文超限、最后发现是工具结果撑爆了窗口"的经历,是我在 AI Agent 开发路上,一次很典型、也很受用的成长。它教给我的,远不止"工具结果要精炼"这一条具体的技术经验,更是一个关于 Agent 工程的核心认知——上下文,是 Agent 最稀缺的资源,要像管理内存和预算一样,精打细算地经营它。我那个 Agent 的失焦与崩溃,根源就在于,我抱着"信息越全越好"的朴素直觉,把上下文当成了无限免费的容器,无节制地往里堆原始数据;却忘了,它有长度的硬上限、有真金白银的成本、更有"噪声会稀释注意力"的微妙陷阱。

所以,当你构建一个 Agent、或任何需要管理上下文的 LLM 应用时,请别再以为"把所有信息都给模型就最好"——而要把上下文,当成模型那宝贵而有限的"工作内存",郑重地去经营:在每一步,都主动地决定,该把哪些"精华"放进去、该把哪些"噪声"挡在外面、该把哪些"陈旧"压缩清理。就像那个 Agent,你只要养成"工具结果提炼后再入上下文、历史定期压缩"的习惯,就绝不会再让它,被自己产生的海量原始数据,活活撑爆、淹没。从"无节制堆砌上下文"到"精打细算经营上下文",从"信息越多越好"的直觉到"信息要精不要多"的清醒,是从一个"会让 Agent 跑起来"的开发,走向一个"能让 Agent 稳定、高效、可控运行"的工程师,必经的修炼。愿你的 Agent,都有一份清爽而聚焦的"工作内存";也愿你我,把管理稀缺资源的那份工程智慧,用到 AI 时代每一个新的稀缺资源上。共勉。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

我遍历一个数字枚举想拿到所有选项,结果拿到了双倍的条目、数字和名字混在一起,我盯着这串诡异的结果查了半天才搞懂枚举反向映射的深度复盘

2026-6-1 23:40:39

技术教程

我在 for 循环里一边遍历列表一边删元素,结果有些该删的没删掉、还漏处理了一些,我盯着这个忽好忽坏的结果排查了大半天的深度复盘

2026-6-1 23:54:22

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索