一份开发者指南警告称,在 AI 驱动的聊天过程中保持数据库事务开启,可能会导致答案出错并使底层 DBMS 瘫痪。该指南面向构建 LLM 后端工具的团队,指出这种做法“不应被采用”,并提供了四种短周期的一致性模式作为替代方案。
为什么这一警告至关重要
由 LLM 驱动的助手通常会提出一系列后续问题:它们先读取一条记录,请求一个细节,然后询问总计。如果底层数据在这些步骤之间发生了变化,助手可能会返回矛盾的数据——其中一个答案将会是错误的。一个诱人的解决方法是在对话开始时开启单个事务,并一直保持开启状态直到聊天结束。但在实践中,这种方法会占用行版本(row versions),填满 tempdb,持有锁,并干扰连接池。
导致长事务的原因
- 多轮提示 (Multi-turn prompting) – LLM 在用户看到响应之前,通常会生成多次提示。
- 访问数据库的工具调用 (Tool calls) – 每一轮对话都可能调用存储过程、SELECT 或 UPDATE 语句。
- 不受控制的事务范围 – 开发人员有时会将整个聊天过程封装在一个 BEGIN…COMMIT 块中,认为这样可以保证一致性。
当聊天过程拉长时,数据库引擎必须保留原始行版本,以便事务能看到一个稳定的视图。这些版本会存储在 tempdb 中,消耗空间和 I/O。长时间持有的锁会阻塞并发写入,而空闲连接可能会耗尽连接池,迫使新的调用者等待空闲槽位。
四种短周期模式
该指南建议将一致性视为“按工具调用”处理的问题,而不是“按对话”处理的问题。这四种模式分别是:
- 实时语句 (Live statements) – 每次调用都在默认隔离级别下运行,仅能看到执行时刻已提交的数据。这是最简单的模型;调用者接受数据自上一轮对话以来可能已经发生变化的事实。
- 有界事务 (Bounded transactions) – 开发人员将若干语句组合在一个单一的短事务中,该事务在下一次 LLM 轮次开始前完成。它保证了该批次操作的原子性,而不会在工具调用之外长期存在。
- 快照读 (Snapshot reads) – 操作从一个定义的快照时间戳开始,在调用期间为数据库提供稳定的视图。调用内的所有读取操作都能看到相同的数据,即使期间发生了并发写入。
- 物化报告 (Materialized reports) – 工具从预先生成的、带有版本的查询结果集中读取数据,该结果集反映了已知截止时间点的数据库状态。随后的分页或进一步计算都基于该冻结的数据集进行。
在 SQL Server 中,请检查 READ_COMMITTED_SNAPSHOT 是否处于激活状态。不要以为仅凭名称就能了解全部情况。
LLM 驱动应用的实践规则
- 批量处理所需内容 – 如果一个问题需要多个数值,请在单个工具调用中计算它们,而不是发出多个各自开启新事务的独立查询。
- 确定性分页 – 在跨页展示结果时,请使用稳定的排序键、游标或物化结果集。切勿在用户滚动页面时保持事务开启。
- 返回证据 – 在返回数据的同时,包含使一致性模型显式化的元数据:一致性级别、快照开始时间、报告截止时间、数据新鲜度、行数、数据库标识以及 trace ID。
- 进行并发压力测试 – 在 LLM 进行提示的同时模拟并发写入,并验证应用程序是否能够优雅地重试或回退。
底线很明确:AI 聊天不应决定数据库事务的生命周期。通过将一致性范围限定在每次工具调用内,开发人员既能保持数据库的健康,又能为所有用户保留性能,同时还能为 LLM 提供足够可靠的数据以确保回答准确。
