579 lines
18 KiB
Markdown
579 lines
18 KiB
Markdown
# TH Hotel SuperAgent MCP Tools 契约
|
||
|
||
## 1. 文档信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 文档版本 | 0.1 |
|
||
| 日期 | 2026-07-09 |
|
||
| 状态 | 草案 |
|
||
| 适用范围 | SuperAgent 可调用的 TH Hotel MCP tools |
|
||
|
||
## 2. 通用约定
|
||
|
||
内嵌 MCP endpoint 对 SuperAgent 暴露工具,并在当前 Spring Boot 进程内直接调用已有业务 Service。
|
||
|
||
通用默认值:
|
||
|
||
| 字段 | 默认值 | 中文说明 |
|
||
| --- | --- | --- |
|
||
| `hotel_id` | 后端解析 | SuperAgent 默认不传;单酒店阶段由 TH Hotel 后端从 `platform_hotel` 唯一 `ACTIVE` 酒店解析,兼容旧调用传入时必须与系统酒店一致。 |
|
||
| `source_provider` | 通常不传 | 查询类工具可作为隔离条件;写入工具不要求 SuperAgent 传数据库 provider。 |
|
||
| `source_channel` | 通常不传 | 查询类工具可作为隔离条件;写入工具不要求 SuperAgent 传数据库 channel,AgentBus 邮件真实入库渠道可能是 `OUTLOOK`。 |
|
||
|
||
通用返回建议:
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"request_id": "req-from-backend-or-mcp",
|
||
"trace_id": "trace-from-superagent",
|
||
"data": {},
|
||
"warnings": [],
|
||
"error": null
|
||
}
|
||
```
|
||
|
||
中文说明:
|
||
|
||
- 只读查询工具优先保持后端查询响应 envelope。
|
||
- 写入工具保持后端任务结果响应的业务字段。
|
||
- MCP tool result 中可以同时提供机器可读结构化数据和简短中文摘要。
|
||
- 如果业务 Service 返回受控错误,MCP endpoint 应把错误码和中文 message 保留到结构化结果中。
|
||
|
||
## 3. Tool: th_hotel_query_case_context
|
||
|
||
### 3.1 用途
|
||
|
||
查询订单上下文,用于判断当前邮件提到的 group、confirmation 或 reservation key 是否已经存在、
|
||
是否存在未完成任务,以及是否可以创建新任务。
|
||
|
||
### 3.2 何时使用
|
||
|
||
- SuperAgent 识别出 `group_code`、`confirmation_number` 或 `reservation_no` 后。
|
||
- 需要判断当前邮件应新建任务、更新已有对象、取消对象或进入人工复核时。
|
||
|
||
### 3.3 不应使用
|
||
|
||
- 不应把该工具当作全文搜索。
|
||
- 不应使用历史邮件中不确定的 key 直接创建业务结论。
|
||
|
||
### 3.4 输入 Schema
|
||
|
||
```json
|
||
{
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"hotel_id": {
|
||
"type": ["string", "null"],
|
||
"description": "可选酒店上下文 ID;默认由 TH Hotel 后端解析"
|
||
},
|
||
"group_code": {
|
||
"type": ["string", "null"],
|
||
"description": "Group / Allotment 查询 key"
|
||
},
|
||
"confirmation_number": {
|
||
"type": ["string", "null"],
|
||
"description": "FIT confirmation number 查询 key"
|
||
},
|
||
"reservation_no": {
|
||
"type": ["string", "null"],
|
||
"description": "OPERA reservation no"
|
||
},
|
||
"object_type_hint": {
|
||
"type": ["string", "null"],
|
||
"description": "调用方推测的对象类型"
|
||
},
|
||
"target_key_source": {
|
||
"type": ["string", "null"],
|
||
"description": "key 来源,例如 body_current 或 body_thread_evidence"
|
||
},
|
||
"body_thread_used_only_as_evidence": {
|
||
"type": "boolean",
|
||
"description": "历史线程 key 是否仅作为证据"
|
||
}
|
||
},
|
||
"required": []
|
||
}
|
||
```
|
||
|
||
补充约束:`group_code`、`confirmation_number`、`reservation_no` 至少一个非空。
|
||
|
||
### 3.5 输出
|
||
|
||
输出对应 REST 接口:
|
||
|
||
```text
|
||
POST /api/ai-query/v1/case-context
|
||
```
|
||
|
||
核心字段:
|
||
|
||
- `matched_order_records[]`:匹配到的订单。
|
||
- `pending_or_open_tasks[]`:未完成或可见任务。
|
||
- `target_object_validation`:是否允许创建、更新、取消或附加凭证。
|
||
- `warnings[]`:缺少 OPERA 投影等限制。
|
||
|
||
完整字段以 `superagent-api-contract.md` 第 4 节为准。
|
||
|
||
## 4. Tool: th_hotel_query_object_detail
|
||
|
||
### 4.1 用途
|
||
|
||
查询指定对象详情。第一版主要用于查询 `ORDER:{order_id}` 对象。
|
||
|
||
### 4.2 何时使用
|
||
|
||
- 已通过上下文查询拿到 `object_id`。
|
||
- 需要查看订单状态、业务 key、可更新/可取消状态或已知字段。
|
||
|
||
### 4.3 输入 Schema
|
||
|
||
```json
|
||
{
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"hotel_id": {
|
||
"type": ["string", "null"],
|
||
"description": "可选酒店上下文 ID;默认由 TH Hotel 后端解析"
|
||
},
|
||
"object_id": {
|
||
"type": "string",
|
||
"description": "查询对象 ID,第一版支持 ORDER:{order_id}"
|
||
},
|
||
"object_type": {
|
||
"type": ["string", "null"],
|
||
"description": "调用方对象类型提示"
|
||
}
|
||
},
|
||
"required": ["object_id"]
|
||
}
|
||
```
|
||
|
||
### 4.4 输出
|
||
|
||
输出对应 REST 接口:
|
||
|
||
```text
|
||
POST /api/ai-query/v1/object-detail
|
||
```
|
||
|
||
核心字段:
|
||
|
||
- `object_id`:对象 ID。
|
||
- `order_id`:订单内部 ID 字符串。
|
||
- `group_code`、`confirmation_number`、`reservation_no`:业务 key。
|
||
- `status`:订单状态。
|
||
- `can_update`、`can_cancel`:可操作状态。
|
||
- `hard_validation_warnings[]`:硬校验提示。
|
||
|
||
说明:该响应中的 `source_message_id` 当前是本系统内部 SourceMessage Inbox ID,不应作为
|
||
SuperAgent 提交任务结果时的外部 `source_message_id`。
|
||
|
||
完整字段以 `superagent-api-contract.md` 第 5 节为准。
|
||
|
||
## 5. Tool: th_hotel_list_message_conversation_tasks
|
||
|
||
### 5.1 用途
|
||
|
||
查询某个邮件会话下已经生成的所有任务,避免 SuperAgent 对同一邮件链重复拆同类任务。
|
||
|
||
### 5.2 何时使用
|
||
|
||
- 当前邮件属于一个已有邮件会话。
|
||
- 需要判断历史邮件是否已经生成任务。
|
||
- 需要按时间顺序查看同一邮件链上的任务进展。
|
||
|
||
### 5.3 输入 Schema
|
||
|
||
```json
|
||
{
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"hotel_id": {
|
||
"type": ["string", "null"],
|
||
"description": "可选酒店上下文 ID;默认由 TH Hotel 后端解析"
|
||
},
|
||
"source_provider": {
|
||
"type": ["string", "null"],
|
||
"description": "来源提供方,默认 AGENTBUS"
|
||
},
|
||
"source_channel": {
|
||
"type": ["string", "null"],
|
||
"description": "来源渠道,默认 EMAIL"
|
||
},
|
||
"external_conversation_id": {
|
||
"type": ["string", "null"],
|
||
"description": "外部邮件会话 ID"
|
||
},
|
||
"source_message_id": {
|
||
"type": ["string", "null"],
|
||
"description": "外部来源消息 ID,可作为锚点反查会话"
|
||
}
|
||
},
|
||
"required": []
|
||
}
|
||
```
|
||
|
||
补充约束:
|
||
|
||
- `external_conversation_id`、`source_message_id` 至少一个非空。
|
||
- 两者同时传入时,后端按 `external_conversation_id` 查询为准。
|
||
- 查询最终按“后端解析出的酒店 ID + source_provider + source_channel + external_conversation_id”隔离。
|
||
|
||
### 5.4 输出
|
||
|
||
输出对应 REST 接口:
|
||
|
||
```text
|
||
POST /api/ai-query/v1/message-conversation/tasks
|
||
```
|
||
|
||
排序规则:
|
||
|
||
1. 先按邮件接收时间正序。
|
||
2. 同一封邮件下按任务创建时间正序。
|
||
3. 时间相同时按任务 ID 正序。
|
||
|
||
核心字段:
|
||
|
||
- `task_count`:任务数量。
|
||
- `tasks[].external_source_message_id`:外部来源消息 ID。
|
||
- `tasks[].task_id`:任务 ID。
|
||
- `tasks[].task_status`:任务状态。
|
||
- `tasks[].system_task_type`:系统任务类型。
|
||
- `tasks[].task_created_at`:任务创建时间。
|
||
|
||
完整字段以 `superagent-api-contract.md` 第 6 节为准。
|
||
|
||
## 6. Tool: th_hotel_list_message_conversation_messages
|
||
|
||
### 6.1 用途
|
||
|
||
查询邮件会话下所有受控正文,供 SuperAgent 在需要历史上下文时读取。
|
||
|
||
### 6.2 何时使用
|
||
|
||
- 当前邮件需要结合历史邮件判断。
|
||
- 需要给业务人员后续展示原文能力预留接口证据。
|
||
- 需要按时间顺序读取邮件链正文。
|
||
|
||
### 6.3 安全边界
|
||
|
||
该工具不返回:
|
||
|
||
- 原始未清洗 HTML。
|
||
- 附件 URL。
|
||
- 内嵌图片 URL。
|
||
- `attachments`、`inline_images`、`external_url`。
|
||
- HTML 中的 `href/src` 外链属性。
|
||
|
||
后端读取正文时会写 SourceMessage 原文访问审计。
|
||
|
||
### 6.4 输入 Schema
|
||
|
||
输入字段与 `th_hotel_list_message_conversation_tasks` 相同:
|
||
|
||
```json
|
||
{
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"hotel_id": {
|
||
"type": ["string", "null"],
|
||
"description": "可选酒店上下文 ID;默认由 TH Hotel 后端解析"
|
||
},
|
||
"source_provider": {
|
||
"type": ["string", "null"],
|
||
"description": "来源提供方,默认 AGENTBUS"
|
||
},
|
||
"source_channel": {
|
||
"type": ["string", "null"],
|
||
"description": "来源渠道,默认 EMAIL"
|
||
},
|
||
"external_conversation_id": {
|
||
"type": ["string", "null"],
|
||
"description": "外部邮件会话 ID"
|
||
},
|
||
"source_message_id": {
|
||
"type": ["string", "null"],
|
||
"description": "外部来源消息 ID,可作为锚点反查会话"
|
||
}
|
||
},
|
||
"required": []
|
||
}
|
||
```
|
||
|
||
### 6.5 输出
|
||
|
||
输出对应 REST 接口:
|
||
|
||
```text
|
||
POST /api/ai-query/v1/message-conversation/messages
|
||
```
|
||
|
||
核心字段:
|
||
|
||
- `message_count`:邮件数量。
|
||
- `messages[].external_source_message_id`:外部来源消息 ID。
|
||
- `messages[].received_at`:邮件接收时间。
|
||
- `messages[].text_body`:纯文本正文。
|
||
- `messages[].html_body_sanitized`:清洗后的 HTML。
|
||
- `messages[].html_render_mode`:HTML 渲染模式。
|
||
|
||
完整字段以 `superagent-api-contract.md` 第 7 节为准。
|
||
|
||
## 7. Tool: th_hotel_submit_task_results
|
||
|
||
### 7.1 用途
|
||
|
||
提交 SuperAgent 对单封外部来源消息的 AI 任务识别结果。该工具会写入 AI 过渡层、订单、任务和任务卡。
|
||
|
||
### 7.2 何时使用
|
||
|
||
- SuperAgent 已完成当前邮件的最终任务拆分。
|
||
- 已确认外部 `source_message_id` 来自 AgentBus payload;`hotel_id` 由 TH Hotel 后端解析。
|
||
- 不需要为写入工具传数据库层 `source_provider` / `source_channel`;后端会按系统酒店和外部消息 ID 匹配真实 Inbox 记录。
|
||
- 需要把 AI 任务结果交给 TH Hotel 后端进入人工确认流程。
|
||
|
||
### 7.3 不应使用
|
||
|
||
- 不应在试探、草稿、未完成推理阶段调用。
|
||
- 不应把历史邮件中的外部来源消息 ID 当作当前邮件 ID 提交。
|
||
- 不应在缺少 `source_message_id` 时调用;`hotel_id` 不需要 SuperAgent 提供。
|
||
|
||
### 7.4 输入 Schema
|
||
|
||
当前 MCP tool 已支持三种输入形态,真实机器可读 schema 以 `/mcp` 的 `tools/list` 返回为准:
|
||
|
||
1. V3 业务根:`source_message + message_events[]`。
|
||
2. V3 S10/S99 入口通知:`source_message + route_code`。
|
||
3. V2 兼容任务结果:`source_message_id + ai_task_results[]`。
|
||
|
||
MCP 层会先调用 `SuperAgentMcpSubmitPayloadAdapter` 做提交前校验和事件索引映射。`E1`、`E_CHILD_1`、`E_PARENT` 等 Agent 内部事件 ID 不会直接进入业务层;adapter 会按 `message_events[]` 顺序生成本系统一基数字 `source_event_index`,并同步映射 `related_source_event_index`、`parent_source_event_index` 和 `related_source_event_indices[]`。
|
||
|
||
补充规则:
|
||
|
||
- V3 业务根或 S10/S99 如果携带 `hotel_id`、`source_provider`、`source_channel`,MCP adapter 会接受这些兼容字段,但转交业务入站层前会移除;业务定位仍以系统酒店和外部 `source_message_id` 为准。
|
||
- 缺失 `source_message.source_message_id` 或整个 `source_message` 时,MCP adapter 不改写错误,业务入站层返回 `MISSING_SOURCE_MESSAGE_ID`。
|
||
- V3 event 业务合法性问题,例如 unsupported `event_type`、不完整 `case_keys`、不完整 `manual_review`,由业务入站层保存为 `adapter_contract_error` transition;MCP adapter 只拦 transport 必需问题,包括未知字段、`source_event_index` 缺失/重复、关系悬空/重复。
|
||
- V2 `ai_task_results[]` item 已在 MCP schema 和 adapter 中完整校验,必填字段为 `source_event_index`、`catalog_code`、`skill_id`、`result_type`、`task_type`。
|
||
|
||
下面 JSON 是关键结构节选;不要手工复制为最终 schema,联调时应以 `tools/list` 实时返回为准。
|
||
|
||
```json
|
||
{
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"hotel_id": {
|
||
"type": ["string", "null"],
|
||
"description": "可选酒店上下文 ID;默认由 TH Hotel 后端解析"
|
||
},
|
||
"source_provider": {
|
||
"type": ["string", "null"],
|
||
"description": "兼容字段;写入工具通常不需要传,后端写入定位不使用该字段"
|
||
},
|
||
"source_channel": {
|
||
"type": ["string", "null"],
|
||
"description": "兼容字段;写入工具通常不需要传,后端写入定位不使用该字段,AgentBus 实际入库渠道可能是 OUTLOOK"
|
||
},
|
||
"source_message": {
|
||
"type": "object",
|
||
"description": "V3 来源邮件元数据;source_message_id 对应 AgentBus source.external_message_id",
|
||
"properties": {
|
||
"source_message_id": {
|
||
"type": "string"
|
||
},
|
||
"subject": {
|
||
"type": ["string", "null"]
|
||
},
|
||
"from": {
|
||
"type": ["string", "null"]
|
||
},
|
||
"cc": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"received_at": {
|
||
"type": ["string", "null"]
|
||
},
|
||
"source_channel": {
|
||
"type": "string",
|
||
"enum": ["Email"]
|
||
}
|
||
},
|
||
"required": ["source_message_id", "subject", "from", "cc", "received_at", "source_channel"]
|
||
},
|
||
"route_code": {
|
||
"type": ["string", "null"],
|
||
"description": "V3 S10/S99 入口通知路由码"
|
||
},
|
||
"handler_type": {
|
||
"type": ["string", "null"],
|
||
"description": "V3 Main Agent 输出处理器类型"
|
||
},
|
||
"result_type": {
|
||
"type": ["string", "null"],
|
||
"description": "V3 入口通知或 V2 任务结果类型"
|
||
},
|
||
"current_or_history": {
|
||
"type": ["string", "null"],
|
||
"description": "V3 current/history 标记"
|
||
},
|
||
"agent_assessment": {
|
||
"type": "object",
|
||
"description": "V3 S10/S99 入口判断摘要"
|
||
},
|
||
"notification": {
|
||
"type": "object",
|
||
"description": "V3 S10/S99 通知展示信息"
|
||
},
|
||
"manual_review": {
|
||
"type": ["object", "null"],
|
||
"description": "V3 人工复核对象;S10 可为空,S99 必须完整"
|
||
},
|
||
"message_events": {
|
||
"type": "array",
|
||
"description": "V3 业务事件数组;MCP Adapter 会按数组顺序生成一基 source_event_index",
|
||
"items": {
|
||
"type": "object"
|
||
}
|
||
},
|
||
"case_candidates": {
|
||
"type": "array",
|
||
"description": "V3 订单候选数组,无候选传空数组",
|
||
"items": {
|
||
"type": "object"
|
||
}
|
||
},
|
||
"unhandled_current_intents": {
|
||
"type": "array",
|
||
"description": "V3 未覆盖当前意图数组,无意图传空数组",
|
||
"items": {
|
||
"type": "object"
|
||
}
|
||
},
|
||
"source_message_id": {
|
||
"type": "string",
|
||
"description": "V2 兼容字段:外部来源消息 ID,对应 AgentBus source.external_message_id"
|
||
},
|
||
"ai_task_results": {
|
||
"type": "array",
|
||
"description": "V2 兼容字段:AI 拆分出的任务结果,必须保留数组顺序",
|
||
"items": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["source_event_index", "catalog_code", "skill_id", "result_type", "task_type"],
|
||
"properties": {
|
||
"source_event_index": {
|
||
"type": ["integer", "string"]
|
||
},
|
||
"catalog_code": {
|
||
"type": "string"
|
||
},
|
||
"skill_id": {
|
||
"type": "string"
|
||
},
|
||
"result_type": {
|
||
"type": "string",
|
||
"enum": ["normal_task", "manual_review", "informational_message"]
|
||
},
|
||
"task_type": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"extraction_warnings": {
|
||
"type": "array",
|
||
"description": "AI 抽取警告;V3/V2 都允许,缺省按空数组处理",
|
||
"items": {
|
||
"type": "object"
|
||
}
|
||
}
|
||
},
|
||
"required": [],
|
||
"oneOf": [
|
||
{
|
||
"required": ["source_message", "message_events", "case_candidates", "extraction_warnings", "unhandled_current_intents"]
|
||
},
|
||
{
|
||
"required": ["source_message", "route_code", "handler_type", "result_type", "current_or_history", "agent_assessment", "notification", "manual_review"]
|
||
},
|
||
{
|
||
"required": ["source_message_id", "ai_task_results"]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
说明:
|
||
|
||
- V3 业务根字段、S10/S99 字段和 V2 `ai_task_results[]` item 完整语义以 `superagent-api-contract.md` 第 8 节为准。
|
||
- BusinessResult 到 MCP payload 的稳定映射、`source_event_index` 正式定义、跨 Child Trace 示例和拒绝示例见 `submit-payload-mapping.md`。
|
||
- MCP endpoint 不应重排 V2 `ai_task_results[]`,也不应重排 V3 `message_events[]`。
|
||
- `source_message_id` 必须是 AgentBus payload 的 `source.external_message_id`,不是内部 `platform_source_message_inbox.id`;写入工具不要求 SuperAgent 知道 Inbox 的真实 channel。
|
||
- 同一系统酒店下如果外部 `source_message_id` 匹配多条 Inbox,业务 Service 返回 `SOURCE_MESSAGE_AMBIGUOUS`,MCP tool result 应原样保留该错误码和 message。
|
||
- MCP adapter 校验失败时返回 `MCP_SUBMIT_PAYLOAD_INVALID`,不会调用业务写入 Service,也不会自动重试。
|
||
|
||
### 7.5 输出
|
||
|
||
输出对应 REST 接口:
|
||
|
||
```text
|
||
POST /api/integrations/superagent/task-results
|
||
```
|
||
|
||
核心字段:
|
||
|
||
- `batch_id`:批次 ID。
|
||
- `idempotent_replay`:是否幂等重放。
|
||
- `accepted_count`:接收数量。
|
||
- `items[].ai_transition_id`:AI 过渡层 ID。
|
||
- `items[].order_id`:订单 ID。
|
||
- `items[].task_id`:任务 ID。
|
||
- `items[].task_status`:任务状态。
|
||
- `mapping_diagnostics`:仅 MCP 写入工具在 V3 业务根映射时返回,记录 Agent 原始事件 ID 到本系统一基索引的映射;不写入业务 JSON。
|
||
|
||
完整字段以 `superagent-api-contract.md` 第 8 节为准。
|
||
|
||
## 8. 错误处理约定
|
||
|
||
MCP endpoint 应保留业务错误信息:
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"request_id": "req-001",
|
||
"trace_id": "trace-001",
|
||
"data": null,
|
||
"warnings": [],
|
||
"error": {
|
||
"code": "AUTH_SIGNATURE_INVALID",
|
||
"message": "签名校验失败。",
|
||
"details": {}
|
||
}
|
||
}
|
||
```
|
||
|
||
常见错误码以 `superagent-api-contract.md` 第 9 节为准。
|
||
|
||
MCP 层新增错误建议:
|
||
|
||
| 错误码 | 中文说明 |
|
||
| --- | --- |
|
||
| `MCP_AUTH_INVALID` | MCP 层访问凭证缺失或无效 |
|
||
| `MCP_TOOL_DISABLED` | 工具未启用,例如生产临时关闭写入工具 |
|
||
| `MCP_REQUEST_INVALID` | MCP JSON-RPC 请求体不合法 |
|
||
| `MCP_REQUEST_BODY_TOO_LARGE` | MCP 请求体超过 10MB 默认限制或环境配置限制 |
|
||
| `MCP_METHOD_NOT_FOUND` | MCP 方法不存在 |
|
||
| `MCP_TOOL_NOT_FOUND` | MCP 工具不存在 |
|
||
| `MCP_SUBMIT_PAYLOAD_INVALID` | 写入工具 payload 未通过 MCP adapter 提交前校验 |
|
||
| `MCP_INTERNAL_ERROR` | MCP endpoint 内部异常 |
|