

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 自动推理策略最佳实践
<a name="automated-reasoning-policy-best-practices"></a>

本页汇总了创建和维护自动推理策略的最佳实践。在创建您的第一个策略之前，请先阅读此内容，并在调试问题时参考该策略。有关这些做法背后的概念基础，请参阅[自动推理检查概念](automated-reasoning-checks-concepts.md)。有关 step-by-step创建说明，请参阅[创建自动推理策略](create-automated-reasoning-policy.md)。

## 从简单开始，然后进行迭代
<a name="bp-start-simple"></a>

创建自动推理策略时最常见的错误是尝试一次性捕获整个复杂文档。取而代之的是，从规则的重点子集开始，然后逐步构建。

1. 在源文档中选择一个定义明确的部分（例如，人力资源手册中的育儿假资格）。

1. 根据该部分创建策略并查看提取的规则和变量。

1. 编写涵盖该部分关键场景的测试。

1. 请先修复所有问题，然后再添加更多内容。

1. 使用迭代策略构建逐个合并其他部分。有关更多信息，请参阅 [迭代策略构建](create-automated-reasoning-policy.md#iterative-policy-building)。

这种方法有两个优点：它使问题更易于隔离（你知道哪个部分引入了问题），并且它可以在开发过程中使策略保持可管理性。包含 10 条经过充分测试的规则的策略比包含 100 条未经测试的规则的策略更有用。

## 使用法学硕士学位预处理文档
<a name="bp-preprocess-with-llm"></a>

对于篇幅较长、包含叙事散文或将规则与非规则内容混为一谈的文档（例如法律免责声明或组织背景），请在将文档上传到自动推理检查之前通过法学硕士学位。要求法学硕士按照明确的 if-then 规则提取内容。此预处理步骤显著提高了提取策略的质量，因为自动推理检查最适合处理清晰的声明性语句而不是非结构化文本。

在编写预处理提示时，请包括以下有关 LLM 的说明：
+ 以 if-then 格式提取规则，其中包含明确的条件和后果。
+ 保留所有条件、逻辑运算符（AND、OR、NOT）、量词（“至少”、“最多”）和例外子句（“除非”、“除外”）。
+ 为常识性限制（例如 “账户余额不能为负” 或 “信用评分必须在 300 到 850 之间”）添加理智规则，这些限制会转化为政策中的边界规则（请参阅）。[验证数值的范围](#bp-validate-ranges)

**重要**  
在将 LLM 用作源文本之前，请务必对照原始文档查看 LLM 的输出。 LLMs 可以幻觉来源中不存在的规则，误解条件或丢弃重要的例外情况。预处理步骤是一个起点，不能取代人工审查。

有关详细的提示模板和 step-by-step预处理工作流程，请参阅[（可选）使用 LLM 将文档重写为逻辑规则](create-automated-reasoning-policy.md#preprocess-with-llm)。

## 使用含义 (=>) 来构造规则
<a name="bp-use-implications"></a>

if-then 格式（使用`=>`隐含运算符）是最重要的规则编写模式。每条表达条件关系的规则都应使用这种格式。


| 好：暗示 | 不好：赤裸的断言 | 
| --- | --- | 
| (=> (and isFullTime (> tenureMonths 12)) eligibleForParentalLeave) | eligibleForParentalLeave | 
| (=> (> loanAmount 500000) requiresCosigner) | requiresCosigner | 

裸露的断言（没有 if-then 结构的规则）会产生公理——这些陈述始终是正确的。该断言`eligibleForParentalLeave`告诉自动推理检查，无论条件如何，育儿假资格始终是正确的。任何说用户*不*符合资格的输入都会返回，`IMPOSSIBLE`因为它与这个公理相矛盾。

裸露的断言仅适用于应始终保持的边界条件，例如：

```
;; Account balance can never be negative
(>= accountBalance 0)

;; Interest rate is always between 0 and 1
(and (>= interestRate 0) (<= interestRate 1))
```

如果您在提取的策略中发现了裸露的断言，请将其重写为条件语句或将其删除。有关查看提取的政策的更多信息，请参阅[查看提取的政策](create-automated-reasoning-policy.md#review-extracted-policy)。

## 撰写全面的变量描述
<a name="bp-variable-descriptions"></a>

变量描述是翻译准确性的主要因素。当自动推理检查将自然语言转换为形式逻辑时，它使用变量描述来确定哪些变量与文本中提到的概念相对应。模糊或不完整的描述是导致`TRANSLATION_AMBIGUOUS`结果的首要原因。

一个好的变量描述应该可以回答四个问题：

1. **这个变量代表什么？** 用通俗易懂的语言解释这个概念。

1. **它使用什么单位或格式？** 指定单位（月、美元、十进制百分比）和任何转换规则。

1. **用户如何提及这个概念？** 包括同义词、替代短语以及用户用日常语言表达此概念的常用方式。

1. **边界条件是什么？** 描述边缘情况、默认值以及变量设置为特定值时的含义。

**示例：之前和之后**


| 模糊（导致翻译失败） | 详细（翻译可靠） | 
| --- | --- | 
| tenureMonths: “员工工作了多长时间。” | tenureMonths：“员工连续受雇的完整月数。当用户提及服务年限时，请转换为月（例如，2 年 = 24 个月）。对于尚未完成第一个月的新员工，设置为 0。” | 
| isFullTime: “全职状态。” | isFullTime：“员工是全职工作（真）还是兼职（假）。当用户提到 “全职”、“全时工作” 或每周工作 40 小时以上时，设置为 true。当用户提到'兼职'、'减少工作时间'或每周工作少于40小时时，设置为false。” | 
| interestRate: “利率。” | interestRate：“年利率以十进制值表示，其中0.05表示5％，0.15表示15％。当用户提及'5％'之类的百分比时，请转换为十进制形式 (0.05)。” | 

## 对非排他性状态使用布尔值
<a name="bp-booleans-non-exclusive"></a>

对可以共存的状态进行建模时，请使用单独的布尔变量而不是单个枚举。一个人既可以是资深人士，也可以是老师。使用枚举会`customerType = {VETERAN, TEACHER}`强制在它们之间做出选择，当两者都适用时，就会产生逻辑上的矛盾。


| 好：分开布尔值 | 错误：非排他状态的枚举 | 
| --- | --- | 
|  `isVeteran`（bool）：“客户是否是退伍军人。” `isTeacher`（bool）：“客户是否是老师。”  |  `customerType`（枚举：退伍军人、老师、学生）：“客户的类型。” 问题：既是资深人士又是老师的客户不能代理。  | 

为真正相互排斥的类别保留枚举，其中一次只能应用一个值，例如`leaveType = {PARENTAL, MEDICAL, BEREAVEMENT}`（员工一次只能申请一种休假）。有关自定义类型的更多信息，请参阅[自定义类型（枚举）](automated-reasoning-checks-concepts.md#ar-concept-custom-types)。

## 在变量描述中指定单位和格式
<a name="bp-units-formats"></a>

单位含糊不清是翻译错误的常见来源。如果用户说 “我在这里工作了 2 年”，而你的变量是`tenureMonths`，那么翻译需要知道将年转换为月。如果您的变量描述未指定单位，则翻译可能会`tenureMonths = 2`改为赋值`tenureMonths = 24`。

请务必指定：
+ 计量单位（月、天、美元、百分比）。
+ 格式（十进制与百分比、日期格式、货币）。
+ 常见替代表达式的转换规则（例如，“2 年 = 24 个月”）。

**示例：**
+ `loanAmount`：“贷款总额以美元计。当用户提及以千为单位的金额（例如'500K'）时，请转换为完整数字（500000）。”
+ `submissionDate`: “提交截止日期后的天数。值为 0 表示提交准时。正值表示延迟提交。”

## 验证数值的范围
<a name="bp-validate-ranges"></a>

对于数值变量，添加限制有效范围的边界规则。这可以防止逻辑上不可能出现的情况，并有助于自动推理检查产生更有意义的结果。

```
;; Account balance cannot be negative
(>= accountBalance 0)

;; Interest rate must be between 0 and 1 (0% to 100%)
(and (>= interestRate 0) (<= interestRate 1))

;; Credit score ranges from 300 to 850
(and (>= creditScore 300) (<= creditScore 850))

;; Tenure in months cannot be negative
(>= tenureMonths 0)
```

如果没有这些边界规则，Automated Reasoning 检查可能会考虑账户余额为负或信用评分高于 1000 的情况，这在您的域中毫无意义。边界规则是为数不多的适合裸露断言（不是 if-then 格式的规则）适用的情况之一。

## 使用中间变量进行抽象
<a name="bp-intermediate-variables"></a>

当多个规则共享一个共同条件时，将该条件提取到中间布尔变量中。这简化了您的规则，使策略更易于维护。

**示例：会员等级**

与其在每条福利规则中重复会员资格条件，不如说：

```
;; Without intermediate variable (repetitive)
(=> (and (> purchaseTotal 1000) (> accountAge 12)) eligibleForFreeShipping)
(=> (and (> purchaseTotal 1000) (> accountAge 12)) eligibleForPrioritySupport)
(=> (and (> purchaseTotal 1000) (> accountAge 12)) eligibleForEarlyAccess)
```

定义一个中间变量并引用它：

```
;; With intermediate variable (cleaner)
(=> (and (> purchaseTotal 1000) (> accountAge 12)) isPremiumMember)
(=> isPremiumMember eligibleForFreeShipping)
(=> isPremiumMember eligibleForPrioritySupport)
(=> isPremiumMember eligibleForEarlyAccess)
```

这种模式使以后更新成员资格标准变得更加容易，您只需要更改一条规则，而不是三条规则。

## 使用枚举进行分类
<a name="bp-enums-categorization"></a>

当变量表示具有一组固定的互斥值的类别时，请使用自定义类型（枚举），而不是多个布尔值或字符串。枚举限制了可能的值并使规则更清晰。


| 好：枚举 | 避免：排他状态有多个布尔值 | 
| --- | --- | 
|  类型：`LeaveType = {PARENTAL, MEDICAL, BEREAVEMENT, PERSONAL}` 变量:`leaveType`(LeaveType) 规则：`(=> (= leaveType PARENTAL) (>= leaveDays 60))`  |  `isParentalLeave` (bool) `isMedicalLeave` (bool) `isBereavementLeave` (bool) 问题：没有什么能阻止多个布尔值同时为真。  | 

**提示**  
如果输入可能与任何定义的类别不匹配，请在枚举中加入`OTHER`或`NONE`值。这样可以防止当输入不完全适合定义的值之一时出现翻译问题。

## 保持逻辑是声明性的，而不是程序性的
<a name="bp-declarative-logic"></a>

自动推理策略描述*的是真实*情况，而不是*如何计算*。避免编写看起来像带有顺序步骤或优先级逻辑的代码的规则。


| 良好：陈述式 | 避免：程序思维 | 
| --- | --- | 
|  “如果员工是全职且任期超过12个月，那么他们就有资格休育儿假。” 这说明了条件与结果之间关系的事实。  |  “首先检查员工是否是全职员工。如果是，请检查任期。如果任期超过 12 个月，则将资格设置为 true。” 这描述的是过程，而不是逻辑关系。  | 

同样，避免在规则之间编码优先级或优先级。在形式逻辑中，所有规则同时适用。如果您需要表示一个条件优先于另一个条件，请在规则条件中对其进行显式编码：

```
;; GOOD: Explicit exception handling
;; General rule: full-time employees with 12+ months get parental leave
(=> (and isFullTime (> tenureMonths 12) (not isOnProbation))
    eligibleForParentalLeave)

;; BAD: Trying to encode precedence
;; "Rule 1 takes priority over Rule 2" — this concept doesn't exist
;; in formal logic. Instead, combine the conditions into a single rule.
```

## 命名规范
<a name="bp-naming-conventions"></a>

一致的命名使策略更易于阅读、维护和调试。请遵循以下惯例：
+ **布尔变量：**使用`is`或`has`前缀。例如：`isFullTime`、`hasDirectDeposit`、`isEligibleForLeave`。
+ **数值变量：**在名称中包含单位。例如：`tenureMonths`、`loanAmountUSD`、`creditScore`。
+ **枚举类型： PascalCase 用于类型**名称，UPPER\$1SNAKE\$1CASE 用于值。例如：`LeaveType = {PARENTAL, MEDICAL, BEREAVEMENT}`。
+ **变量：**使用驼峰大小写。例如：`tenureMonths`、`isFullTime`、`leaveType`。

避免使用可能含糊不清的缩写。使用`tenureMonths`代替`tenMo`和`isFullTime`代替`ft`。清晰的名字对人工审稿人和翻译过程都有帮助。

## 常见的反模式
<a name="bp-anti-patterns"></a>

以下模式经常导致自动推理策略出现问题。如果您遇到意想不到的测试结果，请检查您的策略是否包含任何这些反模式。

### 用公理代替暗示
<a name="bp-anti-axioms"></a>

如中所述[使用含义 (=>) 来构造规则](#bp-use-implications)，裸露的断言会产生始终正确的公理。这是最常见的反模式，也是最具破坏性的——它会使所有类别的输入都返回`IMPOSSIBLE`。

**症状：**应返回`VALID`或`INVALID`返回的`IMPOSSIBLE`测试。

**修复：**在规则中找到裸露的断言并将其重写为含义，或者如果它们不代表边界条件，则将其删除。

### 重叠变量
<a name="bp-anti-overlapping-variables"></a>

如果有两个变量代表相同或相似的概念（例如`tenureMonths`和`monthsOfService`），则会混淆翻译过程。自动推理检查无法确定给定概念使用哪个变量，从而导致翻译和`TRANSLATION_AMBIGUOUS`结果不一致。

**症状：**`TRANSLATION_AMBIGUOUS`即使输入文本清晰明了，测试也会返回。

**修复：**将重叠的变量合并为具有全面描述的单个变量。更新所有引用已删除变量的规则。

### 策略过于复杂
<a name="bp-anti-overly-complex"></a>

具有太多变量、深度嵌套条件或非线性算术的策略可能会超过处理限制并返回`TOO_COMPLEX`结果。

**症状：**测试返回`TOO_COMPLEX`或超时。

**修复：**简化政策。移除未使用的变量，使用中间变量将复杂的规则分解为更简单的规则，并避免使用非线性算术（指数、无理数）。如果您的域名确实很复杂，可以考虑将其拆分为多个重点政策。

### 相互矛盾的规则
<a name="bp-anti-contradictory-rules"></a>

相互矛盾的规则使自动推理检查无法得出结论。例如，一条规定全职员工有资格休假，而另一条规定第一年的员工没有资格休假，但没有具体说明全职员工在第一年的情况。

**症状：**`IMPOSSIBLE`对于涉及冲突规则的输入，则返回测试结果。

**修复：**检查质量报告是否存在冲突规则。通过将规则合并为具有明确条件的单个规则，或者删除其中一个冲突规则，来解决冲突。有关更多信息，请参阅 [查看提取的政策](create-automated-reasoning-policy.md#review-extracted-policy)。

### 未使用的变量
<a name="bp-anti-unused-variables"></a>

未被任何规则引用的变量会给翻译过程带来干扰。当未使用的变量与类似的活动变量竞争时，转换可能会给未使用的变量赋值，从而浪费处理能力，并可能导致`TRANSLATION_AMBIGUOUS`结果。

**症状：**意外`TRANSLATION_AMBIGUOUS`结果，或者为不影响任何规则的变量赋值的转换。

**修复：**删除未使用的变量。在控制台中，查找变量旁边的警告指示器。通过 API，查看来自`GetAutomatedReasoningPolicyBuildWorkflowResultAssets`的质量报告`--asset-type QUALITY_REPORT`。

### 缺少枚举值
<a name="bp-anti-missing-enum-values"></a>

如果你的枚举没有包含用户可能提及的每个可能类别的值，那么当输入与任何定义的值都不匹配时，翻译可能会失败或产生意想不到的结果。

**症状：**测试返回，`TRANSLATION_AMBIGUOUS`或者`NO_TRANSLATIONS`当输入提及不在枚举中的类别时。

**修复：**在枚举中添加`OTHER`或`NONE`值以处理与定义的类别不匹配的输入。更新枚举值描述以明确每个值何时适用。