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.sql 或 samples/ 脱敏 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。


相关推荐
IT_陈寒38 分钟前
React的setState真是个演员,你以为它同步其实在装睡
前端·人工智能·后端
ServBay2 小时前
Claude Fable 5.5 测试曝光,但它在悄悄给你打分
后端·ai编程·claude
IT规划师3 小时前
一文讲透五种发布机制:滚动、蓝绿、金丝雀、红黑与 AB
后端·面试
一条Go4 小时前
两套权限目录,三重闸门:Alioth 的多租户 RBAC 为什么这么拧
后端·程序员·github
Tokenfree4 小时前
把多模态 OCR 接进业务系统:四千张运单,三个坑
后端
用户859313061354 小时前
我给 AI Agent 写了个下载器:293KB 的网页,不再吃掉 7 万 token
后端
phil65 小时前
沙箱核心功能系列 06:编排调度与资源管理
后端
小兔子5 小时前
if (system(cmd) != 0) 判不出命令失败:它返回的是等待状态,不是退出码
后端
艾迪的技术之路5 小时前
16k 条慢查询,128 张分表,我这么解决
后端·github
dpharness5 小时前
我踩过的四个记忆坑,从预算到换机
前端·后端