当长对话偏离时:AI 辅助编码中的隐藏错误
Source: Dev.to
上下文漂移如何悄然出现
我通过惨痛的教训了解到,长时间的聊天并不是单一、稳定的记忆。模型仍然会看到之前的对话,但注意力倾向于最近的 token。这意味着你一小时前提出的约束会被悄悄降级。我会在会话开始时告诉助手使用哪个框架、哪个版本,并且我们更倾向于使用现有的助手。随后在同一线程中,它会开始建议来自不同生态系统的 API,而我只有在测试失败后才注意到。变化是微妙的。建议听起来仍然合理,于是你会一直接受,直到 CI 中出现问题。
我遇到的具体失败
-
HTTP client swap – 早期的消息明确是关于
requests和同步代码的;在几次提示后,模型开始返回异步httpx示例。我合并了更改,因为差异看起来很小。测试在本地通过,但在阶段环境中失败,因为事件循环不同。根本原因是一个丢失的约束:“保持同步”在聊天开头,但后来不再影响后续完成。 -
Language feature assumptions – 我告诉助手我们使用的是 Python 3.9。经过多轮对话后,它在没有提醒的情况下建议使用
match/case代码片段。代码在我本地能够编译,因为我装了 3.10,但团队成员的环境不行。这件事花了我几个小时追踪语法错误的来源。它们不是夸张的幻觉,而是小的偏移,只在运行整个系统时才会显现。
为什么小错误会累积
长时间的对话会形成一连串的微决策。一次提示会更改变量名。下一次则基于该更改并假设了不同的模块布局。如果链中的任何工具调用返回了部分或格式错误的输出,模型往往会用最可能的续写来填补空白。我曾遇到搜索工具超时,助理却继续假设搜索正好返回了所需内容,结果生成的代码引用了我们代码库中根本不存在的函数。
当模型输出被用于脚本、CI 或其他工具时,沉默或部分失败就会成为放大点。缺失的检查、稍有错误的 import,或忘记的 header 都会在后续对话中成为新的假设。这也是我现在把生成和验证视为两个独立步骤的原因。我让模型先草稿,然后运行确定性的检查,并要求对任何关于库行为的声明提供明确的证据或来源,通常在需要验证 API 细节时使用结构化的研究流程。
实际降低事故的运营变更
我首先改变了三件事:强制重置、记录所有内容,并将工具输出设为强制检查点。
- Resets – 我把大型任务拆分成多个聊天,并在每个新会话中明确重新陈述约束条件。听起来可能令人烦恼,但它比调试漂移的会话更有效。
- Logging – 我将助手的输出和每一次工具响应写入我们的追踪层,这样就可以回放建议的来源。回放是我唯一找到在那个 HTTP 客户端事故中决定从同步切换到异步的时刻的方法。
- Guardrails – 我使用明确的提示,将运行时、版本以及风格指南固定为模型在生成代码前必须参考的简短检查清单。
当我需要第二意见时,我会把相同的提示投放到共享聊天工作区的另一个模型中,以观察分歧模式。该比较常常比单一答案更快显现隐藏的假设。为了验证,我要求模型提供引用或 API 变更的精确函数签名,然后使用聚焦的研究流程将其与文档进行核对。
何时停止聊天并运行测试
我的启发式现在很简单。如果会话超过几轮或涉及多个子系统,就停止并进行验证。运行单元测试。检查导入和运行时版本是否匹配代码将运行的每个环境。如果建议的更改需要新依赖项,则将其视为新项目,并开启一个新的对话,事先列出依赖策略。我仍然让模型起草和探索,但不会让草稿在没有明确验证和日志追溯的情况下传播。这降低了小的上下文漂移演变为部署故障的可能性。