[AC-AISVC-02, AC-AISVC-16] 多个需求合并 #1
|
|
@ -9,26 +9,26 @@ last_updated: "2026-02-24"
|
|||
# Python AI 中台进度追踪(AISVC)
|
||||
|
||||
## Phase 1: 基础设施(FastAPI 框架与多租户基础)
|
||||
- [x] T1.1 初始化 FastAPI 项目骨架,配置基础环境与日志(包含 X-Tenant-Id 记录) `[AC-AISVC-01]`
|
||||
- [x] T1.2 实现 `X-Tenant-Id` Header 拦截器,校验必填性并注入 Request State `[AC-AISVC-10, AC-AISVC-12]`
|
||||
- [x] T1.3 定义基础响应模型 `ErrorResponse` 与异常处理器(Exception Handler) `[AC-AISVC-03, AC-AISVC-04]`
|
||||
- [ ] T1.4 初始化 PostgreSQL 数据库客户端(SQLModel/SQLAlchemy),支持租户隔离查询逻辑 `[AC-AISVC-11]`
|
||||
- [ ] T1.5 初始化 Qdrant 客户端,封装按租户动态选择 Collection 的工具函数 `[AC-AISVC-10]`
|
||||
- [x] T1.6 实现 `/ai/health` 健康检查接口 `[AC-AISVC-20]`
|
||||
- [x] T1.1 初始化 FastAPI 项目骨架,配置基础环境与日志(包含 X-Tenant-Id 记录) `[AC-AISVC-01]` ✅ **2026-02-24 完成**
|
||||
- [x] T1.2 实现 `X-Tenant-Id` Header 拦截器,校验必填性并注入 Request State `[AC-AISVC-10, AC-AISVC-12]` ✅ **2026-02-24 完成**
|
||||
- [x] T1.3 定义基础响应模型 `ErrorResponse` 与异常处理器(Exception Handler) `[AC-AISVC-03, AC-AISVC-04]` ✅ **2026-02-24 完成**
|
||||
- [x] T1.4 初始化 PostgreSQL 数据库客户端(SQLModel/SQLAlchemy),支持租户隔离查询逻辑 `[AC-AISVC-11]` ✅ **2026-02-24 完成**
|
||||
- [x] T1.5 初始化 Qdrant 客户端,封装按租户动态选择 Collection 的工具函数 `[AC-AISVC-10]` ✅ **2026-02-24 完成**
|
||||
- [x] T1.6 实现 `/ai/health` 健康检查接口 `[AC-AISVC-20]` ✅ **2026-02-24 完成**
|
||||
|
||||
## Phase 2: 存储与检索实现(Memory & Retrieval)
|
||||
- [ ] T2.1 实现 Memory 层:定义 `chat_sessions` 与 `chat_messages` SQLModel 实体 `[AC-AISVC-13]`
|
||||
- [ ] T2.2 实现 Memory 层:完成基于 `(tenant_id, session_id)` 的历史消息加载与追加 API `[AC-AISVC-13]`
|
||||
- [ ] T2.3 实现 Retrieval 层:定义 `BaseRetriever` 抽象基类(插件点预留) `[AC-AISVC-16]`
|
||||
- [ ] T2.4 实现 `VectorRetriever`:集成 `qdrant-client` 完成向量检索,支持 scoreThreshold 过滤 `[AC-AISVC-16, AC-AISVC-17]`
|
||||
- [ ] T2.5 编写 Memory 与 Retrieval 层的独立单元测试(Mock 数据库与向量库) `[AC-AISVC-10, AC-AISVC-11]`
|
||||
- [x] T2.1 实现 Memory 层:定义 `chat_sessions` 与 `chat_messages` SQLModel 实体 `[AC-AISVC-13]` ✅ **2026-02-24 完成**
|
||||
- [x] T2.2 实现 Memory 层:完成基于 `(tenant_id, session_id)` 的历史消息加载与追加 API `[AC-AISVC-13]` ✅ **2026-02-24 完成**
|
||||
- [x] T2.3 实现 Retrieval 层:定义 `BaseRetriever` 抽象基类(插件点预留) `[AC-AISVC-16]` ✅ **2026-02-24 完成**
|
||||
- [x] T2.4 实现 `VectorRetriever`:集成 `qdrant-client` 完成向量检索,支持 scoreThreshold 过滤 `[AC-AISVC-16, AC-AISVC-17]` ✅ **2026-02-24 完成**
|
||||
- [x] T2.5 编写 Memory 与 Retrieval 层的独立单元测试(Mock 数据库与向量库) `[AC-AISVC-10, AC-AISVC-11]` ✅ **2026-02-24 完成**
|
||||
|
||||
## Phase 3: 核心编排(Orchestrator & LLM Adapter)
|
||||
- [ ] T3.1 实现 LLM Adapter:封装 `langchain-openai` 或官方 SDK,支持 `generate` 与 `stream_generate` `[AC-AISVC-02, AC-AISVC-06]`
|
||||
- [ ] T3.2 实现 Orchestrator:实现上下文合并逻辑(H_local + H_ext 的去重与截断策略) `[AC-AISVC-14, AC-AISVC-15]`
|
||||
- [ ] T3.3 实现 Orchestrator:实现 RAG 检索不足时的置信度下调与 `shouldTransfer` 逻辑 `[AC-AISVC-17, AC-AISVC-18, AC-AISVC-19]`
|
||||
- [ ] T3.4 实现 Orchestrator:整合 Memory、Retrieval 与 LLM 完成 non-streaming 生成闭环 `[AC-AISVC-01, AC-AISVC-02]`
|
||||
- [ ] T3.5 验证 non-streaming 响应字段完全符合 `openapi.provider.yaml` 契约 `[AC-AISVC-02]`
|
||||
- [x] T3.1 实现 LLM Adapter:封装 `langchain-openai` 或官方 SDK,支持 `generate` 与 `stream_generate` `[AC-AISVC-02, AC-AISVC-06]` ✅ **2026-02-24 完成**
|
||||
- [x] T3.2 实现 Orchestrator:实现上下文合并逻辑(H_local + H_ext 的去重与截断策略) `[AC-AISVC-14, AC-AISVC-15]` ✅ **2026-02-24 完成**
|
||||
- [x] T3.3 实现 Orchestrator:实现 RAG 检索不足时的置信度下调与 `shouldTransfer` 逻辑 `[AC-AISVC-17, AC-AISVC-18, AC-AISVC-19]` ✅ **2026-02-24 完成**
|
||||
- [x] T3.4 实现 Orchestrator:整合 Memory、Retrieval 与 LLM 完成 non-streaming 生成闭环 `[AC-AISVC-01, AC-AISVC-02]` ✅ **2026-02-24 完成**
|
||||
- [x] T3.5 验证 non-streaming 响应字段完全符合 `openapi.provider.yaml` 契约 `[AC-AISVC-02]` ✅ **2026-02-24 完成**
|
||||
|
||||
## Phase 4: 流式响应(SSE 实现与状态机)
|
||||
- [x] T4.1 在 API 层实现基于 `Accept` 头的响应模式自动切换逻辑 `[AC-AISVC-06]` ✅ **2026-02-24 完成**
|
||||
|
|
@ -43,167 +43,131 @@ last_updated: "2026-02-24"
|
|||
|
||||
---
|
||||
|
||||
## T4.1 完成详情
|
||||
## 总体进度
|
||||
|
||||
### 实现内容
|
||||
1. **FastAPI 项目骨架** (`ai-service/app/`)
|
||||
- 配置管理 (`app/core/config.py`)
|
||||
- 日志配置
|
||||
- 异常处理器 (`app/core/exceptions.py`)
|
||||
| Phase | 描述 | 进度 | 状态 |
|
||||
|-------|------|------|------|
|
||||
| Phase 1 | 基础设施 | 100% | ✅ 完成 |
|
||||
| Phase 2 | 存储与检索 | 100% | ✅ 完成 |
|
||||
| Phase 3 | 核心编排 | 100% | ✅ 完成 |
|
||||
| Phase 4 | 流式响应 | 100% | ✅ 完成 |
|
||||
| Phase 5 | 集成测试 | 100% | ✅ 完成 |
|
||||
|
||||
2. **数据模型** (`app/models/__init__.py`)
|
||||
- `ChatRequest` - 请求模型
|
||||
- `ChatResponse` - 响应模型(含 reply/confidence/shouldTransfer)
|
||||
- `ErrorResponse` - 错误响应模型
|
||||
- SSE 事件模型(SSEMessageEvent, SSEFinalEvent, SSEErrorEvent)
|
||||
|
||||
3. **X-Tenant-Id Header 拦截器** (`app/core/middleware.py`)
|
||||
- [AC-AISVC-10] 租户上下文注入
|
||||
- [AC-AISVC-12] 缺失 tenant_id 返回 400 错误
|
||||
|
||||
4. **Accept 头响应模式切换** (`app/api/chat.py`)
|
||||
- [AC-AISVC-06] 根据 Accept 头自动切换 JSON/SSE 模式
|
||||
- `Accept: text/event-stream` → SSE 流式响应
|
||||
- 其他 → JSON 响应
|
||||
|
||||
5. **SSE 基础设施** (`app/core/sse.py`)
|
||||
- SSE 状态机(INIT → STREAMING → FINAL_SENT/ERROR_SENT → CLOSED)
|
||||
- 事件生成器(message/final/error)
|
||||
- Ping 保活机制(15s 间隔)
|
||||
|
||||
6. **单元测试** (`tests/test_accept_switching.py`)
|
||||
- JSON 响应模式测试
|
||||
- SSE 响应模式测试
|
||||
- SSE 事件序列测试
|
||||
- 租户隔离测试
|
||||
- 状态机测试
|
||||
|
||||
### 测试结果
|
||||
```
|
||||
24 passed in 2.52s
|
||||
```
|
||||
|
||||
### 验收标准覆盖
|
||||
- [x] AC-AISVC-01: HTTP POST /ai/chat 调用
|
||||
- [x] AC-AISVC-02: 响应包含 reply/confidence/shouldTransfer
|
||||
- [x] AC-AISVC-03: 参数错误返回 400
|
||||
- [x] AC-AISVC-06: Accept 头切换 SSE 模式
|
||||
- [x] AC-AISVC-10: tenantId 贯穿隔离
|
||||
- [x] AC-AISVC-12: 缺 tenantId 返回 400
|
||||
- [x] AC-AISVC-20: 健康检查接口
|
||||
**测试统计: 184 tests passing**
|
||||
|
||||
---
|
||||
|
||||
## T4.2 完成详情
|
||||
## Phase 3 完成详情 (2026-02-24)
|
||||
|
||||
### 实现内容
|
||||
1. **Orchestrator 流式输出优化** (`app/services/orchestrator.py`)
|
||||
- [AC-AISVC-07] 集成 LLM 客户端流式输出
|
||||
- 支持依赖注入 LLM 客户端
|
||||
- 实现 `_stream_from_llm()` 方法包装 LLM chunk 为 message 事件
|
||||
- 实现 `_stream_mock_response()` 模拟流式输出
|
||||
- SSE 事件序列:message* -> final -> close
|
||||
### T3.1 LLM Adapter
|
||||
- 创建 LLMClient 抽象接口 (`app/services/llm/base.py`)
|
||||
- 实现 OpenAIClient 使用 httpx (`app/services/llm/openai_client.py`)
|
||||
- 支持 generate 和 stream_generate
|
||||
- 使用 tenacity 实现重试逻辑
|
||||
- 单元测试: 11 tests
|
||||
|
||||
2. **SSE 事件生成器** (`app/core/sse.py`)
|
||||
- `create_message_event(delta)` - 创建 message 事件,包含增量内容
|
||||
- `create_final_event()` - 创建 final 事件,包含完整响应
|
||||
- `create_error_event()` - 创建 error 事件
|
||||
- 修复 `by_alias=True` 确保 JSON 字段使用 camelCase
|
||||
### T3.2 上下文合并
|
||||
- 创建 ContextMerger 类 (`app/services/context.py`)
|
||||
- 实现消息指纹计算 (SHA256)
|
||||
- 实现去重策略 (local 优先)
|
||||
- 实现 token 截断 (使用 tiktoken)
|
||||
- 单元测试: 20 tests
|
||||
|
||||
3. **单元测试** (`tests/test_sse_events.py`)
|
||||
- message 事件格式测试
|
||||
- unicode 内容测试
|
||||
- final 事件格式测试
|
||||
- error 事件格式测试
|
||||
- Orchestrator 流式输出测试
|
||||
- LLM 客户端集成测试
|
||||
- 状态机集成测试
|
||||
### T3.3 置信度计算
|
||||
- 创建 ConfidenceCalculator 类 (`app/services/confidence.py`)
|
||||
- 实现检索不足判定
|
||||
- 实现置信度计算策略
|
||||
- 实现 shouldTransfer 逻辑
|
||||
- 单元测试: 19 tests
|
||||
|
||||
### 测试结果
|
||||
```
|
||||
79 passed in 3.11s
|
||||
```
|
||||
### T3.4 Orchestrator 完整闭环
|
||||
- 整合 Memory、ContextMerger、Retriever、LLMClient、ConfidenceCalculator
|
||||
- 实现 8 步生成管道:
|
||||
1. Load local history from Memory
|
||||
2. Merge with external history (dedup + truncate)
|
||||
3. RAG retrieval (optional)
|
||||
4. Build prompt with context and evidence
|
||||
5. LLM generation
|
||||
6. Calculate confidence
|
||||
7. Save messages to Memory
|
||||
8. Return ChatResponse
|
||||
- 创建 GenerationContext 数据类追踪生成流程
|
||||
- 实现 fallback 响应机制
|
||||
- 单元测试: 21 tests
|
||||
|
||||
### 验收标准覆盖
|
||||
- [x] AC-AISVC-07: AI 中台多次发送 event: message 事件,每次携带增量文本(delta)
|
||||
- [x] AC-AISVC-08: 生成完成后发送 event: final 事件
|
||||
- [x] AC-AISVC-09: 错误时发送 event: error 事件
|
||||
### T3.5 契约验证
|
||||
- 验证 ChatResponse 字段与 OpenAPI 契约一致性
|
||||
- 验证 JSON 序列化使用 camelCase
|
||||
- 验证必填字段和可选字段
|
||||
- 验证 confidence 范围约束 [0.0, 1.0]
|
||||
- 单元测试: 23 tests
|
||||
|
||||
---
|
||||
|
||||
## T4.3 & T4.4 完成详情
|
||||
## 验收标准覆盖
|
||||
|
||||
### 实现内容
|
||||
1. **API 层状态机集成** (`app/api/chat.py`)
|
||||
- [AC-AISVC-08, AC-AISVC-09] 在 `_handle_streaming_request` 中集成状态机
|
||||
- 状态机确保事件顺序:message* -> final/error -> close
|
||||
- 禁止 final/error 后发送任何事件
|
||||
- 异常自动转换为 error 事件
|
||||
|
||||
2. **状态机行为保证**
|
||||
- `INIT -> STREAMING`: 开始流式输出
|
||||
- `STREAMING -> FINAL_SENT`: 发送 final 后关闭
|
||||
- `STREAMING -> ERROR_SENT`: 发送 error 后关闭
|
||||
- `FINAL_SENT/ERROR_SENT -> CLOSED`: 最终关闭状态
|
||||
- 线程安全:使用 asyncio.Lock 保证并发安全
|
||||
|
||||
3. **异常处理机制**
|
||||
- 流式输出过程中的任何异常都被捕获
|
||||
- 异常自动转换为 `event: error` 事件
|
||||
- 确保 error 事件只发送一次
|
||||
- 连接在 error 后正确关闭
|
||||
|
||||
4. **单元测试** (`tests/test_sse_state_machine.py`)
|
||||
- 状态机转换测试(9 个测试)
|
||||
- SSE 事件序列测试(3 个测试)
|
||||
- 错误处理测试(3 个测试)
|
||||
- 并发安全测试(2 个测试)
|
||||
- Orchestrator 集成测试(2 个测试)
|
||||
|
||||
### 测试结果
|
||||
```
|
||||
117 passed in 4.24s
|
||||
```
|
||||
|
||||
### 验收标准覆盖
|
||||
- [x] AC-AISVC-08: 生成完成后发送一次 event: final,随后关闭连接
|
||||
- [x] AC-AISVC-09: 错误时发送 event: error,并终止事件流
|
||||
| AC 标记 | 描述 | 状态 |
|
||||
|---------|------|------|
|
||||
| AC-AISVC-01 | HTTP POST /ai/chat 调用 | ✅ |
|
||||
| AC-AISVC-02 | 响应包含 reply/confidence/shouldTransfer | ✅ |
|
||||
| AC-AISVC-03 | 参数错误返回 400 | ✅ |
|
||||
| AC-AISVC-04 | 异常处理器 | ✅ |
|
||||
| AC-AISVC-06 | Accept 头切换 SSE 模式 | ✅ |
|
||||
| AC-AISVC-07 | SSE message 事件增量输出 | ✅ |
|
||||
| AC-AISVC-08 | SSE final 事件后关闭连接 | ✅ |
|
||||
| AC-AISVC-09 | 错误时发送 error 事件 | ✅ |
|
||||
| AC-AISVC-10 | tenantId 贯穿隔离 | ✅ |
|
||||
| AC-AISVC-11 | 存储层按 tenant_id 隔离 | ✅ |
|
||||
| AC-AISVC-12 | 缺 tenantId 返回 400 | ✅ |
|
||||
| AC-AISVC-13 | Memory 层会话历史管理 | ✅ |
|
||||
| AC-AISVC-14 | 上下文合并 | ✅ |
|
||||
| AC-AISVC-15 | 历史去重策略 | ✅ |
|
||||
| AC-AISVC-16 | Retriever 抽象接口 | ✅ |
|
||||
| AC-AISVC-17 | RAG 检索质量影响 confidence | ✅ |
|
||||
| AC-AISVC-18 | 检索不足时 confidence 下调 | ✅ |
|
||||
| AC-AISVC-19 | shouldTransfer 转人工建议 | ✅ |
|
||||
| AC-AISVC-20 | 健康检查接口 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 完成详情
|
||||
## 模块结构
|
||||
|
||||
### 实现内容
|
||||
|
||||
1. **多租户集成测试** (`tests/test_integration_tenant.py`)
|
||||
- [AC-AISVC-10, AC-AISVC-11] 并发多租户请求测试
|
||||
- 租户隔离验证(不同租户相同 session_id)
|
||||
- 租户上下文传播测试
|
||||
- 存储/检索层隔离测试
|
||||
- 健康检查绕过租户验证
|
||||
|
||||
2. **RAG 冒烟测试** (`tests/test_rag_smoke.py`)
|
||||
- [AC-AISVC-17] 检索命中场景测试
|
||||
- [AC-AISVC-18] 检索未命中场景测试
|
||||
- 置信度评分测试
|
||||
- SSE 流式 RAG 测试
|
||||
- 历史对话集成测试
|
||||
- 回退行为测试
|
||||
|
||||
3. **契约测试** (`tests/test_contract.py`)
|
||||
- [AC-AISVC-01] ChatRequest 契约验证
|
||||
- [AC-AISVC-02] ChatResponse 契约验证
|
||||
- [AC-AISVC-03] ErrorResponse 契约验证
|
||||
- [AC-AISVC-06,07,08] SSE 响应契约验证
|
||||
- [AC-AISVC-20] 健康检查契约验证
|
||||
|
||||
### 测试结果
|
||||
```
|
||||
184 passed in 5.22s
|
||||
ai-service/
|
||||
├── app/
|
||||
│ ├── api/
|
||||
│ │ └── chat.py # FastAPI 路由层
|
||||
│ ├── core/
|
||||
│ │ ├── config.py # 配置管理
|
||||
│ │ ├── exceptions.py # 异常定义
|
||||
│ │ ├── middleware.py # 中间件 (租户注入)
|
||||
│ │ ├── qdrant_client.py # Qdrant 客户端
|
||||
│ │ └── sse.py # SSE 状态机和事件生成器
|
||||
│ ├── models/
|
||||
│ │ ├── __init__.py # Pydantic 模型
|
||||
│ │ └── entities.py # SQLModel 实体
|
||||
│ └── services/
|
||||
│ ├── llm/
|
||||
│ │ ├── base.py # LLMClient 抽象接口
|
||||
│ │ └── openai_client.py # OpenAI 兼容客户端
|
||||
│ ├── memory.py # Memory 服务
|
||||
│ ├── orchestrator.py # 编排服务
|
||||
│ ├── context.py # 上下文合并
|
||||
│ ├── confidence.py # 置信度计算
|
||||
│ └── retrieval/
|
||||
│ ├── base.py # Retriever 抽象接口
|
||||
│ └── vector_retriever.py # 向量检索实现
|
||||
└── tests/ # 单元测试 (184 tests)
|
||||
```
|
||||
|
||||
### 验收标准覆盖
|
||||
- [x] AC-AISVC-10: tenantId 贯穿所有层级,确保物理/逻辑隔离
|
||||
- [x] AC-AISVC-11: 存储层按 tenant_id 物理隔离
|
||||
- [x] AC-AISVC-17: RAG 检索质量影响 confidence
|
||||
- [x] AC-AISVC-18: 检索不足时 confidence 下调并建议转人工
|
||||
---
|
||||
|
||||
## 关键技术决策
|
||||
|
||||
| 决策 | 原因 | 影响 |
|
||||
|------|------|------|
|
||||
| LLM Adapter 使用 httpx | 更轻量、更可控、减少依赖 | 需要手动处理 OpenAI API 响应解析 |
|
||||
| 使用 tenacity 实现重试 | 简单可靠的重试机制 | 提高服务稳定性 |
|
||||
| Orchestrator 依赖注入模式 | 便于测试和组件替换 | 所有组件可通过构造函数注入 |
|
||||
| GenerationContext 数据类 | 清晰追踪中间结果和诊断信息 | 便于调试和问题排查 |
|
||||
| Pydantic alias 实现驼峰命名 | 符合 OpenAPI 契约的 camelCase 要求 | JSON 序列化时自动转换字段名 |
|
||||
|
|
|
|||
Loading…
Reference in New Issue