当长聊天改变代码时:context drift 与 隐藏错误

发布: (2025年12月30日 GMT+8 17:58)
7 min read
原文: Dev.to

Source: Dev.to

对话在多长时间内悄然重塑模型

我在棘手的调试会话期间会保持一个实时助手线程打开。起初,我会在对话中提供堆栈细节:Python 3.11、FastAPI、Postgres 14、具体的环境名称。几个小时后,模型开始建议的代码片段匹配它在最近几条消息中看到的内容,而不是最初的约束。最近的 token 占主导。

有一次,助手开始返回 aiohttp 的示例,而我的项目是 FastAPI。代码在 REPL 片段中表面上可以编译通过,但在集成测试中失败,因为我依赖的会话级中间件不存在。

隐含假设潜入代码建议

这些并不是夸张的幻觉。它们是微小、合理的默认值,却与我们的基础设施不匹配。模型会假设默认的 AWS 区域、常见的包版本,或者数据库 URL 被称为 DATABASE_URL

我合并了一个补丁,其中生成的 Dockerfile 使用了:

RUN pip install --user .

在根构建步骤中。它在本地构建成功;但在 CI 中它创建了一个缺少 site‑packages 的非 root 运行时镜像,导致服务启动时崩溃。助手在没有询问我们使用的基础镜像的情况下,用一个典型的模式填补了空白。

另一个例子:一个在聊天中看起来不错的 kubectl 命令。它在 kubectl rollout restart 上使用了 --record,而该标志在我们的集群中已被弃用。该命令在测试集群上成功,但在我们的策略代理下失败,并导致了模糊的 rollout 状态。模型把训练中见过的最常见标志当作适用于我们环境的正确选项。

工具故障放大幻觉

我将模型与搜索和代码索引器连接,以确保答案有依据。但这些连接器很脆弱。一次搜索超时返回了空的负载,模型合成了一个在任何文件中都不存在的函数名。我把该回复当作权威信息并将该名称复制到重构中。构建失败。

从外部看这像是一次幻觉,但根本原因是工具层未处理的错误。由于没有真实的证据阻止它,模型随后继续用更多虚构的辅助函数“修复”这个不存在的函数。

Source:

小错误在流水线中会累积

这些错误会相互放大。一次错误的配置——在生成的 CI 作业中缺少环境注入——导致迁移运行出错。迁移在本地对临时数据库能够成功完成,但在预发布环境中只执行到一半,留下了外键损坏。日志记录提供了线索,但警报没有触发,因为我只信任作业的状态字符串,而没有在运行后检查数据库状态。模型建议添加状态检查时出现了 fencepost 错误。看似微不足道,却导致回滚变得手动且繁琐。

另一个复合示例:助手建议在批量插入周围使用 try/except,并静默捕获 IntegrityError,返回通用的成功信息。下游服务的缓存因此变得陈旧,消费者无限重试。少量的错误处理选择缓冲层级最终演变成可见的服务中断。我们对 schema 和 lint 有测试,但没有针对生成代码引入的具体失败处理语义进行测试。

实际使用的实用修复

  • 我不再把长聊天当作稳定的规范。我现在把约束固定在单条消息中,并定期重新发送它们。
  • 如果线程运行时间过长,我会使用简洁的系统消息重置助手,并在仓库中保留一个简短的清单文件,列出版本、环境名称和部署策略。
  • 我记录每个 AI 生成的代码片段,并在具有严格资源预算的隔离沙箱中运行它。
  • 当工具返回无结果时,我会让助手在我接受更改之前明确声明工具的置信度。

我捕获问题的具体防护措施:

  • 将生成的基础设施更改置于功能标志后面。
  • 为环境和版本检查添加运行时断言。
  • 让 CI 运行集成测试,检验模型修改的确切失败路径。

当我需要交叉检查时,我会在共享工作区打开并行提示,并比较不同模型的答案,而不是只信任单一线程。该比较习惯与结构化的验证流程并行,用于来源事实和文档的核实,因此我不会把模型对 API 的建议视为最终结论。你可以使用共享聊天工作区进行比较,并使用更深入的研究工作流进行验证,以使这些实践不那么临时。

Back to Blog

相关文章

阅读更多 »