Claude Code Lab-2(上):自然语言查库助手

中文问库 AI 出 DELETE?Lab-2 只读 NL2SQL + 代码层拦截。

她试过把 schema 贴进 Claude Code 让 AI 写 SQL,结果一次生成了带 DELETE 的语句,还好她先 EXPLAIN 没真跑。

Lab-2 要做的是:中文问题 → 生成 SELECT → 在本地 SQLite 样例库只读执行 → 表格输出 。不写库、不连线上。这篇是 v0.1:单库、单轮问答、人眼确认 SQL 再执行


链路总览

步骤 谁做 说明
1. 加载 schema 程序 / @ 文件 schema/orders.sqlsamples/ 脱敏 DDL
2. 生成 SQL Claude Code Prompt 约束 仅 SELECT
3. 人审 必须 看有没有 JOIN 爆炸、全表扫
4. 执行 程序 只读连接,超时、行数上限
5. 展示 终端表格 或 CSV

铁律: 生成 SQL 默认 不自动执行;v0.1 可以「打印 SQL + 问 y/n」,v0.2 再接 Command 自动化(第 13 篇)。


v0.1 范围

内容
数据库 单个 SQLite 文件 samples/demo.db(培训脱敏数据)
输入 中文一句,如「有多少订单状态是 cancelled」
输出 SQL 文本 + 查询结果(≤100 行)
禁止 INSERT/UPDATE/DELETE/DDL;多库;连线上

schema 怎么喂给 Claude Code

不要把整个线上 dump 贴进去。Lab 用 精简 DDL + 列注释

sql 复制代码
-- samples/schema/orders.sql
CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  status TEXT NOT NULL,  -- pending|paid|cancelled|shipped
  amount_cents INTEGER NOT NULL,
  created_at TEXT NOT NULL
);

Prompt:

text 复制代码
@samples/schema/orders.sql @CLAUDE.md
用户问题:有多少订单 status 是 cancelled?

只输出一条 SQLite SELECT,不要 markdown 代码块包裹。
禁止 UPDATE/DELETE/INSERT/DDL。
表名与列名必须与 schema 完全一致,禁止猜。

执行层:Python 只读守卫

python 复制代码
FORBIDDEN = ("insert", "update", "delete", "drop", "alter", "create", "attach")

def assert_readonly(sql: str) -> None:
    head = sql.strip().split()[0].lower()
    if head != "select" and head != "with":
        raise ValueError("only SELECT allowed")
    low = sql.lower()
    for kw in FORBIDDEN:
        if kw in low:
            raise ValueError(f"forbidden keyword: {kw}")

def run_query(conn, sql: str, max_rows: int = 100):
    assert_readonly(sql)
    cur = conn.execute(sql)
    rows = cur.fetchmany(max_rows + 1)
    if len(rows) > max_rows:
        raise ValueError(f"result exceeds {max_rows} rows")
    return rows

为什么不用「Prompt 说只读就够了」: 模型会漏;代码层拦截是 DBA 的底线。


CLI v0.1 用法

bash 复制代码
python -m nl2sql ask "有多少 cancelled 订单"

实现可以拆两阶段对话:

  1. Claude Code 只 生成 SQL (人复制到文件 last.sql 检查)
  2. 本地脚本 nl2sql run --file last.sql 执行

培训初期 强制人工 y/n,习惯养成后再做 Command。


踩坑实录

坑 1:AI 编造 order_status

schema 里是 status

修正: Prompt 写「必须与 @schema 一致」;执行前用 EXPLAIN QUERY PLAN 或简单 PRAGMA table_info

坑 2:COUNT 变 DELETE(刘姐那次)

修正: assert_readonly + 团队 Prompt 模板 prompts/nl2sql-select-only.md 写入 CLAUDE.md 索引。

坑 3:一次 Agent 写「生成+执行+Web 界面」

修正: v0.1 scope 写死「终端 + 单库」;Web 进非目标。


四阶段怎么套 Lab-2

阶段 产出
澄清 notes/nl2sql-v0.1-scope.md(样例库、行数上限、确认流程)
方案 模块划分:schema_loader, generator(调 Claude), runner
实现 先 runner + 假 SQL;再接 Claude 生成
验证 10 个固定中文问题 + 期望 SQL 或期望结果快照

小结

  1. Lab-2 v0.1 = 中文 → SELECT → 人审 → 只读执行
  2. schema @ 引用 + 代码层禁写 双保险。
  3. 结果行数上限、禁止多语句(; 分割检测)都要写进 runner。
  4. 下篇加 Command、多库与测试自动化。

下一篇

第 12 篇《Command、Agent、Hook 各干什么》 ------ 固定流程用 Command,长任务用 Agent,提交前用 Hook。

第 13 篇《Lab-2(下):多库支持与自动化》 ------ 多 SQLite、schema 切换、/ask-db Command。


相关推荐
吃饱了得干活2 分钟前
Spring Cloud Gateway限流:从Redis到Sentinel的三种方案
后端·spring cloud
IT_陈寒7 分钟前
Python的GIL让我以为CPU跑满了,结果...
前端·人工智能·后端
Jiude14 分钟前
AI 产品的几种付费方式
后端·架构·openai
Java面试题总结1 小时前
Go 语言大白话入门 6 - 判断与循环
开发语言·后端·golang
hsg772 小时前
简述:Rust、GeoRust、自主研发GIS平台
开发语言·后端·rust
谭光志10 小时前
Vibe Coding 时代,程序员该何去何从
前端·后端·ai编程
GoGeekBaird10 小时前
我用 BeeWeave 跑完了一次完整写作闭环
后端·github
仿生狮子11 小时前
别再说“全栈”了,AI 时代团队只认这 5 种人
前端·人工智能·后端
Reart14 小时前
Leetcode 213.打家劫舍2(内含闲谈,打劫真是技术活,好题,716)
后端·算法
触底反弹14 小时前
🔥 RAG 到底是怎么工作的?掰开揉碎了给你讲明白!
javascript·人工智能·后端