上下文工程:懂得何时重新开始

原文:https://every.to/also-true-for-humans/why-i-start-a-new-thread-in-claude-every-time


和我共事的人都知道,我会把 Claude 的记忆功能关掉。ChatGPT 也一样。我之前写过为什么这么做:记忆可能有用,但它也可能把旧偏好和无关指令带进一场对话,而这些东西本不该出现在那里。

关掉记忆并不能彻底解决问题。即便在同一个对话线程里,上下文也会以让模型回答变差的方式累积——这个问题被称为上下文腐化(context rot)。模型可能继续遵循你早已不再需要的指令,在早先的错误上继续搭建,或者忽略埋在对话里的关键细节。

所以,我每做一项任务都会新开一个线程。如果任务变了,我就打开一个新对话——哪怕它还是我五分钟前在做的同一个项目。

在我即将由 O'Reilly 出版的书《Context Engineering with DSPy》中,我探讨了上下文出错的七种方式,以及该如何应对。这本书写给构建 AI 产品的工程师,但下面这些改编过的例子——灵感来自 Drew Breunig 的《How Long Contexts Fail》——适用于任何使用 AI 聊天的人。它们会帮你识别一段对话何时已经偏离方向,并在不丢失有用工作成果的情况下重新开始。

1. 上下文分心(context distraction):旧模式约束新答案

AI 模型被训练得非常严格地遵循提示词中的指令,这通常正是你想要的——但只到某个程度。遵从与创造力之间存在权衡:你提供的上下文越多,回答就越会被限制在对话中已有的内容里。你希望 AI 遵循你的指令,但也希望它在遵守规则会带来更差结果时,能做出良好判断。

我在 AI 培训工作坊里用来演示这个问题的一个例子,是让 ChatGPT 像 Steve Jobs 那样给一款新产品命名。仅靠指令时,它给出的名字里有 21% 以“i-”开头(iPod、iPad、iPhone)。一旦我在提示词里加入几个以“i-”开头的示例名字,ChatGPT 给我的名字就有 100% 以这种方式开头。如果你要的就是僵化遵从,这很好;但模型也不再提出任何我喜欢、却不符合这个模式的名字。

在长线程里,你早先做过的所有事情都会变成模型今后遵循的示例,不管这是不是你的本意。它把你说的每件事都当成金科玉律,这会以你可能注意不到的微妙方式限制它的创造力——除非你新开一个不带旧上下文的线程。模型很难做出这样的判断:对话已经转向,旧指令不再适用。这个判断必须由你来做。

留意: 你要求换个方向,但每个建议仍然遵循你早先给出的示例模式。

该怎么做: 每当语气或任务类型发生变化时,就新开一个线程。当你确实希望 AI 遵循示例时,要有意添加它们,并测试你实际需要多少个示例,才能在你设定的约束内让模型保持创造力。

2. 上下文混淆(context confusion):无关细节带偏回答

AI 模型并不擅长忽略与任务无关的信息。如果它出现在提示词里,即使与你所问的内容无关,模型也会假定它出现在那里必有原因,并试图在回答中使用它。

我的同事 Katie Parrott 为此付出了代价:她的写作风格指南指令从 759 个词增长到 3,855 个词,写出来的东西变得糟糕到难以辨认。模型把每一行都当成一项要求,并试图一次性满足所有要求,于是每轮反馈后的草稿都更差——一篇文章改了 127 稿,超过 100 万词。解决办法是删掉指令:重建后的风格指南只有 513 个词。

为了准备 Microsoft Build 的一次采访,我采访了一个 AI 版的 GitHub COO Kyle Daigle。这个 AI 版本是用开源库 SynthTeam 的修改版,基于他的公开文章、演讲和采访构建的。它用 must/should/could 优先级框架回答了我 12 个问题中的 5 个。Daigle 曾在他的网站上写过这个框架,所以虚拟版本过度倚重它,尽管它与我当时问的问题并不相关。当我与真正的 Daigle 交谈时,他一次也没提到这个框架。

留意: 模型反复提起一个与你当前问题关系不大的事实、偏好或框架。

该怎么做: 保持记忆关闭,这样无关上下文就不会泄漏到当前对话中。把自定义指令保持在最低限度,因为它们会以你无法预料的方式影响你进行的每一次对话。一句随口评论可能影响你各个聊天中的回答,而且你可能很难把问题追溯到它的源头。

3. 上下文忽视(context neglect):中间细节被忽略

斯坦福大学的研究人员发现,AI 模型最关注上下文的开头和结尾,而当它需要的信息位于中间时,表现会显著下降。人类也表现出类似模式:我们倾向于记住并更重视最先或最后遇到的信息,这分别被称为首因效应和近因效应。

在书里,我做过一个实验:给模型九份关于某个项目的文档,其中一份关键 bug 报告位于第六位,然后问它项目的主要风险是什么。模型根据开头的概览和结尾的发布计划作答,完全忽略了那份 bug 报告。当你上传一堆 PDF,或粘贴一份很长的会议记录并就此提问时,也会发生同样的事:答案会偏向最先和最后出现的内容,而线程越长,中间那块就越大。

图表说明:当答案位于 20 份文档中的第一份或最后一份时,GPT-3.5 的准确率最高;当答案位于中间时,它的表现甚至比完全不提供文档时还差(虚线)。(来源:Nelson F. Liu 等,《Lost in the Middle: How Language Models Use Long Contexts》。)

留意: 答案跳过了文档中间的关键细节,同时又准确地引用了其他内容。

该怎么做: 只上传任务需要的文档;如果你对不同文档有好几个问题,就把它们放在不同线程里问。提示词工程师长期以来都会把重要的任务信息放在提示词顶部,把格式指令放在底部;你在自己的消息里也值得这样做。

4. 上下文漂移(context drift):最初目标滑出焦点

随着新信息堆积,模型可能跟丢你的最初目标。它的回答仍然连贯,但会不再遵循你最初的一组指令。也许你在和 Claude 或 ChatGPT 长时间对话后经历过这种情况——它开始引入新角度、关注错误的东西,或者在你最初目标尚未完成时说“让我们退一步”或“让我们收尾”。

在书里,我展示了一个编码助手的例子:对话开始时它被告知“严格遵循 PEP-8”(一份 Python 风格指南),50 条消息之后,它写出的代码完全无视了这份指南。你可能见过日常版本:你在一个线程开头告诉 AI 使用英式拼写,或把回答控制在 200 词以内;一小时后,它又退回了默认设置。

留意: AI 开始忽略你早先告诉它的某件事,比如拼写规范或字数限制。

该怎么做: 把你始终想要的偏好——比如拼写、语气或长度——保存在一个文档里,并在每个新聊天顶部粘贴进去。为了节省 token 成本,Claude 和 Codex 都会在聊天过长时把它压缩成摘要(token 越多,处理成本越高),但这可能以丢失先前细节和重要指令为代价。

5. 上下文冲突(context clash):早期假设与新信息冲突

微软和 Salesforce 的研究人员把通常一次性给出的提示词拆成几条按步骤发送的消息,也就是我们大多数人实际与 AI 交谈的方式。然而,把任务拆开导致各模型的结果变差了 39%。AI 模型倾向于过早做出假设,在掌握全部信息之前就跳到答案,而这个早期答案会留在线程里,与你接下来告诉模型的内容发生冲突。

当我为客户自动化 PowerPoint 幻灯片时,最初的结果很糟。解决办法是在 AI 开始构建任何东西之前,先给它完整图景。我们先让它根据通话笔记写出一份蓝图和详细议程,之后它很少漏掉幻灯片。

留意: 你澄清了任务简报,但模型继续基于你提供这些信息之前所做的假设来构建内容。

该怎么做: 在开始前写好完整简报,把模型需要的一切放进第一条消息,而不是一点一点喂给它。如果你中途意识到漏掉了重要内容,就用完整简报新开一个线程,这样模型从一开始就没有机会锁定错误答案。

6. 上下文中毒(context poisoning):早期错误污染后续回答

“上下文中毒”这个说法来自 Google 的 Gemini 2.5 技术报告。Gemini 团队让一个 AI 智能体(agent)玩《Pokémon Red》。在一次案例中,它把这款游戏和后来的重制版搞混了,认定自己需要一件叫 TEA 的道具才能通过守卫。但它所玩的版本里并不存在这件道具。Gemini 把这个目标写了下来,并花了 100 多个回合寻找一件它永远找不到的东西。

在聊天中,早先编造的统计数据或记错的事实会再次出现在之后的每一版草稿里,因为模型把自己先前的回答当成已定事实。告诉模型它某处弄错了,也不能消除错误:最初的错误和你对它的抱怨都仍然留在线程里。

留意: 你已经纠正过的事实,在下一版草稿里再次出现,或成为另一个回答的基础。

该怎么做: 当 AI 犯错时,不要在线程里和它争论,也不要让它自我纠正。相反,回去编辑你先前那条消息,让它不记得自己做过任何错事。把提到错误的内容全部移除后,它就不太可能陷入反复犯同一个错误的循环。AI 的工作方式,是扮演它认为你想要的“有帮助的助手”。如果它能在聊天历史里看到错误,模型就会认为自己正在扮演“一个会犯错的 AI”。过去于是成了自我实现的预言。ChatGPT 和 Claude 都允许你编辑已经发送的消息或重新生成回答,两者中的任何一个都比和它争论更好。

7. 上下文规格不足(context underspecification):缺失细节迫使模型猜测

到目前为止的每个原因都是上下文过多的问题,但上下文腐化也可能来自模型得到的上下文太少。如果提示词里缺少重要内容,模型就必须猜测,而它的猜测会是其训练数据的平均值。ChatGPT 的输出是互联网的平均值,所以默认答案往往平淡而无差别。

我以前经营过一家 50 人的营销代理机构(agency),所以我知道基于价值的定价(value-based pricing)对代理机构往往行不通。但当你向 AI 询问定价时,它会一致推荐基于价值的定价,附和那些商业评论者——他们在小众业务中使用这一策略取得的成功,在网上获得了不成比例的关注。缺少经营代理机构带来的上下文,AI 可能把他们的建议误当成普遍适用的规则。当你用 Claude 或 ChatGPT 新开一个线程时,你需要给它所需的上下文。在这个例子里,我用语音模式解释了我从经营代理机构中学到的东西。这些细节帮助模型写出了一篇更有用的文章,反映了我的经验。如果你要离开一个长线程,它还有有价值的上下文,但已开始因上下文腐化而退化,就让模型保存一份交接文件——一份总结关键事实、决策和下一步的文档。把它上传到一个新线程,这样模型就拥有继续下去所需的信息。

留意: 答案几乎适用于任何人,却漏掉了让你的情况与众不同的约束或经验。

该怎么做: 在离开一个长线程之前,问模型这个我在处理重复性任务时推荐过的问题:

提示词

What information would have been useful to know at the start of this task that would have eliminated several steps or mistakes?

在这个任务开始时,知道哪些信息本可以省去好几个步骤或错误?

读一读答案,删掉任何错误或过时的内容,再把它作为新简报的一部分粘贴到新线程里。

养成重新开始新对话的习惯

上下文腐化最好的长期解决办法,是把你最好的上下文保存在本地文件里,让智能体(agent)可以按需读取。我经营代理机构时,如果员工或客户三次以上问到同一个问题,我就会写一份标准操作流程(SOP),放进共享的 Google Drive 文件夹。今天我处理提示词也类似:如果 AI 在某个会话里需要一个答案,这个答案在下一个会话里可能也有用。我把提示词保存在 GitHub 的 Markdown 文件里,重新开始时拿来引用,而不是指望正确的细节能在长线程里留存下来。通过控制智能体处在哪个文件夹,我就能控制它的上下文,避免上下文腐化。

你重开 15 次,模型也不会烦;它也不会告诉你线程已经一团糟。它的输出只会变差,所以你得在上下文腐化接管之前阻止它。每次都新开一个线程,意味着我确切知道 AI 手上有什么:只有我给它的东西。

Mike Taylor 是 Every 的评估(evals)负责人,也是 O'Reilly《Context Engineering with DSPy》的作者,以及《Prompt Engineering for Generative AI》的合著者。你可以在 X 上关注他 @hammer_mt,也可以在 LinkedIn 上找到他。


核心启示:上下文腐化往往不是因为 AI 不够聪明,而是因为线程里积累的旧指令、无关细节、早期错误和缺失信息一起把回答带偏;每项任务都从新线程开始,并用完整、必要的上下文替换旧线程,是作者给出的核心做法。

Context Engineering Is Knowing When to Start Over 的发芽报告

材料核心

Mike Taylor 认为,AI 长对话会因上下文不断累积而“腐烂”(context rot):旧指令、无关细节、早期错误和缺失信息都会让模型输出悄悄变差。真正有效的上下文工程,不是让模型记住更多,而是识别任务边界、主动开新线程,并用 handoff 文件或本地 SOP 重建必要上下文。


发芽 01:把线程当“可变状态”,把重开当“故障恢复”

种子

文章表面讲“何时开新聊天”,深层讲的是:对话线程是 AI 的工作记忆,也是一份不断被写入的可变状态。旧偏好、早期假设、模型自己犯过的错,一旦留在 thread 里,就会成为后续推理的“事实”。作者说得很关键:模型不会提醒你线程已经变乱,它只会让输出越来越差。所以人必须替模型做状态管理。

文章里的 Gemini 玩《Pokémon Red》是一个极端案例:它误以为需要寻找一个在该版本中根本不存在的道具 TEA,于是花了 100 多个回合寻找一个永远找不到的东西。更日常的版本是:模型早先写错一个统计数字,之后每一版都把它当作既定事实;你指出错误也没用,因为错误和你的纠错都还在上下文里。作者的建议不是“在坏线程里修”,而是编辑上一条消息、删掉错误记忆,或者带着完整 brief 开新线程。

故事

这让人想到 Erlang/OTP 的故障恢复哲学。Erlang 诞生于 Ericsson 的电话交换系统场景,Joe Armstrong 等人设计的核心思路之一不是让每个进程永不崩溃,而是让进程隔离、让 supervisor 在崩溃后把子进程重启到已知的干净状态。电话系统不能靠“坏掉的进程自己修好自己”来保证高可用;它靠的是快速失败、隔离污染、从干净状态恢复。

AI 对话里的 context poisoning 很像一个已经写入了错误目标的进程:你继续在同一个线程里争论、解释、纠正,只会把更多错误状态写进历史。新线程加 handoff 文件,本质上就是 supervisor 式的恢复:不是修补坏状态,而是把仍然有效的事实、决策和下一步迁移到干净环境里。

Aha 瞬间

“上下文工程的关键动作不是让模型记住更多,而是让坏状态不进入下一轮;新线程不是逃避问题,而是 AI 对话里的 supervisor。”


发芽 02:上下文窗口不是仓库,而是有偏的注意力舞台

种子

文章第 3 节引用 Stanford 研究者 Liu 等人的“Lost in the Middle”:模型对上下文开头和结尾最敏感,关键信息落在中间时,表现会显著下降。作者举了一个很具体的实验:九份项目文档里,关键 bug report 放在第六份,模型却根据开头的概览和结尾的发布计划作答,完全忽略了 bug。这推翻了“上下文越多越好”的直觉:窗口不是均匀照亮的仓库,而是有注意力偏好的舞台。

因此文章的建议不是“把所有资料都塞进去”,而是只上传任务需要的文档;不同文档的问题分开问;重要任务信息放顶部,格式指令放底部。换句话说,context engineering 有一部分其实是“布景工程”。

故事

认知心理学里的“系列位置效应”(serial position effect)早就描述过类似现象:在自由回忆实验中,人们更容易记住列表开头和结尾的项目,中间项目回忆率最低。文章也提到人类有首因效应和近因效应。AI 的“中间丢失”不是简单复制人类,但它提醒我们:注意力从来不是均匀分配。

高风险场景对此有更硬的处理方式。Atul Gawande 在《清单革命》中讨论 WHO 手术安全核查表时,核心并不是让医生“记得更多”,而是把关键检查项固定在麻醉前、切皮前、出室前等流程节点上。关键信息不靠某个人在长流程中间偶然想起,而靠结构把它放到必须被看见的位置。

AI 对话同理:如果你把关键约束埋在 50 条消息之前,然后期待模型在中间把它捞出来,你是在跟注意力偏差对赌。开新线程并重写 brief,就是把关键道具重新放到聚光灯下。

Aha 瞬间

“上下文窗口不是均匀照亮的仓库,而是首尾更亮的舞台;重开线程不是清空信息,而是重新布景,让真正重要的约束回到聚光灯下。”


发芽 03:AI 的默认答案是“幸存者平均”,新线程要把不可见约束写回来

种子

文章最后一个问题很反直觉:context rot 不只会来自“上下文太多”,也会来自“上下文太少”。当 prompt 缺少关键约束时,模型只能猜,而它的猜测往往是训练数据里的平均值。作者用自己经营 50 人营销公司的经历说明:AI 总推荐 value-based pricing,因为网上被广泛传播的是少数成功案例;但真正做过 agency 的人知道,价值定价在很多情况下并不适用。模型不是“错”,它只是把互联网上可见的成功故事误当成了普遍规则。

这也是为什么新线程不能只是“重新开始”,还要带上 brief:事实、约束、决策、失败经验、下一步。作者甚至建议在离开长线程前问模型:“哪些信息如果在任务开始时就知道,会省掉很多步骤或错误?”然后把它整理成 handoff 文件,带进新线程。

故事

二战期间,统计研究小组(SRG)的 Abraham Wald 面对一个经典问题:返航轰炸机哪些部位最该加固?军官们看到返航飞机机翼和机身上弹孔多,自然想加固弹孔密集处。Wald 指出,真正该加固的是弹孔少的地方,比如发动机——因为发动机中弹的飞机根本没能返航。你看到的弹孔分布,是被幸存者筛选过的样本。

AI 的训练语料也有类似的幸存者偏差。网上充斥着“价值定价让 agency 利润翻倍”的成功叙事,但那些因为价值定价失败、流失客户或倒闭的 agency 不会以同样显著的方式留下语料。于是模型给出一个看起来普适、实际上只适用于幸存者的建议。

新线程的价值就在这里:它不是把模型倒空,而是把那些“没有返航的飞机”也写进 brief——你的行业约束、失败经验、组织现实和不可见的成本结构。

Aha 瞬间

“AI 的默认智慧常常不是普适真理,而是幸存者偏差筛过的平均;新线程不是清空上下文,而是把那些没被互联网看见的约束重新放回桌面。”


你的思考空间

  • 你手上哪些“长期线程”其实已经进入 context drift,只是因为输出仍然连贯,所以你没有察觉?
  • 如果每次新线程都要重建 brief,哪些信息应该沉淀为本地 SOP 或文件夹,哪些信息应该每次临时手写?
  • 你所在领域有哪些“网上被过度代表”的成功建议,AI 会默认推荐,但实际存在隐性约束?
  • 你能否设计一个 handoff 模板:关键事实、已做决策、未决问题、禁止项、成功标准,各占什么位置?
  • 当模型犯错时,你更常“在 thread 里纠正它”,还是“编辑历史或重开”?这两种做法分别会把对话推向什么样的自我实现预言?