让数据库代理实现只读访问:由数据库强制执行,而非对SQL使用正则表达式

Reddit r/AI_Agents 工具

摘要

作者分享了在开源数据库客户端中添加自然语言到SQL助手的经验教训,重点关注本地模型的挑战,如模式选择,以及数据库强制只读访问的必要性,以防止语义错误的查询。

上下文:我们构建了一个开源(MIT)的自托管数据库客户端,并添加了一个自然语言到SQL助手,该助手可以指向本地运行时(如Ollama),而不是托管API。我想分享我们使用本地模型针对真实数据库的经验,因为大多数NL2SQL演示使用大型托管模型,并悄悄隐藏了失败模式。这不是推销,只是笔记,我很乐意得知我们的设置哪里有误。 本地模型会出什么问题:模式选择是准确性。你无法将400个表的模式粘贴到短上下文窗口中。在托管模型的长上下文中,选择相关表是锦上添花。在本地7B或8B运行,具有4k到8k上下文以适应GPU的情况下,该选择是整个游戏:放入不相关的表,模型就会追逐它们导致错误的SQL。我们的大部分工作不是提示,而是决定不发送什么。 外观干净的错误SQL。较小的模型生成语法完美但语义错误的SQL:正确的形式,错误的表或列。它运行无误并返回行,因此仅询问“是否运行”的检查会通过它。我们正是为此在生成和执行之间保留人工介入,模型越小,这种分工越显其价值。 只读必须是数据库的职责,而不是对SQL使用正则表达式。我们通过在PostgreSQL上使用只读事务、在SQLite上使用PRAGMA query_only等方式来强制执行。一件让我们惊讶的事:只读事务并不阻止服务器端文件访问(COPY TO、本地文件函数),因此助手需要自己的最小权限角色,而不是所有者角色。 本地端点的好处显而易见:模式、示例行和问题永远不会离开机器。对于任何数据不能跨越边界的人来说,这就是使用助手与不使用助手的区别。 对这个子论坛的问题:对于那些将LLM置于真实数据库前的人,你们在哪里强制只读,以及如何防止一个有效但语义错误的查询到达信任它的人?我们选择了数据库原生只读加上执行前的人工介入,但我想听听其他人如何划界。
查看原文

相似文章