Karpathy 预警:ReAct 上下文膨胀,Plan-and-Act 解法
Karpathy warned about this months ago:
做 Agent 的同学必看,这篇把 ReAct 上下文膨胀的坑和 Plan-and-Act 的拆法讲透了,还给了 WebArena 上的量化对比,赶紧对照你的长任务链路试试重新规划。
Karpathy warned about this months ago:
Karpathy 几个月前就警告过这一点:
"If agents had less knowledge or less memory, maybe they would be better."
"如果智能体拥有更少的知识或更少的记忆,也许它们会表现得更好。"
His point was that everything already inside the model's input competes with the task for attention.
他的观点是,模型输入中已有的所有内容都会与任务竞争注意力。
A standard ReAct loop is built that way, since everything that goes into the prompt is never removed from it.
标准的 ReAct 循环就是这样构建的,因为进入提示的所有内容都不会从中移除。
For more context, the ReAct pattern runs one model in a single loop.
为了提供更多背景,ReAct 模式在单个循环中运行一个模型。
The model generates a thought about what to do next, takes one action, reads the observation that comes back, appends all three to the same prompt, and repeats until it decides the task is over.
模型生成关于下一步做什么的思考,采取一个行动,读取返回的观察结果,将这三者附加到同一个提示中,并重复直到它决定任务完成。
So a failed search from step three is still retained and accessible at subsequent steps, competing with the original objective for the model’s attention.
因此,第三步中失败的搜索仍然保留并在后续步骤中可访问,与原始目标竞争模型的注意力。
Plan-and-Act is one answer to that, and it is aimed at agents that run long enough that context management becomes an actual engineering problem that cannot be directly solved with prompt-tuning.
Plan-and-Act 是对此的一种解决方案,它针对运行时间足够长、上下文管理成为实际工程问题且无法通过提示调整直接解决的智能体。
It splits the loop into two sub-tasks.
它将循环拆分为两个子任务。
The authors of the Plan-and-Act paper experimented on web navigation, so the observation coming back after every action is the raw HTML of the page the agent is currently on.
Plan-and-Act 论文的作者在网页导航上进行了实验,因此每个行动后返回的观察结果是智能体当前所在页面的原始 HTML。
A planner reads the user query and the initial page and writes high-level steps.
规划器读取用户查询和初始页面,并编写高级步骤。
An executor reads the plan, the task, its own past actions, and the current HTML, then emits one grounded action.
执行器读取计划、任务、自身过去的行动和当前 HTML,然后发出一个基于环境的行动。
After each action, the executor strips the HTML it no longer needs before taking the next one, so the execution context does not grow the way a ReAct trace does.
在每个行动之后,执行器在采取下一个行动之前剥离不再需要的 HTML,因此执行上下文不会像 ReAct 轨迹那样增长。
Whether this is helpful is determined by plan granularity.
这是否有帮助取决于计划的粒度。
A good step covers one unit of work, like searching for the product in the search box.
一个好的步骤涵盖一个工作单元,例如在搜索框中搜索产品。
An individual click is too small to be a step, and “analyze the search results” is not a step at all, because it pushes the reasoning back onto the executor.
单个点击太小,不能作为一个步骤,而“分析搜索结果”根本不是步骤,因为它将推理推回给执行器。
A step must also name the actual values it needs.
一个步骤还必须指定它需要的实际值。
The paper’s planner instructions ask for “input New York as the arrival city” instead of “input the arrival city”, because the second version leaves the executor to guess which city goes in the box.
论文中的规划器指令要求“输入纽约作为到达城市”,而不是“输入到达城市”,因为第二个版本让执行器猜测在框中输入哪个城市。
The executor’s job is picking the right element and typing into it, not filling in the blanks the planner left open.
执行器的工作是选择正确的元素并输入,而不是填补规划器留下的空白。
They also found that a badly trained planner makes things worse than no planner at all.
他们还发现,训练不佳的规划器比没有规划器更糟糕。
On WebArena-Lite, a ReAct-style executor with no planner scored 36.97%.
在 WebArena-Lite 上,没有规划器的 ReAct 风格执行器得分 36.97%。
But the same executor with a naively finetuned planner scored just 20.60%.
但同一个执行器使用朴素微调的规划器仅得分 20.60%。
The planner had never seen those sites, so it wrote steps that read fine but matched nothing on the page, and the executor followed them anyway.
规划器从未见过那些网站,因此它写出的步骤读起来没问题,但与页面上的内容完全不匹配,而执行器仍然照做了。
A properly trained planner reached 43.63%.
经过适当训练的规划器达到了43.63%的准确率。
A plan written once and never revised has its own problem. For instance, if the search for “library at CMU” gives no results, the executor will still hold a step that cannot work anymore, and it will keep trying it anyway.
一次性编写且从不修改的计划也有其问题。例如,如果搜索“CMU图书馆”没有结果,执行器仍然会保留一个无法再执行的步骤,并继续尝试它。
Replanning after every action is necessary to recover from that.
每次行动后重新规划对于从这种情况中恢复是必要的。
For instance, in the paper, the planner saw the current state, the previous plans, and the actions taken, and rewrote the step to “libraries near CMU”, which increased the score to 53.94%.
例如,在论文中,规划器看到了当前状态、之前的计划和已采取的行动,并将步骤改写为“CMU附近的图书馆”,这使分数提高到53.94%。
As a result, the failed attempt got replaced in the plan rather than accumulated in the context.
结果,失败的尝试被计划中的新步骤取代,而不是在上下文中累积。
The cost is one planner call per executor step. The authors flag this directly and suggest letting the executor decide when a replan is required.
代价是每个执行器步骤需要一次规划器调用。作者直接指出了这一点,并建议让执行器决定何时需要重新规划。
Here's the paper → https://arxiv.org/pdf/2503.09572
论文链接 → https://arxiv.org/pdf/2503.09572
Under the hood, this is all part of the harness design rather than model choice.
在底层,这完全是框架设计的一部分,而不是模型选择的问题。
If you want to see this in practice, my co-founder rebuilt Claude Code's harness in CrewAI layer by layer, adding planning, delegation, sandboxing, and memory one layer at a time.
如果你想看到实际应用,我的联合创始人用CrewAI逐层重建了Claude Code的框架,一层一层地添加了规划、委派、沙箱和记忆功能。
Read it below.
在下面阅读。
更进一步:量化金融体系
看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力