AI 模块审计报告
审计范围:项目中所有与 AI(人工智能)相关的代码,包括底层 SDK 封装、Provider 管理、各业务模块(备课、错题集、试卷、改题等)中的 AI 集成点。
审计日期:2026-06-23
审计依据:docs/architecture/004_architecture_impact_map.md、docs/architecture/005_architecture_data.json、docs/standards/coding-standards.md
一、现有实现概要
1.1 文件分布
AI 相关代码当前未形成独立模块,而是分散在 5 个不同位置:
| 位置 |
文件 |
行数 |
职责 |
src/shared/lib/ai/ |
api-key-crypto.ts |
28 |
AES-256-GCM 加密 API Key |
src/shared/lib/ai/ |
client.ts |
58 |
OpenAI SDK 封装,创建 chat completion |
src/shared/lib/ai/ |
errors.ts |
8 |
错误消息格式化 |
src/shared/lib/ai/ |
payload-parser.ts |
78 |
请求负载解析与 Zod 守卫 |
src/shared/lib/ai/ |
provider-config.ts |
61 |
从 ai_providers 表查询 Provider 配置 |
src/shared/lib/ai/ |
index.ts |
5 |
聚合导出 |
src/shared/lib/ai.ts |
— |
9 |
向后兼容重导出 |
src/app/api/ai/chat/ |
route.ts |
42 |
AI 聊天 REST API 端点 |
src/modules/exams/ai-pipeline/ |
parse.ts |
426 |
Zod schema、JSON 提取修复、提示词 |
src/modules/exams/ai-pipeline/ |
request.ts |
306 |
AI 请求构造与发送 |
src/modules/exams/ai-pipeline/ |
structure.ts |
209 |
结构生成与预览/草稿转换 |
src/modules/exams/ai-pipeline/ |
index.ts |
172 |
高层编排 |
src/modules/lesson-preparation/ |
actions-ai.ts |
44 |
知识点推荐 Server Action |
src/modules/lesson-preparation/ |
ai-suggest.ts |
65 |
知识点推荐 AI 逻辑 |
src/modules/settings/ |
actions.ts(部分) |
~183 |
AI Provider CRUD Action |
src/modules/settings/ |
data-access.ts(部分) |
— |
ai_providers 表查询 |
src/modules/exams/components/ |
exam-ai-generator.tsx |
224 |
AI 出题 UI 组件 |
1.2 数据流
1.3 架构图记录情况
005_architecture_data.json 中 modules 节点未将 AI 列为独立模块。
- 仅在
dbTables.aiProviders 中记录 usedBy: ["settings", "ai"],但 ai 并非真实存在的模块。
shared 模块下记录了 lib/ai/* 工具函数(createAiChatCompletion、parseAiChatPayload 等)。
exams 模块下记录了 ai-pipeline 子目录的导出函数。
lessonPreparation 模块下记录了 suggestKnowledgePointsAction。
- 结论:架构图对 AI 模块的记录不完整,未反映 AI 作为横切关注点的全貌,也未记录
app/api/ai/chat/route.ts 端点。
1.4 权限点
| 权限常量 |
值 |
用途 |
AI_CHAT |
ai:chat |
使用 AI 聊天 |
AI_CONFIGURE |
ai:configure |
配置 AI Provider |
EXAM_AI_GENERATE |
exam:ai_generate |
AI 出题 |
二、现存问题与原因分析
2.1 架构分层问题
问题 2.1.1:AI 未形成独立模块,逻辑分散在 5 处
- 位置:
shared/lib/ai/、app/api/ai/chat/、modules/exams/ai-pipeline/、modules/lesson-preparation/ai-suggest.ts、modules/settings/
- 原因:AI 能力是按业务需求逐步添加的,每次新增场景都在调用方就地实现,未抽象为独立模块。
- 后果:AI 逻辑无法统一治理(限流、监控、成本控制、Prompt 版本管理);新增 AI 场景需要重复编写请求构造与错误处理;测试时无法 Mock AI 层。
- 违反规则:
项目规则 → 架构分层规则 → 模块标准结构(AI 应作为 modules/ai/ 独立模块存在)。
问题 2.1.2:AI 聊天使用 REST API 路由而非 Server Action
- 位置:route.ts
- 原因:早期实现选择了 REST 路由,未遵循项目 Server Action 统一规范。
- 后果:与项目其他数据操作风格不一致;无法复用
ActionState<T> 返回类型与 useActionMutation Hook;权限校验绕过了 requirePermission() 体系。
- 违反规则:
项目规则 → Server Action 规范(所有数据操作应通过 Server Action,返回 ActionState<T>)。
问题 2.1.3:lesson-preparation/ai-suggest.ts 跨模块直接依赖
- 位置:ai-suggest.ts
- 现状:直接
import { getKnowledgePointsByTextbookId, getKnowledgePointsByChapterId } from "@/modules/textbooks/data-access"。
- 判定:模块间通过对方 data-access 通信符合规则,但 AI 推荐逻辑本身应属于 AI 模块,而非备课模块。当前
ai-suggest.ts 混合了"AI 调用"与"知识点候选获取"两个职责。
- 后果:若其他模块也需要"基于文本推荐知识点",无法复用。
- 违反规则:
项目规则 → 架构分层规则(职责划分不清)。
2.2 权限问题
问题 2.2.1:AI 聊天端点缺少 requirePermission() 校验
- 位置:route.ts:15-18
- 现状:仅检查
session?.user?.id 是否存在,未调用 requirePermission(Permissions.AI_CHAT)。
- 后果:任何已登录用户(包括学生)都能无限制调用 AI 聊天,绕过了角色权限体系;无法按角色限制 AI 使用场景。
- 违反规则:
项目规则 → Server Action 规范 → 每个 Action 必须调用 requirePermission();项目规则 → 安全规范。
问题 2.2.2:AI 出题管线内部无权限二次校验
- 位置:
exams/ai-pipeline/index.ts 的 generateAiCreateDraftFromSource
- 现状:依赖调用方 Action 校验权限,管线本身不校验。
- 后果:若未来有新调用方忘记校验,将导致越权调用 AI。
- 违反规则:
项目规则 → 安全规范 → Server Action 二次校验。
2.3 国际化问题
问题 2.3.1:exam-ai-generator.tsx 大量硬编码文本
- 位置:exam-ai-generator.tsx
- 硬编码中文:第 118 行"新建配置"、第 164 行"加入后台队列(运行 ${...}/3,排队 ${...})"、第 167 行"立即预览"/"Generating..."、第 192 行"后台生成记录"、第 202-207 行"排队中"/"生成中"/"已完成"/"失败:..."、第 211 行"打开预览"。
- 硬编码英文:第 92 行"AI Generation"、第 93-95 行描述、第 104 行"AI Provider"、第 122-124 行对话框标题、第 144 行"Loading providers..."/"Select provider"、第 156 行描述、第 175 行"Source Exam Text"、第 178 行 placeholder、第 184 行描述。
- 后果:无法切换语言;违反 i18n 就绪要求。
- 违反规则:
项目规则 → 所有用户可见文本必须适配 i18n。
问题 2.3.2:AI 管线内部硬编码中文错误消息
- 位置:request.ts:152 "请先粘贴试卷文本"、第 172 行"试卷文本校验失败,请重试"、第 177 行"识别为乱码或混乱文本..."。
- 后果:错误消息无法国际化。
- 违反规则:
项目规则 → i18n。
问题 2.3.3:无独立 ai.json 翻译文件
- 现状:AI 相关翻译散落在
settings.json(Provider 管理)和 lesson-preparation.json(error.aiSuggest),无统一命名空间。
- 后果:AI 文本难以维护与查找。
2.4 类型安全问题
问题 2.4.1:ai-suggest.ts 使用 as 断言
- 位置:ai-suggest.ts:54
- 代码:
JSON.parse(jsonMatch[0]) as { id: string; name: string; reason: string }[]
- 后果:AI 返回的 JSON 结构不可信,直接断言可能导致运行时错误。
- 违反规则:
项目规则 → TypeScript 规则 → 禁止 as 断言。
问题 2.4.2:actions-ai.ts 双重断言
- 位置:actions-ai.ts:34
- 代码:
parsed.data.doc as unknown as LessonPlanDocument
- 后果:绕过类型系统,不安全。
- 违反规则:
项目规则 → TypeScript 规则 → 禁止 as 断言。
2.5 错误处理问题
问题 2.5.1:ai-suggest.ts 静默吞掉错误
- 位置:ai-suggest.ts:50-64
- 现状:
try { JSON.parse(...) } catch { return [] } — JSON 解析失败时静默返回空数组。
- 后果:教师无法区分"AI 未推荐任何知识点"与"AI 返回格式错误";无法排查问题。
- 违反规则:
项目规则 → 错误处理。
问题 2.5.2:无 AI 专用 Error Boundary
- 现状:AI 组件(如
exam-ai-generator)未用 Error Boundary 包裹。
- 后果:AI 调用失败可能导致整个页面崩溃。
- 违反规则:审计要求 → 每个独立数据区块必须用 React Error Boundary 包裹。
问题 2.5.3:无 Suspense/骨架屏
- 现状:AI 异步操作仅用
loading 布尔值切换按钮文字,无骨架屏。
- 后果:用户体验差,无法感知加载进度。
2.6 可复用性问题
问题 2.6.1:无可复用 AI 组件
- 现状:
- AI Provider 选择器硬编码在
exam-ai-generator.tsx 内部,无法在其他模块复用。
- 无通用 AI 聊天面板组件。
- 无通用 AI 建议加载器组件。
- 无通用 AI 结果预览组件。
- 后果:每个需要 AI 的模块都要从零实现 UI。
- 违反规则:审计要求 → 最大化复用。
问题 2.6.2:无 AI 服务接口抽象
- 现状:所有模块直接
import { createAiChatCompletion } from "@/shared/lib/ai"。
- 后果:无法 Mock AI 服务进行单测;无法切换 AI 实现(如本地 mock、不同 SDK)。
- 违反规则:审计要求 → 完全解耦、可测试性。
2.7 功能缺失问题
问题 2.7.1:错题集无 AI 集成
- 现状:
error-book 模块仅有 SM2 间隔复习算法,无 AI 能力。
- 缺失功能:
- AI 相似题推荐(根据错题生成同类练习)
- AI 薄弱点分析(根据错题分布分析学生薄弱知识点)
- AI 解题思路生成(为错题生成分步骤解析)
- AI 复习计划建议(基于错题掌握度智能调整复习节奏)
- 后果:错题本仅是静态记录,无法发挥 AI 的个性化学习价值。
问题 2.7.2:改题(作业批改)无 AI 集成
- 现状:
homework-grading-view.tsx 仅支持手动评分与自动判分(选择题),无 AI 辅助。
- 缺失功能:
- AI 辅助批改主观题(简答题/论述题)
- AI 生成评分反馈建议
- AI 批改一致性校验(检测人工评分偏差)
- 后果:教师批改主观题负担重,效率低。
问题 2.7.3:备课 AI 能力单一
- 现状:
lesson-preparation 仅有"知识点推荐"一个 AI 功能。
- 缺失功能:
- AI 生成教学活动设计
- AI 生成课堂提问
- AI 生成形成性评估
- AI 生成差异化教学建议
- 后果:AI 价值未充分释放。
问题 2.7.4:试卷 AI 无题目变体与智能组卷
- 现状:
exams/ai-pipeline 仅支持"从文本解析生成试卷"。
- 缺失功能:
- AI 生成题目变体(基于已有题目生成同知识点不同表述的变体)
- AI 智能组卷(根据知识点覆盖、难度分布自动组卷)
- AI 难度分析(预测题目难度)
- 后果:AI 出题场景受限。
2.8 性能与监控问题
问题 2.8.1:无流式响应
- 现状:所有 AI 调用等待完整响应才返回。
- 后果:长文本生成时用户体验差(等待 10-30 秒)。
- 违反规则:审计要求 → 性能:支持流式渲染。
问题 2.8.2:无 AI 使用监控
- 现状:无 AI 调用埋点、无成本统计、无延迟监控、无错误率监控。
- 后果:无法优化 AI 使用策略,无法发现异常调用。
- 违反规则:审计要求 → 监控:预留关键操作埋点接口。
2.9 可访问性问题
问题 2.9.1:AI 组件缺少 ARIA 属性
- 位置:
exam-ai-generator.tsx 的后台任务列表无 aria-live,屏幕阅读器无法感知状态变化。
- 违反规则:审计要求 → a11y:ARIA 属性。
三、行业差距对比
3.1 与优秀 K12 产品的差距
| 能力 |
行业主流做法 |
当前状态 |
差距影响 |
| AI 助手入口 |
全局悬浮按钮/侧边栏,可从任何页面唤起 AI 助手 |
无全局入口,仅嵌入特定页面 |
用户无法在需要时随时获取 AI 帮助 |
| 上下文感知 |
AI 助手自动感知当前页面上下文(如正在批改的作业) |
无上下文感知 |
AI 建议不精准,需用户手动输入上下文 |
| 流式输出 |
AI 回复逐字流式显示 |
等待完整响应 |
长文本等待体验差 |
| 错题 AI 推荐 |
根据错题自动生成同类练习题,支持"再练一题" |
无此功能 |
学生无法针对性巩固薄弱点 |
| AI 辅助批改 |
主观题 AI 预评分 + 教师确认 |
无此功能 |
教师批改负担重 |
| 学习路径推荐 |
AI 根据错题与掌握度生成个性化学习路径 |
无此功能 |
缺少个性化学习引导 |
| AI 内容安全 |
学生侧 AI 输出经过内容过滤 |
无过滤机制 |
学生可能接触不当内容 |
| AI 使用历史 |
用户可查看自己的 AI 对话历史 |
无此功能 |
无法回顾 AI 建议结果 |
| 多 Provider 对比 |
同一 Prompt 可对比不同模型输出 |
仅支持选择单一 Provider |
无法评估最优模型 |
| Prompt 版本管理 |
Prompt 模板可配置化、版本化 |
Prompt 硬编码在代码中 |
调整 Prompt 需改代码发版 |
3.2 多角色体验差距
| 角色 |
期望的 AI 能力 |
当前状态 |
| 教师 |
备课内容生成、出题辅助、批改辅助、学情分析 |
仅有知识点推荐 + 试卷解析 |
| 学生 |
错题相似题推荐、解题思路、学习路径 |
无任何 AI 能力 |
| 家长 |
子女学情 AI 摘要、辅导建议 |
无任何 AI 能力 |
| 管理员 |
AI 使用统计、成本监控 |
无任何 AI 能力 |
四、改进优先级建议
P0(紧急,影响安全与基础架构)
| 编号 |
问题 |
改进方向 |
| P0-1 |
AI 聊天端点缺少权限校验 |
改造为 Server Action,添加 requirePermission(AI_CHAT) |
| P0-2 |
AI 未形成独立模块 |
创建 src/modules/ai/,将分散的 AI 逻辑统一收口 |
| P0-3 |
exam-ai-generator.tsx 硬编码文本 |
提取 i18n 键,创建 ai.json 翻译文件 |
| P0-4 |
AI 管线硬编码错误消息 |
通过 Server Action 层返回 i18n 错误键 |
| P0-5 |
ai-suggest.ts 使用 as 断言 |
用 Zod schema 校验 AI 返回 |
P1(重要,影响功能完整性与可维护性)
| 编号 |
问题 |
改进方向 |
| P1-1 |
无 AI 服务接口抽象 |
定义 AiService 接口,通过 React Context 注入 |
| P1-2 |
无可复用 AI 组件 |
抽象 AiChatPanel、AiProviderSelector、AiSuggestionCard、AiErrorBoundary |
| P1-3 |
无 AI Error Boundary |
创建 AiErrorBoundary 包裹所有 AI 区块 |
| P1-4 |
错题集无 AI 集成 |
新增相似题推荐、薄弱点分析 Server Action |
| P1-5 |
改题无 AI 集成 |
新增 AI 辅助批改 Action |
| P1-6 |
无 AI 使用监控 |
预留 trackAiUsage() 埋点接口 |
| P1-7 |
备课 AI 能力单一 |
新增内容生成、活动建议 Action |
P2(优化,提升体验与扩展性)
| 编号 |
问题 |
改进方向 |
| P2-1 |
无流式响应 |
支持 SSE 流式输出 |
| P2-2 |
无 AI 对话历史 |
持久化用户 AI 对话记录 |
| P2-3 |
Prompt 硬编码 |
抽取为可配置 Prompt 模板 |
| P2-4 |
试卷 AI 无变体生成 |
新增题目变体生成 Action |
| P2-5 |
无多 Provider 对比 |
支持并行调用多 Provider 对比 |
| P2-6 |
无内容安全过滤 |
学生侧 AI 输出添加内容过滤 |
| P2-7 |
架构图未记录 AI 模块 |
同步更新 004/005 文档 |
五、架构图同步说明
本次审计发现架构图存在以下遗漏与不一致,需在实现后同步更新:
5.1 需新增的节点
| 文档 |
节点路径 |
内容 |
005_architecture_data.json |
modules.ai |
新增 AI 模块定义:path、description、exports(AiService 接口、Actions、组件) |
005_architecture_data.json |
modules.ai.exports.functions |
createAiChatAction、suggestSimilarQuestionsAction、suggestGradingAction、generateLessonContentAction、generateQuestionVariantAction |
005_architecture_data.json |
modules.ai.exports.components |
AiChatPanel、AiProviderSelector、AiSuggestionCard、AiErrorBoundary |
005_architecture_data.json |
modules.ai.exports.hooks |
useAiChat、useAiSuggestion |
005_architecture_data.json |
dependencyMatrix.ai |
ai → shared、ai → settings(data-access);exams/lesson-preparation/error-book/homework → ai |
004_architecture_impact_map.md |
模块清单 |
新增"AI 模块"章节 |
004_architecture_impact_map.md |
文件清单 |
新增 modules/ai/ 下所有文件 |
5.2 需修改的节点
| 文档 |
节点 |
修改内容 |
005_architecture_data.json |
dbTables.aiProviders.usedBy |
从 ["settings", "ai"] 改为 ["ai"](AI 模块收口后由 AI 模块负责) |
005_architecture_data.json |
modules.shared.exports |
标注 lib/ai/* 为"底层 SDK 封装,业务层应调用 modules/ai" |
005_architecture_data.json |
modules.exams.ai-pipeline |
标注依赖关系变更为"通过 ai 模块服务调用" |
005_architecture_data.json |
routes |
移除 app/api/ai/chat/route.ts(改造为 Server Action 后删除) |
004_architecture_impact_map.md |
调用链路图 |
更新 AI 调用链路:业务模块 → ai/actions → ai/services → shared/lib/ai |
5.3 需删除的节点
| 文档 |
节点 |
原因 |
005_architecture_data.json |
routes./api/ai/chat |
改造为 Server Action 后该 REST 路由删除 |
六、重构方案设计(概要)
详细实现见代码提交,此处仅列出设计要点。
6.1 模块结构
6.2 依赖注入
6.3 i18n 结构
6.4 配置驱动