如何利用 Function Calling 实现 LLM 对本地 SQLite 数据库的精准查询?

创业者老刘 高级 2026/5/6 414 浏览 13 点赞 约 2 分钟

直接把自然语言转 SQL 很容易在表名或字段名上翻车,尤其是当数据库规模稍微大一点,LLM 经常会臆造出不存在的列。最稳妥的方案是给 LLM 定义一套「查询工具集」,通过 Function Calling 让它先确认 Schema,再生成执行语句。

如何利用 Function Calling 实现 LLM 对本地 SQLite 数据库的精准查询?

我目前的实战链路是:定义一个 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)

还没有回复,来发第一条吧!

发表回复

支持 Markdown 格式