实现M002 V3 P0.1 Parent Group路由修订

This commit is contained in:
andy
2026-07-12 11:42:01 +08:00
parent 0358b34159
commit 92489af18e
42 changed files with 3971 additions and 79 deletions

View File

@@ -0,0 +1,160 @@
# 人工复核
## 入口结果边界
Gateway 必须先校验 `source_message.source_message_id`。该值为 `null`、空字符串或纯空白时,形成并校验 `00-output-contract.md` 定义的 `infrastructure_input_error`不得读取正文、附件、OCR、历史或系统上下文也不得调用 `booking-desk-event` skill。冻结该 error 后必须执行一次 mandatory submit再原样返回如果 Gateway 在 Main Agent 前短路Gateway 必须执行同一最终提交钩子。
source message identity 合法后Main Agent 才完成支持范围分类:
- 当前输入可理解,但没有匹配 active event 时,输出 `S10`
- 当前输入不足,无法判断是否匹配 active event 时,输出 `S99`
- `S10``S99` 都展示源邮件并由用户自行决定是否回复或进行其他处理。
- `S10``S99` 不由 `booking-desk-event` skill 输出。
Thank you、裸 FYI、acknowledgement、Noted、Received 等没有具体预订业务信息的文字,以及一般咨询和当前不支持的 Booking Confirmation Request都不匹配 Trace。FYI 或单纯告知中包含与明确预订对象相关的具体补充信息时,匹配 `Trace`。正文只有 `see attached` 且附件无法取得、无法识别业务方向时走 `S99`
需要酒店批准的价格、退款、减免、账期、付款政策或合同条件询问不是 Trace。此类具有当前业务意义但没有任务卡承接的内容必须保留在 `unknowns`:同邮件存在支持事件时输出到 `unhandled_current_intents`,整封邮件没有支持事件时走 S10。意图清楚但不受支持不等于业务判断不安全不得仅因此输出业务人工复核。
## 两种业务人工复核
### 已知业务卡型的人工复核
只要业务 `event_type` 和 subtype 已经能够确定,就必须保留该业务事件,继续输出能够安全抽取的字段,并令该 event 的 `manual_review` 为完整 `business_event_review` 对象。不得仅因为房型、Rate Code、目标对象或某项证据存在歧义就把事件改成 `Need Manual Review`
常见情形包括:
- target object 不明确或不唯一,但业务卡型已确定;
- current/history 边界不明确,但业务卡型已确定;
- 已确定业务卡型但其附件、OCR、表格或必要证据不可读
- required room type、Rate Code、settlement price 或其他必需字段无法唯一确定;
- QBD/LianTai row、highlight 或 current-row evidence 缺失或歧义;
- system context 显示 duplicate、pending/open task、active workflow、lock 或 conflict。
- Parent Group 的 `group_code``block_code` 原始候选冲突,但 `New Booking + Allotment / Control Block``Cancel Allotment` 卡型已确定;此时两 key 均置空,保留候选证据并使用 `target_object_unclear`
- 完整 Parent split 已确认,但 child list、关系 index 或 parent-child 对应不完整;保留 linked `Cancel Allotment` 并使用 `parent_child_split_evidence_unclear`
例如,正文明确 `please update the booking as attached`,因此业务卡型已经确定为 Update附件不可读时仍输出对应 Update event把安全取得的订单号、客人名等保留下来并附非空 `manual_review`。Adapter 据此派生 `manual_review + 原业务 task_type + 原业务 subtype`,而不是 Fallback。
### 业务类型或 subtype 未知的 Fallback
只有业务 `event_type` 或 subtype 本身无法确定时,才输出 `event_type=Need Manual Review`。Adapter 将其派生为:
```text
manual_review + Fallback + business_event_review
```
例如,同一段 current action 同时可能表示 New Booking 或 Update且没有足够证据裁决业务类型无法确定此时才走 Fallback。
不得为了满足 Main Agent 的 skill-call gate 而制造 `Need Manual Review`。如果 Main 给出的所有粗候选都被 skill 否定skill 返回内部 `no_supported_event` disposition由 Main 转成 S10。
## 必要结构和字段类型
业务级 `manual_review` 必须完整包含九个字段:
```json
{
"reason_code": "room_type_mapping_multiple_candidates",
"visible_reason": "房型原文可识别,但无法唯一映射到当前有效 PMS 房型代码。",
"review_record_type": "business_event_review",
"missing_fields": [
"/extracted_fields/room_items/0/pms_room_type_code"
],
"blocking_points": [
"pms_room_type_code is required before Preflight"
],
"conflicting_points": [],
"suggested_human_actions": [
"select_room_type_from_active_pms_catalog"
],
"evidence_to_check": [
"current_body",
"current_attachments"
],
"known_fields": {
"room_type_raw": "SUITE"
}
}
```
固定规则:
- 九个字段必须全部存在。
- `reason_code``visible_reason` 必须是非空字符串。
- `review_record_type` 固定为 `business_event_review`
- `missing_fields``blocking_points``conflicting_points``suggested_human_actions``evidence_to_check` 固定为字符串数组;无内容时使用空数组。
- `known_fields` 固定为对象;没有已知值时使用空对象。
- `missing_fields[]` 每一项必须是指向当前 event 的 RFC 6901 JSON Pointer例如 `/extracted_fields/room_items/0/pms_room_type_code`。不得填写人类说明、点号路径或根邮件路径。
- 不新增 `required_user_inputs`;前端业务卡字段注册表负责将 pointer 映射到可编辑控件。
- pointer 无法映射到该业务卡的已知可编辑字段时,属于 adapter contract error不能展示一个无法完成的复核卡。
## 房型和其他必需字段
房型原文可以识别但映射不唯一时:
- 保留 `room_type_raw`
- `pms_room_type_code=null`
-`manual_review.missing_fields` 中登记对应的 JSON Pointer
- 用户只能从信息系统提供的当前有效 PMS 房型目录中选择,不得由 Agent 猜测,也不得允许用户自由填写 PMS code。
Rate Code、价格或其他业务必需字段遵循相同原则保留安全抽取值待用户确认的目标字段置为 `null` 并用 pointer 标记。`requires_downstream_hard_validation` 不能替代这些字段的人工确认;也不得写成“人工复核或 downstream validation 二选一”。
一个 event 进入人工复核时,不得清空同邮件中的 sibling events。每个 event 独立派生路由:确定且完整的 sibling 仍为 normal task需要确认的 sibling 保留其业务 task type/subtype 并进入 manual-review mode。
## 同卡解阻状态
Agent 输出只描述初始业务判断,保持不可变。信息系统在同一张业务卡上维护复核状态,初始为:
```json
{
"review_status": "pending",
"review_resolution": null
}
```
用户确认后保存:
```json
{
"review_status": "resolved",
"review_resolution": {
"field_overrides": [
{
"field_pointer": "/extracted_fields/room_items/0/pms_room_type_code",
"value": "SU1"
}
],
"resolved_by": "<user_id>",
"resolved_at": "<ISO-8601>"
}
}
```
固定规则:
- 原 Agent payload 和初始 `result_type=manual_review` 不得改写;当前页面模式由 `review_status` 控制。
- `field_overrides[].field_pointer` 必须与待解决字段 pointer 对应,覆盖值和审计信息由信息系统持有。
- 只有所有缺失字段完成、目录值校验通过、依赖字段重新校验通过后,才允许进入现有 Preflight。
- 在 Preflight 完成前不得写 PMS。
- 不创建第二张 linked normal task解决后仍是同一张业务卡。
- 业务字段可以按权限编辑邮件原文、raw evidence、source ID 和审计字段只读。
## 常见 Reason Code
- `current_history_boundary_unclear`
- `target_object_unclear`
- `multiple_target_candidates`
- `attachment_or_ocr_unreadable`
- `event_type_conflict_unclear`
- `subtype_unresolved`
- `room_type_mapping_unconfirmed`
- `room_type_mapping_multiple_candidates`
- `rate_code_unconfirmed`
- `rate_code_rule_not_covered`
- `settlement_price_required`
- `manual_price_unconfirmed`
- `composite_unit_price_unconfirmed`
- `fix_charge_unconfirmed`
- `qbd_liantai_row_evidence_unreadable`
- `parent_child_split_evidence_unclear`
- `stay_date_inference_unclear`
- `existing_order_record_found`
- `pending_or_active_workflow_found`