一线业务人员用自然语言向 ChatBI 提问时最致命的永远不是复杂的聚合函数而是“黑话”与“地方话”。华东的大区经理在群里吼“看下上个月‘金标生抽’在‘苏宁小店’的‘出货量’”华北的城市督导敲过来的是“查一下‘大金标’在‘苏小’的‘动销件数’”而到了西南大区业务甚至直接问“‘老抽酱油’在‘红旗连锁’卖了多少‘件’还是‘提’”。而在我们的数仓事实表dwd_trade_order_di中它对应的标准商品名称是HADAY_SOY_SAUCE_GOLD_500ML渠道维度是channel_code CH_SUNING_OFFLINE指标字段叫sales_qty。早期我们搞同义词库纯靠人工运营在后台维护一张静态的 Excel 表。每个月拉一次日志由数仓建模工程师和业务 BP 对着近万条失败提问逐条标注再导入 ElasticSearch 或 Redis 做关键词替换。这套流程不到两个月就彻底崩了业务造词的速度远超你的迭代周期尤其在大促期间新品代号、方言谐音、简写简称漫天飞。人工配置还极易引发歧义回流——比如业务把“茅子”配成了“贵州茅台53度飞天”结果第二天有人问“茅子配饰礼盒”也被强制重定向到了白酒大宽表直接触发 Text2SQL 逻辑风暴。要把同义词库从“人工搬砖”升级为“自治自愈”必须把日志审计流、大模型语义聚类与 Schema 元数据校验打通搭建一套闭环的挖掘与动态刷新引擎。痛点架构复盘人工词库为什么必然衰退传统同义词维护往往在网关层挂载分词词典或正则匹配表其系统性缺陷体现在三个维度冷启动周期长与滞后性市场部今天发起名为“狂飙行动”的特惠次日早会提问“狂飙方案成单额”底层的分词器将“狂飙”与“方案”拆散SQL 生成模块把它当成了用户表中的某个姓名或普通字符筛选等分析师发现时大促已经过去一半。上下文语义漂移Semantic Drift词语的同义性依赖限定条件。例如“件数”在快消业务中可以指“单品瓶数Bottle”也可以指“外包装物流箱数Carton”。脱离商品品类与组织架构上下文做全局字符替换往往造成指标口径十倍甚至百倍的严重偏离。缺乏反向淘汰机制旧的促销代号下线后词库中沉淀的过期脏词长期占领高优先级与新上线的维度值冲突导致路由判定层不断发生碰撞。自动化挖掘体系三层漏斗设计为了彻底解放人力我们将用户提问日志接入离线与近实时双轨处理链路。整体流水线分为三个核心阶段提问失败/歧义日志 (Kafka / ClickHouse) │ ▼ [阶段 1: 异常模式聚类与新词候选提取] ── 统计特征过滤 (TF-IDF C-Value) │ ▼ [阶段 2: 领域 LLM 意图推断与元数据映射] ── 结合物理表 Schema 与当前有效维表 │ ▼ [阶段 3: 影子执行验证与业务确认阻断门] ── 生成 SQL 试跑判定结果非空率与置信度 │ ▼ 动态推送到 Redis 同义词缓存 正式知识图谱1. 提问日志的异常模式捕获并非所有日志都需要送给大模型那样 Token 成本会把项目拖垮。我们只监控触发了“回退兜底Fallback”、“重试频次 ≥ 2”以及“Text2SQL 生成结果为空”的 Session。通过滑动窗口截取用户会话利用轻量级统计语言模型基于字符级 N-Gram 与 C-Value 算法过滤掉常见通用虚词锁定高频但未在元数据知识库中注册的生词片段。2. 大模型引导的上下文语义解构提取出候选片段后将候选词、该用户当天的提问上下文最近 3 条历史、以及相关事实域的 Schema 描述包含标准指标、维度字段、TOP 50 常用维度值枚举拼装为 Prompt调用模型进行推理输出严格的 JSON Schemaimport json import logging from typing import Dict, Any, List from openai import OpenAI logger logging.getLogger(__name__) # 配置本地或私有化网关客户端 client OpenAI( api_keyEMPTY_OR_YOUR_KEY, base_urlhttp://llm-gateway.internal.net/v1 ) SYSTEM_PROMPT 你是一个企业级数仓元数据对齐专家。 任务根据用户的提问上下文与候选生词结合数仓已有的标准维度与指标判断该生词是否属于方言、行业简称、缩写或错别字并给出标准映射。 约束 1. 必须输出合法 JSON禁止包含 markdown 格式外衣。 2. 若无法确定置信度高于 0.85置信度字段填低并给出 reason。 3. 映射目标必须来自提供的标准元数据列表。 def extract_synonym_mapping( candidate_term: str, user_query_history: List[str], standard_metadata: Dict[str, List[str]] ) - Dict[str, Any]: 通过大模型分析候选生词在特定查询上下文中的真实业务实体映射 prompt { candidate_term: candidate_term, context_queries: user_query_history, candidate_targets: { metrics: standard_metadata.get(metrics, []), dimensions: standard_metadata.get(dimensions, []), dimension_values: standard_metadata.get(dimension_values, []) } } try: response client.chat.completions.create( modelqwen2.5-72b-instruct, temperature0.1, # 降低随机性严守确定性 messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: json.dumps(prompt, ensure_asciiFalse)} ], response_format{type: json_object} ) result json.loads(response.choices[0].message.content) return result except Exception as e: logger.error(fLLM 挖掘同义词失败: {str(e)}, exc_infoTrue) return {term: candidate_term, confidence: 0.0, error: str(e)}模型返回的典型推断格式如下{ raw_term: 苏小, category: DIMENSION_VALUE, target_column: channel_name, standard_value: 苏宁小店, confidence: 0.94, rationale: 用户在上下文连续提问便利店渠道动销苏小是线下业务线对苏宁小店的内部习用简称。 }影子验证与写入防护拒绝“幻觉污染”大模型推断出的结果绝不能直接灌进线上生产词库。历史上我们曾遇到大模型将业务口中的“老破小”指代某种低配置机型自动联想为某不动产维度的“老旧住宅”导致硬件销售报表直接崩盘。因此我们引入了影子执行校验机制Shadow Execution ValidationSQL 试运行将待录入的同义词带入原先失败的用户 Query调用 Text2SQL 生成引擎。如果生成的 SQL 能够顺利通过 AST 解析并且在只读副本上执行时间 800ms、返回行数在合理业务阈值区间 0且 1,000,000则通过初筛。反向双向测试Bidirectional Consistency用生成的标准词替换原句子后再次要求模型将标准句逆向还原为自然口语。如果逆向语义产生分歧说明该映射为多对多模糊映射降低其置信度。低置信度进入人机协同工单池置信度在[0.70, 0.85)区间的候选对推送到飞书运维卡片由领域分析师一键审批或驳回置信度 0.85且通过影子测试的词条直接触发热更新写入 Redis 集群。动态词库在 Text2SQL 运行时的注入实践在线上 Text2SQL 处理链路中我们摒弃了暴力正则全局替换。因为简单的文本替换会破坏 SQL AST 解析器原本对语义树的理解。正确的做法是将同义词作为**知识锚点Knowledge Hints**挂载在 Prompt 的约束模块中-- 注入同义词语义感知后的动态 SQL 生成上下文 -- 原始提问: 查一下大金标在苏小上周的动销件数 WITH matched_sales AS ( SELECT t.store_id, t.sku_id, t.sales_qty, t.order_time FROM dwd_trade_order_di t JOIN dim_channel c ON t.channel_code c.channel_code JOIN dim_goods g ON t.sku_id g.sku_id WHERE -- 命中同义词映射: 苏小 - channel_name 苏宁小店 c.channel_name 苏宁小店 -- 命中同义词映射: 大金标 - goods_name LIKE %金标生抽500ML% AND g.goods_name LIKE %金标生抽500ML% -- 动态时间范围对齐 AND t.order_date date_sub(current_date(), INTERVAL 7 DAY) ) SELECT sum(sales_qty) AS total_sales_qty FROM matched_sales;运行收益与架构演进沉淀上线自动化挖掘方案后我们的 ChatBI 语义识别命中率从初期的71.2%提升并稳定在93.8%以上。更关键的是分析师每周在同义词维护上的工单量从平均 180 张缩减到了不到 10 张。系统核心沉淀出两个不可逾越的红线第一绝对禁止无 Schema 校验的直接替换。同义词必须挂靠在确定的“表-列-值”元数据树上不能变成悬空的字符串字典。第二建立词条衰减机制Decay Rate。对每个动态生成的词条设置 90 天的活跃半衰期。如果一个临时活动简称在连续 60 天内未被任何用户再次提及词条权重自动降级并移入冷备区防止元数据长生不老变成系统的沉重历史包袱。