Files
Edu/services/ai
SpecialX 81a539b9ab
Some checks failed
CI / quality-ts (push) Failing after 6s
CI / quality-go (push) Failing after 25s
CI / quality-proto (push) Failing after 6s
CI / deploy (push) Has been skipped
chore(deps): 统一依赖管理 - pnpm 11 + node:22 + golang:1.25 + python:3.12 + shared-* 集中化
- Node.js 统一到 node:22-alpine,Go 统一到 golang:1.25-alpine,Python 统一到 python:3.12-slim

- pnpm 升级到 11.13.0(corepack),新增 allowBuilds 白名单解决 ERR_PNPM_IGNORED_BUILDS

- 新增 packages/shared-py 集中 Python 共享依赖,shared-ts 补充 graphql-yoga/prom-client

- api-gateway 修复 go.mod 的 shared-go 依赖 + Dockerfile 改用 repo 根作 context

- Python 服务(data-ana/ai)Dockerfile 改用 repo 根作 context + 声明 uv workspace sources

- 16 个服务的 Dockerfile + CI + docker-compose.tools.yml 全部对齐版本矩阵

- known-issues.md 沉淀 9 条 pnpm 11 / uv workspace / Go shared-go 迁移经验

- 验证:4 服务完全成功(api-gateway /healthz 200),其余 install 成功(build 失败为预存 TS 错误)
2026-07-14 12:04:49 +08:00
..
2026-07-10 18:57:39 +08:00
2026-07-10 18:57:39 +08:00
2026-07-10 18:57:39 +08:00

AI 网关服务

版本:1.0(P5 完整实现) 端口: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-settings(12-factor 配置)
  • grpc.aio(gRPC server 8 RPC + client 拦截器)
  • aiokafka(用量事件发布,事务性 + 幂等,派生数据豁免 Outbox)
  • Jinja2 + YAML(Prompt 模板渲染)
  • redis(限流令牌桶 + 用量记录 + 工作流状态存储)
  • OpenTelemetry(HTTP + gRPC 链路追踪)
  • prometheus-client + structlog(指标 + 结构化日志)

架构分层

HTTP 端点(/v1/ai 前缀,ActionState 信封)
    ↓
PermissionGuard(权限校验)→ RateLimiter(三维度令牌桶)
    ↓
Service 层(ChatService / QuestionService / ExpressionService / LessonPlanWorkflowService)
    ↓
LLM ProviderFailoverChain(4 适配器 + CircuitBreaker)
    ↓
LLM Provider(OpenAI / Anthropic / Baichuan / LocalOllama)

gRPC server(端口 50058,8 RPC,interceptor 链)
    ↓
AiServicer(proto ↔ domain 模型转换)
    ↓
Service 层(同 HTTP)

备课工作流:FastAPI BackgroundTasks + Redis 状态存储(24h TTL)
安全层:PIIRedactor + InputSanitizer + OutputModerator
用量:UsageRecorder(Redis)→ KafkaProducer → edu.ai.usage topic

开发

# 安装依赖
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(端口 50058,8 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。