From b949177febbe50cfd83d9b7691106425466eda8d Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 18 Jul 2026 17:01:12 +0700 Subject: [PATCH] =?UTF-8?q?=E8=90=BD=E5=AE=9AM002=20V4=20Agent=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E5=AD=97=E6=AE=B5=E5=A5=91=E7=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...718-M002-V4-Agent回调草案审查与最新答复.md | 541 ++++++++++++++ .../20260718/0718-V4剩余10项确认回复.md | 210 ++++++ .../0718业务基线-Agent回调问题答复.md | 275 +++++++ docs/project/README.md | 2 + .../M002-v4-agent-callback-field-contract.md | 683 ++++++++++++++++++ 5 files changed, 1711 insertions(+) create mode 100644 docs/import/20260718/0718-M002-V4-Agent回调草案审查与最新答复.md create mode 100644 docs/import/20260718/0718-V4剩余10项确认回复.md create mode 100644 docs/import/20260718/0718业务基线-Agent回调问题答复.md create mode 100644 docs/project/requirements/M002-v4-agent-callback-field-contract.md diff --git a/docs/import/20260718/0718-M002-V4-Agent回调草案审查与最新答复.md b/docs/import/20260718/0718-M002-V4-Agent回调草案审查与最新答复.md new file mode 100644 index 0000000..56b2ac3 --- /dev/null +++ b/docs/import/20260718/0718-M002-V4-Agent回调草案审查与最新答复.md @@ -0,0 +1,541 @@ +# 0718 M002 V4 Agent 回调草案审查与最新答复 + +日期:2026-07-18 + +审查对象:`M002-v4-agent-callback-field-contract-draft.md` 0.1 + +适用范围:0718 业务基线下,Agent → Adapter / MCP → 信息系统的业务回调字段 + +## 1. 最重要的修正:Basic Information 是订单级数据 + +最新确认如下: + +- 一笔订单只有一份 Basic Information。 +- Basic Information 跟随订单,不跟随具体 Event。 +- Basic Information 不是 `event_type`,但它是订单任务中的一张独立可确认、独立锁定任务卡。 +- 同一订单下即使同时有 Update、Trace、Rooming List、Payment,也只显示一张 Basic Information 卡。 +- 一封邮件可能包含多笔订单,因此 Basic Information 也不能放成整个结果包唯一的一份。 + +### 与此前结构是否吻合 + +分两层看: + +- 页面和业务结果吻合:此前信息系统会按 `order_ref` 聚合,同一订单最终只显示一张 Basic Information。 +- Agent 回调字段归属不完全吻合:此前要求每个 Event 重复输出 `account_code`,再由系统校验同单一致。这能得到一张卡,但数据本身仍跟着 Event 重复,不能准确表达“Basic Information 属于订单”。 + +因此,最新规则正式改为: + +- `account_code` 不再放在每个 Event 上。 +- 每个 `order_ref` 只提供一份订单级 Basic Information 数据。 +- Event 通过 `order_ref` 关联该订单,不复制 Account。 +- Market、Source 仍由信息系统目录派生,不由 Agent 输出。 + +## 2. 推荐的 V4 结果包骨架 + +以下是当前最容易表达业务语义、同时保留 `source_message + message_events[]` 的推荐结构: + +```json +{ + "route_code": null, + "source_message": { + "source_message_id": "AAMkAG...", + "conversation_id": "thread-001", + "subject": "Booking update", + "sender": "op@example.com", + "sent_at": "2026-07-18T02:10:00Z", + "body": "original current email body", + "attachments": [] + }, + "order_contexts": [ + { + "order_ref": "order-1", + "basic_information": { + "account_code": "ACCOUNT_CODE", + "manual_review": null + } + } + ], + "message_events": [ + { + "order_ref": "order-1", + "event_type": "UPDATE_BOOKING", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "LLTQ260510QVIPA" + }, + "after": { + "arrival_date": "2026-07-27", + "departure_date": "2026-07-30" + }, + "manual_review": null + }, + { + "order_ref": "order-1", + "event_type": "PAYMENT", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "LLTQ260510QVIPA" + }, + "attachment_ids": ["att-1"], + "manual_review": null + } + ] +} +``` + +说明: + +- `order_contexts` 是本答复采用的推荐工作字段名;它表达“一封邮件结果包内的订单级数据集合”。最终技术命名可由 SuperAgent、Adapter、MCP Schema 和信息系统统一,但不能改变订单级归属。 +- 每个非 S10 订单至少有一个非空 `order_ref`,并且在 `order_contexts[]` 中只能出现一次。 +- 每个具体 Event 必须引用一个已存在的 `order_ref`。 +- 同一订单的多个 Event 使用同一个 `order_ref`;不同订单使用不同值。 +- `order_ref` 只在当前结果包内有效,不是 PMS 订单键、系统订单 ID、任务 ID或幂等键。 +- 当前继续保留 Event 自己的 `target_order`,由信息系统按它查单;相同 `order_ref` 下的非空 `target_order` 必须一致。 + +## 3. Basic Information 的最终字段责任 + +订单级结构: + +```json +{ + "order_ref": "order-1", + "basic_information": { + "account_code": "ACCOUNT_CODE | null", + "manual_review": null + } +} +``` + +规则: + +- `account_code` 是信息系统 Account 目录中的稳定 code,不是自由文本或显示名称。 +- Agent 可依据发件人和历史业务信息判断 Account,但不重复输出 sender。 +- Agent 无法可靠确定 Account 时,输出 `account_code=null`,并在同一个 `basic_information` 对象中输出 `manual_review=true`。 +- Basic Information 的人工复核只作用于 Basic Information 卡,不要求同订单所有 Event 都变成 `manual_review=true`。 +- 信息系统根据 Account 目录带出 Market 和 Source。 +- 用户只能从信息系统已有 Account、Market、Source 中受控改选;不存在 Manual 或自由输入。 +- Agent 给出非空 code、但信息系统运行时目录不存在该值时,属于系统目录 / 契约校验问题:Basic Information 卡阻止确认并显示字段错误,但不得反向篡改 Agent 原始 `manual_review`。 +- 同一封邮件的不同 `order_ref` 可以对应不同 Account。 + +删除旧规则: + +- 不再要求每个 Event 都携带 `account_code`。 +- 不再要求信息系统比较同一 `order_ref` 下多个 Event 的 Account 是否冲突。 +- 不因 Event 数量创建多份 Basic Information。 + +## 4. source_message 最终业务内容 + +当前邮件在包级只出现一次,业务最小字段为: + +```json +{ + "source_message_id": "string", + "conversation_id": "string | null", + "subject": "string | null", + "sender": "string | null", + "sent_at": "ISO-8601 string | null", + "body": "string | null", + "attachments": [] +} +``` + +草案需要修正: + +- 不拆 `sender.display / sender.address`;`sender` 直接使用邮件监听提供的单一值。 +- 不同时输出 `text_body` 和 `html_body`;只保留监听到的当前邮件单一原文 `body`。 +- Agent 不摘要、清洗、翻译或改写 `body`。 +- `received_at` 不是当前页面和业务处理必需字段;若基础设施需要,可作为内部技术元数据,不进入业务必传。 +- 完整历史邮件线程不嵌入当前结果包;信息系统通过 `conversation_id` 查询。 +- 标题、发件人、时间、正文、附件字段始终保留;极端不可得时字段值为 null,不删除字段或猜值。 + +## 5. 附件结构 + +当前附件 item 维持: + +```json +{ + "id": "att-1", + "name": "payment-slip.jpg", + "content_type": "image/jpeg", + "url": "https://upstream-storage/...", + "size": 251524 +} +``` + +- `id / name / content_type / url` 必填。 +- `size` 可选。 +- URL 由上游邮件监听或文件存储层提供;Agent 只原样转发,不生成、拼接、刷新或签发。 +- Payment 只按 ID 引用附件,不在 Event 内复制文件名、类型、URL 或完整对象。 + +## 6. Event 公共结构 + +每个具体业务 Event 的公共字段为: + +```json +{ + "order_ref": "order-1", + "event_type": "...", + "target_order": { + "booking_type": "GROUP | FIT | null", + "locator_type": "GROUP_CODE | BOOKING_CODE | CONFIRMATION_NUMBER | null", + "locator_value": "string | null" + }, + "manual_review": null +} +``` + +不再属于 Event 公共字段: + +- `account_code`:改为订单级 Basic Information。 +- `payload`:当前目标契约直接使用各 Event 的专属业务字段,不再增加一层无业务含义的通用 payload。 +- `evidence`:不是信息系统页面业务必传;如 Agent 内部需要,可留在内部诊断,不驱动页面业务。 +- `event_index`:数组顺序不承载业务顺序,页面顺序由信息系统按固定卡片规则决定。 +- `event_id`:不是业务字段;只有真实 transport / 幂等机制需要时才由技术契约另行增加,不能代替 `order_ref`。 + +## 7. event_type 最终枚举 + +只保留: + +```text +NEW_BOOKING +UPDATE_BOOKING +CANCEL_BOOKING +TRACE_RESERVATION_NOTES +ROOMING_LIST +PAYMENT +``` + +- Basic Information 不是 Event。 +- 邮件展示卡不是 Event,由 `source_message` 固定生成。 +- S10 是包级纯通知路由,不属于上述业务枚举。 +- S99、Fallback、`Need Manual Review`、独立 Voucher、Payment Evidence、Voucher Received 均不再作为新 Agent 输出。 + +## 8. target_order 最终规则 + +| 场景 | `booking_type` | `locator_type` | `locator_value` | +|---|---|---|---| +| Group 的所有业务 | `GROUP` | `GROUP_CODE` | Group Code,即 Block Name | +| Fit New,以及与该 New 同包同目标的 Trace | `FIT` | `BOOKING_CODE` | Booking Code | +| 当前无 PMS API、尚无真实 Confirmation Number 的 Fit 后续业务 | `FIT` | `BOOKING_CODE` | 查询信息系统本地订单投影 | +| 已取得真实 Confirmation Number 的 Fit 后续业务 | `FIT` | `CONFIRMATION_NUMBER` | PMS Confirmation Number | + +规则: + +- 当前包内同订单归组使用 `order_ref`,不是使用相同 `target_order` 或相同 null。 +- `target_order` 用于信息系统查单和绑定订单。 +- 定位值未解决时保留原 Event,未知字段为 null,Event 的 `manual_review=true`。 +- Agent 能判断多个 Event 属于同单但定位未解决时,仍使用相同 `order_ref`。 +- Agent 连是否同单都无法判断时,使用不同 `order_ref`,不能把相同 null 合并。 +- 不输出 `case_keys`、定位候选数组、原因码或 `missing_fields[]`。 +- AMEND GROUP CODE 统一走 S10,不形成 Update Event。 + +## 9. 各 Event 最新字段 + +### 9.1 NEW_BOOKING + +```json +{ + "order_ref": "order-1", + "event_type": "NEW_BOOKING", + "target_order": {}, + "arrival_date": "YYYY-MM-DD | null", + "departure_date": "YYYY-MM-DD | null", + "rate_code": "RATE_CODE | null", + "room_items": [ + { + "room_type_code": "ROOM_TYPE_CODE | null", + "room_count": 1 + } + ], + "manual_review": null +} +``` + +Group 条件字段: + +```json +{ + "booking_scenario": "STANDARD | PROPOSAL" +} +``` + +Fit 条件字段: + +```json +{ + "guest_name": "REAL GUEST NAME | null" +} +``` + +修正草案: + +- 删除 `booking_name`;Group Code 已在 `target_order.locator_value`,同时作为 Block Name。 +- 删除独立 `booking_code`;Fit Booking Code 也在 `target_order.locator_value`。 +- `proposal` 改为 Group 专用受控 `booking_scenario=STANDARD | PROPOSAL`。 +- `room_type` 使用受控 `room_type_code`。 +- `room_quantity` 使用 `room_count`。 +- 删除 `adult_per_room`;Adult 由信息系统按 RoomType 映射派生。 +- Agent 不输出 Nights、Breakfast、Group Booking Status、Block ID 或 Confirmation Number。 +- `room_items=[]` 只能用于表示已识别 New 但完整房型清单未解决,并必须 `manual_review=true`;最终 validator 需按这一规则固定。 + +### 9.2 UPDATE_BOOKING + +```json +{ + "order_ref": "order-1", + "event_type": "UPDATE_BOOKING", + "target_order": {}, + "after": { + "guest_name": "NEW NAME | null", + "arrival_date": "YYYY-MM-DD | null", + "departure_date": "YYYY-MM-DD | null", + "room_items": [ + { + "room_type_code": "ROOM_TYPE_CODE | null", + "room_count": 1 + } + ] + }, + "manual_review": null +} +``` + +规则: + +- `after` 是稀疏对象;字段缺省表示本次不修改。 +- 字段存在但为 null,表示已识别要改该字段、但目标值未解决,同时 `manual_review=true`;null 不表示清空。 +- `guest_name` 只用于 Fit Name 更新,不使用 `booking_name`。 +- 只要修改涉及房型或房量,`after.room_items[]` 必须是修改后的完整房型清单,不是变化行。 +- 如果只能识别局部房型变化、无法形成完整目标清单,建议固定为 `after.room_items=null + manual_review=true`,禁止确认直到人工补全。 +- Rate Code 不允许出现在 Update。若 Agent 仍输出,按业务契约错误处理,不能静默忽略后继续执行。 +- Before、原订单和完整最新订单由信息系统查单后生成,不由 Agent 输出。 + +### 9.3 CANCEL_BOOKING + +```json +{ + "order_ref": "order-1", + "event_type": "CANCEL_BOOKING", + "target_order": {}, + "manual_review": null +} +``` + +- `CANCEL_BOOKING` 本身已经表示整单取消。 +- 删除 `cancel_scope`、`cancel_reason`、`after` 和当前订单快照。 +- 减少房量、删除房型、修改日期或修改 Fit Name 属于 Update,不是 Cancel。 + +### 9.4 TRACE_RESERVATION_NOTES + +```json +{ + "order_ref": "order-1", + "event_type": "TRACE_RESERVATION_NOTES", + "target_order": {}, + "trace_items": [ + { + "item_type": "GENERAL", + "text": "HONEYMOON SETUP", + "department_code": "FO" + }, + { + "item_type": "EXTRA_BED", + "target_room_type_code": "TWN", + "extra_bed_room_count": 1, + "department_code": "FO+HSK" + } + ], + "manual_review": null +} +``` + +修正草案: + +- 使用 `item_type=GENERAL | EXTRA_BED`,不使用 `trace_type=NORMAL`。 +- GENERAL 输出 `text + department_code`。 +- EXTRA_BED 不输出自由 `content`;信息系统固定显示 `SET EXTRA BED`。 +- EXTRA_BED 不输出 `adult_after_extra_bed`;信息系统按当前 / 基础 Adult +1 计算,页面确认前允许用户纠正。 +- Department code 由 Agent 必传,值来自信息系统维护的受控部门目录或组合目录。 +- 加床目标房型不在当前订单时,Trace 卡不能确认,并提示用户核对目标房型和订单关联;只有订单定位本身不可信时,才触发共享查单门槛阻断整个订单上下文。 + +### 9.5 ROOMING_LIST + +当前最小 Event: + +```json +{ + "order_ref": "order-1", + "event_type": "ROOMING_LIST", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "GROUP-CODE" + }, + "manual_review": null +} +``` + +- 只适用于 Group。 +- 当前 Agent 只需识别这是 Rooming List 任务。 +- 不输出 `rows[]`、逐人名单、同住分组、18 列、Excel 或 PMS 导入参数。 +- 当前也不要求 Rooming List Event 单独输出 `attachment_ids[]`;原附件已经在包级 `source_message.attachments[]`,只在邮件展示卡查看。 +- 页面固定展示 12 个必填字段表头的标准表格示意,当前内容不代表附件已经真实转换。 +- 未来取得 PMS API 后,按真实接口重新冻结住客与执行参数,不直接恢复草案中的 rows。 + +### 9.6 PAYMENT + +```json +{ + "order_ref": "order-1", + "event_type": "PAYMENT", + "target_order": {}, + "attachment_ids": ["att-1", "att-2"], + "manual_review": null +} +``` + +- `account_code` 已移至订单级 Basic Information,不在 Payment 重复。 +- 一笔订单多份凭证放在同一个 Payment Event。 +- `attachment_ids[]` 没有业务顺序,每个 ID 必须引用同包附件。 +- 不输出金额、日期、付款人、交易号、银行账号、付款状态、Department 或完整附件对象。 +- 推荐把“正常 Payment 的 `attachment_ids[]` 至少一项”设为 validator 规则。 +- 如果 Agent 输出 PAYMENT 但没有任何附件 ID,而来源附件实际存在,属于 Agent 契约错误,不能创建一张正常空 Payment 卡。 +- 如果来源本身没有可用于当前图片卡的付款凭证,无法形成 Payment 任务,则按 S10 展示原邮件。 +- 如果附件 metadata 存在但 URL 读取失败,属于附件 / 存储技术异常,不应伪装成人工复核字段。 + +## 10. manual_review 最终规则 + +唯一合法值: + +```json +null +``` + +或: + +```json +true +``` + +规则: + +- 正常数据为 null,不使用 false。 +- Event 的人工复核只属于该 Event 对应任务卡。 +- Basic Information 的人工复核放在订单级 `basic_information.manual_review`,只属于 Basic Information 卡。 +- 未解决值放在原业务字段位置,例如 `rate_code=null`、`room_type_code=null` 或 `account_code=null`。 +- `manual_review=true` 必须至少能由当前对象中的一个 null、空清单或其他 Schema 可识别未解决值解释。 +- 所有字段完整合法却只给 true,属于 Agent 契约异常。 +- 不输出 `manual_review_info`、`reason_code`、`visible_message`、`missing_fields[]`、JSON Pointer、候选或建议动作。 +- 信息系统依据条件必填、Account / RoomType / Rate Code 目录、日期 / 数量规则和查单结果生成字段级错误路径、错误码与页面提示。 +- 信息系统查单 0 / 多笔或目录运行时校验失败,不反向修改 Agent 原始 `manual_review`。 + +因此,草案第 16 节的扩展 `manual_review_info` 整节应删除。 + +## 11. S10 纯通知 + +业务语义已经冻结: + +```json +{ + "route_code": "S10", + "source_message": {}, + "order_contexts": [], + "message_events": [] +} +``` + +- 只显示邮件展示卡。 +- 不显示 Basic Information、房间信息或其他业务卡。 +- 不需要 `order_ref`、`target_order`、Account 或业务字段。 +- 用户点击“确认”后任务完成。 +- 不提供人工终止。 +- 不调用 PMS,不修改订单。 +- 不输出 S99、Fallback、原因码、通知说明或 `Need Manual Review`。 + +`route_code` 是当前推荐工作字段名;最终 discriminator 的技术命名仍需 Adapter / MCP Schema 统一,但 S10 的业务语义不再有歧义。 + +## 12. 技术异常 + +下列情况不生成酒店用户可见任务,也不转换成 S10 或人工复核: + +- 非法 JSON; +- 输出不符合 Schema; +- Event 引用了不存在的 `order_ref`; +- 同一 `order_ref` 下出现冲突的非空 `target_order`; +- Rate Code 出现在 Update; +- `manual_review=true` 但没有任何可识别的未解决字段; +- Adapter 转换失败; +- MCP 提交失败; +- Agent / Skill 执行异常; +- 附件 metadata 存在但存储 URL 无法读取。 + +后台 debug、告警和技术重试接口属于技术运维需求,不进入本次业务回调,也不在酒店用户任务卡上增加“重试”。 + +## 13. 对草案第 20 节 18 个问题的逐项答复 + +| # | 草案问题 | 最新答案 | +|---:|---|---| +| 1 | `message_events` 字段名是否冻结 | 业务上继续使用事件数组;`message_events` 可作为 V4 工作字段名。新增订单级 `order_contexts[]` 表达每笔订单的 Basic Information。最终 transport key 需四方 Schema 一致 | +| 2 | `route_code=S10` 与 S99 | S10 是唯一纯通知;S99 完全删除。`route_code` 可作为当前工作 key,最终 discriminator 只需技术对齐 | +| 3 | `source_message_id` 是否对应 `external_message_id` | 业务要求是当前邮件稳定 ID;是否映射 AgentBus `external_message_id` 属于 Adapter 技术映射,必须以真实上游契约核对 | +| 4 | source_message 字段 | 固定业务内容为邮件 ID、会话 ID、subject、单值 sender、sent_at、单一 body、attachments;不拆 text / HTML,received_at 非业务必传 | +| 5 | event_type 完整枚举 | 已冻结为 New、Update、Cancel、Trace、Rooming List、Payment 六种 | +| 6 | account_code 包级还是 Event 级 | 两者都不是;它是订单级 Basic Information 字段,每个 `order_ref` 只出现一次 | +| 7 | 同订单多个 Event 的 Account 冲突 | 新结构不再重复,所以正常情况下不存在;旧输入冲突由 Adapter 拒绝 / 迁移,不让信息系统或用户任选 | +| 8 | 是否扩展 manual_review | 不扩展,只允许 null / true;字段级问题由系统按 Schema 和目录生成 | +| 9 | locator_value=null 如何归组 | 使用非空包内 `order_ref`;同单同值,不同订单不同值,不按相同 null 合并 | +| 10 | 无 API Fit 后续只有 Booking Code | 允许临时查询本地订单投影;取得真实 Confirmation Number 后切换正式定位,不生成假编号 | +| 11 | New Booking 字段 | 使用 dates、订单级 rate_code、完整 room_items、Group booking_scenario、Fit guest_name;删除 booking_name、独立 booking_code 和 Adult | +| 12 | Update 是否给完整 After | `after` 整体是稀疏对象;但只要涉及房型 / 房量,`after.room_items` 必须是修改后的完整清单 | +| 13 | Update 出现 Rate Code | 业务契约错误,不静默忽略,不允许正常执行 | +| 14 | Cancel 是否需要 cancel_scope | 不需要;`CANCEL_BOOKING` 已表示整单取消,也不输出 cancel_reason | +| 15 | Trace 字段与 Department 来源 | 使用 GENERAL / EXTRA_BED item;Department 是 Agent 必传的系统受控 code;固定加床文案和 Adult 由系统派生 | +| 16 | Rooming List 是否允许不输出 rows | 不只是允许,而是当前明确不要求 rows;只输出最小 Group Rooming List Event,页面显示表头示意 | +| 17 | Payment attachment_ids 为空 | 推荐正常 Payment 必须非空;空引用属于无法形成正常图片卡。按来源情况进入契约错误、S10 或附件技术异常,不使用复杂人工复核对象 | +| 18 | 技术异常是否需要后台重试 | 不属于本轮业务契约;可另做开发 / 运维需求,但不得生成用户业务任务或卡片重试按钮 | + +## 14. 草案各章节的处理结论 + +| 草案章节 | 处理 | +|---|---| +| 第 3 节总体结论 | 将“相同 target_order 聚合”改为“按 source_message_id + order_ref 聚合,再按 target_order 查单”;增加订单级 Basic Information 集合 | +| 第 4 节包级结构 | 改成单值 sender、单一 body;删除业务必传 text_body、html_body、received_at | +| 第 5 节附件 | 基本正确,保留 | +| 第 6 节 Event 通用结构 | 删除 Event account_code、通用 payload、业务 evidence、event_index;event_id 仅可作为待证实 transport 字段 | +| 第 7 节 target_order | 增加 order_ref 归组和无 API Fit Booking Code 临时定位;AMEND GROUP CODE 冻结为 S10 | +| 第 8 节枚举 | 六种枚举正式冻结 | +| 第 9 节 Basic Information | 改为每个 order_ref 一份订单级对象,不再 Event 级重复 | +| 第 10 节 New | 按第 9.1 节整体替换 | +| 第 11 节 Update | 按第 9.2 节整体替换 | +| 第 12 节 Cancel | 删除整个 cancel payload,保留最小 Event | +| 第 13 节 Trace | 按第 9.4 节整体替换,删除 Agent Adult 与固定加床文案 | +| 第 14 节 Rooming List | 删除 rows 和 Event attachment_ids,改为当前最小 Event | +| 第 15 节 Payment | 删除 Event account_code,保留非空附件 ID 集合 | +| 第 16 节 manual_review | 删除 manual_review_info、reason_code、visible_message 和 missing_fields | +| 第 17 节 S10 | 业务处理正确,补充无订单级数据 | +| 第 18 节技术异常 | 基本正确;后台重试另立技术需求 | +| 第 19 节后端建模 | 不再按 target_order 直接分组;先按 order_ref 形成订单任务,再按 target_order 查单;每个订单只补一张 Basic Information | + +## 15. 目前仍需技术团队最终对齐的内容 + +业务规则已经足够让开发进行领域建模。以下剩余项是技术接口命名或运行机制,不应再次让业务方决定页面含义: + +1. `order_contexts`、`message_events` 和 S10 discriminator 的最终 JSON key。 +2. `source_message_id` 到 AgentBus / SourceMessage Inbox 字段的真实映射。 +3. `conversation_id`、`sent_at` 等 key 与时间格式的最终机器 Schema。 +4. Payment 附件引用 key 是否最终命名为 `attachment_ids`。 +5. 无附件、监听失败、附件 metadata 存在但 URL 读取失败的 transport 错误码。 +6. `event_id` / 幂等键是否为运行时必需;如需增加,它只属于 transport,不是页面业务字段。 +7. Department、Account、RoomType、Rate Code 等受控目录的真实 code 集合和版本管理。 +8. Adapter、MCP Schema、信息系统 DTO 与 validator 的版本切换方式。 +9. 技术失败后台、告警和开发重试入口是否建设。 + +这些技术项不会改变以下业务事实:一封邮件一个结果包、一个 `order_ref` 一笔订单、一笔订单一张 Basic Information、每个 Event 一张对应业务任务卡、每张卡独立确认并永久锁定。 + +## 16. 最终结论 + +开发草案已经覆盖了大部分讨论主题,但不能直接冻结为 V4 Schema。主要原因不是缺少问题,而是其中多项“当前建议”已经被最新业务共识明确否决或替代。 + +开发可按本文继续推进业务模型和页面数据模型;正式实现 Agent 回调前,还需要由 SuperAgent、Adapter、MCP Schema 和信息系统共同完成第 15 节的技术 key 与运行契约对齐。 diff --git a/docs/import/20260718/0718-V4剩余10项确认回复.md b/docs/import/20260718/0718-V4剩余10项确认回复.md new file mode 100644 index 0000000..ed62018 --- /dev/null +++ b/docs/import/20260718/0718-V4剩余10项确认回复.md @@ -0,0 +1,210 @@ +# 0718 V4 剩余 10 项确认回复 + +日期:2026-07-18 + +适用范围:Agent → Adapter / MCP → 信息系统的 V4 回调技术契约 + +说明:以下内容不改变已经确认的页面业务规则,主要用于冻结字段名、校验规则,以及明确需要 SuperAgent、Adapter 和信息系统共同对齐的技术边界。 + +## 1. Key 是否正式冻结 + +建议 V4 正式采用并冻结以下 key: + +- `route_code` +- `source_message` +- `order_contexts` +- `message_events` +- `order_ref` +- `target_order` +- `attachment_ids` + +具体语义: + +- `route_code`:普通业务为 `null`,纯通知为 `S10`。 +- `source_message`:当前触发邮件的包级来源事实,只出现一次。 +- `order_contexts[]`:每个 `order_ref` 一项,承载订单级 Basic Information。 +- `message_events[]`:承载 New、Update、Cancel、Trace、Rooming List、Payment 六类业务 Event。 +- `order_ref`:只用于当前结果包内聚合同一订单,不用于 PMS 查单。 +- `target_order`:用于信息系统查询和绑定真实订单。 +- `attachment_ids[]`:仅用于 Payment 关联包级附件。 + +SuperAgent、Adapter、MCP Schema 和信息系统最终必须使用完全相同的字段名与嵌套位置。 + +## 2. source_message_id 与 external_message_id + +业务要求是:`source_message_id` 必须代表本次触发邮件的稳定唯一 ID。 + +建议 Adapter 将 AgentBus / SourceMessage Inbox 的 `external_message_id` 映射为: + +```text +source_message.source_message_id +``` + +是否能直接一对一使用同一个值,需要根据真实 AgentBus / SourceMessage Inbox 契约确认。这是技术映射,不是新的业务问题。 + +## 3. 时间格式 + +同意统一为 UTC ISO-8601,例如: + +```text +2026-07-18T02:10:00Z +``` + +如果系统需要保留来源邮件原时区,可以作为内部技术元数据保存;Agent 对信息系统的标准时间统一使用 UTC。 + +## 4. body 的内容格式 + +已经确认的业务规则是: + +- 只保留一个 `body`; +- 邮件监听层取得什么原文,Agent 就原样转发什么; +- Agent 不清洗、摘要、翻译、重排或改写; +- 不恢复 `text_body + html_body` 双正文。 + +为了让信息系统选择正确的安全渲染策略,建议增加一个技术字段: + +```text +body_content_type = text/plain | text/html +``` + +信息系统根据该字段进行纯文本转义展示或 HTML 安全渲染。无论使用哪种渲染方式,都不能改写保存的原始 `body`。 + +如果邮件监听层能够保证所有正文永远只有一种固定格式,也可以由 Adapter 固定该类型,不要求 Agent 重新判断。 + +## 5. 受控 code 目录 + +Account、RoomType、RateCode、Department 的目录由信息系统或其主数据服务统一维护,并作为唯一事实源。 + +规则如下: + +- SuperAgent 只能输出目录中已有的稳定 code; +- 不允许输出自由文本或自行创造 code; +- Agent 无法可靠匹配时,按对应业务字段的未解决规则处理; +- Agent 输出非空 code、但信息系统目录不存在该值时,属于目录校验或契约问题; +- 目录如何同步或提供给 SuperAgent,由双方技术方案决定,可以使用版本化目录快照或查询能力。 + +Market 和 Source 仍由信息系统根据订单级 `account_code` 派生,不由 Agent 输出。 + +## 6. 技术异常通知链路 + +同意需要独立的技术运行链路,但技术失败不属于酒店用户任务。 + +建议至少具备: + +- `dispatch_run_id` 或同类技术运行 ID; +- `PENDING / RUNNING / SUCCEEDED / FAILED / TIMED_OUT` 等运行状态; +- Agent 未回调的超时检测; +- Agent、Skill、Adapter、MCP 和附件读取错误记录; +- 面向开发或运维的告警、日志或错误查询入口。 + +技术失败不得创建 S10、人工复核卡或其他酒店用户业务任务。 + +`dispatch_run_id` 如何产生、请求与回调如何关联、错误通过回调还是独立 channel 返回,需要由 AgentBus、SuperAgent 和信息系统共同设计。 + +## 7. PAYMENT 的 attachment_ids + +同意正常 Payment 冻结为: + +```text +attachment_ids.length > 0 +``` + +同时建议校验: + +- `attachment_ids[]` 至少一项; +- ID 不重复; +- 每个 ID 都必须存在于同包 `source_message.attachments[]`; +- 每个 ID 必须属于当前订单的付款凭证; +- 正常 Payment 至少关联一份可用付款凭证。 + +没有任何凭证附件时,不能创建正常的空 Payment 卡: + +- 来源附件存在,但 Agent 没有关联任何 ID:Agent / Adapter 契约错误; +- 来源本身没有可用于 Payment 卡的付款凭证:不形成正常 Payment,按 S10 展示原邮件; +- 附件 metadata 存在但 URL 无法读取:附件或存储技术异常。 + +以上情况都不使用复杂 `manual_review` 对象。 + +## 8. manual_review=true 的 validator + +同意冻结,但必须按当前对象的具体 Schema 判断,不能把任意空值都视为合法。 + +规则如下: + +- `manual_review` 只允许 `null | true`; +- 正常对象为 `null`,不使用 `false`; +- `manual_review=true` 时,当前 Basic Information 或 Event 中必须存在至少一个由该 Schema 允许的未解决标记; +- 未解决标记可以是特定可空字段、被允许的空清单或不完整 item; +- 来源冲突时,把无法可靠决定的原业务字段置为 `null`; +- 不能笼统认为任何空数组都能解释 `manual_review=true`; +- 所有字段完整、合法且通过目录校验,却仍输出 `manual_review=true`,属于 Agent / Adapter 契约异常。 + +不增加以下字段: + +- `manual_review_info` +- `missing_fields[]` +- `reason_code` +- 字段路径 +- 候选值 +- 复核说明对象 + +具体字段错误路径、错误码和页面提示由信息系统根据 Schema、目录和业务规则生成。 + +## 9. Update 的 after.room_items=null + +同意冻结为三态语义: + +| 结构 | 语义 | +|---|---| +| `after` 中不存在 `room_items` | 本次邮件没有要求修改房型或房量 | +| `after.room_items=null` | 已识别本次涉及房型或房量修改,但无法形成修改后的完整房型清单;必须同时 `manual_review=true` | +| `after.room_items=[...]` | 修改后的完整房型清单,不是只输出变化行 | + +不要使用空数组表达“无法形成完整房型清单”。 + +如果修改后整笔订单不再保留任何房间,应按整单 `CANCEL_BOOKING` 处理,而不是提交空的 Update 房型清单。 + +## 10. 无 Confirmation Number 阶段的 Fit 后续定位 + +确认接受既有规则。 + +当前无 PMS API,且该 Fit 尚未取得真实 Confirmation Number 时: + +- Agent 可以输出 `booking_type=FIT`; +- `locator_type=BOOKING_CODE`; +- `locator_value=Booking Code`; +- 信息系统使用 Booking Code 查询本地订单投影。 + +取得真实 Confirmation Number 后: + +- 后续业务切换为 `locator_type=CONFIRMATION_NUMBER`; +- 不生成假的 Confirmation Number; +- Booking Code 不成为未来 PMS 场景的永久关联键; +- 信息系统不使用当前 Name 查询已有 Fit。 + +## 11. 确认状态汇总 + +| 项目 | 当前处理 | +|---|---| +| 1. V4 key | 建议按本文正式冻结,需四方使用同名、同层级 | +| 2. message ID 映射 | 需根据真实 AgentBus / SourceMessage Inbox 契约核对 | +| 3. UTC ISO-8601 | 可以冻结 | +| 4. body 格式 | 原文透传已确认;`body_content_type` 需监听层 / Adapter 技术对齐 | +| 5. code 目录 | 信息系统主数据是唯一事实源;同步方式需技术设计 | +| 6. 技术异常 channel | 需要单独建设;不进入酒店用户任务体系 | +| 7. Payment 非空附件 | 可以冻结 | +| 8. manual_review validator | 可以冻结,并按各对象条件 Schema 校验 | +| 9. Update room_items 三态 | 可以冻结 | +| 10. Fit Booking Code 临时定位 | 已确认,可直接实施 | + +## 12. 开发推进建议 + +后端可以继续进行领域模型与页面数据模型设计,不需要等待所有技术通道完成后才开始。 + +但在正式写入站 validator 和完成端到端联调前,应完成以下技术对齐: + +1. 核对 `source_message_id` 与真实上游 message ID 的映射; +2. 确认 `body_content_type` 的来源与取值; +3. 确认 `dispatch_run_id`、超时和错误 channel; +4. 确认主数据目录如何提供给 SuperAgent; +5. 保证 SuperAgent、Adapter、MCP Schema 和信息系统使用同一份 V4 Schema。 diff --git a/docs/import/20260718/0718业务基线-Agent回调问题答复.md b/docs/import/20260718/0718业务基线-Agent回调问题答复.md new file mode 100644 index 0000000..e62847d --- /dev/null +++ b/docs/import/20260718/0718业务基线-Agent回调问题答复.md @@ -0,0 +1,275 @@ +# 0718 业务基线:Agent 回调结构说明 + +> 以下是 0718 确认的目标业务契约,不代表旧 Agent 和当前 0711 P0 接口已经完成改造。 + +## 1. 最终回调是否仍为 `source_message + message_events[]`? + +是。 + +一封当前邮件对应一个结果包: + +```json +{ + "source_message": {}, + "message_events": [] +} +``` + +规则: + +- `source_message` 在包级只出现一次。 +- `message_events[]` 可以包含同一订单的多个事件,也可以包含不同订单的事件。 +- 信息系统根据每个事件的 `target_order` 聚合同订单、拆分不同订单。 +- `message_events` 是当前工作字段名,最终需要与 Adapter、MCP Schema 和信息系统入站 DTO 统一冻结。 + +## 2. 每个 Event 是否有稳定的订单标识? + +每个具体业务 Event 都必须有稳定的 `target_order`。 + +不再使用旧的 `case_keys`。 + +```json +{ + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "LLTQ260510QVIPA" + } +} +``` + +合法定位组合: + +| 场景 | `booking_type` | `locator_type` | `locator_value` | +|---|---|---|---| +| Group 的所有业务 | `GROUP` | `GROUP_CODE` | Group Code,即 Block Name | +| Fit New Booking | `FIT` | `BOOKING_CODE` | Booking Code | +| 已创建 Fit 的 Update / Cancel / Trace / Payment | `FIT` | `CONFIRMATION_NUMBER` | Confirmation Number | + +如果 Agent 已识别出具体业务,但定位参数缺失或无法确定: + +- 未解决的定位字段为 `null`; +- 该 Event 输出 `manual_review: true`; +- 不输出候选订单数组、`case_keys` 或复杂缺失原因。 + +S10 纯通知是例外,不需要 `target_order`。 + +## 3. Trace、Payment、Rooming List 是独立 Event 还是 Booking Event 的子结构? + +都是独立 Event,与 Booking Event 平级放在 `message_events[]` 中。 + +```json +{ + "message_events": [ + { + "event_type": "UPDATE_BOOKING", + "target_order": {} + }, + { + "event_type": "TRACE_RESERVATION_NOTES", + "target_order": {} + }, + { + "event_type": "PAYMENT", + "target_order": {} + } + ] +} +``` + +它们不是 `NEW_BOOKING` 或 `UPDATE_BOOKING` 下的子结构。 + +信息系统通过相同的 `target_order` 判断这些 Event 属于同一订单,并生成同一订单下的多张独立任务卡。每张卡有自己的状态和“确认”按钮,互不阻塞。 + +业务限制: + +- Trace 可以与 New 或 Update 同时出现,Cancel 不带 Trace。 +- Rooming List 只适用于 Group。 +- Payment 只适用于已有订单,即 Update 场景。 + +## 4. 同一封邮件、同一订单的多个 Event,Agent 是否保证使用同一订单标识? + +是,这是 Agent 输出契约的强制要求。 + +同一订单的所有 Event 必须输出完全一致的: + +```text +booking_type + locator_type + locator_value +``` + +例如同一 Group 订单的 Update、Trace 和 Payment 都必须使用同一个 Group Code: + +```json +{ + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "LLTQ260510QVIPA" +} +``` + +不需要额外增加父子关系、Event 关联索引或 `same_order_id`。 + +如果 Agent 无法获得稳定订单标识,应保留对应 Event,并设置 `manual_review: true`,不能自行猜测订单。 + +## 5. 纯通知如何返回? + +纯通知统一使用 `S10`,不再使用 S99、Fallback 或 `Need Manual Review`。 + +业务语义为: + +```json +{ + "route_code": "S10", + "source_message": {}, + "message_events": [] +} +``` + +其中 `route_code` 是当前建议字段名,最终需要与 Adapter/MCP Schema 冻结。 + +S10 规则: + +- 只返回 S10 类型标识和完整 `source_message`。 +- 不返回 Basic Information、房间信息或其他业务 Event。 +- 不需要 `target_order`、Account 或业务参数。 +- 不进入人工复核,语义上 `manual_review=null`。 +- 前端只显示“邮件展示”卡。 +- 用户查看后点击“确认”,任务完成。 +- 纯通知任务不存在“人工终止”。 + +## 6. Agent 技术异常如何返回? + +Agent 技术异常不应转换成 S10、人工复核或任何业务 Event。 + +需要区分两种情况: + +### 业务参数不完整 + +Agent 已经识别出具体业务类型,只是参数缺失或无法确定: + +```json +{ + "event_type": "UPDATE_BOOKING", + "manual_review": true +} +``` + +这种情况正常回调信息系统并生成对应业务卡。 + +### 技术异常 + +例如: + +- Agent 输出不是合法 JSON; +- 输出不符合 Schema; +- Adapter 转换失败; +- MCP 提交失败; +- Agent 或 Skill 执行异常。 + +这类情况不生成用户业务任务,也不回调一份伪装成正常业务结果的 Payload。 + +如果系统需要记录,应走独立的技术失败状态、日志或告警通道,不进入 `message_events[]`,前端不展示预订任务卡。 + +## 7. 附件字段以及 Payment 如何关联凭证? + +附件统一放在包级: + +```json +{ + "source_message": { + "attachments": [ + { + "id": "att-1", + "name": "payment-slip.jpg", + "content_type": "image/jpeg", + "url": "https://upstream-storage/...", + "size": 251524 + } + ] + } +} +``` + +附件字段: + +| 字段 | 是否必需 | 说明 | +|---|---|---| +| `id` | 是 | 包内稳定附件引用 | +| `name` | 是 | 原始文件名 | +| `content_type` | 是 | MIME 类型 | +| `url` | 是 | 上游邮件监听或文件存储层提供 | +| `size` | 否 | 上游有值时原样传递 | + +Agent 只转发附件 URL,不负责生成、拼接或刷新 URL。 + +Payment Event 使用附件 ID 指向具体凭证: + +```json +{ + "event_type": "PAYMENT", + "target_order": {}, + "account_code": "ACCOUNT_CODE", + "attachment_ids": ["att-1", "att-2"], + "manual_review": null +} +``` + +规则: + +- 多张付款凭证放在一个 Payment Event 中。 +- 凭证之间没有业务顺序。 +- Payment Event 不重复传文件名、URL或完整附件对象。 +- `attachment_ids` 是当前建议字段名,最终联调时需要与 Adapter/MCP Schema 冻结。 + +## 8. Basic Information 的 Account、Market、Source 由谁提供? + +职责划分如下: + +- Agent 只输出 `account_code`。 +- Agent 可以根据邮件发件人识别 Account。 +- Market 和 Source 不由 Agent 输出。 +- 信息系统根据 Account 目录自动带出 Market 和 Source。 + +```json +{ + "account_code": "ACCOUNT_CODE" +} +``` + +如果 Agent 无法可靠确定 Account: + +```json +{ + "account_code": null, + "manual_review": true +} +``` + +前端规则: + +- Account、Market、Source 都是信息系统已有目录中的受控选项。 +- 不允许自由文本输入,也不存在 Manual 选项。 +- 用户可以通过选择器修改 Account。 +- Account 改变后,信息系统自动带出对应的 Market 和 Source。 +- Market 和 Source 仍允许用户从信息系统已有值中改选。 +- Agent 不需要输出选项列表或 Account、Market、Source 的联动规则。 + +## 开发结论 + +前端可以按照以下关系建模: + +```text +source_message + └── 提供邮件展示及附件资源 + +message_events[] + ├── 每个具体业务 Event 都有 target_order + ├── 同一 target_order 聚合到同一订单 + ├── 每个 Event 对应一张独立任务卡 + └── 每张任务卡独立确认和维护状态 + +S10 + └── 只显示邮件展示卡 +``` + +需要注意:`message_events`、S10 discriminator 和 `attachment_ids` 是当前建议字段名,正式联调前需要由 Agent、Adapter、MCP Schema 和信息系统入站接口统一冻结。 diff --git a/docs/project/README.md b/docs/project/README.md index 3aafcd7..9b3ac2e 100644 --- a/docs/project/README.md +++ b/docs/project/README.md @@ -45,6 +45,7 @@ | `requirements/M002-order-task-workflow-v2.md` | 阶段记录 | M002 订单任务主流程 V2,记录当前已阶段实现的 AI 过渡层、S000/S999 兼容、订单任务流转、任务确认和 OPERA 模拟骨架。 | | `requirements/M002-order-task-workflow-v3.md` | 当前有效 | M002 订单任务主流程 V3,基于 2026-07-11 P0 冻结基线和 2026-07-12 P0.1 Parent Group 修订,记录 S10/S99、40 路由、方案 C、type-known manual review 同卡解阻和 fail-closed 边界。 | | `requirements/M002-task-field-control-contract-v1.md` | 当前有效 | M002 任务卡字段控件契约 V1,记录任务详情 `fields[]` 控件元数据、人工复核控件复用和前后端开发边界。 | +| `requirements/M002-v4-agent-callback-field-contract.md` | 当前有效 | M002 V4 Agent 回调字段契约,基于 2026-07-18 业务基线和最新答复,冻结 `source_message`、`order_contexts`、`message_events`、订单级 Basic Information、六类 Event、S10 和校验口径;当前代码尚未按 V4 改造。 | | `requirements/M002-superagent-task-result-api-contract.md` | 阶段记录 | M002 SuperAgent 任务结果入站接口契约阶段记录;对外总契约以 `integrations/superagent-api-contract.md` 为准。 | | `requirements/M002-ai-query-minimal-fields.md` | 阶段记录 | M002 SuperAgent 查询上下文接口 1、2 最小字段落地记录;对外总契约以 `integrations/superagent-api-contract.md` 为准。 | | `requirements/M002-backend-data-model-design.md` | 阶段记录 | M002 后端数据模型设计,记录 AI 过渡层、订单、任务、任务卡、审计和 OPERA 模拟结果表。 | @@ -89,5 +90,6 @@ - 接口暴露、权限、酒店隔离和审计边界以 `security-access-control-boundary.md` 为总检查清单;具体 SuperAgent / MCP / AgentBus 请求响应契约仍以 `integrations/` 下对应文档为准。 - AI-NSES 的通用标准以 `../import/reusable/ai-native-software-engineering-standard.md` 为复用来源;本项目采用方式以 `ai-native-adoption.md` 为准。 - M002 V1 只作为历史参考;V2 记录当前阶段实现;后续 M002 新开发以 `requirements/M002-order-task-workflow-v3.md` 为开发基线。 +- 2026-07-18 导入的业务基线已形成 `requirements/M002-v4-agent-callback-field-contract.md` 字段契约;M002 V4 主流程、后端数据模型和接口改造尚未落地,开发前需要继续形成 V4 主流程方案。 - 前端展示 / 编辑字段以 2026-07-11 P0 冻结基线中的前端字段表、0712 字段控件说明和 `requirements/M002-task-field-control-contract-v1.md` 为白名单和控件契约基线;后端完整校验和 OPERA 映射仍以任务卡完整矩阵、0711 runtime 契约和后端规则为准。 - 时间点语义以 `backend-time-design.md` 为准;数据库时间点按 UTC 理解,API 返回带 `Z` 的 UTC 时间,页面再按酒店或用户时区展示。 diff --git a/docs/project/requirements/M002-v4-agent-callback-field-contract.md b/docs/project/requirements/M002-v4-agent-callback-field-contract.md new file mode 100644 index 0000000..8f82026 --- /dev/null +++ b/docs/project/requirements/M002-v4-agent-callback-field-contract.md @@ -0,0 +1,683 @@ +# M002 V4 Agent 回调字段契约 + +## 文档信息 + +| 项目 | 内容 | +| --- | --- | +| 文档版本 | 1.0 | +| 日期 | 2026-07-18 | +| 状态 | 当前 V4 字段基线;后续需同步 SuperAgent、Adapter、MCP Schema 和信息系统 DTO | +| 适用范围 | 0718 业务基线下,Agent → Adapter / MCP → 信息系统的业务回调字段 | +| 不适用范围 | 数据库表设计、前端视觉细节、真实 PMS API、技术失败后台重试、旧 M002 V3 数据兼容 | + +## 1. 文档定位 + +本文把 2026-07-18 导入的业务基线、Agent 回调问题答复、草案审查答复和剩余 10 项确认回复,整理为 M002 V4 的 Agent 回调字段契约。 + +本契约用于后续 M002 V4 主流程设计、后端领域建模、前端页面模型、Adapter / MCP Schema 对齐和 SuperAgent 联调。当前代码尚未按本文完成改造。 + +当前已确认开发阶段数据可以清空,因此 M002 V4 后续可以按新模型重建,不要求兼容旧任务数据、旧草稿、旧 OPERA 模拟、旧 `S000/S999`、旧 Fallback 或旧 `case_keys`。 + +## 2. 输入资料与优先级 + +| 文档 | 用途 | +| --- | --- | +| `docs/import/20260718/0718给黄哥/01-预订任务信息系统业务需求说明书.md` | 0718 业务权威基线 | +| `docs/import/20260718/0718给黄哥/02-业务字段与卡片规则矩阵.md` | 业务卡字段、展示和确认规则 | +| `docs/import/20260718/0718给黄哥/03-业务验收场景清单.md` | 验收场景 | +| `docs/import/20260718/0718业务基线-Agent回调问题答复.md` | 第一版 Agent 目标回调结构说明 | +| `docs/import/20260718/0718-M002-V4-Agent回调草案审查与最新答复.md` | 对 V4 草案的最新业务修正;与上一份答复冲突时以本文为准 | +| `docs/import/20260718/0718-V4剩余10项确认回复.md` | 对剩余技术 key、校验和运行边界的确认 | + +如果本文与早期 M002 V3、0711 / 0712 P0、旧草案或历史聊天记录冲突,M002 V4 字段和业务语义以本文为准。 + +## 3. 总体结构 + +一封当前邮件对应一个结果包。 + +普通业务包: + +```json +{ + "route_code": null, + "source_message": {}, + "order_contexts": [], + "message_events": [] +} +``` + +纯通知包: + +```json +{ + "route_code": "S10", + "source_message": {}, + "order_contexts": [], + "message_events": [] +} +``` + +核心关系: + +```text +source_message + -> 提供当前邮件展示卡和附件资源 + +order_contexts[] + -> 每个 order_ref 一项,承载该订单任务的 Basic Information + +message_events[] + -> 每个具体业务 Event 生成一张对应业务任务卡 + +source_message.source_message_id + order_ref + -> 一笔订单任务 + +target_order + -> 用于信息系统查单和绑定订单,不用于当前包内归组 +``` + +## 4. 冻结 key + +V4 正式采用并冻结以下 key: + +| key | 中文说明 | +| --- | --- | +| `route_code` | 包级路由。普通业务为 `null`,纯通知为 `S10` | +| `source_message` | 当前触发邮件的包级来源事实,只出现一次 | +| `order_contexts` | 订单级上下文集合,每个 `order_ref` 一项 | +| `message_events` | 业务事件数组,承载六类 Event | +| `order_ref` | 当前结果包内订单引用,用于聚合同一订单,不是 PMS 键或系统 ID | +| `target_order` | 目标订单定位信息,用于信息系统查单和绑定订单 | +| `attachment_ids` | Payment 关联包级附件的 ID 数组 | + +SuperAgent、Adapter、MCP Schema 和信息系统最终必须使用完全相同的字段名与嵌套位置。 + +## 5. source_message + +### 5.1 结构 + +```json +{ + "source_message_id": "string", + "conversation_id": "string | null", + "subject": "string | null", + "sender": "string | null", + "sent_at": "2026-07-18T02:10:00Z", + "body": "string | null", + "body_content_type": "text/plain | text/html", + "attachments": [] +} +``` + +### 5.2 字段规则 + +| 字段 | 必需 | 中文说明 | +| --- | --- | --- | +| `source_message_id` | 是 | 当前触发邮件的稳定唯一 ID;本项目映射为 SourceMessage Inbox 的 `external_message_id` | +| `conversation_id` | 否 | 当前邮件会话 ID;完整历史线程由信息系统按该值查询 | +| `subject` | 是,可为 `null` | 邮件主题 | +| `sender` | 是,可为 `null` | 邮件监听提供的单一发件人值,不拆 display / address | +| `sent_at` | 是,可为 `null` | 邮件发送时间,统一 UTC ISO-8601 | +| `body` | 是,可为 `null` | 当前邮件单一原文,Agent 原样转发,不清洗、摘要、翻译、重排或改写 | +| `body_content_type` | 是 | 正文格式,取值 `text/plain` 或 `text/html` | +| `attachments` | 是 | 包级附件数组 | + +`received_at` 不是当前页面和业务处理必需字段。如基础设施需要,可作为内部技术元数据保存,不作为业务必传字段。 + +`body_content_type` 按当前项目建议由 AgentBus / 邮件监听层或 Adapter 提供;Debug EML 和 AgentBus 入库也应保存或派生该字段。信息系统根据该字段选择纯文本转义或 HTML 安全渲染,但不得改写保存的原始 `body`。 + +## 6. attachments + +### 6.1 结构 + +```json +{ + "id": "att-1", + "name": "payment-slip.jpg", + "content_type": "image/jpeg", + "url": "https://upstream-storage/...", + "size": 251524 +} +``` + +### 6.2 字段规则 + +| 字段 | 必需 | 中文说明 | +| --- | --- | --- | +| `id` | 是 | 包内稳定附件引用 | +| `name` | 是 | 原始文件名 | +| `content_type` | 是 | MIME 类型 | +| `url` | 是 | 上游邮件监听或文件存储层提供的可访问地址 | +| `size` | 否 | 上游有值时原样传递 | + +URL 由上游邮件监听或文件存储层提供。Agent 只原样转发,不生成、拼接、刷新或签发 URL。 + +Payment 只按 `attachment_ids[]` 引用附件,不在 Event 内复制文件名、类型、URL 或完整附件对象。 + +## 7. order_contexts + +### 7.1 结构 + +```json +{ + "order_ref": "order-1", + "basic_information": { + "account_code": "ACCOUNT_CODE", + "manual_review": null + } +} +``` + +### 7.2 规则 + +- 一笔订单只有一份 Basic Information。 +- Basic Information 跟随订单,不跟随具体 Event。 +- Basic Information 不是 `event_type`,但它是订单任务中的一张独立可确认、独立锁定任务卡。 +- 同一订单下即使同时有 Update、Trace、Rooming List、Payment,也只显示一张 Basic Information 卡。 +- 一封邮件可能包含多笔订单,因此 Basic Information 不能放成整个结果包唯一对象。 +- 每个非 S10 订单至少有一个非空 `order_ref`,并且在 `order_contexts[]` 中只能出现一次。 +- 每个具体 Event 必须引用一个已存在的 `order_ref`。 + +### 7.3 Basic Information 字段 + +| 字段 | 必需 | 中文说明 | +| --- | --- | --- | +| `account_code` | 是,可为 `null` | 信息系统 Account 目录中的稳定 code,不是自由文本或显示名称 | +| `manual_review` | 是 | `null` 或 `true`;为 `true` 时 `account_code` 必须存在可解释的未解决状态,例如 `null` | + +Market 和 Source 不由 Agent 输出,由信息系统根据订单级 `account_code` 从目录派生。用户只能从信息系统已有 Account、Market、Source 中受控改选;不存在 Manual 或自由输入。 + +Agent 给出非空 `account_code`,但信息系统运行时目录不存在该值时,属于系统目录 / 契约校验问题:Basic Information 卡阻止确认并显示字段错误,但不得反向篡改 Agent 原始 `manual_review`。 + +不同 `order_ref` 可以对应不同 Account。 + +## 8. message_events 公共字段 + +### 8.1 结构 + +```json +{ + "order_ref": "order-1", + "event_type": "UPDATE_BOOKING", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "LLTQ260510QVIPA" + }, + "manual_review": null +} +``` + +### 8.2 公共字段规则 + +| 字段 | 必需 | 中文说明 | +| --- | --- | --- | +| `order_ref` | 是 | 当前包内订单引用,必须存在于 `order_contexts[]` | +| `event_type` | 是 | 业务事件类型 | +| `target_order` | 是 | 目标订单定位信息,用于信息系统查单和绑定订单 | +| `manual_review` | 是 | `null` 或 `true`;只作用于当前 Event 对应任务卡 | + +以下字段不属于 Event 公共字段: + +- `account_code`:已改为订单级 Basic Information。 +- `payload`:V4 直接使用各 Event 的专属业务字段,不增加通用 payload 层。 +- `evidence`:不是信息系统页面业务必传。 +- `event_index`:数组顺序不承载业务顺序,页面顺序由信息系统按固定卡片规则决定。 +- `event_id`:如 transport / 幂等需要,另由技术契约增加,不能代替 `order_ref`。 + +## 9. event_type + +V4 新数据只允许以下六种: + +```text +NEW_BOOKING +UPDATE_BOOKING +CANCEL_BOOKING +TRACE_RESERVATION_NOTES +ROOMING_LIST +PAYMENT +``` + +| `event_type` | 对应卡片 | 中文说明 | +| --- | --- | --- | +| `NEW_BOOKING` | 房间信息 | 新建预订 | +| `UPDATE_BOOKING` | 房间信息 | 修改预订 | +| `CANCEL_BOOKING` | 房间信息 | 整单取消 | +| `TRACE_RESERVATION_NOTES` | Trace | 普通备注 / 加床备注 | +| `ROOMING_LIST` | Rooming List | 任务详情内嵌 Rooming List | +| `PAYMENT` | Payment | 付款凭证 | + +Basic Information 不是 Event。邮件展示卡不是 Event,由 `source_message` 固定生成。 + +S10 是包级纯通知路由,不属于上述业务枚举。 + +S99、Fallback、`Need Manual Review`、独立 Voucher、Payment Evidence、Voucher Received 均不再作为新 Agent 输出。 + +## 10. target_order + +### 10.1 结构 + +```json +{ + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "LLTQ260510QVIPA" +} +``` + +### 10.2 合法组合 + +| 场景 | `booking_type` | `locator_type` | `locator_value` | +| --- | --- | --- | --- | +| Group 的所有业务 | `GROUP` | `GROUP_CODE` | Group Code,即 Block Name | +| Fit New,以及与该 New 同包同目标的 Trace | `FIT` | `BOOKING_CODE` | Booking Code | +| 当前无 PMS API、尚无真实 Confirmation Number 的 Fit 后续业务 | `FIT` | `BOOKING_CODE` | 查询信息系统本地订单投影 | +| 已取得真实 Confirmation Number 的 Fit 后续业务 | `FIT` | `CONFIRMATION_NUMBER` | PMS Confirmation Number | + +### 10.3 规则 + +- 当前包内同订单归组使用 `order_ref`,不是使用相同 `target_order` 或相同 `null`。 +- `target_order` 用于信息系统查单和绑定订单。 +- 同一 `order_ref` 下的非空 `target_order` 必须一致。 +- 定位值未解决时保留原 Event,未知字段为 `null`,Event 的 `manual_review=true`。 +- Agent 能判断多个 Event 属于同单但定位未解决时,仍使用相同 `order_ref`。 +- Agent 连是否同单都无法判断时,使用不同 `order_ref`,不能把相同 `null` 合并。 +- 不输出旧 `case_keys`、定位候选数组、原因码或 `missing_fields[]`。 +- AMEND GROUP CODE 统一走 S10,不形成 Update Event。 + +## 11. NEW_BOOKING + +### 11.1 结构 + +```json +{ + "order_ref": "order-1", + "event_type": "NEW_BOOKING", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "GROUP-CODE" + }, + "arrival_date": "2026-07-26", + "departure_date": "2026-07-29", + "rate_code": "RATE_CODE", + "booking_scenario": "STANDARD", + "room_items": [ + { + "room_type_code": "TWN", + "room_count": 1 + } + ], + "manual_review": null +} +``` + +Fit 条件字段: + +```json +{ + "guest_name": "REAL GUEST NAME | null" +} +``` + +### 11.2 字段规则 + +| 字段 | 适用 | 必需 | 中文说明 | +| --- | --- | --- | --- | +| `arrival_date` | Group / Fit | 是,可为 `null` | 入住日期,酒店本地日期 | +| `departure_date` | Group / Fit | 是,可为 `null` | 离店日期,酒店本地日期 | +| `rate_code` | Group / Fit | 是,可为 `null` | 订单级 Rate Code | +| `room_items[]` | Group / Fit | 是 | 完整房型清单 | +| `room_items[].room_type_code` | Group / Fit | 是,可为 `null` | 受控 RoomType code | +| `room_items[].room_count` | Group / Fit | 是 | 房量,正整数 | +| `booking_scenario` | Group | 是 | `STANDARD` 或 `PROPOSAL` | +| `guest_name` | Fit | 否,可为 `null` | Fit 真实客人姓名;首封无真实姓名时可以为空 | + +### 11.3 派生和禁止字段 + +- Group Code 已在 `target_order.locator_value`,同时作为 Block Name。 +- Fit Booking Code 已在 `target_order.locator_value`。 +- Agent 不输出 `booking_name`、独立 `booking_code`、Nights、Breakfast、Group Booking Status、Adult、Block ID 或 Confirmation Number。 +- `proposal` 不再使用布尔字段,改为 `booking_scenario=STANDARD | PROPOSAL`。 +- Adult 由信息系统按 RoomType 映射派生。 +- `room_items=[]` 只能表示已识别 New 但完整房型清单未解决,并必须 `manual_review=true`。 + +## 12. UPDATE_BOOKING + +### 12.1 结构 + +```json +{ + "order_ref": "order-1", + "event_type": "UPDATE_BOOKING", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "GROUP-CODE" + }, + "after": { + "arrival_date": "2026-07-27", + "departure_date": "2026-07-30", + "room_items": [ + { + "room_type_code": "TWN", + "room_count": 3 + } + ] + }, + "manual_review": null +} +``` + +### 12.2 after 三态和字段规则 + +`after` 是稀疏对象:字段缺省表示本次不修改。 + +| 字段 | 语义 | +| --- | --- | +| `after.guest_name` | Fit Name 更新 | +| `after.arrival_date` | 修改后入住日期 | +| `after.departure_date` | 修改后离店日期 | +| `after.room_items` 不存在 | 本次邮件没有要求修改房型或房量 | +| `after.room_items=null` | 已识别本次涉及房型或房量修改,但无法形成修改后的完整房型清单;必须同时 `manual_review=true` | +| `after.room_items=[...]` | 修改后的完整房型清单,不是只输出变化行 | + +### 12.3 规则 + +- 字段存在但为 `null`,表示已识别要改该字段、但目标值未解决,同时 `manual_review=true`;`null` 不表示清空。 +- 只要修改涉及房型或房量,`after.room_items[]` 必须是修改后的完整房型清单。 +- 不使用空数组表达“无法形成完整房型清单”。 +- 如果修改后整笔订单不再保留任何房间,应按整单 `CANCEL_BOOKING` 处理,而不是提交空的 Update 房型清单。 +- Rate Code 不允许出现在 Update。若 Agent 仍输出,按业务契约错误处理,不能静默忽略后继续执行。 +- Before、原订单和完整最新订单由信息系统查单后生成,不由 Agent 输出。 + +## 13. CANCEL_BOOKING + +### 13.1 结构 + +```json +{ + "order_ref": "order-1", + "event_type": "CANCEL_BOOKING", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "GROUP-CODE" + }, + "manual_review": null +} +``` + +### 13.2 规则 + +- `CANCEL_BOOKING` 本身已经表示整单取消。 +- 不输出 `cancel_scope`、`cancel_reason`、`after` 或当前订单快照。 +- 减少房量、删除房型、修改日期或修改 Fit Name 属于 Update,不是 Cancel。 +- 当前订单快照由信息系统查单后只读展示。 + +## 14. TRACE_RESERVATION_NOTES + +### 14.1 结构 + +```json +{ + "order_ref": "order-1", + "event_type": "TRACE_RESERVATION_NOTES", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "GROUP-CODE" + }, + "trace_items": [ + { + "item_type": "GENERAL", + "text": "HONEYMOON SETUP", + "department_code": "FO" + }, + { + "item_type": "EXTRA_BED", + "target_room_type_code": "TWN", + "extra_bed_room_count": 1, + "department_code": "FO+HSK" + } + ], + "manual_review": null +} +``` + +### 14.2 字段规则 + +| 字段 | 适用 | 必需 | 中文说明 | +| --- | --- | --- | --- | +| `trace_items[]` | Trace | 是 | 同一订单一张 Trace 卡,卡内多条事项 | +| `item_type` | Trace item | 是 | `GENERAL` 或 `EXTRA_BED` | +| `text` | GENERAL | 是,可为 `null` | 普通备注内容 | +| `department_code` | GENERAL / EXTRA_BED | 是 | 信息系统受控部门或组合部门 code | +| `target_room_type_code` | EXTRA_BED | 是,可为 `null` | 加床目标房型 | +| `extra_bed_room_count` | EXTRA_BED | 是 | 加床房间数量 | + +### 14.3 规则 + +- EXTRA_BED 不输出自由 `content`;信息系统固定显示 `SET EXTRA BED`。 +- EXTRA_BED 不输出 `adult_after_extra_bed`;信息系统按当前 / 基础 Adult +1 计算,页面确认前允许用户纠正。 +- Department code 由 Agent 必传,值来自信息系统维护的受控部门目录或组合目录。 +- 加床目标房型不在当前订单时,Trace 卡不能确认,并提示用户核对目标房型和订单关联。 +- 只有订单定位本身不可信时,才触发共享查单门槛阻断整个订单上下文。 + +## 15. ROOMING_LIST + +### 15.1 结构 + +```json +{ + "order_ref": "order-1", + "event_type": "ROOMING_LIST", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "GROUP-CODE" + }, + "manual_review": null +} +``` + +### 15.2 规则 + +- 只适用于 Group。 +- 当前 Agent 只需识别这是 Rooming List 任务。 +- 不输出 `rows[]`、逐人名单、同住分组、18 列、Excel 或 PMS 导入参数。 +- 当前也不要求 Rooming List Event 单独输出 `attachment_ids[]`。 +- 原附件已经在包级 `source_message.attachments[]`,只在邮件展示卡查看。 +- 页面固定展示 12 个必填字段表头的标准表格示意,当前内容不代表附件已经真实转换。 +- 未来取得 PMS API 后,按真实接口重新冻结住客与执行参数,不直接恢复历史草案中的 `rows[]`。 + +## 16. PAYMENT + +### 16.1 结构 + +```json +{ + "order_ref": "order-1", + "event_type": "PAYMENT", + "target_order": { + "booking_type": "GROUP", + "locator_type": "GROUP_CODE", + "locator_value": "GROUP-CODE" + }, + "attachment_ids": ["att-1", "att-2"], + "manual_review": null +} +``` + +### 16.2 规则 + +- `attachment_ids[]` 至少一项。 +- ID 不重复。 +- 每个 ID 都必须存在于同包 `source_message.attachments[]`。 +- 每个 ID 必须属于当前订单的付款凭证。 +- 一笔订单多份凭证放在同一个 Payment Event。 +- `attachment_ids[]` 没有业务顺序。 +- Payment 不输出 `account_code`、金额、付款日期、付款人、交易号、银行账号、付款状态、Department 或完整附件对象。 + +没有任何凭证附件时,不能创建正常的空 Payment 卡: + +- 来源附件存在,但 Agent 没有关联任何 ID:Agent / Adapter 契约错误。 +- 来源本身没有可用于 Payment 卡的付款凭证:不形成正常 Payment,按 S10 展示原邮件。 +- 附件 metadata 存在但 URL 无法读取:附件或存储技术异常。 + +## 17. manual_review + +### 17.1 合法值 + +`manual_review` 只允许: + +```json +null +``` + +或: + +```json +true +``` + +正常数据为 `null`,不使用 `false`。 + +### 17.2 校验规则 + +- Event 的人工复核只属于该 Event 对应任务卡。 +- Basic Information 的人工复核放在订单级 `basic_information.manual_review`,只属于 Basic Information 卡。 +- 未解决值放在原业务字段位置,例如 `rate_code=null`、`room_type_code=null` 或 `account_code=null`。 +- `manual_review=true` 时,当前 Basic Information 或 Event 中必须存在至少一个由该 Schema 允许的未解决标记。 +- 未解决标记可以是特定可空字段、被允许的空清单或不完整 item。 +- 来源冲突时,把无法可靠决定的原业务字段置为 `null`。 +- 不能笼统认为任何空数组都能解释 `manual_review=true`。 +- 所有字段完整、合法且通过目录校验,却仍输出 `manual_review=true`,属于 Agent / Adapter 契约异常。 + +不增加以下字段: + +- `manual_review_info` +- `missing_fields[]` +- `reason_code` +- 字段路径 +- 候选值 +- 复核说明对象 + +具体字段错误路径、错误码和页面提示由信息系统根据 Schema、目录和业务规则生成。 + +## 18. S10 纯通知 + +### 18.1 结构 + +```json +{ + "route_code": "S10", + "source_message": {}, + "order_contexts": [], + "message_events": [] +} +``` + +### 18.2 规则 + +- 只显示邮件展示卡。 +- 不显示 Basic Information、房间信息或其他业务卡。 +- 不需要 `order_ref`、`target_order`、Account 或业务字段。 +- 用户点击“确认”后任务完成。 +- 不提供人工终止。 +- 不调用 PMS,不修改订单。 +- 不输出 S99、Fallback、原因码、通知说明或 `Need Manual Review`。 + +## 19. 技术异常 + +下列情况不生成酒店用户可见任务,也不转换成 S10 或人工复核: + +- 非法 JSON。 +- 输出不符合 Schema。 +- Event 引用了不存在的 `order_ref`。 +- 同一 `order_ref` 下出现冲突的非空 `target_order`。 +- Rate Code 出现在 Update。 +- `manual_review=true` 但没有任何可识别的未解决字段。 +- Adapter 转换失败。 +- MCP 提交失败。 +- Agent / Skill 执行异常。 +- 附件 metadata 存在但存储 URL 无法读取。 + +技术失败不属于酒店用户任务。后台 debug、告警和技术重试接口属于技术运维需求,不进入本次业务回调,也不在酒店用户任务卡上增加“重试”。 + +当前项目可以保留 `platform_superagent_dispatch_run` 或同类技术运行记录作为主链路技术状态载体,后续另行设计查询、告警、超时和重试能力。 + +## 20. 受控 code 目录 + +Account、RoomType、RateCode、Department 的目录由信息系统或其主数据服务统一维护,并作为唯一事实源。 + +规则: + +- SuperAgent 只能输出目录中已有的稳定 code。 +- 不允许输出自由文本或自行创造 code。 +- Agent 无法可靠匹配时,按对应业务字段的未解决规则处理。 +- Agent 输出非空 code、但信息系统目录不存在该值时,属于目录校验或契约问题。 +- Market 和 Source 由信息系统根据订单级 `account_code` 派生,不由 Agent 输出。 + +当前项目接受“SuperAgent 确定后把目录给本系统”的落地方式。第一阶段可以先以固定种子目录或版本化目录快照对齐;后续如需在线查询或目录同步接口,再另开需求。 + +## 21. 后端 V4 建模建议 + +后端 V4 可以按以下聚合模型实现: + +```text +AI 回调包 + -> 按 source_message.source_message_id 反查 SourceMessage Inbox external_message_id + -> 保存 AI Batch / 原始 payload + -> 校验 order_contexts[] 和 message_events[] + -> 按 source_message_id + order_ref 创建订单任务 + -> 每个 order_ref 创建一张 Basic Information 卡 + -> 每个 Event 创建一张业务卡 + -> 固定补邮件展示卡 + -> target_order 用于查单和绑定本地订单投影 +``` + +建议新增或调整模型概念: + +| 概念 | 中文说明 | +| --- | --- | +| 订单任务 | 同一来源邮件 + 同一 `order_ref` 的聚合容器 | +| 任务卡 | 独立确认、独立锁定的业务卡 | +| 本地订单投影 | 当前无 PMS API 阶段,用于保存 New / Update / Cancel 后的信息系统内最新订单状态 | +| 技术失败记录 | Agent / Adapter / MCP 技术异常,不进用户任务列表 | + +## 22. 已确认技术口径 + +| 项目 | 当前口径 | +| --- | --- | +| V4 key | `route_code`、`source_message`、`order_contexts`、`message_events`、`order_ref`、`target_order`、`attachment_ids` | +| `source_message_id` 映射 | 本项目按 SourceMessage Inbox 的 `external_message_id` 处理 | +| 时间格式 | UTC ISO-8601,例如 `2026-07-18T02:10:00Z` | +| 正文格式 | 单一 `body` + `body_content_type=text/plain/text/html` | +| code 目录 | 信息系统主数据是唯一事实源,目录同步方式后置 | +| 技术异常 channel | 需要独立建设,不进入酒店用户任务体系;当前先保留设计空间 | +| Payment 附件 | 正常 Payment 必须 `attachment_ids.length > 0` | +| `manual_review` validator | 按各对象条件 Schema 校验,必须能由可识别未解决字段解释 | +| Update room_items | 不存在 / `null` / 数组三态 | +| Fit Booking Code 临时定位 | 当前无 Confirmation Number 时可用 Booking Code 查本地订单投影 | + +## 23. 后续仍需技术对齐 + +以下事项不会改变 V4 页面业务含义,但会影响联调和实现细节: + +1. SuperAgent、Adapter、MCP Schema 和信息系统 DTO 使用同一份 V4 Schema。 +2. `body_content_type` 的来源是 AgentBus / 邮件监听层还是 Adapter 派生。 +3. `dispatch_run_id`、超时、错误 channel 和技术失败查询入口如何落地。 +4. Account、RoomType、RateCode、Department 目录如何提供给 SuperAgent,以及目录版本如何管理。 +5. 如需 `event_id` 或幂等键,应作为 transport 字段设计,不作为业务页面字段。 + +## 24. 当前开发结论 + +- 0718 业务基线覆盖 M002 V3 的任务级草稿、READY、OPERA 模拟、Fallback、S99 和旧 Need Manual Review 页面语义。 +- 新数据只按 `S10` 表达纯通知。 +- 用户可见任务按订单任务 + 多卡建模。 +- 每张业务卡独立确认、确认后永久锁定。 +- 不保存草稿。 +- 当前无 PMS API,不生成 OPERA 模拟操作和 PMS 成功语义。 +- 技术异常不创建用户可见任务。 +- 开发阶段不兼容老数据,允许清空旧任务相关数据后迁移。