如何利用 Function Calling 实现 LLM 对本地 SQLite 数据库的精准查询?
直接把自然语言转 SQL 很容易在表名或字段名上翻车,尤其是当数据库规模稍微大一点,LLM 经常会臆造出不存在的列。最稳妥的方案是给 LLM 定义一套「查询工具集」,通过 Function Calling 让它先确认 Schema,再生成执行语句。
我目前的实战链路是:定义一个 execute_sql 函数 → 传入 Read-only 数据库连接 → LLM 输出参数 → 本地执行并回传结果。
核心配置技巧:限制 LLM 的权限
千万不要给 LLM 全权限的 DB 连接,否则一个 DROP TABLE 就能让你崩溃。建议在 Python 中创建一个只读连接:
import sqlite3
# 强制使用只读模式打开数据库,防止 AI 误删数据
conn = sqlite3.connect('file:local_data.db?mode=ro', uri=True)
cursor = conn.cursor()
def execute_sql(query: str):
try:
cursor.execute(query)
return cursor.fetchall()
except Exception as e:
return f"SQL Error: {str(e)}"效率提升:把 Schema 塞进 System Prompt
如果每次查询都让 AI 去查 sqlite_master 表,会浪费大量 Token 且增加延迟。我把所有表的结构精简后直接写在系统提示词里,但关键点在于:必须给每个字段加上业务描述。
你是一个数据库专家。可用表结构如下:
- users (id: 用户唯一ID, nickname: 用户昵称, last_login: 最后登录时间-ISO格式)
- orders (order_id: 订单号, user_id: 关联用户ID, amount: 订单金额, status: 状态(0-待支付, 1-已完成))
注意:查询金额时必须使用 amount 字段,禁止使用 total_price。踩过的坑:处理「模糊查询」和「空结果」
最常见的坑是 AI 在处理中文查询时,习惯用 = 而不是 LIKE。比如用户问「查一下关于苹果的订单」,AI 生成 WHERE product = '苹果',结果数据库里存的是 苹果手机15,导致返回空结果。
我的解决办法是在 Function 定义的 description 里强制约束。
具体的 Function 定义片段(JSON):
{
"name": "execute_sql",
"description": "执行SQLite查询。注意:涉及文本搜索时,必须使用 LIKE 运算符并配合 % 通配符,例如 'LIKE %关键词%'",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "标准的SQLite查询语句"
}
},
"required": ["query"]
}
}实战流程闭环:
用户输入 → LLM 识别出需要查库 → 调用 execute_sql(query="SELECT ...") → 本地代码执行并获取结果 → 将结果作为 tool_response 喂回 LLM → LLM 将原始数据转化为自然语言回答。
这套方案比单纯的 Text-to-SQL 稳得多,因为 AI 成了「调度员」而非「代码生成器」,错误率降低了约 40%。
全部回复 (0)
还没有回复,来发第一条吧!
