10 KiB
10 KiB
Booking 邮件处理架构 v0.4
| 项目 | 内容 |
|---|---|
| 文档状态 | 当前有效 |
| 架构版本 | booking-architecture-v0.4 |
| 契约版本 | booking-contracts-v1 |
| 业务基线 | BR00-BASELINE-1 |
| 范围终点 | 用户确认;不调用 PMS、Opera、付款或部门流转 |
1. 目的与替代关系
本架构把邮件获取、附件识别、固定渠道确定性解析、历史上下文、Booking Agent、校验和人工确认收敛为一条可追溯主线。它替代以附件 Parser 或旧 V4 入站模型为中心的实施方式。
早期 architecture-v0.3、M002 叙述和 M012 V0.1 实现记录仍可用于迁移和回归,但不能再单独作为新功能的实施依据。新增实现必须以本文和 Booking 邮件 contracts-v1 为准;发生冲突时,contracts-v1 优先。
2. 七层职责与边界
| 层 | 负责什么 | 输入 | 输出 | 不负责什么 |
|---|---|---|---|---|
| 1. 信息系统接入与编排 | 接收 AgentBus 邮件或手工 EML,建立幂等、处理批次与状态查询 | AgentBus payload / .eml |
SourceMessageEnvelope |
不理解业务、不直接建最终任务 |
| 2. 材料预处理 | 分离 current/quoted history,列举附件、图片、工作簿结构和候选材料,保留证据引用 | SourceMessageEnvelope |
MaterialPackage |
不把历史内容重复当作本次动作 |
| 3. 确定性 Parser + Catalog | 对适用固定渠道使用版本化渠道 Profile、字段别名和底色规则提取标准事实 | MaterialPackage |
ParsedFactSet |
不猜映射、不做最终业务决定 |
| 4. 当前态与邮件上下文 | 按 Group Code、订单线索或会话定向读取当前事实、有效未完成任务与计划完成态 | ParsedFactSet + 来源/历史线索 |
ContextPackage |
不扫描全库、不让历史邮件重新触发动作 |
| 5. 业务识别 / Booking Agent | 合并当前材料、Parser 事实和 Context,形成候选业务决定;Parser 失败/不适用/歧义时按需兜底 | ParsedFactSet + ContextPackage |
CandidateDecision |
不下载附件、不直接读写数据库、不建最终任务、不调用 PMS |
| 6. Validator 与人工确认准备 | 校验 schema、Catalog、证据、目标、生命周期、前置关系和确认必填项 | CandidateDecision |
ValidationResult、ConfirmationProjection |
不绕过校验建卡、不执行外部业务动作 |
| 7. 用户确认 | 展示安全的关键参数、证据、阻断、可编辑字段和链接动作;冻结已确认参数与审计 | ConfirmationProjection |
CONFIRMED 记录 |
不调用 PMS/Opera,不改变付款或部门状态 |
2.1 信息系统与 Agent 的职责分界
- 信息系统拥有 SourceMessage、幂等、附件/证据存储、Catalog、确定性 Parser、Context 查询、Validator、数据库事务、确认 API 和审计。
- AgentBus既是邮件消息入口适配器,也是 Booking Agent 的承载平台;它不成为业务事实源。
- Booking Agent只消费最小化的
ParsedFactSet + ContextPackage,其中唯一的正文材料是 policy 脱敏、限长的agent_input_materialcurrent excerpt;它不能自行扩大材料范围、下载附件、调用 PMS 或写任务表。 - Parser、Agent 和 Validator 使用同一
catalog_version。Catalog 是跨层的版本化业务词典,不属于某一个 Agent skill;Agent 的 reference 是 Catalog 的受控消费视图。 Name of Group、Group Name、Tour Code、Group Code是固定渠道对同一团号的不同列名;第 3 层统一写入group_code,第 4 层也只以该统一值定向查询,不能把列名差异制造成多目标。
3. 统一状态机
处理运行(processing run)使用以下状态;状态是运行主线,不等同于单张业务卡的用户可见状态:
RECEIVED
→ MATERIAL_READY
→ PARSER_COMPLETE | PARSER_NOT_APPLICABLE | PARSER_FAILED
→ CONTEXT_READY
→ AGENT_COMPLETE(仅在需要 Agent 时)
→ VALIDATED
→ AWAITING_CONFIRMATION
→ CONFIRMED
PARSER_FAILED、PARSER_NOT_APPLICABLE不代表整封邮件失败;它们是允许进入 Context 和按需 Agent 的受控分支。- Validator 可以把受影响目标隔离为 Risk,但同封其他清晰目标继续到确认准备。
- 任何阶段发生可重试技术错误时记录 run attempt、错误代码和安全摘要,不伪造业务完成。
CONFIRMED是本期终点。PMS/Opera 适配器必须是后续独立状态机,不得从本状态机隐式触发。
4. 处理结果与隔离规则
每封邮件及每个候选目标都使用以下稳定结果类型:
| 结果 | 适用条件 | 后续行为 |
|---|---|---|
IN_SCOPE_TASKS |
当前邮件存在可识别的 Booking 业务目标 | 形成候选卡,经过 Validator 后进入确认 |
GENERAL_NOTIFICATION |
整封 current 邮件确定没有任何支持的业务任务 | 最多一条 General 通知 |
RISK_NOTIFICATION |
业务类型、目标、材料或 Parser 结果存在无法安全消解的歧义 | 每封最多一张 Risk;隔离不明确部分 |
IGNORED_DIRECTION |
确定为酒店外发、内部邮件或不属于本系统处理范围 | 不创建待办任务,保留安全处理记录 |
补充规则:
- 已知业务类型但字段缺失,保留原业务类型并标记
REVIEW_REQUIRED,不能降格成 General 或 Risk。 - 同封邮件存在清晰任务和不清晰片段时,清晰任务继续,Risk 只承载不清晰片段。
- 重复投递、真实新邮件、revision、历史底色遗留和业务内容相同是不同判断维度;由 Validator 结合证据、消息幂等键和生命周期处理。
5. 固定渠道材料与 Parser 边界
5.1 预处理为何独立
Excel、图片和正文的原始材料体积大、结构多变且含历史内容。预处理把“能安全给 Parser/Agent 的本次材料”缩小为可定位、可审计的引用集合,因此 Agent 不必读取整张工作簿或整段会话。
- current body 和 quoted history 必须分开;quoted history 只能辅助理解、继承身份或提示重复,不可再次触发动作。
- Excel 附件保留工作簿/Sheet/行/列/底色/哈希等证据;普通任务 API 不返回整行原文。
- 图片作为
IMAGE材料进入预处理。它可辅助判断 Trace、Payment/Voucher 或不在范围,但不因“有图片”自动创建业务卡。 - 无附件邮件仍经过第 1 层接入和第 4 层 Context;仅跳过 Excel 专用预处理与 Parser。
- 对 Parser fallback,信息系统可从 current subject/body 生成受控 Agent excerpt,并提取唯一明确的 Group Code 或 old→new relation 供 Context 定向查询;这不是把全文、quoted history 或附件重新交给 Agent。
5.2 严格底色与 Profile
- 固定渠道 Profile 必须同时满足文件信号、明确业务 Sheet 规则和表头签名;平分、未知或非法 Sheet 均停止确定性解析,进入 Risk/fallback。
STRICT_CURRENT_CANDIDATE必须在 Catalog 定义的业务范围内整行非白底。字体颜色、批注、条件格式推测和白底不计入。- anchor 行提供身份/明细列;合法 continuation 行仅补动作/状态列。任意多行互补都不能升级为确定事实。
- 未知房量保持
booking_type=null/UNRESOLVED,不能按 0 推断 FIT;Trace 部门只有邮件证据唯一明确时预填,否则由用户选择 FO、HSK 或二者。
5.3 改团号与 Trace 生命周期
- old→new 团号只在 current body 明确标注后进入
GROUP_CODE_REPLACEMENT;Context 只读 old/new 两个 Group Code,old 有效且 new 不存在才允许 Update 继续。两个普通团号、历史引用或多条矛盾关系均进入复核。 - 同团同封的 standalone Trace 在信息系统内合并为一张候选卡,保留每条服务项和证据;跨封 Trace 绝不并入旧卡,Context 只以无自由文本的时间序摘要提供历史顺序。
- Trace 的最终确认至少选择
FO或HSK,可同时选择二者;本期确认不触发部门流转。
5.4 运行重试与可观测性
FAILEDrun 只能从已保存的PARSED_FACT_SET、CONTEXT_PACKAGE、MATERIAL_PACKAGE重放;不会重新拉取邮件、附件或历史,也不会创建新的 source revision。重试在 worker 中继续,processing attempt 与retry_count形成可审计的尝试链。FAILED之外的状态拒绝重试;旧的确认投影在重试期间不返回,避免用户确认过期候选。- 管理员只读指标固定统计最近 24 小时:失败率、Agent fallback 比率、Risk 比率、活跃积压、已重试 run 与 retry attempt。指标只来自
th_hotel_booking聚合,不含个人数据、邮件内容、附件、团号或跨库查询。 - 任何监控、重试或 retention 任务都以用户确认前为终点,不能触发 PMS/Opera、付款、库存扣减或部门流转。
6. 数据与事实源
- 新 Booking 主线的事实源是 PostgreSQL schema
th_hotel_booking。处理运行、版本化契约、证据引用、候选、校验和确认投影均落入该 schema。 - 旧 MySQL V4 数据仅作历史兼容读取;禁止未定义双写、跨库事务或把 MySQL 记录当作新主线事实源。
- 每次读取 Context 必须按 Group Code、订单线索或已知 SourceMessage 定向查询;无目标线索时不能扫描全库找“最像”的订单。
- 主数据(渠道白名单、sender → Account/Market/Source、Rate Code 映射)也是版本化事实。零候选、多候选和未配置均保留待用户补充,不能猜测。
7. 接口与并行工作边界
后续实现可以并行,但只能依赖 contracts-v1:
- Track A:
BookingMessageOrchestrator和入口适配器。 - Track B:Booking Agent profile、prompt、skill/reference 与离线 contract tests。
- Track C:Context/lifecycle assembler。
- Track D:PostgreSQL repository、Flyway、主数据与 processing run。
四条线不能直接依赖对方内部 Entity、Parser 私有 record 或 AgentBus payload。共享只通过 contracts-v1 的版本化数据结构、错误码和 evidence reference。
8. 实施前置与验收
G1 通过条件:信息系统、Agent、Context、数据库、Validator、前端和 QA 能在不引用旧 architecture-v0.3 的前提下,只基于 contracts-v1 明确输入、输出、版本字段、状态机、结果类型和失败边界后开始实现。
与现有 V0.1 的关系:V0.1 保留为受控纵向切片和回归基线;在 contracts-v1 适配完成前,不以其旧 V4 内部结构作为新模块之间的接口。