首页/数据能力/数据能力总览

数据能力总览

首页的「数据能力」入口在这里展开。 「数据能力」指的是让系统知道数据是什么意思的那一层—— 它决定了可答边界在哪、答案可不可信。

八组能力对照

#能力组一句话机制详解
01 语义层 把计划确定性地编译成 SQL,编不动的地方明确拒绝或留骨架 语义层
02 本体 数据集声明成对象、关系声明业务名、维度链声明成层级——声明一次,全链用业务的词说话 本体
03 判定规则 同一份语义模型换个问法:「算不算有问题」,定时求值且零 LLM 判定规则
04 知识库 五个 YAML 按「谁能写」分工,自动写入一律 pending 知识库
05 混合检索 关键词 + 向量两路,加权 RRF 融合,分数归一化 混合检索
06 多数据源 一个注册表,驱动懒加载,注册即连接探测 本页
07 统一存储 内部状态一个抽象两档后端,迁移版本化且各自幂等 本页
08 评测基建 离线回放 + 带方向容差的回归门,判定不花钱 评测与回归门
flowchart LR
    subgraph can["决定能答什么"]
        SEM["01 语义层
计划 → 权威 SQL / 骨架"]:::gen ONT["02 本体
对象 / 关系 / 层级声明"]:::gen KB["04 知识库
五个 YAML 按谁能写分工"]:::entry RET["05 混合检索
两路召回 → 加权 RRF"]:::exec end subgraph trust["决定答得对不对"] DEC["03 判定规则
同一份语义模型,换个问法"]:::gate EV["08 评测基建
离线回放 + 回归门:判定不花钱"]:::gate end subgraph where["决定在哪跑"] DS["06 多数据源
注册表 + 驱动懒加载"]:::ext ST["07 统一存储
一个抽象,两档后端"]:::entry end %% 无连线也要按左→右排:三组之间没有依赖关系,只是并列 can ~~~ trust ~~~ where classDef entry fill:#71717a14,stroke:#71717a59,stroke-width:1px; classDef gen fill:#6366f114,stroke:#6366f199,stroke-width:1.5px; classDef exec fill:#14b8a614,stroke:#14b8a699,stroke-width:1.5px; classDef gate fill:#f59e0b14,stroke:#f59e0b99,stroke-width:1.5px; classDef ext fill:transparent,stroke:#71717a80,stroke-width:1.5px,stroke-dasharray:4 4;
图 1 · 八组能力按「管什么」分成三撮:划定可答边界的四组、判定对不对的两组、以及决定跑在哪的两组。编号与上表一致。 上面这段以源码显示:图渲染库没加载起来(离线、CDN 被拦或浏览器禁用了 JavaScript 时会这样)。这段 Mermaid 文本本身就说明了上面那些框与连线。

一条贯穿的取舍:确定性优先

八组能力背后是同一个判断准则——能用代码算准的,不要交给模型。 这不是对模型能力的怀疑,而是三个具体的好处:

好处在企业问数场景里意味着什么
可解释 「这个数怎么来的」有确定答案:哪个指标、哪条 join 路径、哪条规则放行
可回归 改动能被离线门拦住,而不是「看起来好像没变差」
换模型不退化 确定性部分的行为不随模型版本漂移

所以在这套系统里:join 路径由语义层算 (compiler.py:149 JoinResolver)、 编不动的地方有结构化的分因 (compiler.py:1374 PartialCompile)、 检索先做表锚定过滤再排序 (service.py:1618 keep)、 回归对比是纯函数 (gate.py:414 compare_metrics)。

06 多数据源:注册表与懒加载

数据源类型由一张注册表管理。关键设计是驱动懒导入: 导入注册表本身不要求装任何数据库驱动,只有真正去连某类库时才要求对应的包。 所以「支持六种数据源」不会让基础安装背上六个驱动的依赖。

registry.py:42 _ADAPTER_REGISTRY

管理端注册一个数据源时是事务性的:先连接探测成功,才落库, 才进注册表;任何一步失败都回滚,并以 400 报出原因。 这样不会出现「配置里有一个连不上的源」这种半成品状态。 完整流程见接入数据源。

07 统一存储:抽象管什么、不管什么

会话、任务、记忆、认证、设置、调度、检查点等内部状态,统一在一个 StorageBackend 抽象后面,由环境变量在后端之间切换。

sqlite.py:138 build_backend sqlite.py:166 resolve_backend

这个抽象刻意不覆盖两样东西

知识库镜像与 业务数据源留在抽象之外。前者因为 PostgreSQL 生产环境走的是另一条检索后端,后者因为用户的数据本来就不归 Trove 的状态管理管。

换句话说,它管的是「Trove 自己的状态」。把边界划在这里,是为了避免它膨胀成一个「所有数据库访问都要经过」的中间层——那种中间层最后会什么都抽象不好。

08 评测基建:不花钱的判定

这一组能力的目标很具体:让「这次改动有没有让系统变差」这个问题可以在不调用模型的前提下回答。

件作用
eval/replay.py 录制轨迹离线回放打分(零 LLM、零网络)
eval/gate.py 纯函数:指标口径化 → 对比 → Markdown 记分卡
scripts/eval_gate.py 把 baseline 与 current 结果文件对比,有回归即退出码 1
检索评测脚本 Recall@k / MRR / nDCG,输出可被门消费的 scorecard

gate.py:169 metrics_from_entries replay.py:321 score_replay gate.py:539 render_report

继续读

想了解去哪
可答边界在概念上怎么理解产品概念
怎么接入自己的库接入数据源
回归门具体怎么用评测与回归门
数据变了怎么发现数据漂移治理
怎么让系统每天自己判「有没有问题」判定规则
本页源码锚点的基准提交:anchor-base: 7c6df87 GitHub 仓库 文档首页