说人话,查数据:构建一个自然语言驱动的 SQLite 后台

写在前面

AI First 时代:用自然语言操作数据库,让非技术人员也能"写"SQL

"未来,开发能力将不再局限于程序员。"------在大语言模型(LLM)的赋能下,这一设想正加速落地。

最近,我在一个探索性项目中尝试将自然语言转 SQL 的功能嵌入到日常数据操作流程中。通过集成 DeepSeek 等开源大模型,并搭配轻量级的 SQLite 数据库,我快速构建了一个简洁但富有潜力的 "AI 驱动型后台管理原型" 。今天就来聊聊这个思路及其初步实现。

📌 范式演进:从 "Mobile First" 到 "AI First"

回顾技术发展,我们经历了从 PC 优先到移动优先的转变;如今,随着大模型能力的成熟,"AI First" 正逐渐成为新一代应用设计的主流思维。

"以 AI 为核心,结合自然语言生成 SQL 的能力(如 Gemini、DeepSeek 等),将其深度整合进业务系统,让内容编辑、运营人员甚至普通用户都能自主完成数据查询与管理。"

这带来的变革是:不再依赖专业数据库知识或后端支持。用户只需用口语化表达需求------例如"显示上季度活跃用户最多的三个地区"------系统即可自动解析语义、生成合规的 SQL 语句,并返回所需结果。数据访问的门槛,正在被 AI 彻底打破。

让 LLM 看懂你的数据库:Schema 的正确打开方式

在 Text-to-SQL 系统中,给大模型提供表结构(Schema)的方式,直接决定了生成 SQL 的准确性。很多人习惯手写一段自然语言描述,比如:

"employees 表有 id、name、department 和 salary 字段......"

但这种方式既冗余又容易与实际表结构不一致。

我们来看一种更工程化的做法:

Python 复制代码
def get_schema_str(cursor):
    schema = cursor.execute("PRAGMA table_info(employees)").fetchall()
    return "CREATE TABLE EMPLOYEES (\n" + "\n".join([f"{col[1]} {col[2]}" for col in schema]) + "\n)"

这里利用了 SQLite 内置的 PRAGMA table_info 命令,动态获取真实表结构 ,并拼接成标准的 CREATE TABLE 语句。这不仅是语法上的"规范输出",更是对 LLM 训练数据分布的精准对齐------LLM 在预训练阶段见过海量 CREATE TABLE 语句,远比自定义描述更熟悉。

同时,配合 init_db() 中的 CREATE TABLE IF NOT EXISTSINSERT OR IGNORE,整个初始化流程具备幂等性,支持反复运行而不污染数据。这种细节,正是从"能跑"到"可靠"的关键分水岭。

经验之谈:不要让 LLM 猜你的 Schema,要让它"看"到和数据库一模一样的定义。

db.py完整代码如下:

python 复制代码
import sqlite3

def init_db():
    conn = sqlite3.connect("text.db")
    cursor = conn.cursor()
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS employees(
            id INTEGER PRIMARY KEY,
            name TEXT,
            department TEXT,
            salary INTEGER
        )
    """)
    sample_data = [
        (6, "黄佳", "销售", 50000),
        (7, "宁宁", "工程", 75000),
        (8, "谦谦", "销售", 60000),
        (9, "悦悦", "工程", 80000),
        (10, "黄仁勋", "市场", 55000),
        (11, "刘苗苗", "工程", 55001)
    ]
    cursor.executemany("INSERT OR IGNORE INTO employees VALUES(?,?,?,?)", sample_data)
    conn.commit()
    return conn, cursor

def get_schema_str(cursor):
    schema = cursor.execute("PRAGMA table_info(employees)").fetchall()
    return "CREATE TABLE EMPLOYEES (\n" + "\n".join([f"{col[1]} {col[2]}" for col in schema]) + "\n)"

可靠的 SQL 不来自创意,而来自约束

在 Text-to-SQL 系统中,调用大模型的代码往往只占几行,但其背后的 Prompt 设计却决定了整个系统的上限。来看一个典型实现:

llm.py

python 复制代码
from openai import OpenAI

client = OpenAI(
    api_key='your_api_key',
    base_url='https://api.deepseek.com/v1'
)

def ask_deepseek(query, schema):
    prompt = f"""
    这是一个数据库的Schema:
    {schema}
    根据这个Schema,请输出一个SQL查询来回答以下问题。
    只输出SQL查询语句本身,不要使用任何 Markdowm 格式
    不要包含反引号、代码块标记或额外说明
    问题:{query}
    """
    response = client.chat.completions.create(
        model="deepseek-chat",
        max_tokens=2048,
        messages=[{"role": "user", "content": prompt}],
        temperature=0
    )
    return response.choices[0].message.content.strip()

这段代码看似简单,实则体现了三个关键工程原则:

  1. 上下文精准注入 :将动态生成的 CREATE TABLE Schema 直接嵌入 Prompt,确保 LLM 基于真实结构推理;
  2. 输出强约束:明确要求"只输出 SQL",并禁止 Markdown、反引号等常见干扰项------这是后续直接执行 SQL 的前提;
  3. 确定性控制temperature=0 关闭随机性,保证相同输入始终返回相同 SQL,提升系统可预测性。

💡 很多开发者抱怨"LLM 生成的 SQL 不能直接用",其实问题不在模型,而在 Prompt 没有强制规范输出格式。在这里,我们不是在"请求帮助",而是在"下达指令"。

这种克制而精确的交互方式,正是 LLM 从玩具走向生产的关键一步。


🔗 让 LLM 成为你的"自然语言数据库接口

有了可靠的 Schema 上下文和精准的 Prompt 约束,LLM 就不再是"聊天机器人",而是一个可编程的自然语言 SQL 引擎。主流程代码清晰展示了这一思想的落地:

main.py

py 复制代码
from db import init_db, get_schema_str
from llm import ask_deepseek

conn, cursor = init_db()
schema_str = get_schema_str(cursor)

# 1. 查询
question = "工程部门员工的姓名和工资是多少?"
sql_query = ask_deepseek(question, schema_str)
print(sql_query)
results = cursor.execute(sql_query).fetchall()
print(results)

# 2. 插入
question = "在销售部门增加一个新员工,姓名为张三,工资为45000"
sql_query = ask_deepseek(question, schema_str)
print(sql_query)
cursor.execute(sql_query)
conn.commit()

# 3. 删除
question = "删除市场部门的黄仁勋"
sql_query = ask_deepseek(question, schema_str)
print(sql_query)
cursor.execute(sql_query)
conn.commit()

# 4. 查询所有
question = "查询所有员工的信息"
sql_query = ask_deepseek(question, schema_str)
print(sql_query)
results = cursor.execute(sql_query).fetchall()
print(results)

conn.close()

整个过程没有中间解析、没有后处理、没有格式转换------LLM 的输出即系统输入。这种端到端的集成,依赖两个前提:

  1. Schema 动态同步 (来自 get_schema_str),确保 LLM "所见即库中所有";
  2. Prompt 强约束 (来自 ask_deepseek),确保输出是干净、合法的 SQLite 语句。

更值得注意的是,这套流程不仅支持 SELECT,还能处理 INSERTDELETE 等写操作------这意味着用户可以用自然语言完成完整的 CRUD 操作,而开发者只需维护一张表结构。

💡 这不是"AI 写 SQL",而是用自然语言驱动数据库的新交互范式

而实现它的全部秘密,就藏在这十几行看似平凡的 glue code 中。

无需人工干预,从自然语言到数据库结果的完整链路如下:

这个原型足够轻量,非常适合作为你自己实验的起点。如有其他需求,也可在此基础上灵活扩展。

项目结构如下。你可以直接复制上文代码,运行 main.py,即可在控制台看到完整的输出结果。

🎯 自然语言,正在成为新一代数据库的"入口"

通过一个不到百行的原型,我们验证了一个关键趋势:大语言模型 + 精准上下文 + 强约束输出 = 可执行的自然语言数据接口

这不仅仅是"让 AI 写 SQL",而是一次交互范式的迁移------

从"人适应数据库"(学语法、写查询、调接口),

转向"数据库适应人"(说需求、得结果、零编码)。

当然,当前方案仍是一个最小可行原型:它没有权限控制、不支持复杂 JOIN、也未处理模糊语义。但它的价值在于证明了:在特定领域内,LLM 已具备替代传统 CRUD 后端的能力

未来,随着模型对 Schema 理解更深、执行更安全、反馈更智能,我们或许不再需要为简单数据操作开发 API。运营人员一句"把上月离职的销售员工标红",系统就能自动完成查询、更新甚至前端渲染。

而这,正是 AI First 时代最真实的模样

不是炫技,而是让技术消失在体验之中。

代码已开源,思路可复用。你,准备好构建自己的自然语言后台了吗?

相关推荐
gr178543 分钟前
通过dify文件上传能力,解决较大文本与LLM实时交互问题
python·llm·aigc·dify
realhuizhu9 小时前
你有多少次对着设计稿说"感觉不对,但说不上来"?
提示词工程·设计效率·deepseek·ai设计工具·品牌logo
EdisonZhou13 小时前
MAF快速入门(14)快速集成A2A Agent
llm·agent·.net core
gentle coder20 小时前
【langchain】AI应用开发框架
langchain·llm·rag
doll ~CJ1 天前
Large Language Model(LLM)应用开发学习实践(三)
langchain·llm·提示词工程·ai应用
码界奇点1 天前
基于Django的超市管理系统设计与实现
数据库·python·django·sqlite·毕业设计·源代码管理
Rolei_zl1 天前
(AI生成) openClaw 的前世今生
llm·aigc
人工智能培训1 天前
具身智能如何在保证安全的前提下高效探索学习?
语言模型·llm·数据采集·模型量化·多模态学习·具身智能·环境感知
AC赳赳老秦1 天前
DeepSeek一体机部署:中小企业本地化算力成本控制方案
服务器·数据库·人工智能·zookeeper·时序数据库·terraform·deepseek
Elwin Wong1 天前
浅析DeepSeek-OCR v1&v2
人工智能·大模型·llm·ocr·deepseek