当长对话导致上下文漂移与隐蔽错误时

本文分享了作者在与AI模型进行长时间结对编程时,因对话上下文漂移而产生的隐蔽错误,包括数据库事务、库版本假设等具体案例,并提出了分离线程、定期重置上下文、实施模式校验等实用防护措施。

AI

LLM

讨论

编程

为什么长线程感觉一致但实际上会悄悄漂移

我为了配合模型进行重构,保持一个聊天窗口开启了一周。起初,模型的建议符合我的风格:小函数、描述性名称、单元测试草图。到周中,它开始推荐我从不使用的模式。并非明显错误,只是存在细微差异。模型仍以相同的口吻回复,但其注意力已转移到线程中更近期的示例。近期的标记占主导地位。引导早期提示的心理状态逐渐淡化。 这种漂移并非戏剧性的切换,而是一种缓慢的渗透。我会询问数据库迁移,却得到一个假设了不同ORM的答案。我接受了代码结构,后来才意识到某个调用签名并不存在。到那时,一些本地更改已经依赖于这个错误的假设。

微小的隐藏假设如何变成错误

一个具体例子:我请求模型帮助将一组SQL更新转换为批量事务。在长线程的某个地方,它开始假设自动提交行为已关闭。它生成的代码在一个分支中省略了显式提交。本地测试通过是因为开发数据库驱动程序的行为与生产环境不同。这种不匹配在线上造成了静默故障。我没有询问提交语义,因为我以为模型记得之前关于我们数据库的说明。但它并没有可靠地记住。 另一次,它建议了一个配置标志名称,该名称匹配了某个库的旧版本。重构将其中几个建议串联成一个迁移脚本。该脚本在预演环境中运行,并写入了错误的S3路径前缀。每个错误单独看都是合理的。但结合在一起就导致了一次面向用户的服务中断。

工具调用失败,模型填补空白

我们将模型连接到各种工具:代码检查器、测试运行器、包管理器、小型Shell。这增加了故障发生的表面。我曾见过编排器返回一个不完整的测试摘要JSON,而模型却继续运行,仿佛缺失的字段存在。输出看起来连贯。但它也忽略了一个失败的任务,因为工具输出格式有误。在日志中,唯一的线索是一个不同的校验和以及一个后来撤销了预期行为的更改。 这教会我将工具输出视为不可信的输入。我们现在记录原始工具响应,而不仅仅是模型摘要。当响应被截断或缺少必需字段时,我们会中止,并将原始载荷呈现给人工检查。然后可以要求模型使用完整数据重新处理。这强制进行硬停止,而不是产生无形的假设。

我设置的实用防护措施

我添加了三条简单的规则,这些规则比任何提示调整都更能减少这些隐蔽错误。第一,分离研究和编码线程。我将深度探索移到单独的工作区,以便编码线程保持简短和指令性。对于探索,我们使用一个集中的研究流程,将引用和原始输出保存在一起;当我需要验证来源时,我会将这项工作推送到一个研究会话,而不是使用共享工作区进行实时重构会话以进行比较。 第二,每隔几轮对话就重置或快照上下文。如果一个线程增长超过六次编辑,我们会快照状态,然后重新开始一个明确列出假设的新提示。第三,对模型输出强制实施模式检查。如果模型声称某个函数签名或依赖项名称,在应用更改之前,一个小的验证器会对照代码库对其进行检查。快速失败。记录一切。这些做法并不光鲜,但它们能阻止一连串的小错误。

何时记录、何时重置、何时要求提供证明

记录比巧妙的提示更重要。我保留了一个模型建议、工具输出和人工批准的时间轴纯文本记录。这个时间轴使得重建线上事故并查看假设最初出现的位置变得容易。当预演环境中出现异常情况时,我会回放产生该更改的确切模型输入。可重现性是发现漂移的方式。 与调试一连串错误相比,重置上下文的成本更低。如果一个会话混合了多种风格或多个研究分支,请开始一个新的聊天,重申约束,并仅粘贴已验证的代码片段。当模型引用版本、测试或更新日志时,要求提供来源,并在可能的情况下,强制工具获取权威文件。我们为这类溯源使用单独的频道,以便主线程不会积累噪音。我仍然信任模型来起草,但我不再信任它能记住每一个隐藏的假设。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计