AI 模块 nextstep-v2
模块:ai | gRPC 50058 | HTTP 3008 | Python (FastAPI + gRPC aio)
更新时间:2026-07-14
前序文档:nextstep.md(v1,8 RPC / 10 端点)
§1 当前状态
v2 新增第 9 个 RPC GenerateReport(学情报告生成),满足 teacher-bff generateReport mutation 需求。9 RPC 全部实现,402 个测试通过,覆盖率 88.5%。
v2 新增
完整 9 RPC 清单
| # |
RPC |
类型 |
用途 |
状态 |
| 1 |
Chat |
一元 |
非流式聊天 |
✅ 已实现 |
| 2 |
StreamChat |
流式 |
流式聊天(SSE over gRPC) |
✅ 已实现 |
| 3 |
GenerateQuestion |
一元 |
生成题目 |
✅ 已实现 |
| 4 |
StreamGenerateQuestion |
流式 |
流式生成题目 |
✅ 已实现 |
| 5 |
OptimizeExpression |
一元 |
优化表达 |
✅ 已实现 |
| 6 |
GenerateLessonPlan |
一元 |
启动备课工作流 |
✅ 已实现 |
| 7 |
GetLessonPlanStatus |
一元 |
查询备课工作流状态 |
✅ 已实现 |
| 8 |
ConfirmLessonPlan |
一元 |
确认备课结果入库 |
✅ 已实现 |
| 9 |
GenerateReport |
一元 |
生成学情报告(v2 新增) |
✅ 已实现 |
完整 11 HTTP 端点清单
| # |
端点 |
方法 |
权限 |
状态 |
| 1 |
/healthz |
GET |
- |
✅ 已实现 |
| 2 |
/readyz |
GET |
- |
✅ 已实现 |
| 3 |
/v1/ai/chat |
POST |
ai:chat |
✅ 已实现 |
| 4 |
/v1/ai/chat/stream |
POST |
ai:chat |
✅ 已实现 |
| 5 |
/v1/ai/generate/question |
POST |
ai:question:generate |
✅ 已实现 |
| 6 |
/v1/ai/generate/question/stream |
POST |
ai:question:generate |
✅ 已实现 |
| 7 |
/v1/ai/optimize/expression |
POST |
ai:expression:optimize |
✅ 已实现 |
| 8 |
/v1/ai/lesson-plan/generate |
POST |
ai:lesson:generate |
✅ 已实现 |
| 9 |
/v1/ai/lesson-plan/status/{id} |
GET |
- |
✅ 已实现 |
| 10 |
/v1/ai/lesson-plan/confirm/{id} |
POST |
ai:lesson:confirm |
✅ 已实现 |
| 11 |
/v1/ai/generate/report |
POST |
ai:report:generate |
✅ 已实现 |
权限点清单
| 权限点 |
teacher |
admin |
student |
用途 |
| ai:chat |
✅ |
✅ |
✅ |
聊天 |
| ai:question:generate |
✅ |
✅ |
❌ |
生成题目 |
| ai:expression:optimize |
✅ |
✅ |
❌ |
优化表达 |
| ai:lesson:generate |
✅ |
✅ |
❌ |
生成教案 |
| ai:lesson:confirm |
✅ |
✅ |
❌ |
确认教案 |
| ai:report:generate |
✅ |
✅ |
❌ |
生成学情报告 |
§2 GenerateReport 实现详情
§2.1 数据流
§2.2 报告类型
| report_type |
用途 |
必填参数 |
data-ana 数据源 |
| class_summary |
班级学情总结 |
class_id |
GetClassPerformance |
| student_detail |
学生个人学情详情 |
class_id + student_id |
GetClassPerformance + GetStudentWeakness + GetLearningTrend |
| exam_analysis |
考试分析 |
class_id |
GetClassPerformance |
§2.3 降级策略
| 场景 |
降级行为 |
degraded |
degraded_reason |
| LLM 全部不可用 |
返回空 content + 空 summary + 空 recommendations |
true |
"LLM unavailable: ..." |
| data-ana 不可用 |
上下文降级(空数据),LLM 仍可生成(基于空数据) |
false |
(报告内容会说明无数据) |
| ReportService 未注入 |
gRPC 返回空 GeneratedReport |
true |
"report_service not initialized" |
| 未知异常 |
gRPC 抛 AIError(AI_INTERNAL_ERROR) |
- |
- |
§3 上游依赖(ai 依赖谁)
§3.1 gRPC 同步调用
| 被调用方 |
端口 |
Service.RPC |
用途 |
状态 |
| content |
50054 |
KnowledgeGraphService.GetPrerequisites |
查询知识点前置依赖(备课工作流 Step 2) |
✅ 已实现 |
| content |
50054 |
KnowledgeGraphService.GetLearningPath |
查询学习路径(备课工作流 Step 2) |
✅ 已实现 |
| content |
50054 |
QuestionService.BatchCreateQuestions |
批量创建题目入库(备课工作流 Confirm) |
✅ 已实现 |
| data-ana |
50055 |
AnalyticsService.GetClassPerformance |
查询班级学情(备课工作流 + 学情报告) |
✅ 已实现 |
| data-ana |
50055 |
AnalyticsService.GetStudentWeakness |
查询学生薄弱点(备课工作流 + 学情报告) |
✅ 已实现 |
| data-ana |
50055 |
AnalyticsService.GetLearningTrend |
查询学习趋势(备课工作流 + 学情报告) |
✅ 已实现 |
| iam |
50052 |
IamService.GetEffectiveDataScope |
查询用户数据范围(多租户配额) |
✅ 已实现 |
v2 变更:data-ana 的 3 个 RPC 现在同时服务于备课工作流和学情报告两条业务线。
§3.2 基础设施依赖
| 依赖 |
用途 |
状态 |
| Redis |
限流 + 工作流状态存储 + 用量记录 |
✅ 已实现 |
| Kafka |
AIUsageEvent 事件发布(topic: edu.ai.usage) |
✅ 已实现 |
| OpenTelemetry Collector |
链路追踪 + 指标导出 |
✅ 已实现 |
§3.3 LLM Provider 依赖
| Provider |
环境变量 |
用途 |
状态 |
| OpenAI |
OPENAI_API_KEY / OPENAI_BASE_URL |
首选 LLM |
✅ 已实现 |
| Anthropic |
ANTHROPIC_API_KEY |
Failover 第二 |
✅ 已实现 |
| 百川 |
BAICHUAN_API_KEY |
Failover 第三 |
✅ 已实现 |
| Ollama |
OLLAMA_BASE_URL |
本地降级 |
✅ 已实现 |
§4 下游就绪信号(谁依赖 ai)
§4.1 teacher-bff — P1
| 就绪标志 |
消费方式 |
状态 |
| AiService.Chat / StreamChat 可调用 |
gRPC 50058 + SSE 3008 |
✅ 已就绪 |
| AiService.GenerateQuestion 可调用 |
gRPC 50058 |
✅ 已就绪 |
| AiService.GenerateLessonPlan 可调用 |
gRPC 50058 |
✅ 已就绪 |
| AiService.GetLessonPlanStatus / ConfirmLessonPlan 可调用 |
gRPC 50058 |
✅ 已就绪 |
| AiService.OptimizeExpression 可调用 |
gRPC 50058 |
✅ 已就绪 |
| AiService.GenerateReport 可调用 |
gRPC 50058 |
✅ 已就绪 |
teacher-bff 通过 AI_GRPC_TARGET=ai:50058 连接,留空时走降级模式 B。
§4.2 student-bff — P1
| 就绪标志 |
消费方式 |
状态 |
| AiService.Chat 可调用(同步 AI 答疑) |
gRPC 50058 |
✅ 已就绪 |
| AiService.StreamChat 可调用(流式答疑) |
gRPC 50058 |
✅ 已就绪 |
§4.3 api-gateway — P2
| 就绪标志 |
消费方式 |
状态 |
| ai HTTP 3008 /healthz 可达 |
HTTP 反向代理 /api/v1/ai/* → ai:3008 |
✅ 已就绪 |
§4.4 data-ana — P2
| 就绪标志 |
消费方式 |
状态 |
Kafka topic edu.ai.usage 有事件发布 |
CDC 消费者 → ClickHouse ai_usage_log |
✅ 已就绪 |
§5 需要上下游实现的工作(nextstep-v2 新增)
§5.1 teacher-bff 需要完成
| # |
工作项 |
当前状态 |
优先级 |
| 1 |
AI gRPC 客户端添加 generateReport 方法 |
当前返回降级响应(degraded) |
P1 |
| 2 |
teacher.service.ts 的 generateReport() 调用真实 gRPC |
当前硬编码降级响应 |
P1 |
| 3 |
GraphQL schema GeneratedReport type 字段对齐 proto |
需确认字段一致性 |
P2 |
详细说明:
teacher-bff 的 ai-grpc.client.ts 目前实现了 chat / streamChat / generateQuestion / optimizeExpression,但 generateLessonPlan 和 generateReport 走降级。现在 ai 侧 GenerateReport RPC 已就绪,teacher-bff 需:
ai.proto GenerateReportRequest 字段:
§5.2 student-bff 需要确认
| # |
工作项 |
当前状态 |
优先级 |
| 1 |
确认 ChatService.Chat gRPC 调用可用 |
ai 侧已就绪,待 student-bff 确认 |
P1 |
| 2 |
确认 ChatService.StreamChat gRPC 调用可用 |
ai 侧已就绪,待 student-bff 确认 |
P1 |
student-bff nextstep-v2.md §5.4 标注这两个 RPC "需确认"。ai 侧 Chat 和 StreamChat RPC 已在 v1 实现,gRPC 50058 可直接调用。
§5.3 data-ana 需要保持
| # |
工作项 |
当前状态 |
优先级 |
| 1 |
AnalyticsService 3 RPC 保持可用 |
✅ 已就绪 |
P1 |
| 2 |
GenerateReport 依赖 GetClassPerformance 等 3 RPC |
✅ 已就绪 |
P1 |
学情报告功能依赖 data-ana 的 3 个 AnalyticsService RPC。如果 data-ana 不可用,报告会基于降级上下文(空数据)生成,但 LLM 仍可工作。
§5.4 api-gateway 需要保持
| # |
工作项 |
当前状态 |
优先级 |
| 1 |
/api/v1/ai/* → ai:3008 反向代理路由保持可用 |
✅ 已就绪 |
P2 |
| 2 |
新增 /v1/ai/generate/report 自动被 /api/v1/ai/* 通配覆盖 |
✅ 已就绪 |
P2 |
api-gateway 使用通配路由 /api/v1/ai/*,新增的 /v1/ai/generate/report 端点自动被覆盖,无需额外配置。
§6 联调待办
| # |
联调项 |
联调方 |
阻塞条件 |
状态 |
| 1 |
ai gRPC + teacher-bff SSE 联调 |
teacher-bff |
ai 服务容器启动 |
✅ ai 侧就绪(待 teacher-bff 接入) |
| 2 |
ai gRPC StreamChat + student-bff 联调 |
student-bff |
ai 服务容器启动 |
✅ ai 侧就绪(待 student-bff 确认) |
| 3 |
ai /healthz + api-gateway 联调 |
api-gateway |
ai 服务容器启动 |
✅ ai 侧就绪(待 api-gateway 路由) |
| 4 |
AIUsageEvent + data-ana CDC 消费联调 |
data-ana |
ai Kafka 生产 + data-ana 消费 |
✅ ai 生产就绪(待 data-ana 消费) |
| 5 |
ai ↔ content gRPC 联调 |
content |
双方容器启动 |
✅ ai 客户端就绪(待 content 启动) |
| 6 |
ai ↔ data-ana gRPC 联调 |
data-ana |
双方容器启动 |
✅ ai 客户端就绪(待 data-ana 启动) |
| 7 |
ai ↔ iam gRPC 联调 |
iam |
双方容器启动 |
✅ ai 客户端就绪(待 iam 启动) |
| 8 |
GenerateReport + teacher-bff 联调 |
teacher-bff |
ai RPC 就绪 + teacher-bff 客户端更新 |
✅ ai RPC 就绪(待 teacher-bff 客户端更新) |
| 9 |
GenerateReport + data-ana 数据联调 |
data-ana |
双方容器启动 + 真实学情数据 |
✅ ai 客户端就绪(待 data-ana 有数据) |
§7 测试验证
§7.1 单元测试
| 测试文件 |
新增用例数 |
覆盖范围 |
| test_grpc_servicer.py |
5 |
GenerateReport 成功/学生详情/未初始化降级/LLM降级/内部错误 |
| test_services.py |
9 |
ReportService 生成成功/学生详情/LLM降级/无data-ana/摘要提取/建议提取(2)/prompt构建 |
| test_main_app.py |
5 |
HTTP 端点 class_summary/student_detail/invalid_type/missing_class_id/permission_denied |
| test_models.py |
5 |
report 模型 默认值/invalid_type/missing_class_id/student_detail/data_defaults |
| test_permission.py |
2 |
teacher 有 report 权限 / student 无 report 权限 |
| 合计 |
26 |
v1 377 → v2 402(+25 净增,1 个修复 _extract_recommendations bug) |
§7.2 质量校验
| 校验项 |
结果 |
详情 |
| ruff check |
✅ 通过 |
零警告 |
| pytest |
✅ 通过 |
402 passed, 0 failed |
| 覆盖率 |
✅ 88.5% |
report_service.py 91%,models/report.py 100% |
§7.3 Docker 验证(待执行)
arch.db 本次不扫描,Docker 验证待 infra 环境就绪后执行。
| # |
验证项 |
状态 |
| 1 |
Docker 镜像构建 |
⏳ 待验证 |
| 2 |
容器启动 + gRPC 50058 |
⏳ 待验证 |
| 3 |
HTTP /healthz |
⏳ 待验证 |
| 4 |
HTTP /readyz |
⏳ 待验证 |
| 5 |
GenerateReport gRPC |
⏳ 待验证 |
§8 关键实现文件
| 文件 |
变更类型 |
说明 |
packages/shared-proto/proto/ai.proto |
修改 |
新增 GenerateReport RPC + 2 message |
src/ai/proto_gen/ai_pb2.py |
重新生成 |
protobuf 代码 |
src/ai/proto_gen/ai_pb2_grpc.py |
重新生成 |
gRPC stub/servicer 代码 |
src/ai/models/report.py |
新建 |
Pydantic 请求/响应模型 |
src/ai/models/__init__.py |
修改 |
导出 report 模型 |
src/ai/services/report_service.py |
新建 |
ReportService 业务编排 |
src/ai/services/__init__.py |
修改 |
导出 ReportService |
src/ai/grpc_server/servicer.py |
修改 |
GenerateReport 方法 + report_service 注入 |
src/ai/grpc_server/server.py |
修改 |
create_grpc_server 添加 report_service 参数 |
src/ai/middleware/permission.py |
修改 |
新增 PERMISSION_AI_REPORT_GENERATE 权限点 |
src/ai/main.py |
修改 |
ReportService 实例化 + HTTP /generate/report |
tests/test_grpc_servicer.py |
修改 |
5 个 GenerateReport servicer 测试 |
tests/test_services.py |
修改 |
9 个 ReportService 测试 |
tests/test_main_app.py |
修改 |
5 个 HTTP 端点测试 |
tests/test_models.py |
修改 |
5 个 report 模型测试 |
tests/test_permission.py |
修改 |
2 个 report 权限测试 |
§9 P6+ 待评估
| # |
待评估项 |
说明 |
| 1 |
Temporal 引入评估 |
备课工作流 P5 用 BackgroundTasks + Redis,P6 评估是否引入 Temporal |
| 2 |
content 事件订阅 |
P5 不订阅 content 事件,P6+ 评估是否需要知识点变更事件驱动 |
| 3 |
MockLLMProvider |
02 文档提到但未实现,测试环境用 httpx Mock 替代 |
| 4 |
报告持久化 |
当前 GenerateReport 不持久化报告,P6+ 评估是否需要入库 |
| 5 |
报告模板管理 |
当前用内联 fallback 模板,P6+ 评估是否需要独立模板管理服务 |
| 6 |
报告异步生成 |
当前同步生成,长报告可能超时,P6+ 评估是否改为异步 + 轮询模式 |