让数据库代理实现只读访问:由数据库强制执行,而非对SQL使用正则表达式
摘要
作者分享了在开源数据库客户端中添加自然语言到SQL助手的经验教训,重点关注本地模型的挑战,如模式选择,以及数据库强制只读访问的必要性,以防止语义错误的查询。
上下文:我们构建了一个开源(MIT)的自托管数据库客户端,并添加了一个自然语言到SQL助手,该助手可以指向本地运行时(如Ollama),而不是托管API。我想分享我们使用本地模型针对真实数据库的经验,因为大多数NL2SQL演示使用大型托管模型,并悄悄隐藏了失败模式。这不是推销,只是笔记,我很乐意得知我们的设置哪里有误。
本地模型会出什么问题:模式选择是准确性。你无法将400个表的模式粘贴到短上下文窗口中。在托管模型的长上下文中,选择相关表是锦上添花。在本地7B或8B运行,具有4k到8k上下文以适应GPU的情况下,该选择是整个游戏:放入不相关的表,模型就会追逐它们导致错误的SQL。我们的大部分工作不是提示,而是决定不发送什么。
外观干净的错误SQL。较小的模型生成语法完美但语义错误的SQL:正确的形式,错误的表或列。它运行无误并返回行,因此仅询问“是否运行”的检查会通过它。我们正是为此在生成和执行之间保留人工介入,模型越小,这种分工越显其价值。
只读必须是数据库的职责,而不是对SQL使用正则表达式。我们通过在PostgreSQL上使用只读事务、在SQLite上使用PRAGMA query_only等方式来强制执行。一件让我们惊讶的事:只读事务并不阻止服务器端文件访问(COPY TO、本地文件函数),因此助手需要自己的最小权限角色,而不是所有者角色。
本地端点的好处显而易见:模式、示例行和问题永远不会离开机器。对于任何数据不能跨越边界的人来说,这就是使用助手与不使用助手的区别。
对这个子论坛的问题:对于那些将LLM置于真实数据库前的人,你们在哪里强制只读,以及如何防止一个有效但语义错误的查询到达信任它的人?我们选择了数据库原生只读加上执行前的人工介入,但我想听听其他人如何划界。
相似文章
如何在不让代理拥有写入权限的情况下授权数据库访问?
一位开发者分享了一种解决方案,通过MCP服务器为AI代理提供只读数据库访问,该服务器强制实施READ ONLY事务和突变防护,防止写入操作并降低影响范围。
自然语言转SQL,但带有只读保护
一个将自然语言查询转换为SQL的工具,带有只读限制以防止数据修改。
@LangChain:只读代理易于分支和测试,但可写入生产数据的写访问代理对许多团队来说仍是未解决的评估问题
只读代理比写访问代理更容易测试;对许多团队来说,生产数据的写访问仍是一个未解决的评估问题。
为智能体提供可靠的“对话数据仓库”访问模式,无需原始文本到SQL
一种为AI智能体提供可靠数据仓库访问的模式,使用精心策划的语义层(Databricks Genie)而非原始文本到SQL,提高了准确性和治理能力。智能体将Genie的Conversation API作为工具调用,同时接收自然语言响应和精确SQL。
如何阻止编码代理接触生产数据?
讨论防止AI编码代理意外修改生产数据库的策略,主张使用只读访问、沙盒环境和审批关口,而不是仅仅依赖提示。