跳转到内容

NL2SQL 工具

这个工具用于将自然语言转换为 SQL 查询。传给 agent 后,它会生成查询语句,并用这些语句与数据库交互。

这支持多种工作流,例如让 Agent 访问数据库、基于目标获取信息,然后用这些信息生成响应、报告或其他输出。 同时,它也提供了让 Agent 基于自身目标更新数据库的能力。

注意:默认情况下,该工具是只读的(仅允许 SELECT/SHOW/DESCRIBE/EXPLAIN)。写操作需要 allow_dml=True 或环境变量 CREWAI_NL2SQL_ALLOW_DML=true。启用写权限时,请尽量让 Agent 使用受限数据库用户或只读副本。

NL2SQLTool 是一个具备执行能力的工具。它会直接对配置好的数据库连接执行模型生成的 SQL。

这意味着风险取决于你的部署选择:

  • 你在 db_uri 中提供了哪些凭据
  • 不受信任的输入是否会影响提示词
  • 执行前是否添加了 tool-call guardrails

如果你把不受信任的输入路由给使用该工具的 agents,请把它视为高风险集成。

生产环境中应同时采用以下措施:

  • 尽可能使用只读数据库用户
  • 对分析/检索工作负载优先使用只读副本
  • 授予最小权限(不使用 superuser/admin 角色,也不授予文件/系统级能力)
  • 在数据库侧设置资源限制(statement timeout、lock timeout、cost/row limits)
  • 添加 before_tool_call hooks 以强制允许的查询模式
  • 为破坏性语句启用查询日志和告警

NL2SQLTool 默认以只读模式运行。未经额外配置时,仅允许以下语句类型:

  • SELECT
  • SHOW
  • DESCRIBE
  • EXPLAIN

任何尝试执行写操作(INSERTUPDATEDELETEDROPCREATEALTERTRUNCATE 等)都会报错,除非显式启用 DML。

包含分号的多语句查询(例如 SELECT 1; DROP TABLE users)在只读模式下也会被阻止,以防止注入攻击。

你可以通过两种方式启用 DML(Data Manipulation Language):

方式 1 - 构造函数参数:

from crewai_tools import NL2SQLTool
nl2sql = NL2SQLTool(
db_uri="postgresql://example@localhost:5432/test_db",
allow_dml=True,
)

方式 2 - 环境变量:

Terminal window
CREWAI_NL2SQL_ALLOW_DML=true
from crewai_tools import NL2SQLTool
# DML enabled via environment variable
nl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")

只读模式(默认)- 适合分析与报表:

from crewai_tools import NL2SQLTool
# Only SELECT/SHOW/DESCRIBE/EXPLAIN are permitted
nl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")

启用 DML - 写入型工作负载必需:

from crewai_tools import NL2SQLTool
# INSERT, UPDATE, DELETE, DROP, etc. are permitted
nl2sql = NL2SQLTool(
db_uri="postgresql://example@localhost:5432/test_db",
allow_dml=True,
)
  • SqlAlchemy
  • 任何兼容数据库的库(例如 psycopg2、mysql-connector-python)

安装 crewai_tools 包

Terminal window
pip install 'crewai[tools]'

要使用 NL2SQLTool,你需要向工具传入数据库 URI。该 URI 应采用 dialect+driver://username:password@host:port/database 格式。

from crewai_tools import NL2SQLTool
# psycopg2 was installed to run this example with PostgreSQL
nl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config["researcher"],
allow_delegation=False,
tools=[nl2sql]
)

主要任务目标是:

“检索每个城市的月收入平均值、最大值和最小值,但只包含拥有超过一个用户的城市。同时,统计每个城市的用户数量,并按月平均收入降序排序”

因此,Agent 先尝试从数据库获取信息,第一次结果是错误的,于是 Agent 再试一次并拿到正确结果,然后把结果交给下一个 agent。

alt text alt text

第二个任务目标是:

“审查数据并创建一份详细报告,然后根据提供的数据在数据库中创建表。包括每个城市的月收入平均值、最大值和最小值,但只包含拥有超过一个用户的城市。同时,统计每个城市的用户数量,并按月平均收入降序排序。”

现在事情开始变得有意思了,Agent 生成的 SQL 查询不仅创建了表,还把数据插入到了表中。最后,Agent 仍然返回了最终报告,而这份报告与数据库中的内容完全一致。

alt text alt text

alt text alt text

这是一个简单示例,展示了 NL2SQLTool 如何与数据库交互,并基于数据库中的数据生成报告。

这个 Tool 为 Agent 的逻辑以及它如何与数据库交互提供了无限可能。

DB -> Agent -> ... -> Agent -> DB