# 用语义配置提升知识库问数准确性

MOI 的语义层位于数据库 Schema 与自然语言问答之间，是一层可治理、可复用的业务抽象。它不改变原始表结构，而是把技术字段、业务名称、指标公式、企业内部编码和查询约束组织成可执行的语义契约，并在生成 SQL 时提供给规划和执行过程使用。通用模型可能认识 `NETWR`、`VBELN`、`GBSTA` 等常见 SAP 字段，但仅凭 Schema 仍无法确定企业内部的考核口径、地区编码，或知识库允许查询的币种范围。

本教程的销售订单表包含三个仅靠 Schema 无法还原的内部口径：考核销售额按已完成订单 `NETWR` 的 90% 计算；`VKORG = 1000/2000/3000` 分别代表华北、华东和华南；销售分析只能使用人民币订单，USD 记录不得与 CNY 直接相加。接下来先记录未配置语义的结果，再通过指标、业务规则和强制约束分别补齐这三部分信息。少配置任何一类，最终结果都会出现计算错误、地区归属错误或数据范围不合规。

## 你将完成什么

- 将销售订单 CSV 导入 Catalog 并加入知识库；
- 配置指标、业务规则和强制约束；
- 使用同一个销售分析问题，对比配置前后的订单统计、地区名称和币种范围。

## 开始前准备

- 准备一个 MOI 账号并进入目标工作区；
- 下载示例文件 [semantic-sales-data.csv](../assets/downloads/semantic-sales-data.csv)。

## 操作步骤

### 1. 导入销售订单 CSV

1. 在左侧导航进入 **数据 > 导入任务**，点击 **新建导入任务**。
2. 选择 **结构化** 和 **本地上传**，上传 `semantic-sales-data.csv`。
3. 选择 **新建表**，目标位置填写：

   ```text
   tutorial_data / semantic_demo / sales_orders
   ```

4. 确认第一行是列名，并检查 `ERDAT` 为 `DATE`，`KWMENG` 为 `INT`，`NETWR` 为 `DECIMAL(15,2)`；其余字段保持默认设置。SAP 中 `NETWR` 通常对应货币字段 `CURR(15,2)`。

   ```{image} ../assets/images/tutorials/semantic-sales-import-config.png
   :alt: 导入 SAP 风格销售订单 CSV 并配置 NETWR 为 DECIMAL(15,2)
   ```

5. 点击 **创建并开始导入**，等待任务状态变为 **已完成**。

   ```{image} ../assets/images/tutorials/semantic-sales-import-completed.png
   :alt: 导入任务列表中 semantic-sales-data.csv 显示已完成
   ```

### 2. 创建知识库并添加数据表

1. 进入 **资源中心 > 知识库**，点击 **创建知识库**。
2. 输入名称 `sales_semantic_knowledge`，用途填写“用于按企业管理口径查询销售考核数据”。
3. 打开知识库详情，点击 **添加数据**，选择 `tutorial_data / semantic_demo / sales_orders`。

   ```{image} ../assets/images/tutorials/semantic-sales-add-table.png
   :alt: 在知识库中选择 Catalog 的 sales_orders 表并添加
   ```

4. 等待数据源处理完成后，打开 **高级配置 > 语义配置**。

### 3. 先不配置语义，记录对照结果

在语义配置中暂不新建条目，先进入知识库 **对话**，发送：

```text
统计 2026 年第一季度华东、华南和华北三个业务地区的考核销售额、有效订单数和平均考核订单金额，并按考核销售额从高到低排序。结果中显示业务地区名称。
```

记录回答和生成的 SQL：

```{image} ../assets/images/tutorials/semantic-sales-before-semantic.png
:alt: 未配置语义时对 SAP 风格销售订单数据的问答结果
```

未配置语义时，系统只能根据字段名和常见 SAP 知识猜测口径。请重点检查以下三处：

- **考核指标**：Schema 没有记录 90% 的考核系数，也没有说明“有效订单”只统计 `GBSTA = 'C'`，系统容易直接汇总 `NETWR`；
- **业务地区**：Schema 没有记录本企业采用 `1000 = 华北`、`2000 = 华东`、`3000 = 华南` 的非顺序映射，系统可能按照代码顺序错误猜测地区；
- **币种范围**：表中同时存在 CNY 和 USD。直接汇总 `NETWR` 会把不同币种相加，得到没有业务意义的销售净值。

这些问题都不是字段类型能够解决的，因此该结果只能作为配置前的对照，不能作为业务结论。

### 4. 配置指标、业务规则和强制约束

返回 **高级配置 > 语义配置**。点击相应分类右侧的 **新建**，每次保存一条语义配置。除特别说明外，关联表都选择 `sales_orders`。

#### 指标

点击 **指标 > 新建指标**，按照前端表单依次创建下面三个基础指标。每创建一项，都先填写基本信息，再完成 **基础指标计算**，最后点击 **创建**。

| 配置项 | 考核销售额 | 有效订单数 | 平均考核订单金额 |
| --- | --- | --- | --- |
| **指标标识** | `assessed_sales` | `valid_order_count` | `average_assessed_order_value` |
| **名称** | 考核销售额 | 有效订单数 | 平均考核订单金额 |
| **指标说明** | 已完成订单按 `NETWR` 的 90% 计入考核销售额，用于预留 10% 渠道返利 | 统计已完成销售订单的数量 | 已完成订单 `NETWR` 的平均值按 90% 折算 |
| **同义词** | 绩效销售额、管理口径销售额 | 完成订单数、有效单量 | 平均考核客单价、考核订单均额 |
| **指标类型** | 基础指标 | 基础指标 | 基础指标 |
| **来源表** | `sales_orders` | `sales_orders` | `sales_orders` |
| **聚合函数** | `sum` | `count` | `avg` |
| **聚合字段** | `NETWR` | `VBELN` | `NETWR` |
| **乘数** | `0.9` | `1` | `0.9` |
| **固定筛选条件** | 字段 `GBSTA`、比较方式 `equals`、值 `C` | 字段 `GBSTA`、比较方式 `equals`、值 `C` | 字段 `GBSTA`、比较方式 `equals`、值 `C` |

样例表中每行对应一笔订单，`VBELN` 不重复，因此前端提供的 `count` 可以直接作为订单数。三个指标都通过固定筛选条件仅统计 `GBSTA = 'C'` 的已完成订单。90% 是本企业预留 10% 渠道返利后的管理考核系数，并不存在于数据库 Schema 中，因此不配置指标时无法得到正确的考核金额。

```{image} ../assets/images/tutorials/semantic-sales-metric-basic.png
:alt: 考核销售额指标的指标标识、名称、说明、同义词和指标类型配置
```

```{image} ../assets/images/tutorials/semantic-sales-metric-calculation.png
:alt: 考核销售额指标的来源表、聚合函数、聚合字段、乘数和固定筛选条件配置
```

按照表格完成另外两个指标后，返回指标列表，确认页面中显示 `assessed_sales`、`valid_order_count` 和 `average_assessed_order_value` 三项指标。

```{image} ../assets/images/tutorials/semantic-sales-metrics-list.png
:alt: 语义配置中已创建考核销售额、有效订单数和平均考核订单金额三个指标
```

#### 业务规则

点击 **业务规则 > 新建业务规则**，按下表填写并创建：

| 配置项 | 配置值 |
| --- | --- |
| **业务规则标识** | `sales_region_mapping` |
| **关联表** | `sales_orders` |
| **规则内容** | 本企业销售组织与业务地区的对应关系为：`VKORG = '1000'` 表示华北，`VKORG = '2000'` 表示华东，`VKORG = '3000'` 表示华南。查询涉及地区时，应按照该映射筛选和分组，并在结果中显示业务地区名称。 |

```{image} ../assets/images/tutorials/semantic-sales-business-rule.png
:alt: 语义配置中已创建销售组织与业务地区映射规则
```

业务规则补充 Schema 中没有记录的企业内部编码含义。本例故意采用不能按代码大小猜测的地区映射；未配置该规则时，即使系统输出了中文地区名称，也可能把地区归属判断错误。

#### 强制约束

点击 **高级配置 > 强制约束 > 新建强制约束**，按下表填写并创建：

| 配置项 | 配置值 |
| --- | --- |
| **强制约束标识** | `cny_sales_scope` |
| **关联表** | `sales_orders` |
| **约束条件** | 字段 `WAERK`、比较方式 `equals`、值 `CNY` |

```{image} ../assets/images/tutorials/semantic-sales-constraint.png
:alt: 强制约束 cny_sales_scope 限定 sales_orders 仅查询 CNY 数据
```

样例表中包含 USD 订单；该约束会在 `sales_orders` 参与查询时自动加入，避免将 USD 与 CNY 的 `NETWR` 直接相加。它规定的是知识库可查询的数据范围，与指标的计算公式、业务规则的地区映射互不重复。

保存后执行语义配置的 **校验**，确认每条配置都通过。

### 5. 验证指标、业务规则和强制约束

回到知识库 **对话**，再次发送步骤 3 的问题。

```{image} ../assets/images/tutorials/semantic-sales-after-semantic.png
:alt: 配置指标、业务规则和强制约束后的销售考核问答结果
```

核对回答，并展开思考过程查看 SQL。配置后应能看到：

- 使用 `assessed_sales`、`valid_order_count` 和 `average_assessed_order_value` 的定义；
- 考核销售额使用 `sum(NETWR)` 并设置乘数 `0.9`，有效订单数使用 `count(VBELN)`，平均考核订单金额使用 `avg(NETWR)` 并设置乘数 `0.9`；
- 查询包含 `GBSTA = 'C'`；
- 查询按照 `VKORG` 分组，并将 `1000`、`2000`、`3000` 分别显示为华北、华东、华南；
- 强制约束自动加入 `WAERK = 'CNY'`；
- 按考核销售额降序得到华北、华东、华南，考核销售额分别为 14,940、6,336 和 1,080 元；对应有效订单数为 4、2 和 1，平均考核订单金额为 3,735、3,168 和 1,080 元。

其中，指标解决 90% 考核系数、已完成状态筛选和聚合方式；业务规则提供销售组织到业务地区的内部映射；强制约束排除 USD 数据并限定人民币范围。删除或漏配其中任何一项，都无法得到上述完整结果。

| 缺少的配置 | 可观察到的错误 |
| --- | --- |
| 指标 | 系统可能直接汇总 `NETWR`，遗漏 90% 考核系数，或没有将指标范围固定为已完成订单 |
| 业务规则 | 系统可能把 `1000/2000/3000` 按顺序猜成华东、华南、华北，而正确映射是华北、华东、华南 |
| 强制约束 | USD 订单会进入汇总；即使使用 90% 考核系数，华北考核销售额也会从正确的 14,940 变成 15,840 |

如果结果仍不符合预期，先检查语义条目的来源表、标识符、指标字段和筛选条件，再重新校验并提问。

## 教程完成

您已经用一份 CSV 完成了从数据导入、知识库建模到问答对比的完整流程。这个例子说明：SAP Schema 只能提供技术结构，完整业务信息需要通过指标、业务规则和强制约束补充，才能让自然语言问数得到可解释、可复核的结果。
