# 公共 Agent 平台接口规范(历史稿,已废弃) > 版本:v1.0 > 修订日期:2026-09-08 > 文档性质:历史评审稿,不再作为实现依据 > 适用对象:底座负责人、业务模块开发者、前端与客户端、编码 Agent > 关联文档:`00-新数据库基线设计.md`(数据基线)、`01-通用Agent平台开发设计.md`(架构与内部契约权威源)、`02-数据库建表设计.md`(增量表)、`03-平台端到端流程文档.md`(业务流程) > **废弃声明(2026-09-09)**:本文已被 [`05-接口文档.md`](05-接口文档.md) 完整取代,不得据此新增或修改接口。两份文档冲突时,以 `05-接口文档.md` 为唯一 HTTP 接口权威源;本文仅保留用于追溯早期设计决策。 --- ## 0. 文档定位 ### 0.1 本文负责 - HTTP 信封、认证方式、幂等、分页、追踪和 SSE 传输规则。 - 公共 Agent 平台接口:运行、会话、记忆、配置查询、模型路由查询、Prompt 引用、知识引用、转人工入口、审计查询。 - 平台管理面接口:配置发布与回滚、模型端点、模型路由规则、Prompt 版本、意图配置、禁止表达。 - 业务接口的**扩展格式、命名映射、权限声明和契约测试**要求。 ### 0.2 本文不负责 - 内部 Service / Repository / 事件类型定义:见第 4 章索引,本文不复制。 - 业务域字段、状态机和业务校验规则:由各业务模块文档定义。 - 数据库表结构与迁移:以 `00-新数据库基线设计.md` 为不可变基线,增量见 `02`。 - Agent 执行骨架、配置权威链、工具与合规策略:以 `01` 为权威源。 ### 0.3 权威源矩阵 | 契约项 | 唯一权威源 | 本文的处理方式 | |---|---|---| | HTTP 路径、信封、认证、幂等、分页、追踪、SSE 传输 | **本文** | 唯一定义 | | SSE 事件名与载荷 | 01 §12 | 索引,不重复定义 | | Service Protocol(9 个依赖) | 01 §5.4 | 索引 | | 错误分类 `AgentError` 体系 | 01 §5.5 | 索引;本文只定义 HTTP 状态码映射 | | `AgentRequest`、`RequestContext`、`AgentResult`、`CoreResult` 等 | 01 §5.2、§5.3 | 索引 | | 执行骨架与七步顺序 | 01 §6 | 索引 | | 配置权威链与发布回滚 | 01 §7.3、§7.4 | 索引 | | `DomainEvent` 与 Outbox 语义 | 01 §5.3、02 §8.2 | 索引;本文只定义“何时产生” | | 表结构、字段、约束 | 00 基线 + 02 | 索引 | | 业务字段、状态机、业务校验 | 各业务模块文档 | 本文只列入口与 Agent 边界 | ### 0.4 边界裁决规则 1. **骨架优先**:本文定义的通用约定(信封、错误码、认证、幂等、分页、追踪、SSE 传输)优先于任何业务文档;业务文档不得在信封之外新增顶层字段。 2. **载荷归属**:业务字段、状态机、业务校验一律由业务文档定义,本文只引用。 3. **冲突处理**:同一契约项出现两处定义时,以《权威源矩阵》指定的文档为准,另一处必须删除并改为引用。禁止两个定义同时进入实现或迁移。 4. **新增错误码**:本文若需新增错误码,必须先在 01 §5.5 注册,再在本文映射 HTTP 状态码;未注册的 `code` 不得出现在响应中。 --- ## 1. 通用约定 ### 1.1 前缀与版本 - 所有接口统一前缀 `/api/v1`,网关按前缀做统一限流、大小限制和来源校验。 - 版本策略:路径版本。不兼容变更升为 `/api/v2`,同一版本内只允许向后兼容的新增字段。 - 01 §3.3 示例中的 `/agents/{agent_type}/chat` 在本文固化为 `POST /api/v1/agent-runs`(见 2.1)。 ### 1.2 认证与上下文 - 认证方式:`Authorization: Bearer `,所有接口强制,无匿名接口。 - **JWT 载荷**: | 声明 | 含义 | 说明 | |---|---|---| | `sub` | `user_id` | 唯一身份标识 | | `jti` | 令牌唯一 ID | 用于吊销与审计 | | `iat` / `exp` / `iss` / `aud` | 标准声明 | 标准校验 | | `portal` | 入口标识 | **签发时绑定**,请求参数不得覆盖 | - **不得放入 JWT 的字段**:`roles`、`data_scope`、`assigned_customer_ids`。 依据 03 §4.2“FastAPI 认证依赖解析令牌,并重新加载有效角色”:角色与数据范围每次请求从 `sys_user_role` / `sys_role_permission` / `sys_customer_assignment` 加载(Redis 缓存 + 版本失效),保证权限降级即时生效;客户归属是动态集合,无法进令牌。 - 01:319 的约束在 HTTP 层落地为:`user_id`、`roles`、`portal`、`data_scope`、`clarification_round` **只来自服务端上下文**,客户端通过 query、header 或 body 提交这些字段一律忽略并记安全审计。 **网关与应用层职责(防御纵深)** | 层 | 职责 | 不承担 | |---|---|---| | 网关 | JWT 签名校验、过期校验、限流、请求大小、来源白名单、`/api/v1` 前缀路由 | 业务授权、数据范围过滤 | | 应用层 | 加载有效角色与数据范围、构造 `RequestContext`、`AgentFactory` 授权、工具与数据层过滤 | 不做令牌签名校验的替代 | ### 1.3 请求与响应信封 **请求头** | 头 | 必填 | 说明 | |---|---|---| | `Authorization` | 是 | `Bearer ` | | `Content-Type` | 写操作是 | `application/json; charset=utf-8` | | `Idempotency-Key` | 写操作是 | 长度 8–64,见 1.5 | | `X-Request-Id` | 否 | 客户端链路号,仅用于关联,不替代 `trace_id` | **成功响应** ```json { "code": "OK", "message": "成功", "data": {}, "trace_id": "b7f1c2e0-4a6d-4f2b-9c31-0d5e7a8b9c01" } ``` **错误响应** ```json { "code": "AGENT_INPUT_INVALID", "message": "请求参数不正确", "trace_id": "b7f1c2e0-4a6d-4f2b-9c31-0d5e7a8b9c01", "error_id": null, "details": [] } ``` - `details` 只在参数校验失败时填充字段级错误,禁止回传堆栈、SQL 或依赖原始响应。 - SSE 接口不使用该信封,见 1.8。 ### 1.4 错误码与 HTTP 状态映射 错误码取值以 01 §5.5 为权威源,本文只做 HTTP 映射。 | code | HTTP | 场景 | 来源 | |---|---|---|---| | `OK` | 200 | 成功 | 本文 | | `AGENT_INPUT_INVALID` | 400 | 参数、编码、长度校验失败 | 01:506 | | `AGENT_PERMISSION_DENIED` | 403 | 角色、入口或数据范围不允许 | 01:511 | | `AGENT_SESSION_NOT_FOUND` | 404 | 会话不存在**或**不属于当前用户 | **本文新增,需在 01 §5.5 注册** | | `AGENT_IDEMPOTENCY_CONFLICT` | 409 | 同幂等键但请求体不同 | 01:984 | | `AGENT_IDEMPOTENCY_PROCESSING` | 202 | 同幂等键请求仍在处理中 | 01:984 | | `AGENT_RATE_LIMITED` | 429 | 网关或应用层限流 | 本文 | | `AGENT_INTERNAL_ERROR` | 500 | 未预期异常,响应含 `error_id` | 01:669 | **重要约定** - **降级不是错误**:模型失败、Milvus 超时等可恢复故障经安全模板降级后,HTTP 返回 `200`,结果中带 `degraded: true` 与 `degradation_reason`(01 §6.2 的 `REPLACE` + `done` 路径)。客户端不得把 `degraded` 当作失败处理。 - **会话不存在与越权统一返回 404**:避免通过 403/404 差异探测他人会话是否存在。 - `AGENT_SESSION_NOT_FOUND` 注册前,实现方应临时使用 `AGENT_INPUT_INVALID`,不得自定义其他 `code`。 ### 1.5 幂等 - 所有写操作(`POST` / `PUT` / `PATCH` / `DELETE`)必须携带 `Idempotency-Key`。 - 幂等范围:`user_id + agent_type + idempotency_key`(01:984),落表 `request_idempotency`(02 §8.3)。 - 行为: | 情况 | 响应 | |---|---| | 键不存在 | 抢占记录(`processing`),正常执行 | | 键存在、`request_hash` 不同 | `409 AGENT_IDEMPOTENCY_CONFLICT` | | 键存在、`completed` | 返回原结果,`code=OK` | | 键存在、`processing` 且租约未过期 | `202 AGENT_IDEMPOTENCY_PROCESSING` | | 键存在、`processing` 且租约已过期 | 允许接管,重新执行 | | 键存在、`failed` | 按业务决定是否允许重试,默认允许 | - `request_hash` 由服务端对规范化后的请求体计算,客户端不得提交该字段。 ### 1.6 分页 - 统一游标分页:`?limit={1..100}&cursor={opaque}`,`limit` 默认 20,上限 100。 - 响应结构: ```json { "code": "OK", "message": "成功", "data": { "items": [], "next_cursor": "eyJpZCI6MTIzfQ", "has_more": false }, "trace_id": "..." } ``` - `cursor` 为不透明字符串,客户端不得解析或构造。禁止使用 `offset` 深分页。 ### 1.7 追踪 - 服务端为每个请求生成唯一 `trace_id`,贯穿 API、模型、工具、数据库与事件日志(01 §6.4)。 - 响应头必须回传 `X-Trace-Id`,响应体 `trace_id` 与之一致。 - `trace_id` 同时是 Agent 运行的对外标识(见 2.1),本文不引入独立的 `run_id`。 ### 1.8 SSE 传输规则 事件名称与载荷以 01 §12 为权威源,本节只定义如何通过 HTTP 传输。 **响应头** ```text Content-Type: text/event-stream; charset=utf-8 Cache-Control: no-cache Connection: keep-alive X-Accel-Buffering: no X-Trace-Id: ``` **认证**:与 1.2 一致,`Authorization: Bearer `。不接受把令牌放在 query 参数中。 **事件帧格式** ```text id: event: data: ``` - `id` 为单调递增序号(从 1 开始),供客户端排序与去重;即使 MVP 不实现事件级续传,服务端也必须提供该字段。 - `data` 为单行 JSON,不得包含裸换行;多行文本按 JSON 字符串转义。 **事件顺序与终止条件** | 阶段 | 事件 | 说明 | |---|---|---| | 1 | `start` | 首帧,携带 `trace_id`、`session_id` | | 2 | `tools` | 可选,工具调用摘要(已脱敏) | | 3 | `delta` | 0..N 帧,安全文本分块 | | 4 | `replace` | 可选,降级时用完整安全文本替换 | | 5 | `done` | 正常终止,携带 intent、confidence、sources、suggestions、degraded | | — | `error` | 异常终止,携带 error_code、message、trace_id | - `done` 或 `error` 之后服务端必须关闭连接,不再发送任何帧。 - 合规约束:`delta` 只在输出合规检查完成后发送(01:987);MVP 为“全量生成、全量合规、持久化后分块发送”,不承诺模型 Token 级真流式(01 §12)。 - 持久化约束:`AgentPersistenceService.complete_run()` 成功返回后才允许发送最终 SSE(01:963、03 §5.6)。 **心跳** - 空闲超过 15 秒发送注释行:`: keep-alive` + 空行。 - 注释帧不占 `id` 序号,客户端必须忽略。 **重连与断流恢复(结果级)** - MVP **不实现事件级续传**。客户端可选携带 `Last-Event-ID`,服务端若无法续传,应按 2.1 的规则正常结束连接,不返回部分流。 - 断流后的恢复方式:客户端调用 `GET /api/v1/agent-runs/{trace_id}` 获取完整结果。 - 该规则与 01 §6.4“同一 `trace_id` 的重复请求返回已有结果”一致:运行结果在发送 `delta` 之前已落库,因此恢复查询总是能拿到最终内容。 - 客户端断开后,服务端仍须完成归档与审计(01 §6.4、03 §13)。 **超时** - 服务端整体 SSE 生命周期上限 120 秒;超时发送 `error`(`AGENT_INTERNAL_ERROR`)并关闭。 - 模型单次调用超时 15 秒、最多 3 个端点(01:1168-1170)。 ### 1.9 时间、金额与编码 | 项 | 约定 | |---|---| | 时间 | ISO 8601 UTC,微秒精度,如 `2026-09-08T12:00:00.000000Z`,与 02 §3 的 `DATETIME(6)` 对齐 | | 金额 | 字符串,两位小数,语义同 `DECIMAL(18,2)`;禁止用浮点数 | | 价格 | 字符串,六位小数 | | 数量 | 字符串,四位小数 | | 编码 | UTF-8;`Content-Type: application/json; charset=utf-8` | | 空值 | 统一使用 `null`,禁止空字符串与 `null` 混用表达“无值” | ### 1.10 审计写入范围 审计表 `interaction_audit` 只追加、不可改(02 §12)。为避免技术噪声淹没受监管记录,写入范围固定如下。 **必须写入 `interaction_audit`** | # | 类别 | 示例 | |---|---|---| | 1 | 受监管业务状态变化 | 委托、成交、资金、持仓、预警处置、工单流转 | | 2 | 配置发布 | `config_release` 的创建、校验、审核、激活、回滚 | | 3 | 权限决策 | 越权拒绝、适当性拦截、跨客户访问拒绝 | | 4 | 人工处置 | 工单分配/接单/解决/关闭、投顾方案审核 | | 5 | 对客内容与运行留痕 | `client_facing_content` 发布、Agent 运行结果 | **只写运行日志与指标,不写审计** | # | 类别 | 示例 | |---|---|---| | 1 | 心跳与租约 | SSE 心跳、幂等租约续期 | | 2 | 幂等重试 | 抢占失败、`processing` 轮询 | | 3 | 缓存操作 | 配置缓存命中/失效、记忆热缓存刷新 | | 4 | 传输状态 | SSE 游标、断流、重连 | | 5 | 运维流量 | 健康检查、限流拒绝、网关拦截 | **边界情况** - `request_idempotency` 的**完成**随 `complete_run` 在同一事务写审计(与业务结果绑定);**租约续期与接管**只写日志。 - 降级运行写审计(`outcome="degraded"`,01:888),但降级原因的技术细节写日志。 - 审计写入失败时,受监管业务不得返回成功(01 §13)。 --- ## 2. 公共平台接口 统一约定:均需认证;均返回 1.3 信封(SSE 除外);均按 `data_scope` 过滤;均写 `trace_id`。 ### 2.1 Agent 运行 #### 2.1.1 发起运行(SSE) ```text POST /api/v1/agent-runs ``` **权限**:由 `AgentFactory` 按 `AgentDefinition.allowed_roles` + `allowed_portals` 判定;本文不在此处重复权限规则。 **幂等**:`Idempotency-Key` 必填。 **请求体** ```json { "agent_type": "customer_service", "session_id": "session-uuid", "message": "基金赎回多久到账?", "idempotency_key": "client-request-uuid", "end_session": false, "metadata": {} } ``` **与内部契约的映射(重要)** `agent_type` 不在 01 §5.2 的 `AgentRequest` 中。为避免修改该契约,Controller 使用独立的 HTTP DTO `AgentRunRequest`,再映射为 Service 层命令对象: ```python class AgentRunRequest(BaseModel): model_config = ConfigDict(extra="forbid") agent_type: str session_id: str message: str idempotency_key: str end_session: bool = False metadata: dict[str, Any] = Field(default_factory=dict) def to_agent_request(self) -> AgentRequest: return AgentRequest( session_id=self.session_id, message=self.message, idempotency_key=self.idempotency_key, end_session=self.end_session, metadata=self.metadata, ) @router.post("/agent-runs") async def create_agent_run( payload: AgentRunRequest, context: RequestContext = Depends(build_request_context), service: AgentService = Depends(get_agent_service), ) -> StreamingResponse: events = service.run_stream( payload.agent_type, payload.to_agent_request(), context ) return AgentSseView.response(events) ``` 该写法符合 MVC+S:Controller 持有 API DTO,Service 持有命令对象,Controller 不含业务判断(01:131)。 **响应**:`200` + `text/event-stream`,事件见 1.8 与 01 §12。 #### 2.1.2 查询运行结果(断流恢复) ```text GET /api/v1/agent-runs/{trace_id} ``` **权限**:仅可查询本人或职责范围内的运行;越权统一返回 `404 AGENT_SESSION_NOT_FOUND`。 **数据来源**:由 `conversation_message` + `request_idempotency` + `interaction_audit` 按 `trace_id` 聚合,不新增运行实体表。 **响应 `data`** ```json { "trace_id": "b7f1c2e0-...", "session_id": "session-uuid", "agent_type": "customer_service", "status": "completed", "reply": "……", "intent": "faq", "confidence": "0.8231", "source_references": [], "tool_calls": [], "suggestions": [], "transfer_required": false, "degraded": false, "degradation_reason": null, "created_at": "2026-09-08T12:00:00.000000Z" } ``` - `status` 取值:`processing` / `completed` / `failed`(由 `request_idempotency.status` 映射)。 - `tool_calls` 为脱敏后的摘要,字段结构以 01 §5.3 `ToolCallRecord` 为权威源。 - 运行不存在或尚未落库时返回 `404 AGENT_SESSION_NOT_FOUND`。 #### 2.1.3 运行列表(可选) ```text GET /api/v1/agent-runs?session_id=&agent_type=&limit=&cursor= ``` 按 1.6 分页;仅返回数据范围内的运行。 ### 2.2 会话与消息 | 方法 | 路径 | 说明 | 关联表 | |---|---|---|---| | `GET` | `/api/v1/conversations` | 会话列表,按 `last_active_at` 倒序 | `svc_conversation_session` | | `GET` | `/api/v1/conversations/{session_id}` | 会话详情,含状态与 `clarification_round` | 同上 | | `GET` | `/api/v1/conversations/{session_id}/messages` | 消息列表,游标分页 | `conversation_message` | | `POST` | `/api/v1/conversations/{session_id}/end` | 结束会话,幂等 | `svc_conversation_session` | | `POST` | `/api/v1/conversations/{session_id}/feedback` | 提交反馈 | `conversation_feedback` | | `POST` | `/api/v1/conversations/{session_id}/handover` | 发起转人工 | `svc_handover_ticket` | **约束** - `clarification_round` 为只读字段,只能由服务端在澄清路径中原子递增(01:985),客户端不得提交。 - 反馈接口按 `message_id` 去重;匿名场景的唯一性由业务文档定义(见 7.2 遗留项)。 - 会话归属校验失败统一返回 `404`。 ### 2.3 记忆 | 方法 | 路径 | 说明 | |---|---|---| | `GET` | `/api/v1/memories` | 记忆列表,按状态与有效期过滤 | | `GET` | `/api/v1/memories/{memory_id}` | 记忆详情 | | `GET` | `/api/v1/memories/{memory_id}/evidences` | 证据列表 | | `GET` | `/api/v1/memories/conflicts` | 冲突列表(仅员工角色) | | `POST` | `/api/v1/memories/{memory_id}/forget` | 发起遗忘,异步清理 Milvus/Neo4j/Redis | **约束** - 客户只能访问自己的记忆;员工按 `data_scope` 与客户归属过滤。 - 遗忘是异步流程(03 §12.5),接口返回受理状态,不代表物理删除已完成。 - 依法必须保留的交易、审计与对话归档不参与遗忘。 ### 2.4 配置查询 | 方法 | 路径 | 说明 | |---|---|---| | `GET` | `/api/v1/agent-configs/{agent_type}/resolved` | 返回解析后的 `ResolvedAgentConfig`(脱敏) | | `GET` | `/api/v1/agent-configs/releases/active` | 当前 active 发布批次摘要 | - 响应中不得出现 `secret_ref` 的实际值、密钥、供应商完整地址。 - 配置的写操作见第 3 章;本组接口只读,用于排障与前端展示。 ### 2.5 模型路由查询 ```text GET /api/v1/model-routes/resolved?agent_type=&task_type= ``` - 返回本次会选中的策略名、主端点代号、备用链代号、`max_attempts`、`latency_budget_ms`。 - 不返回 `secret_ref`、完整 `base_url`、成本单价。 - 端点与路由的增删改见第 3 章。 ### 2.6 Prompt 引用 - 公共侧不提供 Prompt 内容的读取接口;每次运行使用的 Prompt 版本通过 2.1.2 的 `trace_id` 关联审计记录获取(01 §7.4)。 - Prompt 的创建与版本管理见 3.4。 ### 2.7 知识引用 | 方法 | 路径 | 说明 | |---|---|---| | `GET` | `/api/v1/knowledge/{knowledge_id}` | 查询已发布知识元数据(不含全文) | | `GET` | `/api/v1/agent-runs/{trace_id}` | 已包含本次运行的 `source_references` | - 只返回 `review_status='published'` 且 `status='active'` 且在有效期内的条目(02 §6.2)。 - 知识上传、审校与发布流程由知识运营业务文档负责(03 §7)。 ### 2.8 转人工(通用入口) ```text POST /api/v1/conversations/{session_id}/handover ``` **请求体** ```json { "reason_code": "complaint", "reason_detail": "客户投诉资金争议" } ``` **响应 `data`** ```json { "ticket_no": "HT20260908000001", "status": "pending", "priority": "P0" } ``` **边界** - 本接口只负责“发起转接”这一跨 Agent 骨架动作,落 `svc_handover_ticket`。 - 工单的队列、分配、接单、解决、关闭状态机与字段由客服业务文档定义(02 §7.2、03 §6.4)。 - 转人工事件 `conversation.transfer_requested` 由底座在 `complete_run` 时同事务写入 Outbox(01:937)。 ### 2.9 审计查询 ```text GET /api/v1/audit-records?actor_id=&action_type=&target_customer_id=&from=&to=&limit=&cursor= ``` - 权限:`admin`、`super_admin`;`risk_operator` 按风控数据范围。 - 只读;`interaction_audit` 不允许任何更新或删除接口(02 §12)。 - `detail` 字段的结构由产生该审计的业务模块文档定义。 --- ## 3. 平台管理面接口 统一前缀 `/api/v1/admin`,权限限 `admin` / `super_admin`。所有写操作需 `Idempotency-Key`,全部写审计(1.10 第 2 类)。 ### 3.1 配置发布批次 | 方法 | 路径 | 说明 | |---|---|---| | `POST` | `/admin/config-releases` | 创建草稿 | | `GET` | `/admin/config-releases` | 批次列表 | | `GET` | `/admin/config-releases/{id}` | 批次详情与配置项 | | `POST` | `/admin/config-releases/{id}/validate` | Schema 与安全上限校验 | | `POST` | `/admin/config-releases/{id}/review` | 审核(`reviewer_id <> created_by`) | | `POST` | `/admin/config-releases/{id}/activate` | 原子激活 | | `POST` | `/admin/config-releases/{id}/rollback` | 回滚到指定历史版本 | **约束** - 状态机以 02 §8.4 的 CHECK 取值为准:`draft` / `validating` / `pending_review` / `approved` / `active` / `superseded` / `rejected` / `rolled_back`。 - 全局同一时刻只允许一个 `active` 批次,由 `uk_config_release_active_one` 在数据库层强制(02:582)。 - 回滚是重新激活历史不可变版本,不原地修改历史记录(01 §7.4)。 - 激活后必须使 `agent-config:{agent_type}:{release_id}` 缓存失效。 ### 3.2 模型端点 | 方法 | 路径 | 说明 | |---|---|---| | `GET` | `/admin/model-endpoints` | 端点列表(`secret_ref` 只回显引用名) | | `POST` | `/admin/model-endpoints` | 新建端点 | | `POST` | `/admin/model-endpoints/{id}/status` | 启用/禁用/归档 | - 禁止通过任何接口读取或写入明文密钥(02 §8.6、§12)。 ### 3.3 模型路由规则 | 方法 | 路径 | 说明 | |---|---|---| | `GET` | `/admin/model-routes?release_id=` | 规则列表 | | `POST` | `/admin/model-routes` | 在指定 release 内新增规则 | - `max_attempts` 取值 1–3,由 02:683 的 CHECK 强制。 - `fallback_endpoint_ids` 为 JSON 数组,端点有效性由应用层在发布校验阶段验证(见 7.2 遗留项)。 ### 3.4 Prompt 版本 | 方法 | 路径 | 说明 | |---|---|---| | `GET` | `/admin/prompts?task_type=&agent_type=` | 版本列表 | | `POST` | `/admin/prompts` | 新增不可变版本 | - `prompt_code + version` 唯一(02 §8.8),版本一经创建不可修改。 ### 3.5 意图配置 | 方法 | 路径 | 说明 | |---|---|---| | `GET` | `/admin/intent-configs?agent_type=` | 配置列表 | | `POST` | `/admin/intent-configs` | 新增版本 | - 不得新增 `AgentDefinition.supported_intents` 之外的意图(01:1106)。 - 工具白名单按意图配置,解析时与代码上限、角色权限求交集(01:1099)。 ### 3.6 禁止表达 | 方法 | 路径 | 说明 | |---|---|---| | `GET` | `/admin/negative-words` | 规则列表 | | `POST` | `/admin/negative-words` | 新增规则(初始 `draft`) | | `POST` | `/admin/negative-words/{id}/status` | 启用/停用/归档 | - 只有审核通过的规则才可置为 `active`(02 §7.1)。 --- ## 4. 内部契约索引 本章只做索引,不复制任何定义。修改内部契约必须修改权威源,并同步本节引用。 | 契约 | 权威源 | 变更要求 | |---|---|---| | `AgentRequest`、`RequestContext`、`AgentDefinition`、`ResolvedAgentConfig` | 01 §5.2 | 改动需评估 HTTP 映射影响 | | `SseEvent`、`IntentResult`、`SourceReference`、`ToolCallRecord`、`ToolResult`、`CoreResult`、`AgentResult` | 01 §5.3 | 本文 2.1.2 响应结构随之更新 | | 依赖协议(`ModelGateway`、`MemoryService`、`ComplianceService`、`ToolExecutor`、`AgentPersistenceService` 等 9 项) | 01 §5.4 | 不影响 HTTP 层 | | 错误分类 `AgentError` 体系 | 01 §5.5 | 新增 `code` 必须在此注册 | | 执行骨架与七步顺序 | 01 §6 | 决定 SSE 事件时序 | | `AgentFactory` / `AgentRegistry` | 01 §7 | 决定 2.1.1 的权限判定入口 | | 配置权威链与发布回滚 | 01 §7.3、§7.4 | 决定第 3 章接口语义 | | `DomainEvent` | 01 §5.3 | 本文只定义何时产生 | | `domain_event_outbox`、`request_idempotency`、`svc_conversation_session` 等增量表 | 02 §8 | 字段变更以 02 为准 | | 基线表与字段 | 00 基线 | 只增不改(`AGENTS.md` 第 2–4 条) | --- ## 5. 扩展规范 ### 5.1 A 类扩展:Agent 能力 新增某类 Agent 的意图与 `handle()` 时: - **不新增 HTTP 接口**,复用 `POST /api/v1/agent-runs`。 - 变更范围限定为:`implementations/_agent.py`、`bootstrap.py`(一行注册)、单元测试、契约测试数据(01 §16.4)。 - 禁止修改 `base.py`、`factory.py`、`contracts.py`、`app/controller/**`、`app/view/**`(01 §16.5)。 ### 5.2 B 类扩展:业务 API 新增领域接口(如模拟下单、预警处置、方案审核)时: - **新增 Controller 与 Service**,且 Controller 只做路由、参数校验、调用 Service、返回 View。 - 必须继承以下公共骨架,缺一不可: | # | 约束 | 依据 | |---|---|---| | 1 | 统一前缀 `/api/v1`、统一信封与错误码 | 1.1、1.3、1.4 | | 2 | 认证走统一上下文,禁止自建鉴权 | 1.2 | | 3 | 写操作必须幂等 | 1.5 | | 4 | 列表必须游标分页 | 1.6 | | 5 | 响应回传 `trace_id` | 1.7 | | 6 | 按 1.10 写入审计 | 1.10、02 §12 | | 7 | Controller 禁止访问 Model / ORM,禁止业务条件 | 01:131、02 §3 | - 业务字段、状态机、业务校验规则必须在对应业务模块文档中定义,本文不预先写死。 ### 5.3 命名映射规则 | 场景 | 规则 | 示例 | |---|---|---| | `agent_type` | snake_case,正则 `[a-z][a-z0-9_]{1,31}` | `customer_service` | | HTTP 路径段 | kebab-case,资源用复数 | `/api/v1/risk-alerts` | | 域路径 | 仅在该域存在独立业务 API 时使用,与 `agent_type` 无强制同名 | `customer_service` → `/api/v1/customer-service/**` | | 状态流转 | 资源 + 子资源 | `/risk-alerts/{id}/actions` | | 数据库表名 | 沿用基线前缀约定 | `fin_`、`sys_`、`svc_`、`agent_` | - `operations` 仅作为 `agent_type` 保留,对话走统一 `agent-runs`,**不设** `/operations/**` 域前缀。 - 场外运营业务 API 使用语义明确的独立资源名,例如 `/api/v1/offshore-subscriptions`、`/api/v1/fund-operation-mails`,并遵守 `AGENTS.md` 第 8 条(独立建表、独立接口)。 ### 5.4 权限声明格式 每个 B 类接口必须在业务文档中声明: ```text 接口:POST /api/v1/sim-orders allowed_roles: customer, operator, admin allowed_portals: web, app data_scope: own_only 幂等: 必需,幂等键 = client_order_no 审计: 是(1.10 第 1 类,受监管业务状态变化) Agent 边界: Agent 只读查询委托与成交,不得代客下单 ``` ### 5.5 契约测试要求 每个 B 类接口至少覆盖: - 未认证 → `401`;令牌无效 → `401`。 - 角色/入口不允许 → `403`。 - 越权访问他人数据 → `404`(统一口径)。 - 写操作缺少 `Idempotency-Key` → `400`;重复提交 → 幂等命中。 - 分页边界:`limit=0`、`limit=101`、非法 `cursor`。 - 审计写入成功且不可被业务接口修改。 - 响应信封与错误码符合第 1 章。 --- ## 6. 业务接口清单 本清单只列入口、归属文档和 Agent 边界;详细字段与状态机由归属文档负责。 | 入口 | 类型 | 归属文档 | Agent 边界 | |---|---|---|---| | `POST /api/v1/sim-orders` | B | 交易域文档 | Agent 只读查询委托/成交,**不得代客下单**(03 §2) | | `GET /api/v1/sim-orders`、`/api/v1/holdings` | B | 交易域文档 | 只读,按客户归属过滤 | | `POST /api/v1/risk-alerts/{alert_id}/actions` | B | 风控域文档 | Agent **不能**确认、关闭或升级预警(03 §10.3) | | `POST /api/v1/risk-scan-runs` | B | 风控域文档 | 规则引擎产生预警,模型只做辅助研判(03 §10.1) | | `POST /api/v1/advisory-plans/{plan_id}/reviews` | B | 投顾域文档 | Agent 只生成草案,审核由持证投顾执行(03 §8) | | `GET/POST /api/v1/client-facing-contents` | B | 投顾域文档 | 草稿状态内容不得作为正式建议返回(03 §8) | | `GET/POST /api/v1/handover-tickets` | B | 客服域文档 | 状态流转由人工执行(02 §7.2、03 §6.4) | | `GET/POST /api/v1/faq-synonyms` | B | 知识运营文档 | 只有 `approved` 参与检索(02 §7.3) | | `GET/POST /api/v1/knowledge-documents` | B | 知识运营文档 | 发布需审校(03 §7) | | `GET/POST /api/v1/offshore-subscriptions` | B | 场外运营文档 | 人工在回路确认后才提交清算(03 §11) | | `GET/POST /api/v1/feedback-reviews` | B | 客服域文档 | 质检池归人工处理(03 §6.5) | > 本清单为**索引**,不是接口定义的权威源。新增业务接口时在此登记一行,并在归属文档中定义字段。 --- ## 7. 边界裁决与遗留项 ### 7.1 裁决规则 见 0.4。补充两条操作要求: - 修改权威源后,必须同步本文第 4 章索引,并在提交说明中写明“权威源 + 同步位置”。 - 任何契约项若出现两处定义,实现与迁移脚本必须停止推进,先完成裁决再继续。 ### 7.2 已知遗留项 | # | 遗留项 | 影响 | 处理 | |---|---|---|---| | 1 | `AGENT_SESSION_NOT_FOUND`、`AGENT_RATE_LIMITED` 尚未在 01 §5.5 注册 | 错误码权威性 | 提请在 01 §5.5 补注册 | | 2 | 匿名反馈的唯一性依赖 API 限流,`uk_feedback_message_customer` 对 `customer_id IS NULL` 不生效 | 重复刷票风险 | 由客服业务文档定义哨兵值或指纹方案 | | 3 | `fallback_endpoint_ids` 为 JSON 数组,无外键约束 | 备用端点可能失效 | 3.3 的发布校验必须验证端点存在且状态为 `active` | | 4 | `fin_knowledge_meta.content_text` 基线定义为非空,02 实施为可空 | 基线一致性 | 由 02 登记偏差或提请基线修订 | | 5 | 事件级 SSE 续传未实现 | 重连体验 | MVP 采用结果级恢复(1.8) | --- ## 8. 变更记录 | 版本 | 日期 | 变更 | |---|---|---| | v1.0 | 2026-09-08 | 首版:确立 HTTP 层权威源边界、七章结构、SSE 传输规则、审计写入范围、A/B 类扩展规范 |