Cortex Analyst 语义模型规范

为什么使用语义模型?

Cortex Analyst 使用户可以使用自然语言询问关于 Snowflake 数据的问题。通常,业务用户在询问数据问题时使用的词汇与数据库架构中使用的词汇之间存在差异。这些用户通常使用业务或特定领域的术语,而数据库架构可能使用 ETL 管道中常用的缩写或术语。此外,数据库架构通常缺乏相应的语义细节,来帮助不熟悉数据集的人理解数据。这种词汇差异使得 Cortex Analyst 在高精度回答数据问题时面临挑战。

语义模型是一种轻量级机制,通过允许为数据集指定额外的语义细节来解决这些问题。这些额外的语义细节(比如更具描述性的名称或同义词),使得 Cortex Analyst 能够更可靠地回答数据问题。

备注

语义模型被视为 元数据

关键概念

备注

在本主题中,基础数据库相关的工件被称为“物理”工件,而语义模型相关的工件被称为“逻辑”工件。

语义模型的结构和概念与数据库架构中的相似,但语义模型使您可以提供有关数据的更多语义信息。

Snowflake 语义模型的核心概念是 逻辑表。逻辑表可以被视为物理数据库表或视图之上的简单视图。每个逻辑表都是逻辑列的集合,这些列被分类为 dimensionstime_dimensionsmeasures

逻辑列可以是对基础物理列的引用,也可以是涉及一个或多个物理列的表达式。此类表达式可以很简单(比如字符串连接或数学运算),也可以包括聚合表达式。例如,您可以使用像 SUM(click)/SUM(spend) 这样的表达式来计算每次点击的成本 (CPC)。

语义模型还可以包含 已验证的查询存储库 (VQR),它可以提供一系列问题及相应的 SQL 查询来回答这些问题,从而帮助提高结果的准确性和可信度。

Cortex Analyst 规范的语义模型采用的是 YAML (https://yaml.org/spec/)。它提供了必要的语义信息,从而高精度地回答自然语言问题。

一般语法为:

# Name and description of the semantic model.
name: <name>
description: <string>

# A semantic model can contain one or more logical tables.
tables:

  # A logical table on top of a base table.
  - name: <name>
    description: <string>

    # The fully qualified name of the base table.
    base_table:
      database: <database>
      schema: <schema>
      table: <base table name>

    # Dimension columns in the logical table.
    dimensions:
      - name: <name>
        synonyms: <array of strings>
        description: <string>
        expr: <SQL expression>
        data_type: <data type>
        unique: <boolean>
        cortex_search_service:
          service: <string>
          literal_column: <string>
          database: <string>
          schema: <string>
        is_enum: <boolean>

    # Time dimension columns in the logical table.
    time_dimensions:
      - name: <name>
        synonyms:  <array of strings>
        description: <string>
        expr: <SQL expression>
        data_type: <data type>
        unique: <boolean>

    # Measure columns in the logical table.
    measures:
      - name: <name>
        synonyms: <array of strings>
        description: <string>
        expr: <SQL expression>
        data_type: <data type>
        default_aggregation: <aggregate function>

    # Commonly used filters over the logical table.
    filters:
      - name: <name>
        synonyms: <array of strings>
        description: <string>
        expr: <SQL expression>

# Example questions and queries that answer them
verified_queries:

# Verified Query (1 of n)
- name:                         # A descriptive name of the query.
  question:                     # The natural language question that this query answers.
  verified_at:                  # Optional: Time (in seconds since the UNIX epoch, January 1, 1970) when the query was verified.
  verified_by:                  # Optional: Name of the person who verified the query.
  use_as_onboarding_question:   # Optional: Marks this question as an onboarding question for the end user.
  sql:                          # The SQL query for answering the question.
Copy

使用模型生成器创建语义模型

使用语义模型生成器通过表创建语义模型。您无需使用 YAML 规范手动创建语义模型,在 Snowsight 中使用模型生成器即可,还能节省时间。创建语义模型的过程涉及执行以下操作:

  1. 提供有关模型基本信息的描述。

  2. 提供用于创建模型的数据源。必须至少提供一个表或视图。

  3. 选择用于创建模型的列。

要开始创建模型,请导航到 Let's Create a Semantic Model 页面:

  1. 在 Snowsight 中,选择 AI & ML

  2. Cortex Analyst 旁,选择 Try

  3. 选择 Create new

您已打开语义模型生成器的描述页。要创建语义模型,请执行以下操作:

  1. Description,指定有关语义模型的信息。您必须提供文件名、文件位置和模型名称。您还可以提供有关数据上下文的描述。

  2. (可选)对于 User Questions,指定用户可以针对数据询问的问题类型。模型生成器使用您在字段中提供的信息来建议可用于创建模型的表、视图、列。

  3. 对于 Select Data (Table/View),提供用于创建语义模型的数据源。必须至少提供一个表或视图。您可以指定的表或视图没有限制,但我们建议语义模型使用的数量不要超过 10 个。

  4. 对于 Select Columns,选择用于创建语义模型的列。您可以选择所有列或特定列。出于性能考虑,我们建议使用的列不要超过 50 个。

创建模型后,将其保存到暂存区。要保存,请选择屏幕右上角的 Save。如果需要进一步修改,可以使用 Snowsight 或直接编辑 YAML 文件来编辑模型。

打开现有语义模型

创建语义模型后,可以在 Snowsight 中打开。要打开语义模型,请执行以下操作:

  1. 选择 Open semantic model

  2. 选择 Open

  3. 选择 Select from stage

  4. 选择数据库和架构。

  5. 单点击对话框外部。

  6. 选择保存文件的暂存区。

  7. 选择 Open

备注

如果暂存区中没有看到语义模型,请尝试刷新模型列表,而不是页面。

定义联接

Cortex Analyst 支持 SQL 联接,能够在多个表之间进行更高级的数据分析。此功能让您可以轻松查询事实表和相关维度表中的数据。

在语义上下文 YAML 文件中定义联接

要在 Cortex Analyst 中使用联接,请使用关系定义更新语义上下文 YAML。在表列表后提供定义:

relationships:
  - name: <string>
    left_table: <string>
    right_table: <string>
    relationship_columns:
      - left_column: <string>
        right_column: <string>
      - left_column: <string>
        right_column: <string>
    join_type: <join_type>
    relationship_type: <relationship_type>
Copy

其中:

  • name:关系的唯一标识符。

  • left_tableright_table:先前在 YAML 文件中定义的逻辑表名称。

  • relationship_columns:仅指定等值联接。当前不支持非等值联接。必须使用逻辑列名称(不允许使用表达式)。

  • join_type:支持 left_outerinner joins

  • relationship_type:支持 many_to_oneone_to_one 关系。

为了确保正确的联接功能,必须为关系涉及的表定义主键。请参阅以下示例:

tables:
  - name: orders
    primary_key:
      columns:
        - order_id
        - location_id
Copy

示例

对于使用简单星型架构的联接,请参阅 jaffle_shop_star_schema.yaml

创建语义模型的提示

  • 按业务领域或主题组织 YAML 文件

    • 根据特定的业务域或主题来组织 YAML 文件,保持范围明确。例如,分别为销售分析和营销分析创建单独的语义模型。

    • 根据目标受众、预期问题或 KPIs 以及所需数据来定制用例。定义明确的用例可带来更丰富的语义模型和更有效的数据检索。

  • 从最终用户的角度思考

    • 确定用户可能就相关主题提出的关键问题,并仅包含回答这些问题所需的表和列。

    • 使用与最终用户所用的词汇相似的名称和同义词。

    • 在描述字段中包含重要的详细信息,使其对第一次在此数据集上编写查询的人们有所帮助,例如 DATETIME 列的时区。

  • 捕捉复杂计算

    将更困难或特定于业务的查询纳入表达式中。

  • 使用宽表而不是长表

    如果您有一个包含“指标”和“值”列的表,请将表扁平化,使每个指标成为一列。这种方法为模型的每个指标提供了更多的语义信息。

  • 查看自动生成的描述

    如果您使用的是 语义模型生成器 (https://github.com/Snowflake-Labs/semantic-model-generator),它会尝试自动生成表和列的描述。请务必仔细查看这些描述,确保其合理且具有相关性;根据需要进行修改。

  • 从简单开始,逐渐扩展

    范围设置恰到好处的语义文件可确保结果具有更高的精度和准确性。从少量的表和列开始,逐步扩展语义模型 YAML,以涵盖更多种类的问题。请记住,YAML 的构建是一个持续的过程。

  • 包含经过验证的查询

    已验证的查询存储库 (VQR) 是一组由简单的英语问题和对应查询组成的集合,可以帮助提高结果的准确性和可信度。

已知限制

  • Cortex Analyst 对语义模型文件施加了 1MB 的大小限制,以限制 API 输入的大小。

  • Cortex Analyst 在内存中检索添加到语义 YAML 中的示例值和经过验证的查询。在去除所有示例值和经过验证的查询后,语义模型不能超过 32K 个词元(大约 4 x 32K 个字符或大约 128 KB)。您可以使用语义模型生成器验证命令来确保文件不超过这些限制。随着对具有更大上下文窗口的模型的支持增加,限制可能会提高。

规范

语义模型

一个语义模型表示一组表。该模型包含表的描述,每个表都包含对表的具体方面的描述。模型中描述的每个表都映射到 Snowflake 中的一个物理基表。

它有以下字段:

必填

name

此语义模型的描述性名称。

必须是唯一的,并遵循 未加引号的标识符要求。它也不能与 Snowflake 保留的关键字 冲突。

可选(推荐)

description

该语义模型的描述,包括其用于何种分析的详细信息。

tables

此语义模型中的逻辑表列表。

逻辑表可以被视为物理数据库表或视图之上的视图。它有以下字段:

必填

name

此表的描述性名称。

必须是唯一的,并遵循 未加引号的标识符要求。它也不能与 Snowflake 保留的关键字 冲突。

base_table

数据库中底层基表的完全限定名称。

可选(推荐)

synonyms

用于指代此表的其他术语/短语的列表。在逻辑表的同义词中,必须是唯一的。

description

对于此表的描述。

dimensions

此表中的维度列列表。

time_dimensions

此表中的时间维度列列表。

measures

此表中的度量值列表。

filters

此表上的预定义筛选器(如果有)。

维度

维度描述了诸如状态、用户类型、平台等分类值。它有以下字段:

必填

name

此维度的描述性名称。

必须是唯一的,并遵循 未加引号的标识符要求。它也不能与 Snowflake 保留的关键字 冲突。

expr

此维度的 SQL 表达式。这可能是对物理列的引用,或者是包含底层基表中一列或多列的 SQL 表达式。

data_type

此维度的数据类型。有关 Snowflake 中所有数据类型的概述,请参阅 SQL 数据类型参考。请注意,目前不支持 VARIANTOBJECTGEOGRAPHYARRAY

可选

synonyms

用于指代此维度的其他术语/短语的列表。在这个语义模型的所有同义词中,必须是唯一的。

description

关于此维度的简要描述,包括其包含哪些数据。

unique

一个布尔值,表示此维度具有唯一值。

sample_values

此列的示例值(如果有)。可以添加任何可能在用户问题中被引用的值。

cortex_search_service

指定要用于此维度的 Cortex Search 服务。它有以下字段:

  • service:Cortex Search 服务的名称。

  • literal_column:(可选)Cortex Search 服务中包含字面量值的列。

  • database:(可选)Cortex Search 服务所在的数据库。默认为 base_table 的数据库。

  • schema:(可选)Cortex Search 服务所在的架构。默认为 base_table 的架构。

此字段替换 cortex_search_service_name 字段,该字段只能指定名称。cortex_search_service_name 已弃用。

is_enum

布尔值。如果为 True,则 sample_values 字段中的值将被视为可能值的完整列表,模型仅在筛选该列时从这些值中进行选择。

时间维度

时间维度描述的是时间值,例如销售日期、创建时间和年份。它有以下字段:

必填

name

此时间维度的描述性名称。

必须是唯一的,并遵循 未加引号的标识符要求。它也不能与 Snowflake 保留的关键字 冲突。

expr

此列的 SQL 表达式。这可能是对物理列的引用,或者是包含底层基表中一列或多列的 SQL 表达式。

data_type

此时间维度的数据类型。有关 Snowflake 中所有数据类型的概述,请参阅 SQL 数据类型参考。请注意,目前不支持 VARIANTOBJECTGEOGRAPHYARRAY

可选(推荐)

synonyms

用于指代此时间维度的其他术语/短语的列表。在这个语义模型的所有同义词中,必须是唯一的。

description

关于此维度的简要描述,包括其包含哪些数据。请提供相应信息,帮助人们使用此表编写查询。例如,对于 DATETIME 列,请指定数据的时区。

unique

一个布尔值,表示此列具有唯一值。

sample_values

此列的示例值(如果有)。可以添加任何可能在用户问题中被引用的值。此字段是可选字段。

度量值

度量值描述的是数值,例如收入、展示次数和薪水。它有以下字段:

必填

name

此度量值的描述性名称。

必须是唯一的,并遵循 未加引号的标识符要求。它也不能与 Snowflake 保留的关键字 冲突。

expr

此列的 SQL 表达式。这可能是对物理列的引用,或者是包含底层基表中一列或多列的 SQL 表达式。

data_type

此度量值的数据类型。有关 Snowflake 中所有数据类型的概述,请参阅 SQL 数据类型参考。请注意,目前不支持 VARIANTOBJECTGEOGRAPHYARRAY

可选(推荐)

synonyms

用于指代此度量值的其他术语/短语的列表。在这个语义模型的所有同义词中,必须是唯一的。

description

关于此度量值的简要描述,包括此列包含哪些数据。

unique

一个布尔值,表示此列具有唯一值。

default_aggregation

在分组上下文中应用于此列的默认聚合。一些示例值包括 sum、avg、min、max、median、count、count_distinct 等。

sample_values

此列的示例值(如果有)。可以添加任何可能在用户问题中被引用的值。

筛选器

筛选器表示用于筛选的 SQL 表达式。它有以下字段:

必填

name

此筛选器的描述性名称。

必须是唯一的,并遵循 未加引号的标识符要求。它也不能与 Snowflake 保留的关键字 冲突。

expr

此筛选器的 SQL 表达式,引用逻辑列。

可选(推荐)

synonyms

用于指代此筛选器的其他术语/短语的列表。在这个语义模型的所有同义词中,必须是唯一的。

description

关于此筛选器的简要描述,包括此筛选器通常用途的详细信息。

基表

基表用于表示完全限定的表名称。这是逻辑表映射到的物理表。它有以下字段:

必填

database

数据库的名称。

schema

架构的名称。

table

表的名称。

经过验证的查询

请参阅 Cortex Analyst 验证查询存储库,了解 YAML 文件中此节的用途和结构。

示例 YAML

本节展示了一个示例语义模型 YAML。

此示例假设您的架构中有以下表:

CREATE TABLE sales.public.sd_data (
    id INT PRIMARY KEY,
    dt DATETIME,
    cat VARCHAR(255),
    loc VARCHAR(255),
    cntry VARCHAR(255),
    chn VARCHAR(50),
    amt DECIMAL(10, 2),
    unts INT,
    cst DECIMAL(10, 2)
);
Copy

此表的列名称较为晦涩,关于列的语义信息也不多。以下是一个语义模型 YAML,提供了关于此表的更多语义信息:

# Name and description of the semantic model.
name: Sales Data
description: This semantic model can be used for asking questions over the sales data.

# A semantic model can contain one or more tables.
tables:

  # A logical table on top of the 'sd_data' base table.
  - name: sales_data
    description: A logical table capturing daily sales information across different store locations and product categories.

    # The fully qualified name of the base table.
    base_table:
      database: sales
      schema: public
      table: sd_data

    # Dimension columns in the logical table.
    dimensions:
      - name: product_category
        synonyms:
          - "item_category"
          - "product_type"
        description: The category of the product sold.
        expr: cat
        data_type: NUMBER
        unique: false
        sample_values:
          - "501"
          - "544"

      - name: store_country
        description: The country where the sale took place.
        expr: cntry
        data_type: TEXT
        unique: false
        sample_values:
          - "USA"
          - "GBR"

      - name: sales_channel
        synonyms:
          - "channel"
          - "distribution_channel"
        description: The channel through which the sale was made.
        expr: chn
        data_type: TEXT
        unique: false
        sample_values:
          - "FB"
          - "GOOGLE"

    # Time dimension columns in the logical table.
    time_dimensions:
      - name: sale_timestamp
        synonyms:
          - "time_of_sale"
          - "transaction_time"
        description: The time when the sale occurred. In UTC.
        expr: dt
        data_type: TIMESTAMP
        unique: false

    # Measure columns in the logical table.
    measures:
      - name: sales_amount
        synonyms:
          - "revenue"
          - "total_sales"
        description: The total amount of money generated from the sale.
        expr: amt
        data_type: NUMBER
        default_aggregation: sum

      - name: sales_tax
        description: The sales tax paid for this sale.
        expr: amt * 0.0975
        data_type: NUMBER
        default_aggregation: sum

      - name: units_sold
        synonyms:
          - "quantity_sold"
          - "number_of_units"
        description: The number of units sold in the transaction.
        expr: unts
        data_type: NUMBER
        default_aggregation: sum

      - name: cost
        description: The cost of the product sold.
        expr: cst
        data_type: NUMBER
        default_aggregation: sum

      - name: profit
        synonyms:
          - "earnings"
          - "net income"
        description: The profit generated from a sale.
        expr: amt - cst
        data_type: NUMBER
        default_aggregation: sum

    # A table can define commonly used filters over it. These filters can then be referenced in user questions directly.
    filters:
      - name: north_america
        synonyms:
          - "North America"
          - "N.A."
          - "NA"
        description: "A filter to restrict only to north american countries"
        expr: cntry IN ('canada', 'mexico', 'usa')
Copy
语言: 中文