跳到正文
土土金API

数据分析与智能问数

智能问数(用自然语言查数据,也叫 Text-to-SQL)的做法是:把相关表的结构和字段说明写进提示词,让模型生成 SQL,程序确认这是一条只读查询后,用只读数据库账号执行,再由模型把查询结果写成几句业务结论。按每月 2 万次提问、另加 300 份报表和表格汇总估算,用各模型最低价分组的实时价格计算,模型费用每月约 ¥395。

价格更新于 2026年11月13日 17:58

月成本估算

假设:每月 2 万次提问(约 100 名业务人员,每人每个工作日 10 次);生成 SQL 每次输入约 4,000 tokens(指令和示例约 1,000、相关表结构约 2,500、问题约 500),输出约 300 tokens,约 10% 校验不通过要重写一次;解读结果每次输入约 1,500 tokens(最多 50 行结果);另有 300 份报表和表格汇总,每份输入约 8,000 tokens 的统计摘要。

¥394.66/ 月

  • 问题向量化¥0.04
  • 生成 SQL¥291.2
  • 校验不通过重写(约 10%)¥31.92
  • 解读查询结果¥67.2
  • 报表与表格汇总¥4.3
看用量假设

业务问题

运营、销售和管理层经常要临时查一个数:上周各渠道的退货率、华东区有多少复购用户、哪家门店的客单价降得最多。每次都要找数据团队写 SQL,简单的问题也要排队等。

大模型可以把这类问题翻译成 SQL,但它不知道你们的表名、字段含义和统计口径,容易编出不存在的字段,或者漏掉“已退款订单不计入销售额”这样的条件。生成的语句如果不加检查就执行,还可能修改数据,或者一次扫描整张大表、拖慢数据库。

稳妥的做法是:只把相关表的结构交给模型,生成的 SQL 先过程序校验,再用只读账号在只读副本上执行,限制返回行数和执行时间;结果和 SQL 一起展示给用户,口径对不对一眼就能核对。

推荐模型组合

推荐模型按实时目录自动选取,价格取各模型最低价分组,更新于 2026年11月13日 17:58。点模型名可查看全部分组价格。

参考架构

  1. 1

    整理表结构说明

    为开放查询的表写说明:表的用途、每个字段的含义和单位、枚举值、表之间怎么关联,以及“销售额是否含退款”这类统计口径。说明写得越清楚,生成的 SQL 越准。

  2. 2

    找出相关的表

    表多的时候,把每张表的说明向量化入库;用户提问时取最相关的 3 到 5 张表,把它们的建表语句和说明放进提示词。

  3. 3

    生成 SQL

    提示词里写明数据库类型(MySQL、PostgreSQL 等)、可用的表结构和几条“问题 → 核对过的 SQL”示例,要求只输出一条查询语句,不加解释。

  4. 4

    程序校验

    执行前检查:只能有一条语句,必须以 SELECT 或 WITH 开头,不能含 INSERT、UPDATE、DELETE、DROP 等写操作,只引用允许查询的表,并且带 LIMIT。不合格的把原因交回模型重写一次,仍不合格就请用户换个问法。

  5. 5

    只读执行

    用只有查询权限的数据库账号连接只读副本或数据仓库,设置查询超时和返回行数上限。即使校验漏掉了什么,这个账号也改不了数据。

  6. 6

    解读与展示

    把查询结果交给模型写成两三句结论,和 SQL、原始数据一起展示给用户。月度报表和上传的表格,先用程序算好合计、同比环比和排名,再让模型写文字说明,数字以程序算出的为准。

成本估算

假设:每月 2 万次提问(约 100 名业务人员,每人每个工作日 10 次);生成 SQL 每次输入约 4,000 tokens(指令和示例约 1,000、相关表结构约 2,500、问题约 500),输出约 300 tokens,约 10% 校验不通过要重写一次;解读结果每次输入约 1,500 tokens(最多 50 行结果);另有 300 份报表和表格汇总,每份输入约 8,000 tokens 的统计摘要。

项目模型用量假设费用
问题向量化text-embedding-3-small20,000 次 × 输入 50 tokens¥0.04
生成 SQLdeepseek-v4.1-flash20,000 次 × 输入 4,000 + 输出 300 tokens¥291.2
校验不通过重写(约 10%)deepseek-v4.1-flash2,000 次 × 输入 4,500 + 输出 300 tokens¥31.92
解读查询结果qwen3.5-plus20,000 次 × 输入 1,500 + 输出 250 tokens¥67.2
报表与表格汇总qwen3.5-plus300 次 × 输入 8,000 + 输出 800 tokens¥4.3
合计(每月)¥394.66

按各模型最低价分组的实时价格计算,价格更新于 2026年11月13日 17:58。

只含模型调用费用,不含数据库、向量库和服务器成本。表结构说明首次向量化是一次性费用,按 300 张表、每张说明约 400 tokens 算,约 12 万 tokens。生成 SQL 的输入里表结构和示例占大头,模型支持上下文缓存时命中部分按缓存读取价计费,实际费用会更低;推理模型的思考过程按输出计费,输出可能多于表中假设。提问量翻倍,费用大致翻倍。

示例代码

模型生成 SQL,程序检查这条语句:只有一条查询、只查允许的表、带 LIMIT,通过后用只读连接执行,再让模型解读结果。示例用 SQLite,换成你们的数据库和只读账号即可。

示例代码(Python,智能问数)
import os
import re
import sqlite3
from openai import OpenAI

client = OpenAI(base_url="https://www.tutujin.com/v1", api_key=os.environ["TUTUJIN_API_KEY"])

# Only the tables relevant to the question (with many tables, find them by embedding search with text-embedding-3-small).
SCHEMA = """
CREATE TABLE stores (id INTEGER PRIMARY KEY, name TEXT, region TEXT);  -- region: east, north, south, west
CREATE TABLE orders (id INTEGER PRIMARY KEY, store_id INTEGER, paid_at TEXT, amount REAL, status TEXT);
-- status: paid or refunded. Sales = sum(amount) of paid orders. paid_at looks like 2026-10-31 18:05:00.
"""
ALLOWED = {"stores", "orders"}
WRITES = re.compile(r"\b(insert|update|delete|drop|alter|create|truncate|attach|pragma|grant)\b", re.I)


def write_sql(question, problem=None):
    prompt = "Question: " + question
    if problem:
        prompt += "\nYour previous query was rejected (" + problem + "). Write it again."
    resp = client.chat.completions.create(
        model="deepseek-v4.1-flash",
        messages=[
            {"role": "system", "content": "Write one SQLite SELECT query for the question, using only these tables:\n"
             + SCHEMA + "\nAlways add a LIMIT. Reply with the SQL only."},
            {"role": "user", "content": prompt},
        ],
    )
    sql = resp.choices[0].message.content.strip()
    return re.sub(r"^\x60{3}(?:sql)?\s*|\s*\x60{3}$", "", sql).strip().rstrip(";")  # drop a code fence


def check(sql):
    """Why the query is unsafe, or None. A SQL parser is sturdier than regexes; keep the read-only user anyway."""
    if ";" in sql:
        return "more than one statement"
    if not re.match(r"(select|with)\b", sql, re.I):
        return "not a SELECT query"
    if WRITES.search(sql):
        return "contains a write keyword"
    ctes = set(re.findall(r"\b(\w+)\s+as\s*\(", sql, re.I))
    tables = set(re.findall(r"\b(?:from|join)\s+(\w+)", sql, re.I)) - ctes
    if not tables <= ALLOWED:
        return "unknown table " + ", ".join(sorted(tables - ALLOWED))
    if not re.search(r"\blimit\s+\d+", sql, re.I):
        return "no LIMIT"
    return None


def ask(question):
    sql = write_sql(question)
    problem = check(sql)
    if problem:  # one rewrite, then give up
        sql = write_sql(question, problem)
        problem = check(sql)
        if problem:
            raise ValueError("no safe query: " + problem)
    # read-only connection; in production, a SELECT-only database user on a replica, with a query timeout
    db = sqlite3.connect("file:shop.db?mode=ro", uri=True)
    rows = db.execute(sql).fetchmany(50)
    db.close()
    resp = client.chat.completions.create(
        model="qwen3.5-plus",
        messages=[
            {"role": "system", "content": "Explain the result in two or three sentences for a business reader. Use only the numbers given."},
            {"role": "user", "content": f"Question: {question}\nSQL: {sql}\nRows: {rows}"},
        ],
    )
    return sql, rows, resp.choices[0].message.content


sql, rows, summary = ask("Which 5 stores in the east region had the highest sales last month?")
print(sql, rows, summary, sep="\n\n")

用一把 Key 试试这个方案

注册后在控制台创建 API Key,把上面代码里的 base_url 和 Key 换成你的就能运行。企业采购、开发票可以加客服微信 JsnonoChat。

土土金客服微信二维码
微信JsnonoChat

扫码或搜索微信号添加客服

常见问题

智能问数每月要花多少钱?

按每月 2 万次提问、每次给模型约 4,000 tokens 的表结构和示例,再加 300 份报表汇总估算,用最低价分组计算约 ¥395。费用主要取决于提问量和每次放进提示词的表结构有多长。

模型生成的 SQL 能直接执行吗?

不建议。执行前用程序检查:只能是一条查询、只查允许的表、必须带 LIMIT;执行时用只有查询权限的数据库账号,连只读副本或数据仓库,并设置查询超时。这样即使模型写错,也改不了数据,也不会拖垮主库。

查出来的数一定对吗?

不一定。SQL 能执行不代表口径正确,比如漏掉了退款订单、时区或去重条件。建议把 SQL 和结果一起展示给用户;销售额、毛利这类关键指标,用你们定义好的标准 SQL 或指标表,模型只负责把问题对应到这些指标上。

表很多、字段名都是缩写怎么办?

给每张表和每个字段写中文说明,包括单位、枚举值和统计口径;表多时先用向量检索找出相关的几张表,只把它们放进提示词。再把用户问过的典型问题和核对过的 SQL 整理成示例,一起放进提示词。

能分析 Excel 表格吗?

可以,但不要把整张表交给模型去加总和比较。先用程序(例如 pandas)读取表格,算好合计、同比环比和排名,再把这些结果交给模型写成文字说明。大模型做算术容易出错,数字以程序算出的为准。

业务数据会发给模型吗?

生成 SQL 时,请求里只需要表结构和字段说明,不需要真实数据;解读结果时,查询结果会随请求经本站转发给模型服务处理。涉及个人信息或敏感经营数据的,先脱敏或只发送聚合后的数字,并按你们自己的数据合规要求评估。