diff --git a/docs/troubleshooting/known-issues.md b/docs/troubleshooting/known-issues.md index 5d52548..14ec0a3 100644 --- a/docs/troubleshooting/known-issues.md +++ b/docs/troubleshooting/known-issues.md @@ -444,28 +444,30 @@ ### 2.9 ai(Python/FastAPI,P5) -| 场景 | 技术/规则 | -| ------------------------- | ------------------------------------------------------------------------------------------------------------------ | -| LLM Provider 适配 | 4 适配器(OpenAI/Anthropic/Baichuan/Ollama)+ ProviderFailoverChain + CircuitBreaker(3 次失败 60s 熔断) | -| 降级模式方案 B | success=true + error=null + data 内 degraded=true + degraded_reason(总裁 §2.6,非顶层 degraded 字段) | -| ActionState 信封 | 所有 HTTP 响应统一 `{success, data, error:{code,message,details?,traceId?}}`(004 §11.5 强制) | -| 路由前缀 | /v1/ai 前缀(APIRouter prefix="/v1/ai"),Gateway 代理 /api/v1/ai/* → /v1/ai/* | -| gRPC server | grpc.aio 端口 50058,8 RPC + 3 interceptor(Logging/Auth/Error) | -| 评估三道防线 | RuleValidator(JSON/字段/难度校验)→ LLMJudge(语义评分)→ QualityGate(综合决策门控) | -| 备课工作流 | P5 用 asyncio.create_task + Redis 状态存储(24h TTL),P6+ 评估 Temporal | -| 工作流状态机 | pending→analyzing→generating→pending_review→persisted/failed,生成失败重试最多 3 次 | -| 限流三维度 | user 10/min + IP 30/min + school 100/min,Redis Lua 原子令牌桶,Redis 不可用降级放行 | -| 用量记录 | Redis INCRBY 按 user/school/month 维度,35 天过期;Kafka 发布 AIUsageEvent 到 edu.ai.usage topic | -| Kafka 派生数据豁免 Outbox | AIUsageEvent 为派生数据,004 §12.2 豁免 Outbox,直接 aiokafka producer(事务性 + 幂等) | -| 安全层全本地 | PIIRedactor(5 类 PII 正则脱敏)+ InputSanitizer(prompt injection 检测)+ OutputModerator(5 类敏感内容审核) | -| 六边形架构端口模式 | ContentClient/DataAnaClient/IamClient 均为抽象接口 + Mock + gRPC 实现,全并行模式用 Mock | -| 权限校验 | PermissionGuard 5 权限点(ai:chat / ai:question:generate / ai:expression:optimize / ai:lesson:generate / confirm) | -| dev_mode tracer | dev_mode=true 时跳过 OTel exporter 初始化 + 跳过权限校验 | -| proto 包名 | 保持 `next_edu_cloud..v1`(coord G17 裁决覆盖 project_rules §5) | -| proto_gen 排除 ruff | pyproject.toml `[tool.ruff] exclude = ["src/ai/proto_gen"]`,自动生成文件不参与 lint | -| ruff UP017 | `datetime.now(timezone.utc)` 改用 `datetime.now(datetime.UTC)` 别名(Python 3.12+) | -| ruff SIM103/SIM110 | `if x: return False; return True` 改 `return not x`;for 循环改 `all()` 表达式 | -| PowerShell 不支持 && | RunCommand 用 cwd 参数指定工作目录,不用 `cd ... && uv run` | +| 场景 | 技术/规则 | +| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| LLM Provider 适配 | 4 适配器(OpenAI/Anthropic/Baichuan/Ollama)+ ProviderFailoverChain + CircuitBreaker(3 次失败 60s 熔断) | +| 降级模式方案 B | success=true + error=null + data 内 degraded=true + degraded_reason(总裁 §2.6,非顶层 degraded 字段) | +| ActionState 信封 | 所有 HTTP 响应统一 `{success, data, error:{code,message,details?,traceId?}}`(004 §11.5 强制) | +| 路由前缀 | /v1/ai 前缀(APIRouter prefix="/v1/ai"),Gateway 代理 /api/v1/ai/* → /v1/ai/* | +| gRPC server | grpc.aio 端口 50058,9 RPC + 3 interceptor(Logging/Auth/Error) | +| 评估三道防线 | RuleValidator(JSON/字段/难度校验)→ LLMJudge(语义评分)→ QualityGate(综合决策门控) | +| 备课工作流 | P5 用 asyncio.create_task + Redis 状态存储(24h TTL),P6+ 评估 Temporal | +| 工作流状态机 | pending→analyzing→generating→pending_review→persisted/failed,生成失败重试最多 3 次 | +| 限流三维度 | user 10/min + IP 30/min + school 100/min,Redis Lua 原子令牌桶,Redis 不可用降级放行 | +| 用量记录 | Redis INCRBY 按 user/school/month 维度,35 天过期;Kafka 发布 AIUsageEvent 到 edu.ai.usage topic | +| Kafka 派生数据豁免 Outbox | AIUsageEvent 为派生数据,004 §12.2 豁免 Outbox,直接 aiokafka producer(事务性 + 幂等) | +| 安全层全本地 | PIIRedactor(5 类 PII 正则脱敏)+ InputSanitizer(prompt injection 检测)+ OutputModerator(5 类敏感内容审核) | +| 六边形架构端口模式 | ContentClient/DataAnaClient/IamClient 均为抽象接口 + Mock + gRPC 实现,全并行模式用 Mock | +| 权限校验 | PermissionGuard 6 权限点(ai:chat / ai:question:generate / ai:expression:optimize / ai:lesson:generate / confirm / ai:report:generate) | +| dev_mode tracer | dev_mode=true 时跳过 OTel exporter 初始化 + 跳过权限校验 | +| proto 包名 | 保持 `next_edu_cloud..v1`(coord G17 裁决覆盖 project_rules §5) | +| proto_gen 排除 ruff | pyproject.toml `[tool.ruff] exclude = ["src/ai/proto_gen"]`,自动生成文件不参与 lint | +| ruff UP017 | `datetime.now(timezone.utc)` 改用 `datetime.now(datetime.UTC)` 别名(Python 3.12+) | +| ruff SIM103/SIM110 | `if x: return False; return True` 改 `return not x`;for 循环改 `all()` 表达式 | +| PowerShell 不支持 && | RunCommand 用 cwd 参数指定工作目录,不用 `cd ... && uv run` | +| Markdown 章节关键词提取 | `_extract_recommendations` 仅匹配 `#` 开头的标题行或纯文本标题行,避免列表项自身含「建议」关键词被误判为章节标题 | +| main.py 模块级变量顺序 | ReportService 依赖 DataAnaClientGrpc,必须在 `_data_ana_client` 定义后实例化,否则 NameError | ### 2.10 shared-proto(契约包)