
把“智能问数”想成一个套了 ChatGPT 外壳的 SQL 查询工具是我见过的最贵的误会。不少团队立项的时候PPT 里写的是“自然语言取数”“AI 生成报表”“对话式数据分析”听起来很性感。可一旦进入需求评审问题马上转向用户问“这个月卖得怎么样”到底是指订单金额、回款金额还是毛利“东北区”是按订单收货地址算还是按分公司归属算大模型生成的 SQL 如果真的把全表扫了一遍数据权限怎么控回答错了责任归算法还是归产品这些才是智能问数项目的真实阻力。今天这篇文章我会用 AI 产品经理的视角把一个智能问数也叫生成式 BI项目从 0 到 1 落地涉及的需求拆解、技术链路、提示词设计、权限治理、效果评估全部过一遍。不是泛泛讲概念而是把它当成一个需要长期运营的数据产品来拆。如果你正准备在公司内部做智能问数或者刚接手类似项目这篇文章可以帮你避开前三板斧的坑。哪怕你现在是后端开发、数据分析师或测试工程师看完也能理解为什么这个产品不能只靠一个“大模型 API 数据库”堆出来。1. 智能问数到底解决什么问题先看三个真实场景。第一个场景来自业务线。销售负责人想看一眼华南区本月的 Top 10 客户贡献正常流程是找数据分析师提需求分析师根据排期决定今天还是明天给如果数据口径有疑问还要来回确认。一个简单取数需求链路是三到五个工作日。第二个场景来自数据部门。你问三个业务主管“本月续费率是多少”可能得到三个数字。有人按合同金额算有人按回款算有人把试用期客户也算进去了。口径不统一数据越看越乱业务对数据部门的信任一点点流失。第三个场景来自 BI 平台。公司采购了成熟的 BI 工具也建好了数据仓库。但业务人员打开报表工具后发现要自己拖拽维度、理解字段含义、知道过滤条件怎么加学习成本远超预期。最后报表平台成了少数几个分析师的自留地。智能问数试图解决的核心问题不是“提高取数速度”而是降低从业务问题到数据结果之间的认知成本。它把“会 SQL、懂数据模型、知道口径”这些门槛用自然语言交互的方式包裹起来让业务人员用提问的方式获得数据。这里要给出一个明确判断智能问数不是数据分析师的替代品而是消化“简单但高频”的取数请求。它最适合的场景是那些重复发生、答案相对标准、口径已经固化的查询。真正复杂的归因分析、AB 实验解读、业务异动排查仍然需要数据分析师介入。反过来如果一家公司连数据仓库都是乱的指标口径散落在 Excel 和邮件里那智能问数项目的第一优先级不是买模型而是先做指标治理。否则大模型越“聪明”生成的错误结果传播得越快。2. 核心概念NL2SQL、生成式 BI 与智能问数 Agent聊智能问数之前几个基础概念先对齐。2.1 NL2SQL 是什么NL2SQL 全称 Natural Language to SQL就是让机器把自然语言问题自动转换成可执行的 SQL 查询语句。它是智能问数最底层的技术能力。比如用户输入“上个月各区域的销售额”NL2SQL 模块需要把它转换成类似下面的查询SELECT region, SUM(amount) AS total_amount FROM sales_order WHERE order_date BETWEEN 2025-01-01 AND 2025-01-31 GROUP BY region一般认为 NL2SQL 的历史可以追溯到 2015 年前后的 WikiSQL 数据集但那时的模型只能处理单表简单查询。真正让它进入工程视野的是大语言模型带来的语义理解能力提升以及 Text2SQL 评测集出现后模型效果可以被量化评估。2.2 生成式 BI 与传统 BI 的区别生成式 BI 不是简单地把报表工具加一个搜索框而是在交互方式、分析路径和交付形态上都发生了变化。维度传统 BI自助式 BI生成式 BI使用门槛管理员做报表业务看结果业务拖拽字段理解维度模型直接自然语言提问交互方式固定看板、定时邮件拖拽图表对话式追问数据口径报表层固定用户自行选择易出错语义层统一管理分析深度浅看结果中靠用户操作中高依赖提示词与模型能力部署成本中等中等较高涉及模型、提示词、评估体系传统 BI 的逻辑是“先定义报表再给业务使用”。生成式 BI 的逻辑是“先定义数据语义再让模型动态生成分析”。前者是固定答案后者是实时生成答案这也意味着答案的不确定性必须被产品机制对冲。2.3 智能问数 Agent 的组成在实际项目中智能问数产品通常是一个 Agent 应用而不只是单个模型接口。一个最小可用的智能问数 Agent 至少包含五个模块自然语言理解模块识别用户意图、提取时间条件、地区、品类等实体。指标与语义映射模块把用户口语化的表达匹配到标准指标和维度。比如“卖了多少”可能对应“销售额”或“销售量”。SQL 生成模块基于数据字典和对话上下文生成 SQL。执行与权限控制模块校验权限、改写 SQL、执行查询、设置返回行数上限。结果生成模块把 SQL 查询结果转换成自然语言摘要或调用图表能力生成可视化。这五个模块拆开看都不难难在串联。产品经理要把用户从“提问”到“理解答案”的全流程体验设计好技术团队则要保证每一环可观测、可干预、可回退。2.4 指标语义层最容易忽略的部分很多团队做智能问数一上来就研究大模型提示词却忘了先搭指标语义层。所谓指标语义层是在物理表和用户问题之间增加一层“业务翻译”。它定义了每个指标的看数公式、可选维度、数据来源表。比如“GMV”在语义层里应该是“已支付订单金额之和”并且限定订单状态为已支付。没有这一层大模型面对“销售额”时只能靠猜。同一个词在不同表里含义不同同一个指标在不同部门口径不同最终生成的 SQL 五花八门业务根本不敢信。从产品经理的角度指标语义层不只是技术组件更是数据治理的抓手。建好了它智能问数、传统报表、数据 API 都能复用同一套口径定义。3. AI 产品经理如何拆智能问数需求产品经理拿到智能问数项目第一步不是画原型而是回答三个问题给谁用、回答什么问题、哪些问题不能回答。3.1 用户分层智能问数的用户通常可以分为三类一线业务人员比如销售、运营、客服。他们的特点是问题口语化、高频、简单往往只关心自己负责的板块。中层管理者比如区域经理、部门负责人。他们关注目标完成率、趋势变化、团队排名问题带有比较和归因倾向。管理层关注核心经营指标问题更宏观有时会涉及跨域数据。产品经理需要明确首期服务哪一层。我的建议是先做透一线业务人员的高频取数场景原因有三场景标准化程度高、口径容易收敛、价值感知最快。3.2 问题清单整理启动前可以找业务方收集过去三个月的取数需求记录整理成一张问题清单。每条记录包含用户原始提问用户角色背后对应的真实指标涉及的数据表与过滤条件需求频率这张清单既是产品需求文档的输入也是后续效果评估的测试集基础。没有这个动作智能问数上线后很容易出现“业务问的问题模型答不了模型答得好的问题业务根本不问”的尴尬。3.3 需求优先级矩阵建议从四个维度评估每个需求优先级发生频率一个月出现几次。口径标准化程度是否已经被数据团队定义过。业务价值答错或不出结果的损失有多大。实现难度涉及几张表、需要多少上下文理解。只有频率高、口径明确、价值高且难度可控的需求才值得放进 MVP 范围。那种一个月只问一次的复杂分析让它走人工取数通道反而更稳妥。3.4 一个关键取舍智能问数产品在 MVP 阶段必须接受一个事实不是所有问题都应该用大模型回答。遇到以下情况产品里要设计“转人工”或“不支持”的兜底路径问题涉及数据权限之外的表。问题本身是开放式归因分析SQL 无法直接回答。指标尚未在语义层定义。模型生成 SQL 的置信度低于阈值。聪明的产品不是让用户觉得“什么都能问”而是让用户知道“哪些问题问得最好”然后逐步扩大能力边界。4. 技术链路与架构设计智能问数项目的技术链路从用户提问到结果展示大致可以拆成六个环节用户输入 → 查询改写与意图识别 → 指标匹配与上下文管理 → SQL 生成 → SQL 安全执行 → 结果解析与可视化下面逐一说明。4.1 查询改写与意图识别用户输入往往是不完整的。比如“跟上周比呢”如果没有上下文模型不知道“上周”指什么。因此系统需要维护多轮对话状态自动把省略部分补全。意图识别则要做分类是取数、看图、做比较还是闲聊。建议在入口处做一层判断业务问题才进入后续链路无关问题直接拦截。4.2 指标匹配与上下文管理这一层连接语义层。用户的“卖了多少”“表现怎么样”要通过倒排索引或模型匹配到标准指标。匹配结果建议返回多个候选并把候选指标及解释让用户确认。这看起来多了一步交互但在实际项目中非常有用。因为直接让模型猜猜错了用户也看不出来。让用户点选候选指标本质上是把“隐含的口径确认”显性化。4.3 SQL 生成这是大模型主要发挥作用的环节。推荐做法不是直接把整个问题丢给模型而是把“数据字典 Schema 指标定义 用户原始问题 对话历史 少量示例”组合成结构化提示词要求模型只输出 SQL 或 JSON。4.4 SQL 安全执行大模型生成的 SQL 不能直接执行。必须经过三层防线只读校验把 SQL 改写成只读模式禁止 UPDATE、DELETE、DDL。权限注入根据登录用户的数据权限自动拼接行级过滤条件。资源限制强制限制返回行数比如最多返回 1000 行超时自动终止。这三层防线从产品规划第一天就要设计进去。它解决的不是性能问题而是数据安全问题。4.5 结果解析与可视化拿到执行结果后需要根据用户问题和数据特征自动决定展示形态。一个数字可以直接输出时间趋势用折线图地区对比用柱状图地区分布用地图。这一步的规则引擎要尽量简单稳定不依赖模型自由发挥。5. 提示词设计与代码实现示例这一节给出可落地的示例。需要注意不同大模型 API 格式不同下面代码以通用理解为主注意适配自己项目的模型服务。5.1 系统提示词框架智能问数项目的提示词不是一句话而是一整套结构化指令。建议放在单独的prompt_templates/sql_generation.txt文件中管理。假设数据有两张表分别是订单表sales_order和区域表dim_region提示词可以这样设计你现在是一名资深数据分析师负责根据用户的业务问题生成 SQL 查询语句。 请严格按照以下数据字典和业务规则执行不要臆造不存在的字段。 【数据表结构】 表名sales_order - order_id VARCHAR 订单号 - order_date DATE 下单日期 - amount DECIMAL 订单金额 - region_id INT 区域ID - product_category VARCHAR 产品品类 - customer_level VARCHAR 客户等级普通/银卡/金卡 表名dim_region - region_id INT 区域ID - region_name VARCHAR 区域名称 - company_id INT 分公司ID 【业务规则】 1. amount 指的是订单金额单位是元不包含退款订单。 2. 查询“销售额”时对 amount 做 SUM 汇总。 3. 默认时间范围为最近 30 天除非用户明确指定时间。 4. 生成 SQL 时禁止使用事务、禁止修改数据只能使用 SELECT。 【输出要求】 只输出合法的 SQL 语句不要解释过程。 如果问题不涉及数据查询请输出NOT_SUPPORTED这个提示词框架有三个好处约束了字段范围、固定了计算口径、规定了模型输出的边界。实际项目中提示词里还可以加入少量正确示例即 few-shot 示例帮助模型理解复杂查询模式。5.2 后端调用与 SQL 生成模块接下来是一个 Python 服务端的示例代码。假设我们封装了一个LLMClient实际项目里可以替换为任意模型服务 SDK。重点看整体逻辑不纠结具体客户端实现。# 文件路径service/sql_generator.py import json from typing import Dict, Optional class SQLGenerator: 负责把用户问题转换为 SQL 的模块 def __init__(self, llm_client, template_loader): self.llm_client llm_client self.template_loader template_loader def generate( self, user_question: str, context: Dict[str, Optional[str]], username: str, ) - str: system_prompt self.template_loader.load(sql_generation.txt) user_prompt self._build_user_prompt(user_question, context) messages [ {role: system, content: system_prompt}, {role: user, content: user_prompt}, ] response self.llm_client.chat( messagesmessages, temperature0.1, # SQL 生成场景尽量降低随机性 ) return self._extract_sql(response) def _build_user_prompt(self, user_question: str, context: Dict) - str: # 把多轮上下文、当前问题、时间条件拼成结构化输入 history context.get(history, ) current_date context.get(current_date, ) return ( f当前日期{current_date}\n f对话历史\n{history}\n f用户问题{user_question}\n ) def _extract_sql(self, response: str) - str: # 如果模型返回了 markdown 代码块需要去掉外壳 if sql in response: return response.split(sql)[1].split()[0].strip() if in response: return response.split()[1].split()[0].strip() return response.strip()这里有两个容易被忽略的细节第一temperature要调低SQL 生成不是创意写作随机性越低越好第二模型输出要做格式化清洗很多模型习惯返回 Markdown 代码块直接拼接会执行失败。5.3 权限注入与安全校验示例生成的 SQL 不能直接执行。下面是一个行级权限注入函数它的作用是根据用户所属区域自动把 SQL 包装成带过滤条件的子查询。# 文件路径service/sql_security.py import re from typing import Dict def validate_readonly(sql: str) - bool: 校验 SQL 是否为只读查询禁止非 SELECT 开头 stripped sql.strip().lower() return stripped.startswith(select) def add_row_permission_filter(sql: str, user_permission: Dict[str, list]) - str: 根据用户权限注入行级过滤条件。 示例user_permission {region_name: [华南区, 华东区]} if not user_permission: return sql region_list user_permission.get(region_name, []) if not region_list: return sql placeholders ,.join([{}.format(r) for r in region_list]) wrapped_sql ( fSELECT * FROM (\n{sql}\n) AS protected_query fWHERE region_name IN ({placeholders}) ) return wrapped_sql def limit_result_rows(sql: str, max_rows: int 1000) - str: 给 SQL 增加返回行数上限防止一次查询拖垮数据库。 if limit in sql.lower(): return sql return f{sql.rstrip().rstrip(;)} LIMIT {max_rows}在服务层执行 SQL 前应该按照“先校验、再注入权限、最后限制行数”的顺序依次调用。# 文件路径service/query_service.py from service.sql_security import ( validate_readonly, add_row_permission_filter, limit_result_rows, ) class QueryService: def execute(self, sql: str, user_permission: dict): if not validate_readonly(sql): raise ValueError(仅支持 SELECT 查询) safe_sql add_row_permission_filter(sql, user_permission) safe_sql limit_result_rows(safe_sql, max_rows1000) # 这里的 db 连接对象由项目自行管理 result db_connector.query(safe_sql) return result这套逻辑的价值在于即使大模型生成的 SQL 漏掉了权限过滤条件最终执行层的安全函数也会强制兜底。权限控制绝不能依赖模型自觉。6. 效果评估智能问数怎么量化好不好智能问数和传统报表不同它没有唯一的“正确答案”所以必须建立一套评估机制。否则你无法回答“模型到底行不行”这个问题。6.1 离线评估在开发阶段建议先建一个评估数据集。这个数据集不用很大但必须是真实用户问题。每一条包括原始问题文本。对应的标准 SQL。涉及的指标和维度。期望回答类型。评估指标可以有四类指标类别指标名称说明SQL 正确率Execution Accuracy生成 SQL 执行结果与标准 SQL 结果是否一致SQL 逻辑正确率Logical Match忽略表别名差异SQL 逻辑是否等价指标识别准确率Metric Accuracy是否正确识别用户问的指标业务可接受率Human Accept Rate业务人员是否认可这个结果这里最推荐优先看Execution Accuracy。因为它容易被自动化而且直接反映用户最终看到的数据对不对。逻辑等价判断目前自动化还不够可靠建议配合人工抽检。6.2 评测脚本示例下面是一个简单的离线评测脚本结构实际使用时可以把评测集放在 SQLite 或本地文件中。# 文件路径evaluate/evaluate_dataset.py from service.sql_generator import SQLGenerator TEST_CASES [ { question: 上个月每个区域的销售额是多少, expected_sql: SELECT region_name, SUM(amount) ..., metric: 销售额, }, { question: 最近7天金卡客户的订单量, expected_sql: SELECT COUNT(*) ..., metric: 订单量, }, ] def run_offline_evaluation(sql_generator: SQLGenerator): total len(TEST_CASES) exec_ok 0 for case in TEST_CASES: generated_sql sql_generator.generate( user_questioncase[question], context{}, usernameevaluate_user, ) # 这里需要接入 SQL 执行器对比结果是否一致 if execute_and_compare(generated_sql, case[expected_sql]): exec_ok 1 print(fExecution Accuracy: {exec_ok / total:.2%})评测集要持续维护。每上线一个新版本模型都要在同样的测试集上跑一遍确保效果没有回退。6.3 线上体验评估离线评测通过后还需要做线上灰度。建议挑选一到两个业务团队以小范围灰度方式试用用三个指标判断是否值得全量推广回答成功率多少比例的问题最终成功返回了结果。用户留存率试用用户第二周是否还在使用。提问重复率用户是否会以更高阶的方式继续追问。回答成功率不是越高越好高也可能是因为问题太简单。要结合用户业务数据来判断系统是否真正消化了高频取数需求。7. 常见问题与排查思路智能问数项目上线后问题往往是综合性的。这里整理几个高频问题方便排查。问题现象可能原因排查方式解决方案用户问题明明有数据模型却说查询不到指标未在语义层定义或匹配到了错误指标查看日志中指标匹配的候选结果补充语义层指标和同义词生成的 SQL 字段名不存在Schema 未更新模型看到了过期结构对比数据字典与数据库实际结构建立 Schema 自动同步机制查询结果正确但回答语气生硬结果生成 prompt 缺少解释性指令查看结果生成模块的提示词增加数据分析口径说明要求用户问的比较问题回答不了多轮上下文丢失模型看不到上一轮指标查看对话历史传递是否完整修复上下文管理逻辑SQL 执行超时大表缺少分区过滤条件或指标模型复杂查看数据库慢查询日志增加执行超时与提示词约束同一问题两次结果不同模型随机性过高或数据实时变化检查 temperature 设置与数据仓库更新频率调低 temperature固定时间口径排查时需要先看链路日志。智能问数项目一定要在最初设计时就埋好日志用户原问题、改写后问题、匹配到的指标、生成的 SQL、执行的 SQL、执行耗时、最终回答文本。没有日志问题只能靠猜。8. 工程化落地的关键治理与最佳实践8.1 指标治理是前提智能问数能不能让业务放心用取决于指标口径是不是统一。建议在项目启动前先由数据团队输出一本“指标字典”每个指标至少包含指标名称、指标定义、计算公式、统计维度、数据来源、负责人。这不是一次性工作。业务调整、新增业务线时指标字典要同步更新否则模型能力越强错误信息传播越广。8.2 权限设计要前置不要把权限控制留给模型。最佳的权限设计是“数据源层 语义层 SQL执行层”三层同时控制。数据源层保证用户只能连接被授权的数据源。语义层保证未授权的指标和维度不会出现在候选列表里。SQL执行层强制注入行级过滤条件。当用户问了一个超出权限范围的问题时产品不要直接给出空结果而应该友好提示“当前账号没有查看该数据的权限如需开通请联系数据管理员”。8.3 兜底与转人工无论模型多强智能问数系统都必须设计“不知道”的回答路径。推荐的做法是当模型无法确定用户意图时主动给出候选指标让用户确认。当生成 SQL 置信度低时显示“暂不支持该问题可以换个说法或联系数据分析师”。当连续多次失败时自动推荐人工取数入口。兜底不是系统能力不足的表现而是产品成熟的表现。它告诉用户边界在哪里比让用户对结果产生误判要安全得多。8.4 灰度发布与反馈闭环上线智能问数建议按以下节奏推进内部小范围测试数据团队、产品团队自己先用。单一业务团队灰度选一个配合度高、需求明确的团队。效果复盘评估回答成功率、问题覆盖度、用户满意度。分阶段扩大范围按业务线逐步放开每次放开都观察权限和效果指标。每次用户对回答点“赞”或“踩”都要进入反馈数据库。这个数据的价值不亚于模型训练数据——它直接告诉你产品在真实场景里的薄弱点。8.5 大模型之外的稳定性投入智能问数有一个容易被忽略的工程问题大模型接口延迟和故障影响用户体验。建议在架构上做如下设计模型调用设置超时时间超时后切换备用模型或返回统一提示语。对高频问题做缓存模型生成过的 SQL 可以按“语义指纹”缓存减少重复调用成本。维护模型输入输出的敏感信息过滤避免用户输入的手机号、合同号等泄露到外部模型服务。生成式 BI 不是“模型很聪明就能上线”的产品它更像是一个需要长期维护的数据基础设施稳定性、成本、安全都需要产品经理和工程团队一起兜住。9. 总结与后续学习方向智能问数项目真正考验的不是大模型调参能力而是产品经理能不能把模糊的业务诉求拆成指标、口径、权限、上下文、兜底策略这些可工程化的部分。如果你准备上手这样的项目建议按这个顺序实践先收集整理高频问题清单再协同数据团队建立指标语义层然后开发最小链路跑通一个场景最后才逐步扩大模型能力边界。不要一开始就追求“什么都能问”的泛化效果那是很多项目失控的起点。后续值得继续深挖的方向包括Text2SQL 模型的微调与评测方法、指标语义层建模的最佳实践、多轮对话中的指代消解、以及智能问数结果的归因解释能力。今天的文章偏工程落地下一期可以专门聊聊如何搭建一套完整的智能问数评测集把答案正确率真正管起来。希望这篇文章能在你立项或调研时帮上忙。如果你正在做类似项目欢迎在评论区聊聊你踩过的坑。