凡人小北

凡人小北

0 关注者

1天前

《How to Fix Your Context》这篇上下文工程指南,建议跟 Manus 六大上下文工程法则一起看,它们分别来自两个方向:一个是跑在工程一线踩过坑的 Agent 系统实践者,一个是站在系统架构角度思考 LLM 工作方式的认知构建者。 我把这两篇文章有一起读了一篇,有种“内功交叉灌顶”的感觉。 作者回顾了长上下文为什么会失败? 1️⃣ 上下文污染:当幻觉或其他错误进入上下文,并被反复引用时。 2️⃣ 上下文干扰:当上下文变得过长,以至于模型过度关注上下文,忽视了训练期间学到的内容。 3️⃣ 上下文混淆:当上下文中的多余信息被模型用来生成低质量的响应时。 4️⃣ 语境冲突:当你在语境中积累了与提示中的其他信息相冲突的新信息和工具时。 回忆下是不是都是自己遇到的问题,作者给了一些解决的思路,有很多跟 manus 惊人的一致。 1️⃣ RAG:有选择地添加相关信息以帮助 LLM 生成更好的响应 统一下认知,信息添加的底层逻辑一定不是查到了,而是查对了。作者强调 RAG 要有选择性的添加,而不是全部贴上;重点是围绕当前任务构建语义增强。 Manus 的做法是干脆放弃查入,把信息挂载在文件系统,留 path + 摘要 + 可调用工具。能明显感觉到 manus 对 token 成本的极致敏感🤭。 我自己的实践中最常见的失败是,RAG 查得很准,但 LLM 输出完全无感,因为 context 本身没告诉它该往这个方向推理。RAG 本质是建模信息在认知链条中的地位,不重要的别查入,重要的也别硬塞,要设计成“知道在哪 + 能够调”。这跟这两篇文章的底层逻辑就高度一致,真正高质量的 RAG,不在检索,在策略。 2️⃣ 工具配置:仅选择相关的工具定义添加到您的上下文中 作者提倡按需加载工具定义,而 Manus 的哲学是工具全集保持不变,用 mask 控制直接把权重干成负数。相比而言 Manus 的做法太巧妙了,可以说是对大模型底层原理应用的最佳实践了。 如果你踩过“工具定义变了导致 cache miss + hallucination 增多”的坑,一定能彻底折服。 但这两种方式解决的问题都高度一致,无非是你是靠 prompt 配置行为,还是靠 logits 控制行为? 我理解只要你希望上下文命中率高、模型行为稳定,就必须构建一个“行为可变但结构不变”的系统。至于选择哪种,重点都在让模型以为它有哪些选择。 3️⃣ 上下文隔离:将上下文隔离在各自专用的线程中 作者讲上下文隔离是为避免多任务混淆。Manus 虽然没有“线程”的抽象,但通过 append-only 的 context + 每轮状 态复述 + 工具调用封装,其实完成了逻辑线程的构建。 失败的上下文不要强行修复,而是重新创建一个上下文分支,把之前的 trace 作为引用历史保存下来。这点在实际开发中很关键 ,很多工程实践中都会出现“污染后还想继续用旧 context”的习惯,反而越补越乱。 我现在更倾向于一旦感知幻觉或目标漂移,就把当前上下文 snapshot 掉,开一个 fresh context thread,哪怕代价是多一次调用,也比把幻觉当真实继续往前错更稳定。 4️⃣ 上下文修剪:从上下文中移除不相关或不需要的信息 很多人以为修剪就是删“旧内容”,其实真正的 pruning,是删除“结构上已经失效的信息”。 他们的“能 offload 的就 offload,不能 offload 的就摘要”。我也一度以为摘要是浪费时间,但后来发现一段带摘要的 context,远比一堆片段更有推理价值。 尤其是在长任务执行中,摘要除了压缩信息,更多的是给大模型构造构造注意力锚点。我现在会把某些任务 summary 放在末尾,一方面压缩 token,另一方面也是引导模型聚焦。 顺带一提,很多人会选择把失败信息也修剪掉,但其实保留失败的 trace 本身也是一种重要策略。Manus 的做法是把失败信息 offload 到外部 trace 文件中(参考6️⃣),再在后续回顾或 summary 阶段引用。这跟人学习有点像,错误是成本最大的训练材料,不应该被直接忘掉。 补充个方法论: 上下文修剪,千万不要认为目的是“省空间”,核心是要让每个 token 都承担“策略密度”。我们最终修建掉的是模型注意力的错位。 5️⃣ 上下文总结:将累积的上下文浓缩成一个简要的总结 作者强调总结是为了更高效的行为生成。Manus 做得更极致,每一轮都复述当前目标 + 状态 + 期望动作,用自然语言重新激活注意力焦点。 我实测过不复述 vs 复述的差别:前者行为漂移率接近 30%,后者几乎稳定在主任务路径上。你能感受到的是 LLM 的注意力其实是个滑动窗口,不持续提醒,很容易跑偏,这一点就跟我们管理一个想法很多的员工一个道理。 说白了,总结不是让模型记住,而是让他去遗忘,终极目的是要做注意力的再分配。 6️⃣ 上下文卸载:将信息存储在 LLM 的上下文之外,通常通过一个存储和管理数据的工具来实现 这一部分我必须单独点个赞,确实简单有力量,很多人不以为然:就把信息放到外面嘛,有什么大不了的? 但真正在 Agent 系统里跑起来你才会发现:Context Offloading 是少数能从认知层面、工程层面、可扩展性层面都闭环的设计策略。 作者在文中提到 Anthropic 的 “think” 工具,他们干的事儿就很朴素:给 Claude 搞了一个专用 scratchpad,让它在正式输出前可以先写一写、想一想。我们过去总觉得 scratchpad 是辅助产出,但 Anthropic 的设计更像是,让 Claude 在回答前自己反刍一下。 Manus 给出的做法本质也是一样的,只不过它没有叫 scratchpad,而是把这套行为模块化写进 agent 文件系统,每一个都是模型在任务过程中产生的“中间态”,不属于主 memory,但又比 response 更结构化。 我们太容易陷入一个错觉,以为上下文是一个扔进去的信息堆,但其实真正有用的信息往往是过程中的状态,而不是最终的答案。但是这些状态恰恰是最不适合塞在主上下文里的,既容易冲淡主任务注意力,又会拖垮 token 成本。 实际上验证下来,给 Agent 留出一块临时记忆区,效果极其稳定,特别是在多步骤长任务里,模型不担不会迷失,反而行为会越来越收敛。 作者说得对,这东西简单到你不相信它有用。也许未来大模型的长记忆系统,真正的突破口不是在上下文窗口扩到多少 M,而是什么该存在主线程里,什么该写在 scratch 区。 简单总结下:从“怎么放信息”到“怎么设计上下文作为系统运行时” 加上最近对 vibe coding 的观察和体验,我现在越来越确信:未来 AI 系统真正的代码,一定是你写给模型的上下文构建逻辑。 这两篇文章,建议放进上下文工程必读清单。搞懂它们,搞 Agent 才算入门。

相关新闻