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_callhooks 以强制允许的查询模式 - 为破坏性语句启用查询日志和告警
只读模式与 DML 配置
Section titled “只读模式与 DML 配置”NL2SQLTool 默认以只读模式运行。未经额外配置时,仅允许以下语句类型:
SELECTSHOWDESCRIBEEXPLAIN
任何尝试执行写操作(INSERT、UPDATE、DELETE、DROP、CREATE、ALTER、TRUNCATE 等)都会报错,除非显式启用 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 - 环境变量:
CREWAI_NL2SQL_ALLOW_DML=truefrom crewai_tools import NL2SQLTool
# DML enabled via environment variablenl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")只读模式(默认)- 适合分析与报表:
from crewai_tools import NL2SQLTool
# Only SELECT/SHOW/DESCRIBE/EXPLAIN are permittednl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")启用 DML - 写入型工作负载必需:
from crewai_tools import NL2SQLTool
# INSERT, UPDATE, DELETE, DROP, etc. are permittednl2sql = NL2SQLTool( db_uri="postgresql://example@localhost:5432/test_db", allow_dml=True,)- SqlAlchemy
- 任何兼容数据库的库(例如 psycopg2、mysql-connector-python)
安装 crewai_tools 包
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 PostgreSQLnl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")
@agentdef researcher(self) -> Agent: return Agent( config=self.agents_config["researcher"], allow_delegation=False, tools=[nl2sql] )主要任务目标是:
“检索每个城市的月收入平均值、最大值和最小值,但只包含拥有超过一个用户的城市。同时,统计每个城市的用户数量,并按月平均收入降序排序”
因此,Agent 先尝试从数据库获取信息,第一次结果是错误的,于是 Agent 再试一次并拿到正确结果,然后把结果交给下一个 agent。

第二个任务目标是:
“审查数据并创建一份详细报告,然后根据提供的数据在数据库中创建表。包括每个城市的月收入平均值、最大值和最小值,但只包含拥有超过一个用户的城市。同时,统计每个城市的用户数量,并按月平均收入降序排序。”
现在事情开始变得有意思了,Agent 生成的 SQL 查询不仅创建了表,还把数据插入到了表中。最后,Agent 仍然返回了最终报告,而这份报告与数据库中的内容完全一致。


这是一个简单示例,展示了 NL2SQLTool 如何与数据库交互,并基于数据库中的数据生成报告。
这个 Tool 为 Agent 的逻辑以及它如何与数据库交互提供了无限可能。
DB -> Agent -> ... -> Agent -> DB