如何利用 Function Calling 实现 LLM 自动调用本地数据库执行 SQL 查询

Prompt工程师陈 专家 2026/4/26 149 浏览 7 点赞 约 1 分钟

把 LLM 当成数据库的“自然语言接口”,核心不在于让它写 SQL,而在于通过 Function Calling 把执行权交还给本地环境。很多人直接把 Schema 丢给 AI 让它写 SQL,然后手动复制到 Navicat 运行,这太低效了。

如何利用 Function Calling 实现 LLM 自动调用本地数据库执行 SQL 查询

我目前在项目里跑的一套闭环流程是:LLM 识别意图 → 输出结构化参数 → 本地 Python 脚本执行 → 结果回传 LLM → 自然语言总结

关键配置技巧:精准定义 Tool 描述

AI 能不能准确调用,全看 tools 列表里的 description 写得够不够具体。如果你只写“查询数据库”,它经常会乱写字段名。我建议把表结构快照直接写在函数描述里。

{
  "name": "execute_sql_query",
  "description": "执行只读SQL查询。可用表:users(id, name, email, created_at), orders(id, user_id, amount, status)。注意:必须使用 LIMIT 限制结果集,禁止执行 DROP/DELETE 操作。",
  "parameters": {
    "type": "object",
    "properties": {
      "sql": {
        "type": "string",
        "description": "标准的 PostgreSQL SQL 查询语句"
      }
    },
    "required": ["sql"]
  }
}

本地执行端的避坑指南

最容易踩的坑是权限失控。千万不要给 LLM 连接数据库的 root 权限。我创建了一个名为 ai_readonly 的数据库用户,仅授予 SELECT 权限。

执行逻辑建议采用这种结构:

import psycopg2
from openai import OpenAI

client = OpenAI()

def run_query(sql):
    # 建立只读连接
    conn = psycopg2.connect(dbname="mydb", user="ai_readonly", password="password", host="localhost")
    cur = conn.cursor()
    try:
        cur.execute(sql)
        return cur.fetchall()
    except Exception as e:
        return f"SQL Error: {str(e)}"
    finally:
        cur.close()
        conn.close()

# 处理 LLM 返回的 tool_calls
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "帮我看看上个月订单金额最高的前三个用户是谁?"}],
    tools=tools
)

if response.choices[0].message.tool_calls:
    for tool_call in response.choices[0].message.tool_calls:
        # 提取 SQL 并运行
        import json
        args = json.loads(tool_call.function.arguments)
        result = run_query(args['sql'])
        # 将结果喂回给 AI 转化为人话
        # ... 再次调用 API 传入 tool 响应 ...

效率提升点:上下文压缩

如果查询结果集太大,直接塞回给 LLM 会瞬间撑爆 Token 窗口,甚至导致 AI 迷失。我的处理方式是:在 run_query 之后,先判断结果行数。如果超过 20 行,只截取前 5 行并告知 AI “结果过多,已截断”,强制它在 SQL 中使用更精准的过滤条件,而不是在内存里过滤。

这种方案比传统的 RAG 强在能够处理聚合计算(如 SUM, AVG),而不需要把整个数据库向量化。

全部回复 (0)

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

发表回复

支持 Markdown 格式