实现SuperAgent特殊入口结果处理

This commit is contained in:
andy
2026-07-10 12:05:57 +08:00
parent 9de4f0e7b6
commit 74e429a2cb
29 changed files with 1121 additions and 97 deletions

View File

@@ -4,15 +4,15 @@
| 项目 | 内容 |
| --- | --- |
| 文档版本 | 0.2 |
| 日期 | 2026-07-07 |
| 文档版本 | 0.3 |
| 日期 | 2026-07-10 |
| 状态 | 后端接口契约草稿 |
| 适用范围 | SuperAgent / Main Agent 调用本系统提交 AI 任务结果 |
| 主要读者 | 后端、SuperAgent 对接方、测试、后续协作 agent |
## 1. 文档定位
本文定义 SuperAgent / Main Agent 向本系统提交 `ai_task_results[]`第一版后端接口契约。
本文定义 SuperAgent / Main Agent 向本系统提交 `ai_task_results[]` 结构化结果,以及提交 S000/S999 特殊入口结果的后端接口契约。
本文承接 `M002-order-task-workflow-v2.md`,只定义本系统入站接口、鉴权、幂等、请求响应和技术校验边界,不定义 SuperAgent 内部 prompt、Skill 实现、OPERA 真实接口或前端展示细节。
@@ -22,17 +22,19 @@
| --- | --- |
| Method | `POST` |
| Path | `/api/integrations/superagent/task-results` |
| Content-Type | `application/json` |
| Content-Type | `application/json``text/plain` |
| 响应格式 | `application/json` |
| 一次请求范围 | 只能包含一个 `source_message_id` |
| 业务动作 | 接收 AI 结果、写入 AI 过渡层、生成订单 / 任务 / 任务卡 |
| 业务动作 | 接收 AI 结果或入口结果、写入 AI 过渡层、生成订单 / 任务 / 任务卡 |
| 鉴权方式 | HMAC-SHA256 签名 |
中文说明:
- 该接口是服务到服务的入站接口,不给前端直接调用。
- SuperAgent 不直连数据库,只能通过本接口提交任务结果。
- SuperAgent 不直连数据库,只能通过本接口提交任务结果或入口处理结果
- 本接口只做技术校验和系统接收,不替代用户确认和 OPERA 模拟操作。
- `application/json` 用于 `normal_task` / `manual_review` 结构化任务。
- `text/plain` 用于 `S000,source_message_id` / `S999,source_message_id` 特殊入口结果。
### 2.1 SourceMessage ID 口径
@@ -114,13 +116,16 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
4. 计算原始请求体 SHA-256。
5. 使用 HMAC secret 重新计算签名。
6. 使用常量时间比较签名。
7. 鉴权通过后再解析 JSON
7. 校验 `Content-Type` 是否为 `application/json``text/plain`,避免不支持的媒体类型消耗 nonce
8. 鉴权通过后再按 body 内容解析 JSON 或 S000/S999 文本。
日志和错误响应不得输出 secret、签名原文、完整请求体、邮件正文、附件 URL 或个人敏感信息。
## 4. 请求体
请求体沿用 AI 导入文档定义的聚合结构。
### 4.1 JSON 结构化任务请求体
JSON 请求体沿用 AI 导入文档定义的聚合结构。
```json
{
@@ -155,7 +160,7 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
}
```
### 4.1 顶层字段
### 4.2 顶层字段
| 字段 | 是否必填 | 中文说明 |
| --- | --- | --- |
@@ -166,16 +171,16 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
| `ai_task_results[]` | 是 | AI 拆分出的任务结果列表,必须保留数组顺序 |
| `extraction_warnings[]` | 否 | 抽取警告;不直接等同于业务任务 |
第一版要求 `ai_task_results[]` 至少包含一条记录。没有业务动作时应由 AI 输出 `Message Notification``Fallback/manual_review`,而不是提交空数组
第一版要求 `ai_task_results[]` 至少包含一条记录。没有业务动作的纯信息类邮件不要提交空数组,也不要新生成 `informational_message`;应改用 `S000,source_message_id` 文本结果
### 4.2 `ai_task_results[]` 字段
### 4.3 `ai_task_results[]` 字段
| 字段 | 是否必填 | 中文说明 |
| --- | --- | --- |
| `source_event_index` | 是 | AI current 事件序号,建议从 1 开始 |
| `catalog_code` | 是 | Skill 目录代码,例如 S01、S02 |
| `skill_id` | 是 | Skill 标识 |
| `result_type` | 是 | 只接受 `normal_task``manual_review``informational_message` |
| `result_type` | 是 | 新入口只接受 `normal_task``manual_review``informational_message` 仅历史兼容 |
| `task_type` | 是 | AI 原始任务类型 |
| `task_subtype` | 否 | 业务动作 subtype有则用于任务卡路由 |
| `current_or_history` | 否 | 当前或历史标识 |
@@ -186,10 +191,42 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
| `context_used` | 否 | AI 使用的上下文 |
| `extracted_fields` | 否 | 业务字段主体 |
| `manual_review` | 条件必填 | `result_type=manual_review` 时应提供 |
| `informational_message` | 条件必填 | `result_type=informational_message` 时应提供 |
| `informational_message` | 条件必填 | 仅历史兼容;新数据不再生成 |
| `additional_operations` | 否 | 附加动作建议 |
| `idempotency_key` | 否 | 可忽略;本系统第一版自行生成幂等键 |
### 4.4 S000/S999 文本结果请求体
当 SuperAgent 入口阶段没有结构化任务 JSON 时,可以直接提交纯文本 body
```text
S000,mail-20260708-0001
```
或:
```text
S999,mail-20260708-0001
```
字段说明:
| 片段 | 中文说明 |
| --- | --- |
| `S000` | 纯信息类邮件,不形成业务素材包 |
| `S999` | 入口阶段无法形成业务素材包 |
| `source_message_id` | 逗号后面的值,外部来源消息 ID对应 AgentBus `source.external_message_id` |
处理规则:
- 第一版使用系统默认酒店反查 SourceMessage Inbox不要求文本 body 携带 `hotel_id`
- 后端按 `默认酒店 + AGENTBUS + EMAIL + external_message_id` 查询 SourceMessage。
- 命中后创建 `SOURCE_MESSAGE_ONLY` 只读任务。
- 任务列表可见,订单列表不可见。
- 不允许编辑、确认、转换订单、执行 OPERA 或重试 OPERA。
- 同一 SourceMessage 重复提交相同文本 body 返回幂等重放。
- 同一 SourceMessage 已经存在不同 AI 结果请求时返回幂等冲突。
## 5. 技术校验边界
本接口只做技术校验,不做业务合法性判断。
@@ -198,12 +235,13 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
- 鉴权签名合法。
- 请求体大小不超过限制。
- JSON 可解析
- `hotel_id` 存在。仅本地旧夹具兼容缺少 `hotel_id``source_message_id` 为内部数字 ID 的调用。
- JSON body 可解析S000/S999 文本 body 必须符合 `结果码,source_message_id`
- JSON body 中 `hotel_id` 存在。仅本地旧夹具兼容缺少 `hotel_id``source_message_id` 为内部数字 ID 的调用。
- S000/S999 文本 body 第一版使用系统默认酒店,不读取 `hotel_id`
- 顶层只有一个 `source_message_id`
- `source_message_id` 对应的外部来源消息已经写入 SourceMessage Inbox。
- `ai_task_results[]` 是非空数组。
- `result_type` 属于允许值。
- JSON `result_type` 属于允许值。
- `task_type` 属于当前系统可识别的稳定值或可进入 Fallback 处理。
- 同一个请求内 `source_event_index` 和数组顺序可保存。
- 关键字符串长度不超过数据库限制。
@@ -246,6 +284,7 @@ sha256(
- 相同请求体重复提交时识别为幂等重放。
- 同一个外部 `source_message_id` 解析到的内部 SourceMessage 如果提交了不同请求体,不会被误认为同一个批次。
- S000/S999 文本 body 也使用同一批次幂等规则。
### 6.3 item 幂等键
@@ -296,7 +335,8 @@ sha256(
| `case_keys` | `case_keys_json` | 保存订单候选键 |
| `extracted_fields` | `extracted_fields_json` | 保存业务字段 |
| `manual_review` | `manual_review_json` | 保存人工复核结构 |
| `informational_message` | `informational_message_json` | 保存信息提醒 |
| `informational_message` | `informational_message_json` | 仅历史兼容的信息提醒结构 |
| `S000/S999` 文本结果 | `SOURCE_MESSAGE_ONLY` 只读特殊任务 | 保存入口阶段原始结果,不创建真实业务订单 |
系统主任务类型映射以 `M002-order-task-workflow-v2.md` 为准。
@@ -331,6 +371,35 @@ sha256(
}
```
S000 / S999 文本结果创建成功时,同样返回 `201 Created`。这类结果会创建只读特殊任务和隐藏技术订单,供任务列表展示和任务详情查看来源邮件;该隐藏技术订单不会出现在订单列表。
```json
{
"request_id": "req-20260707-0003",
"source_message_id": "mail-20260708-0001",
"batch_id": "1900000000000005001",
"idempotent_replay": false,
"accepted_count": 1,
"items": [
{
"source_event_index": 1,
"array_index": 1,
"ai_transition_id": "1900000000000006001",
"order_id": "1900000000000007001",
"task_id": "1900000000000008001",
"system_task_type": "SOURCE_MESSAGE_ONLY",
"task_card_type": "SOURCE_MESSAGE_ONLY",
"task_status": "COMPLETED",
"order_status": "TEMPORARY",
"execution_order": 1
}
],
"warnings": []
}
```
前端通过任务详情查看该类任务时,字段列表和 OPERA 操作列表为空,按钮应全部只读;`source_message_only_result` 会返回 `entry_result_code``entry_result_meaning``entry_result_description``entry_result_source_message_id``raw_answer`
### 8.2 幂等重放
相同请求体重复提交时返回 `200 OK`