语义层(dbt MetricFlow)
让 Agent 沿用 dbt 中的指标定义,保持分析口径一致。
Cappy Agent 支持 dbt MetricFlow 语义层。如果你的 dbt 项目已经定义了语义模型和指标,Cappy 可以直接使用这些定义回答问题。
在 config.yaml 中配置由 dbt parse 生成的 semantic_manifest.json,完成同步后,Cappy Agent 就可以使用 execute_semantic_query 工具查询其中定义的指标。
使用语义层的意义
- 保持计算口径一致:同一指标在不同对话中使用相同的计算定义,避免 Agent 每次编写 SQL 时重新判断计算规则。
- 统一维护指标定义:计算规则由团队在 dbt 中管理和审核,Cappy 查询时沿用这些定义。
- 减少重复编写上下文:同步时自动生成指标和维度说明,无需在
RULES.md中重复描述已有的指标定义。
接入语义层
用 dbt 生成指标定义文件
在已定义语义模型和指标的 dbt 项目目录中运行:
dbt parse文件默认生成在 target/semantic_manifest.json。下一步将这个文件的路径配置到 Cappy。
在 config.yaml 中配置语义层
打开 Cappy 项目中的 config.yaml,添加:
semantic_layer:
type: metricflow
manifest_path: /path/to/dbt-project/target/semantic_manifest.json
database: warehousemanifest_path:替换为文件的实际路径,也可以使用相对于config.yaml的路径。database:执行查询的 Cappy 数据库连接名。这里的warehouse需要已在databases中配置;只有一个连接时可以省略。
当前支持的数据库类型为 Athena、BigQuery、Databricks、DuckDB / MotherDuck、PostgreSQL、Redshift、Snowflake 和 Trino。MetricFlow 在 Cappy 内部生成 SQL,无需连接 dbt Cloud 的语义层服务。
同步到 Cappy
在 Cappy 项目目录中运行:
cappy sync -p semantics同步后会生成以下文件。以包含订单数指标 orders 的项目为例:
my-project/
├── .meta/
│ └── semantic_layer/
│ └── semantic_manifest.json
└── semantics/
├── README.md
├── dimensions.md
└── metrics/
├── orders.md
└── ...semantics/ 中的 Markdown 文件供 Agent 查阅:
README.md:语义查询的用法和参数说明。dimensions.md:可用维度及时间粒度。metrics/orders.md:订单数指标的定义、可用维度和查询示例。每个指标生成一个以指标名命名的文件。
.meta/semantic_layer/semantic_manifest.json 是 dbt 定义文件的副本,供 MetricFlow 在执行语义查询时生成 SQL。
使用已有 Cappy 实例时,将这些文件连同 config.yaml 一起更新到 Cappy。查询使用同步后的定义副本,无需访问原 dbt 项目的 target/ 目录。
Agent 什么时候调用这个工具
默认情况下,当问题涉及已定义的指标时,Agent 会优先调用 execute_semantic_query。例如,dbt 中定义了 orders(订单数)指标,以及地区和订单状态维度,用户问:
按月份和地区统计已完成的订单数。月份从早到晚排列,同一个月内按订单数从多到少排列。
Agent 会先在 semantics/metrics/ 中查找匹配的指标,读取订单数指标的说明文件 orders.md,了解它的计算定义;再查阅 semantics/dimensions.md,确认月份、地区和订单状态这些维度的名称。随后调用 execute_semantic_query,传入指标、分组、筛选和排序条件:
{
"metrics": ["orders"],
"group_by": ["metric_time__month", "customer__region"],
"where": ["{{ Dimension('order__status') }} = 'completed'"],
"order_by": ["metric_time__month", "-orders"]
}这里的 group_by 按月份和地区分组;where 只保留状态为 completed 的订单,通过 Dimension(...) 引用已定义的订单状态维度;order_by 先按月份升序排列,再按订单数降序排列,名称前的 - 表示降序。示例中的名称和状态值需与你的 dbt 定义一致。
工具将这些参数交给 MetricFlow,由它根据指标定义生成 SQL。Cappy 随后通过 warehouse 连接执行 SQL,将结果返回给 Agent,用于回答问题或绘制图表。
对话中会显示一张语义查询卡片。点击卡片右侧的图标,可以切换查看语义查询、查看编译后的 SQL和查看结果:分别查看上面的请求参数、实际执行的 SQL,以及每个月各地区的订单数量。
如果问题需要的指标或维度没有定义,默认仍允许 Agent 使用 SQL 查询。项目管理员可以在项目设置 → 能力 → 语义层中调整这一行为:
| 模式 | 何时使用语义查询 |
|---|---|
| 优先使用语义层(默认) | 优先查询已定义的指标;未覆盖的问题可以使用 SQL |
| 仅使用语义层 | 数据库查询必须通过已定义的指标完成;SQL 仅用于处理本地文件和已有结果 |
| 不使用语义层 | 不提供 execute_semantic_query 工具;指标说明仍可作为上下文读取 |