# AI 中台对接文档 ## 1. 概述 本文档描述 Python AI 中台对渠道侧(Java 主框架)暴露的 HTTP 接口规范,用于智能客服对话生成和服务健康检查。 ### 1.1 服务信息 - **服务名称**: AI Service (Python AI 中台) - **服务地址**: `http://ai-service:8080` - **协议**: HTTP/1.1 - **数据格式**: JSON / SSE (Server-Sent Events) - **字符编码**: UTF-8 - **契约版本**: v1.1.0 ### 1.2 核心能力 - ✅ 智能对话生成(基于 LLM + RAG) - ✅ 多租户隔离(基于 `X-Tenant-Id`) - ✅ 会话上下文管理(基于 `sessionId`) - ✅ 流式/非流式双模式输出 - ✅ 置信度评估与转人工建议 - ✅ 服务健康检查 --- ## 2. 认证与租户隔离 ### 2.1 API Key 认证(必填) 所有接口请求(除健康检查外)必须在 HTTP Header 中携带 API Key: ```http X-API-Key: ``` **说明**: - API Key 用于身份认证和访问控制 - 缺失或无效的 API Key 将返回 `401 Unauthorized` - API Key 由 AI 中台管理员分配,请妥善保管 - 以下路径无需 API Key:`/health`、`/ai/health`、`/docs` ### 2.2 租户标识(必填) 所有接口请求必须在 HTTP Header 中携带租户 ID: ```http X-Tenant-Id: ``` **租户 ID 格式规范**:`name@ash@year` 示例: - `szmp@ash@2026` - 深圳某项目 2026 年 - `abc123@ash@2025` - ABC 项目 2025 年 **说明**: - 租户 ID 用于数据隔离(知识库、会话历史、配置等) - 缺失或格式错误的租户 ID 将返回 `400 Bad Request` - 不同租户的数据完全隔离,不可跨租户访问 - 租户不存在时会自动创建 --- ## 3. 接口列表 | 接口路径 | 方法 | 功能 | 响应模式 | |---------|------|------|---------| | `/ai/chat` | POST | 生成 AI 回复 | JSON / SSE | | `/ai/health` | GET | 健康检查 | JSON | --- ## 4. 接口详细说明 ### 4.1 生成 AI 回复 **接口路径**: `POST /ai/chat` **功能描述**: 根据用户消息和会话历史生成 AI 回复,支持 RAG 检索增强、上下文管理、置信度评估。 #### 4.1.1 请求参数 **Headers**: ```http Content-Type: application/json X-API-Key: X-Tenant-Id: Accept: application/json # 或 text/event-stream(流式输出) ``` **Body** (JSON): | 字段 | 类型 | 必填 | 说明 | |-----|------|------|------| | `sessionId` | string | ✅ | 会话 ID,用于关联同一会话的对话历史 | | `currentMessage` | string | ✅ | 当前用户消息内容 | | `channelType` | string | ✅ | 渠道类型,枚举值:`wechat`、`douyin`、`jd` | | `history` | array | ❌ | 历史消息列表(可选,AI 中台会自动管理会话历史) | | `metadata` | object | ❌ | 扩展元数据(可选) | **history 数组元素结构**: ```json { "role": "user | assistant", "content": "消息内容" } ``` **请求示例**: ```json { "sessionId": "kf_001_wx123456_1708765432000", "currentMessage": "我想了解产品价格", "channelType": "wechat", "metadata": { "channelUserId": "wx123456", "extra": "..." } } ``` #### 4.1.2 响应格式 ##### 模式 1: JSON 响应(非流式) **状态码**: `200 OK` **响应体**: ```json { "reply": "您好,我们的产品价格根据套餐不同有所差异...", "confidence": 0.92, "shouldTransfer": false, "transferReason": null, "metadata": { "retrieval_count": 3, "rag_enabled": true } } ``` **字段说明**: | 字段 | 类型 | 必填 | 说明 | |-----|------|------|------| | `reply` | string | ✅ | AI 生成的回复内容 | | `confidence` | number | ✅ | 置信度评分(0.0-1.0),越高表示回答越可靠 | | `shouldTransfer` | boolean | ✅ | 是否建议转人工(true=建议转人工) | | `transferReason` | string | ❌ | 转人工原因(可选) | | `metadata` | object | ❌ | 响应元数据(可选) | ##### 模式 2: SSE 流式响应 **触发条件**: 请求头包含 `Accept: text/event-stream` **响应头**: ```http Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive ``` **事件流格式**: 1. **增量消息事件** (可多次发送) ``` event: message data: {"delta": "您好,"} event: message data: {"delta": "我们的产品"} ``` 2. **最终结果事件** (发送一次后关闭连接) ``` event: final data: {"reply": "完整回复内容", "confidence": 0.92, "shouldTransfer": false} ``` 3. **错误事件** (发生错误时发送) ``` event: error data: {"code": "INTERNAL_ERROR", "message": "错误描述"} ``` **事件序列保证**: - `message*` (0 或多次) → `final` (1 次) → 连接关闭 - 或 `message*` (0 或多次) → `error` (1 次) → 连接关闭 #### 4.1.3 错误响应 **401 Unauthorized** - 认证失败 ```json { "code": "UNAUTHORIZED", "message": "Missing required header: X-API-Key", "details": [] } ``` **400 Bad Request** - 请求参数错误 ```json { "code": "INVALID_REQUEST", "message": "缺少必填字段: sessionId", "details": [] } ``` **400 Bad Request** - 租户 ID 格式错误 ```json { "code": "INVALID_TENANT_ID", "message": "Invalid tenant ID format. Expected: name@ash@year (e.g., szmp@ash@2026)", "details": [] } ``` **500 Internal Server Error** - 服务内部错误 ```json { "code": "INTERNAL_ERROR", "message": "LLM 调用失败", "details": [] } ``` **503 Service Unavailable** - 服务不可用 ```json { "code": "SERVICE_UNAVAILABLE", "message": "向量数据库连接失败", "details": [] } ``` --- ### 4.2 健康检查 **接口路径**: `GET /ai/health` **功能描述**: 检查 AI 服务是否正常运行,用于服务监控和负载均衡健康探测。 #### 4.2.1 请求参数 无需请求参数,无需认证头。 #### 4.2.2 响应格式 **200 OK** - 服务正常 ```json { "status": "healthy" } ``` **503 Service Unavailable** - 服务不健康 ```json { "status": "unhealthy" } ``` --- ## 5. 调用示例 ### 5.1 Java 调用示例(非流式) ```java import org.springframework.http.*; import org.springframework.web.client.RestTemplate; public class AIServiceClient { private final RestTemplate restTemplate; private final String aiServiceUrl = "http://ai-service:8080"; private final String apiKey = "your_api_key_here"; public ChatResponse generateReply(String tenantId, ChatRequest request) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("X-API-Key", apiKey); headers.set("X-Tenant-Id", tenantId); HttpEntity entity = new HttpEntity<>(request, headers); ResponseEntity response = restTemplate.postForEntity( aiServiceUrl + "/ai/chat", entity, ChatResponse.class ); return response.getBody(); } } ``` ### 5.2 Java 调用示例(流式) ```java import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Flux; public class AIServiceStreamClient { private final WebClient webClient; private final String apiKey = "your_api_key_here"; public Flux> generateReplyStream( String tenantId, ChatRequest request ) { return webClient.post() .uri("/ai/chat") .header("X-API-Key", apiKey) .header("X-Tenant-Id", tenantId) .header("Accept", "text/event-stream") .bodyValue(request) .retrieve() .bodyToFlux(ServerSentEvent.class); } } ``` ### 5.3 cURL 调用示例 ```bash # 非流式调用 curl -X POST http://ai-service:8080/ai/chat \ -H "Content-Type: application/json" \ -H "X-API-Key: your_api_key_here" \ -H "X-Tenant-Id: szmp@ash@2026" \ -d '{ "sessionId": "kf_001_wx123456_1708765432000", "currentMessage": "我想了解产品价格", "channelType": "wechat" }' # 流式调用 curl -X POST http://ai-service:8080/ai/chat \ -H "Content-Type: application/json" \ -H "X-API-Key: your_api_key_here" \ -H "X-Tenant-Id: szmp@ash@2026" \ -H "Accept: text/event-stream" \ -d '{ "sessionId": "kf_001_wx123456_1708765432000", "currentMessage": "我想了解产品价格", "channelType": "wechat" }' # 健康检查(无需认证) curl http://ai-service:8080/ai/health ``` --- ## 6. 业务逻辑说明 ### 6.1 会话管理 - **会话标识**: `sessionId` 用于唯一标识一个对话会话 - **自动持久化**: AI 中台会自动保存会话历史,无需调用方每次传递完整历史 - **可选历史**: 调用方可通过 `history` 字段提供外部历史,AI 中台会合并处理 - **租户隔离**: 相同 `sessionId` 在不同 `tenantId` 下视为不同会话 ### 6.2 RAG 检索增强 - **自动触发**: AI 中台会根据用户问题自动判断是否需要检索知识库 - **多知识库**: 支持按知识库类型(产品知识、FAQ、话术模板等)分类检索 - **置信度评估**: 检索结果质量会影响 `confidence` 评分 - **兜底策略**: 检索失败或无结果时,AI 会基于通用知识回答并降低置信度 ### 6.3 转人工建议 `shouldTransfer` 字段由以下因素决定: - ✅ 置信度低于阈值(默认 0.6) - ✅ 检索无结果或结果质量差 - ✅ 用户明确要求人工服务 - ✅ 意图识别命中"转人工"规则 **注意**: `shouldTransfer=true` 仅为建议,最终是否转人工由调用方(Java 主框架)决策。 ### 6.4 意图识别与规则引擎 - **前置处理**: 用户消息会先经过意图识别 - **固定回复**: 命中固定规则时直接返回预设话术(跳过 LLM 调用) - **话术流程**: 命中流程规则时进入多轮引导对话 - **定向检索**: 命中 RAG 规则时使用指定知识库检索 ### 6.5 输出护栏 - **禁词过滤**: AI 回复会自动过滤禁词(竞品名称、敏感词等) - **替换策略**: 支持星号替换、文本替换、整条拦截三种策略 - **行为约束**: Prompt 中注入行为规则(如"不承诺具体赔偿金额") --- ## 7. 性能与限制 ### 7.1 性能指标 | 指标 | 非流式 | 流式 | |-----|-------|------| | 首字响应时间 | 1-3 秒 | 200-500 毫秒 | | 完整响应时间 | 2-5 秒 | 3-8 秒 | | 并发支持 | 100+ QPS | 50+ QPS | ### 7.2 限制说明 - **消息长度**: 单条消息最大 4000 字符 - **历史长度**: 建议历史消息不超过 20 轮(AI 中台会自动截断) - **超时设置**: 建议调用方设置 10 秒超时(非流式)、30 秒超时(流式) - **重试策略**: 503 错误建议指数退避重试,500 错误建议降级处理 --- ## 8. 错误码参考 | 错误码 | HTTP 状态码 | 说明 | 处理建议 | |-------|-----------|------|---------| | `UNAUTHORIZED` | 401 | 认证失败(缺少或无效 API Key) | 检查 X-API-Key 请求头 | | `INVALID_REQUEST` | 400 | 请求参数错误 | 检查必填字段和参数格式 | | `MISSING_TENANT_ID` | 400 | 缺少租户 ID | 添加 X-Tenant-Id 请求头 | | `INVALID_TENANT_ID` | 400 | 租户 ID 格式错误 | 使用正确格式:name@ash@year | | `INTERNAL_ERROR` | 500 | 服务内部错误 | 降级处理或重试 | | `LLM_ERROR` | 500 | LLM 调用失败 | 降级处理或重试 | | `SERVICE_UNAVAILABLE` | 503 | 服务不可用 | 指数退避重试 | | `QDRANT_ERROR` | 503 | 向量库不可用 | 指数退避重试 | | `STREAMING_ERROR` | 200 (SSE) | 流式传输错误 | 关闭连接并重试 | --- ## 9. 最佳实践 ### 9.1 API Key 管理 - API Key 由 AI 中台管理员通过管理后台分配 - 建议为不同环境(开发/测试/生产)使用不同的 API Key - API Key 应存储在配置文件或环境变量中,不要硬编码 - 定期轮换 API Key 以提高安全性 ### 9.2 会话 ID 生成规范 建议格式: `{业务前缀}_{租户ID}_{渠道用户ID}_{时间戳}` 示例: `kf_001_wx123456_1708765432000` ### 9.3 流式 vs 非流式选择 - **流式**: 适用于 Web/App 实时对话场景,用户体验更好 - **非流式**: 适用于批量处理、异步任务、API 集成场景 ### 9.4 降级策略建议 ```java public ChatResponse generateReplyWithFallback(String tenantId, ChatRequest request) { try { return aiServiceClient.generateReply(tenantId, request); } catch (ServiceUnavailableException e) { // 降级策略 1: 返回固定话术 return ChatResponse.builder() .reply("抱歉,当前咨询量较大,请稍后再试或转人工服务。") .confidence(0.0) .shouldTransfer(true) .build(); } catch (Exception e) { // 降级策略 2: 直接转人工 return ChatResponse.builder() .reply("系统繁忙,正在为您转接人工客服...") .confidence(0.0) .shouldTransfer(true) .transferReason("AI 服务异常") .build(); } } ``` ### 9.5 监控指标建议 - ✅ 接口响应时间(P50/P95/P99) - ✅ 接口成功率 - ✅ 置信度分布 - ✅ 转人工率 - ✅ 错误码分布 --- ## 10. 变更日志 | 版本 | 日期 | 变更内容 | |-----|------|---------| | v1.1.0 | 2026-02-27 | 新增流式输出支持、意图识别、输出护栏 | | v1.0.0 | 2026-02-20 | 初始版本,支持基础对话生成和健康检查 | --- ## 11. 联系方式 - **技术支持**: AI 中台开发团队 - **问题反馈**: 提交 Issue 到项目仓库 - **文档更新**: 参考 `spec/ai-service/openapi.provider.yaml` --- **文档生成时间**: 2026-02-27 **契约版本**: v1.1.0 **维护状态**: ✅ 活跃维护