db-ally
用自然语言安全查询结构化数据库,View+IQL 双层抽象让 LLM 只在预定义能力内工作
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
用自然语言安全查询结构化数据库,View+IQL 双层抽象让 LLM 只在预定义能力内工作
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
假设你正在开发一个 HR 管理系统的智能问答模块。产品经理突然抛出一个需求:"能不能让招聘专员直接用自然语言查询人才库,比如'找所有法国的、有3年以上经验的数据科学家候选人'?"传统的思路是引入 Text-to-SQL——让大语言模型直接生成 SQL。但实际落地时,问题接踵而至:
SQL 生成的不可控性:LLM 可能生成语法错误的 JOIN、漏掉关键 WHERE 条件,甚至产生 SQL 注入风险。尤其是当数据库 schema 复杂(有十几张表、上百个字段)时,LLM 很难准确理解每张表之间的业务关系,生成的结果往往差强人意。
上下文缺失:LLM 不了解你公司的具体业务逻辑。比如"高级职位"在不同公司定义不同,"合适的候选人"涉及哪些维度的筛选,这些隐性知识无法从数据库 schema 中获取。
安全问题:让 LLM 任意生成和执行 SQL,意味着它理论上可以读写整个数据库,任何 prompt injection 都可能造成数据泄露。
这些痛点,正是 db-ally 试图解决的核心问题。
db-ally 由波兰 AI 公司 deepsense.ai 开发并开源。deepsense.ai 在众多项目中频繁遇到需要用自然语言查询结构化数据的需求,最初他们也采用 Text-to-SQL 方案,但实际效果始终不够理想。
团队最终摸索出一套更可控的方案:与其让 LLM 自由生成 SQL,不如提前由开发者定义好数据查询的能力边界,LLM 只需在预定义的框架内选择合适的过滤器(filter)和聚合(aggregation)操作。这种"有限选项"的设计思路,让 LLM 的输出更可预测、更安全,也更容易调试。
2023年,deepsense.ai 将这套方法论封装成 Python 库并开源,也就是现在的 db-ally。
db-ally 的设计哲学可以概括为一句话:把 Text-to-SQL 变成 Text-to-IQL(Intermediate Query Language)。
开发者不直接暴露数据库表结构,而是通过实现 BaseView 类来定义"这个视图能查什么、怎么查":
class CandidateView(SqlAlchemyBaseView):
def get_select(self):
return sqlalchemy.select(Candidate)
@decorators.view_filter()
def from_country(self, country: str):
return Candidate.country == country
每个 @decorators.view_filter() 装饰的方法,就是一个 LLM 可以调用的"过滤能力"。这些方法有明确的参数类型和 docstring,LLM 能准确理解每个过滤器的含义和使用方式。
这种方法的优势:
IQL 是 db-ally 自研的中间查询语言,格式类似:
filters: [from_country("France"), senior_data_scientist_position()]
aggregations: [count()]
IQL 经过处理器解析后,再由各个数据源适配器(如 SqlAlchemy、FAISS)转换为对应后端的实际查询。这种设计让 db-ally 天然具备多数据源支持的能力——同一套自然语言查询,可以同时路由到 PostgreSQL、SQLite、FAISS 向量索引等多种数据源。
Collection 是 db-ally 的顶层入口,负责管理多个 View。通过 collection.add() 注册视图后,LLM 可以根据用户意图自动选择合适的视图处理查询。Collection 还支持 freeform 模式,在这种模式下,LLM 可以自由组合多个视图的过滤器,灵活性更高。
图1:db-ally 事件处理链路示意(来源:项目官方文档)
db-ally 的源码结构非常清晰,主要模块包括:
| 模块 | 职责 |
|---|---|
dbally/ | 核心库,包含 Collection、View、IQL 处理器 |
dbally/assistants/ | LLM 适配器(OpenAI、LiteLLM 等) |
dbally/embeddings/ | 向量嵌入支持(用于语义相似度匹配) |
dbally/audit/ | 事件追踪(CLI、LangSmith、OpenTelemetry) |
dbally/gradio/ | Gradio Web UI 界面 |
dbally/iql/ | IQL 解析器和类型验证器 |
dbally_cli/ | 命令行工具 |
dbally_codegen/ | 自动代码生成工具 |
LLM 集成:db-ally 默认通过 LiteLLM 支持 100+ 种大模型,包括 GPT-4、Claude、Llama 等,无需为每个模型单独编写适配器。通过 create_collection("name", llm) 传入 LLM 实例即可。
向量检索:db-ally 支持通过 FAISS 构建向量索引,对非结构化数据(如简历文本)进行语义相似度搜索,在自然语言查询中作为降级方案(fallback)。
审计日志:内置多种事件处理器,支持将查询过程记录到 CLI、LangSmith(付费)或 OpenTelemetry(适合生产环境),方便排查 LLM 生成的 IQL 是否符合预期。
Web UI:db-ally 提供了 Gradio 界面,可通过 dbally.gradio 快速启动一个交互式 Demo。HuggingFace Spaces 上也有官方在线演示。
图2:deepsense.ai 官方头像(项目维护方)
db-ally 是纯 Python 库,安装极为简单:
pip install dbally
# 或包含 LLM 支持的完整版
pip install "dbally[litellm,faiss,langsmith]"
依赖项非常干净——核心库只需要 SQLAlchemy 和 Pydantic。最低 Python 版本要求 3.10。
没有 Dockerfile,也没有 docker-compose,这是目前最大的部署短板。对于需要容器化部署的团队(比如 Kubernetes 环境),db-ally 目前无法直接支持,需要自己编写镜像。docker 目录中只有 precommit 和 tests 环境的配置,并非面向最终用户的部署镜像。
好消息是,Gradio UI 支持可以通过 pip 单独安装的 dbally[gradio] 依赖快速启动一个 Web 界面。
db-ally 并非银弹,以下问题值得注意:
1. 视图定义成本:虽然 db-ally 降低了 LLM 生成错误 SQL 的风险,但代价是开发者需要预先编写和维护 View 代码。对于 schema 经常变化的数据源,这会变成额外的维护负担。db-ally 提供了 dbally_codegen 自动代码生成工具来缓解这一问题,但目前生成质量仍需人工校验。
2. 复杂查询受限:由于 LLM 只能在预定义的过滤器中选择,db-ally 不适合需要任意 SQL 灵活性的场景。如果你的需求本身就是"什么都能查",db-ally 反而是限制。
3. Gradio 演示 vs 生产级 UI:HuggingFace Spaces 上的 Demo 适合体验,但内置 Gradio UI 不适合直接用于生产环境,需要自行封装 API 服务。
db-ally 代表的"结构化 LLM 查询"思路,与 LangChain 的 SQL Agent、OpenAI 的 Code Interpreter 走了完全不同的路线——不是给 LLM 更多自由,而是给它更少但更精准的选择。
这种设计哲学在企业级应用中非常有价值。随着 RAG(检索增强生成)和 Agent 架构的流行,如何让 LLM 可靠地访问结构化数据成为一个核心命题。db-ally 提供了一个介于"纯 SQL 生成"和"硬编码规则"之间的折中方案,值得在 AI 应用开发工具链中关注。
项目当前 168 stars,虽然绝对数量不大,但在 Text-to-SQL/NLIDB 细分领域属于活跃项目。MIT 许可,代码质量规范(完整类型注解、mypy 严格模式、pre-commit 检查),社区参与度高。