ai-robot-core/AI中台对接文档.md

512 lines
13 KiB
Markdown
Raw Permalink Normal View History

# 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: <your_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: <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: <your_api_key>
X-Tenant-Id: <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<ChatRequest> entity = new HttpEntity<>(request, headers);
ResponseEntity<ChatResponse> 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<ServerSentEvent<String>> 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
**维护状态**: ✅ 活跃维护