Files
Edu/services/ai/README.md
2026-07-10 18:57:39 +08:00

131 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 网关服务
> 版本1.0P5 完整实现)
> 端口HTTP 3008 + gRPC 50058
> 定位D6 智能洞察领域 · 生成子域Python/FastAPI严格无状态
## 职责
统一封装 LLM 调用(多模型路由 + 故障切换 + 熔断 + 限流 + 成本控制),提供:
- **聊天**:非流式 + SSE 流式
- **题目生成**:非流式 + 流式 + 评估三道防线RuleValidator + LLMJudge + QualityGate
- **表达优化**:文字清晰度/简洁度/语气优化
- **备课工作流**4 步编排(分析学情 → 推荐知识点 → 生成题目 → 教师审核入库)
通过 gRPC 查询 content 题库与 data-ana 学情数据。通过 Kafka 发布 AIUsageEvent 供 data-ana 统计。
## 技术栈
- Python 3.12 + FastAPI 0.115
- Pydantic 2 + pydantic-settings12-factor 配置)
- grpc.aiogRPC server 8 RPC + client 拦截器)
- aiokafka用量事件发布事务性 + 幂等,派生数据豁免 Outbox
- Jinja2 + YAMLPrompt 模板渲染)
- redis限流令牌桶 + 用量记录 + 工作流状态存储)
- OpenTelemetryHTTP + gRPC 链路追踪)
- prometheus-client + structlog指标 + 结构化日志)
## 架构分层
```
HTTP 端点(/v1/ai 前缀ActionState 信封)
PermissionGuard权限校验→ RateLimiter三维度令牌桶
Service 层ChatService / QuestionService / ExpressionService / LessonPlanWorkflowService
LLM ProviderFailoverChain4 适配器 + CircuitBreaker
LLM ProviderOpenAI / Anthropic / Baichuan / LocalOllama
gRPC server端口 500588 RPCinterceptor 链)
AiServicerproto ↔ domain 模型转换)
Service 层(同 HTTP
备课工作流FastAPI BackgroundTasks + Redis 状态存储24h TTL
安全层PIIRedactor + InputSanitizer + OutputModerator
用量UsageRecorderRedis→ KafkaProducer → edu.ai.usage topic
```
## 开发
```bash
# 安装依赖
uv sync
# 启动开发服务dev_mode=true 跳过 OTel exporter
DEV_MODE=true uv run uvicorn src.ai.main:app --reload --port 3008
# Lint
uv run ruff check src/
# 测试
uv run pytest
```
## HTTP API
| 方法 | 路径 | 权限 | 说明 |
|------|------|------|------|
| GET | /healthz | — | liveness |
| GET | /readyz | — | readiness含 LLM/gRPC/Provider 状态) |
| GET | /metrics | — | Prometheus 指标 |
| POST | /v1/ai/chat | ai:chat | 非流式聊天 |
| POST | /v1/ai/chat/stream | ai:chat | 流式聊天SSE |
| POST | /v1/ai/generate/question | ai:question:generate | 生成题目 |
| POST | /v1/ai/generate/question/stream | ai:question:generate | 流式生成题目SSE |
| POST | /v1/ai/optimize/expression | ai:expression:optimize | 优化表达 |
| POST | /v1/ai/lesson-plan/generate | ai:lesson:generate | 启动备课工作流 |
| GET | /v1/ai/lesson-plan/status/{workflow_id} | — | 查询工作流状态 |
| POST | /v1/ai/lesson-plan/confirm/{workflow_id} | ai:lesson:confirm | 教师确认入库 |
所有业务响应统一使用 ActionState 信封:`{success, data, error:{code, message, details?, traceId?}}`
降级采用方案 B总裁裁决 §2.6`success=true + error=null + data 内 degraded=true + degraded_reason`
## gRPC API端口 500588 RPC
| RPC | 请求 | 响应 |
|-----|------|------|
| Chat | ChatRequest | ChatResponse |
| StreamChat | ChatRequest | stream ChatChunk |
| GenerateQuestion | GenerateQuestionRequest | GeneratedQuestion |
| StreamGenerateQuestion | GenerateQuestionRequest | stream GeneratedQuestionChunk |
| OptimizeExpression | OptimizeExpressionRequest | OptimizedExpression |
| GenerateLessonPlan | GenerateLessonPlanRequest | LessonPlanResponse |
| GetLessonPlanStatus | GetLessonPlanStatusRequest | LessonPlanStatus |
| ConfirmLessonPlan | ConfirmLessonPlanRequest | ConfirmResult |
## 环境变量
| 变量 | 默认值 | 说明 |
|------|--------|------|
| http_port | 3008 | HTTP 端口 |
| grpc_port | 50058 | gRPC 端口 |
| dev_mode | false | 开发模式(跳过 OTel + 权限校验) |
| openai_api_key | — | OpenAI API 密钥 |
| anthropic_api_key | — | Anthropic API 密钥 |
| baichuan_api_key | — | 百川 API 密钥 |
| ollama_base_url | — | 本地 Ollama 地址 |
| llm_provider_priority | openai,anthropic,baichuan,local_ollama | Provider 故障切换顺序 |
| redis_url | redis://localhost:6379/0 | Redis 连接 |
| kafka_bootstrap_servers | localhost:9092 | Kafka 连接 |
| kafka_ai_usage_topic | edu.ai.usage | 用量事件 topic |
| otel_endpoint | http://localhost:4318 | OpenTelemetry OTLP 端点 |
## 限流(三维度)
| 维度 | 限制 | 算法 |
|------|------|------|
| user | 10 req/min | Redis Lua 令牌桶 |
| IP | 30 req/min | Redis Lua 令牌桶 |
| school | 100 req/min | Redis Lua 令牌桶 |
Redis 不可用时降级放行(记录警告)。
## 错误码
前缀 `AI_*`,完整 21 个错误码见 [02-architecture-design.md §6.2](docs/02-architecture-design.md)。