告别"大海捞针":Data Agent 如何优雅实现指标问数与实体匹配?

0 阅读10分钟

作者:魏浩浩 枫清科技技术架构师

在企业数字化转型的浪潮中,Data Agent(数据智能体/经营分析助手)正逐渐成为业务人员的"标配"。想象一下,当你作为分行行长或业务主管,在对话框里敲下"上月苏州分行人民币对公存款日均"或者"2025 Q1 各分行不良贷款率排名"时,你期待的是秒级返回的精准图表,而不是一句冷冰冰的"抱歉,我没听懂"。

然而,在技术实现层面,将这句日常自然语言映射为结构化的查询指令(如{ metricId, dimensionHolds, dimensionFilters, timeWindow }),却是一场充满挑战的"翻译"之旅。

面对动辄上万条的指标库和错综复杂的业务维度,如果直接把所有指标丢给大模型(LLM)去选,不仅 Token 成本爆炸,AI 还容易"胡言乱语"(即幻觉);如果让 AI 自己去"猜"维度值,把"苏州分行"写成"苏州"或"苏分",下游的数据库查询必然报错。

那么,如何构建一个既聪明又靠谱的 Data Agent?本文将带你深入剖析我们的 Data Agent 核心设计,看看它是如何通过实体识别、双路召回与精准匹配,优雅地解决"指标问数"难题的。

核心设计理念:漏斗模型与"各司其职"

整个数据查询的过程,本质上是一个"漏斗":从万级候选指标 → 百级初步召回 → Top-5 精准排序 → 最终单选与维度填充。

在这个漏斗中,我们坚持以下三个设计原则:

  1. 粗排靠引擎,精排靠 AI:检索引擎负责在海量数据中快速圈定范围(粗排),大模型负责在小范围内做精准判断(精排)。绝不让 AI 在海量数据中"大海捞针"。
  2. 白名单收口:意图、维度名、维度值都必须先比对数据库内字典,未命中则剔除或警告,绝不盲目相信 AI 的"自觉"。
  3. 每步可独立失败:任何一步 AI 出现异常,都能降级到默认规则,保证链路不断,最终依然能给用户返回结果。 图片1.png 如上图所示,整个流程被拆分为 7 个独立的步骤,每个步骤都有独立的计时和日志。这种细粒度的编排不仅便于观测每个环节的耗时瓶颈,还能实现单步重放(缓存)和优雅降级。例如,如果召回失败,系统会给出一个空的候选列表;如果大模型解析失败,系统会降级使用默认模型,确保下游依然能跑通。

环节一:实体识别(Gazetteer Hint)—— 给 AI 戴上"老花镜"

在理解用户意图时,AI 常常会漏掉关键实体, 尤其是分行名称、产品简称等业务专有名词与行业黑话。仅依靠提示词(Prompt)无法让 AI 全部识别各类专有名词,而数据库内置的别名表,正好能弥补这一识别短板。

为此,我们引入了实体词典(Entity Gazetteer) 机制。

业务场景

用户问:"苏分对公存款多少?"

AI 可能不知道"苏分"是什么。但通过实体词典,系统会在极短的时间内扫一遍用户问题,发现"苏分"是"苏州分行"的别名。系统会将这个信息作为"提示(Hint)"悄悄告诉 AI:"注意,这里的'苏分'指的是'苏州分行'。"这样,AI 就能准确理解用户的真实意图。

技术实现

在技术底层,我们使用了 Aho-Corasick 多模式匹配自动机,它只需要扫一遍用户的提问,就能一次性把里面所有已知的专业名词、关键词全都找出来。我们匹配用到的词汇库,从三个方面整理而来:各种业务指标及其别名、业务维度及其别名,还有每个数据库里最常用的前 5000 个高频维度值。 为了保证性能,词典在进程内缓存,并通过 Redis 维护版本号。一旦后台数据同步完成,版本号自动更新,下次匹配时自动重建词典。实测表明,AC 自动机匹配本身耗时不到 5 毫秒,而词典冷启动构建约需 1.5 秒。

Hint 注入策略

匹配到的实体信息不会直接修改用户的原始问题(避免污染历史上下文),而是把这些实体信息当作补充提示(Hint),给到这一轮的 Agent 使用。 hint_md = entity_gazetteer.match(question, lib_ids).render()agent_input = f"{hint_md}\n\n{question}" 为什么不直接写回原始问题?因为系统会将用户消息写入历史记录,如果把 Hint 拼到原始问题中,下一轮对话的历史改写就会带入噪声,影响后续的理解准确性。

环节二:双路召回与 RRF 融合 —— 扎实的粗排底座

在指标召回阶段,我们面临两种截然不同的检索需求:

  • 语义泛化:用户问"坏账",我们需要能联想到"不良贷款"。这需要向量检索(理解语义)。
  • 精准匹配:用户问特定的短词或别名,向量模型可能抓瞎。这需要字面匹配(如倒排索引)。

为此,我们采用 Qdrant 向量 + Elasticsearch (BM25/kNN)双路并发召回架构。系统支持通过配置灵活切换检索模式:默认使用双路并发,整体鲁棒性最优;纯向量模式检索速度更快,但易出现别名漏检问题;纯 BM25 模式检索适配短关键词匹配,但语义理解能力较弱。

融合排序的艺术:RRF双路召回带来的问题是:BM25 的打分范围是 0-∞,而向量相似度是 0-1,两边的打分标准完全不同,无法直接相加。如果使用 Min-Max 归一化,又容易受到长尾极值的影响——一个极高分会把其他候选的分数全部压成接近 0。

工业界的标准解法是RRF(Reciprocal Rank Fusion,倒数排名融合),它不看绝对分数,只看排名。其核心公式如下:

score(d) = Σ 1/(60 + rank_i) × (1 + bonus_双路命中)

其中rrf_k=60 是论文推荐值,bonus=0.1 表示如果一个指标同时被两路命中,额外给予 10% 的加权奖励。这种设计对绝对分数不敏感,对长尾极值也不敏感,非常适合异构检索结果的融合。 图片2.png 依托该方案,我们可从万级指标库中快速筛选出 Top-20 候选,为后续 AI 精排做好铺垫。整个召回过程耗时约 200~400ms(双路并发 + 网络),是整条链路中最"物美价廉"的环节。

环节三:AI 精排(Pick)与维度识别 —— 裁判登场

经过召回,候选集已经足够小。此时,大模型(LLM)终于作为"裁判"登场,执行两个关键任务:选指标(Index Pick)和抽维度(Dimension Recognizer)。

1. 指标精排(Index Pick)

为了降低 Token 消耗和幻觉率,我们对输入给 AI 的候选集进行了极致压缩:仅保留 index(编号)、name(名称)、alias(别名)、associated_dimension(仅维度名称)和截断到 100 字符的 description。 强制使用 Index 引用是一个关键设计:要求 AI 返回选中的指标编号(如 [0, 2]),而不是复述指标名称。指标名可能含特殊字符、长度不一,AI 复述的错误率很高。而 Index 是整数,强约束、好校验,且容易在代码层面进行 Hard Cap——即使 AI 不遵守"最多选 5 个"的约束,代码也会强制截断。

2. 维度识别(Per-Metric)

维度识别要按指标(Per-Metric)单独调用,而不是合并在一次 Prompt 里。原因很简单:不同指标的合法维度值域不同。如果合并处理,AI 极易发生"串台",把 A 指标的维度抄给 B 指标。虽然单独调用会增加延迟,但通过并发执行可以有效挽回。 在识别过程中,我们还会对问题进行占位替换(将指标名替换为[指标名]),防止 AI 把指标名本身当成维度值抽出来。

3. 规则兜底:5 步严格校验

AI 抽出的维度,必须经过 5 步严格的规则校验:

  • 清理通配符:删去*、全部、所有 这种无意义的通配符。
  • 校验维度名:做数据分组(Group By)时,只能选用当前指标已配置好的关联维度。
  • 校验维度值(白名单):Filter 的值必须在数据库的实际值集中存在。时间类维度(年/月/季度等)一律剔除,交由专门的时间识别器处理。
  • 去重 Hold/Filter:如果一个维度已经被作为单值 Filter,就不再进行 Group By。
  • 补充默认值:补充指标配置的默认维度值(如"币种=人民币")。 图片3.png 规则永远在 AI 后面兜底。AI 错了,顶多多一次澄清交互;规则错了,直接出业务事故。例如,在处理 must_not(排除)条件时,如果用户问"除苏州外的分行",但"苏州"拼错了,系统绝不会轻易删除这个条件(否则就变成查询"全部分行"),而是给出警告让用户重问。

失败与降级策略在企业级应用中,系统的鲁棒性至关重要。降级不是"假装没事",而是"保证后端能继续跑出 SQL"。

失败点现象降级策略Gazetteer Redis 不可达匹配抛错记录警告,注入空 Hint,不阻断流程Qdrant 向量库超时召回半残自动降级走 ES 单路召回ES 倒排索引超时召回半残自动降级走 Qdrant 单路召回AI 指标精排解析失败无法决定默认选择召回排名第一的指标AI 维度识别失败单个指标无维度该指标给空维度,其他指标不受影响校验时拿不到实际值集无法校验跳过校验,保留原值(记录警告日志)让用户在结果页看到"维度未识别",也比看到一个冷冰冰的"500 Internal Server Error"要强一万倍。

总结与展望

构建一个好用的 Data Agent,绝不是简单地把数据库 Schema 扔给大模型。 在这条 Text-to-Metric 链路中,我们看到了**"双源索引 + 单 Workflow + 多 Step"**的架构魅力。检索引擎负责大范围圈选(Recall),AI 负责精准判断(Precision),规则代码负责安全兜底。每一步都遵循"AI 提议 + 规则审核 + 默认降级"的三段式设计。 目前,AI 环节仍占据了约 80% 的延迟(指标精排约1.53s,维度识别约 1.54s)。未来,我们将继续在以下几个方向进行优化:

  • 并发化:将维度识别的顺序调用改为真并发,预计可降低 60% 延迟。
  • Prompt 瘦身:进一步精简输入给 AI 的描述信息,减少 Token 消耗。
  • 规则短路:当实体词典强命中(指标和维度都明确)时,直接跳过 AI 意图路由,进一步提升响应速度。
  • RRF 参数调优:面向短问句业务场景,把 rrf_k 参数从默认 60 调整为 10 至 20,以优先保证首位结果的匹配准确度。 Data Agent 的进化之路,就是在 AI 的"聪明"与工程的"严谨"之间,找到那个最优雅的平衡点。