Spaces:
Sleeping
Sleeping
| ## AI Courseware 结构化 API 使用说明(前后端协作) | |
| 本说明基于《AI Courseware AI 接口文档 v1.0》,结合当前 Clare Courseware 实现,帮助前端与其他后端服务正确调用 AI 课程设计相关接口。 | |
| --- | |
| ### 1. 服务 Base URL 与部署 | |
| - 所有接口均由 Clare 后端 (`api/server.py`) 暴露。 | |
| - 部署在本地开发环境时: | |
| - Base URL 通常为 `http://localhost:8000` | |
| - 部署在 Hugging Face Space 或其他环境时: | |
| - 前端通过 Vite 环境变量 `VITE_API_BASE` 配置 Base URL | |
| - 例如:`VITE_API_BASE=https://your-space.hf.space` | |
| > 下文统一用 `{{BASE}}` 表示后端根地址(如 `http://localhost:8000`)。 | |
| --- | |
| ### 2. 路由概览 | |
| #### 2.1 现有 Clare Teacher/Courseware 接口(非结构化文本) | |
| 这些接口主要给当前 Clare 前端使用,返回 Markdown/文本: | |
| - `POST {{BASE}}/api/courseware/vision` | |
| - `POST {{BASE}}/api/courseware/activities` | |
| - `POST {{BASE}}/api/courseware/copilot` | |
| - `POST {{BASE}}/api/courseware/qa-optimize` | |
| - `POST {{BASE}}/api/courseware/content` | |
| 对应的前端封装函数在 `web/src/lib/api.ts` 中: | |
| - `apiCoursewareVision` | |
| - `apiCoursewareActivities` | |
| - `apiCoursewareCopilot` | |
| - `apiCoursewareQAOptimize` | |
| - `apiCoursewareContent` | |
| #### 2.2 新增 AI Courseware 结构化接口(建议给 LMS/独立前端用) | |
| 新路由前缀:`/ai/courseware`,在 `api/routes_courseware_ai.py` 中实现,返回结构化 JSON (`data + meta`): | |
| 1. **生成大纲草案** | |
| - `POST {{BASE}}/ai/courseware/syllabus/generate` | |
| 2. **生成单个模块的教学流程** | |
| - `POST {{BASE}}/ai/courseware/flow/generate` | |
| 3. **局部重构教学流程(Copilot)** | |
| - `POST {{BASE}}/ai/courseware/flow/regenerate-partial` | |
| 4. **生成/润色教案长文** | |
| - `POST {{BASE}}/ai/courseware/plan/detail/generate` | |
| 5. **生成反思看板数据** | |
| - `POST {{BASE}}/ai/courseware/reflection/generate` | |
| 6. **生成跨期改进提案** | |
| - `POST {{BASE}}/ai/courseware/improvement/generate` | |
| 所有成功响应都遵循统一包装: | |
| ```json | |
| { | |
| "data": { ... }, // 每个接口自己的数据结构 | |
| "meta": { | |
| "model": "gpt-4o", | |
| "model_version": null, | |
| "prompt_version": "v1.0", | |
| "temperature": 0.4, | |
| "tokens_used": 1234, | |
| "latency_ms": 5678 | |
| } | |
| } | |
| ``` | |
| `meta` 由后端统一生成,包含模型、Prompt 版本、token 消耗和延迟,便于监控。 | |
| --- | |
| ### 3. 前端 TypeScript 封装(`web/src/lib/api.ts`) | |
| 前端已经在 `web/src/lib/api.ts` 中提供了 6 个结构化接口的封装函数,可直接在 React 组件中调用。 | |
| #### 3.1 生成大纲草案 `apiAiSyllabusGenerate` | |
| ```ts | |
| import { | |
| apiAiSyllabusGenerate, | |
| type AiSyllabusGenerateReq, | |
| type AiSyllabusGenerateResp, | |
| } from "@/lib/api"; | |
| const req: AiSyllabusGenerateReq = { | |
| requestId: "req_cw_101", | |
| context: { | |
| courseName: "IST 345 Building Generative AI Application", | |
| learningOutcome: "Understand LLMs and build a RAG application", | |
| studentLevel: "BEGINNER", | |
| teachingFocus: "PRACTICE_ORIENTED", | |
| courseLength: 4, | |
| }, | |
| }; | |
| const resp: AiSyllabusGenerateResp = await apiAiSyllabusGenerate(req); | |
| // resp.data.syllabus -> Week 级别数组 | |
| // resp.meta -> 模型与性能信息 | |
| ``` | |
| #### 3.2 生成单个模块的教学流程 `apiAiFlowGenerate` | |
| ```ts | |
| import { | |
| apiAiFlowGenerate, | |
| type AiFlowGenerateReq, | |
| type AiFlowGenerateResp, | |
| } from "@/lib/api"; | |
| const req: AiFlowGenerateReq = { | |
| requestId: "req_cw_102", | |
| moduleContext: { | |
| title: "Introduction to Generative AI", | |
| learningObjectives: ["Understand basic LLM concepts"], | |
| topics: ["History of AI", "Transformer Architecture"], | |
| durationMinutes: 90, | |
| }, | |
| systemPrompts: ["(可选) 来自 Improve 阶段的长期提示"], | |
| }; | |
| const resp: AiFlowGenerateResp = await apiAiFlowGenerate(req); | |
| // resp.data.steps -> 每个 step 含 type/title/estimated_duration/ai_understanding | |
| ``` | |
| #### 3.3 局部重构教学流程 `apiAiFlowRegeneratePartial` | |
| ```ts | |
| import { | |
| apiAiFlowRegeneratePartial, | |
| type AiFlowPartialReq, | |
| type AiFlowPartialResp, | |
| } from "@/lib/api"; | |
| const req: AiFlowPartialReq = { | |
| requestId: "req_cw_103", | |
| prompt: "Split the 30-min explanation into two shorter parts with a quiz in between.", | |
| currentFlow: { | |
| lockedSteps: [{ id: "step_1", title: "Welcome", duration: 15 }], | |
| unlockedSteps: [{ id: "step_2", title: "Heavy Explanation", duration: 30 }], | |
| }, | |
| }; | |
| const resp: AiFlowPartialResp = await apiAiFlowRegeneratePartial(req); | |
| // resp.data.explanation -> Copilot 气泡文案 | |
| // resp.data.proposedSteps -> 用于替换 unlockedSteps 的新步骤 | |
| ``` | |
| #### 3.4 教案长文 `apiAiPlanDetailGenerate` | |
| ```ts | |
| import { | |
| apiAiPlanDetailGenerate, | |
| type AiPlanDetailReq, | |
| type AiPlanDetailResp, | |
| } from "@/lib/api"; | |
| const req: AiPlanDetailReq = { | |
| requestId: "req_cw_104", | |
| finalizedSteps: stepsArray, // 来自 Flow 阶段确定的完整 steps | |
| }; | |
| const resp: AiPlanDetailResp = await apiAiPlanDetailGenerate(req); | |
| // resp.data.sections -> 多个 section(Lesson Objectives / Content 等),content 支持 Markdown | |
| ``` | |
| #### 3.5 反思看板 `apiAiReflectionGenerate` | |
| ```ts | |
| import { | |
| apiAiReflectionGenerate, | |
| type AiReflectionReq, | |
| type AiReflectionResp, | |
| } from "@/lib/api"; | |
| const req: AiReflectionReq = { | |
| requestId: "req_cw_105", | |
| teachAnnotations: [ | |
| { | |
| category: "NEEDS_MORE_TIME", | |
| selectedText: "Gradient Descent", | |
| feedback: "Students were confused by the math", | |
| }, | |
| ], | |
| quizAggregations: { | |
| averageScore: 72, | |
| lowestTopic: "Matrix Operations", | |
| }, | |
| }; | |
| const resp: AiReflectionResp = await apiAiReflectionGenerate(req); | |
| // resp.data.understanding / engagement / difficulty / misconceptions / nextLessonSuggestions | |
| ``` | |
| #### 3.6 改进提案 `apiAiImprovementGenerate` | |
| ```ts | |
| import { | |
| apiAiImprovementGenerate, | |
| type AiImprovementReq, | |
| type AiImprovementResp, | |
| } from "@/lib/api"; | |
| const req: AiImprovementReq = { | |
| requestId: "req_cw_106", | |
| reflectionReports: previousReflectionReports, // 来自 2.5 的历史数据数组 | |
| }; | |
| const resp: AiImprovementResp = await apiAiImprovementGenerate(req); | |
| // resp.data.proposals -> 每条包含 title/priority/affectedWeeks/evidence/rootCause/proposedSolution/expectedImpact | |
| ``` | |
| --- | |
| ### 4. 后端如何配置 OpenAI 模型(固定为 gpt‑4o) | |
| 后端 `api/config.py` 使用环境变量 `CLARE_DEFAULT_MODEL` 控制默认模型: | |
| ```python | |
| DEFAULT_MODEL = (os.getenv("CLARE_DEFAULT_MODEL") or "gpt-4.1-mini").strip() | |
| ``` | |
| 在 Hugging Face Space(或其他部署环境)中: | |
| - 打开 **Settings → Variables and secrets** | |
| - 设置: | |
| ```text | |
| CLARE_DEFAULT_MODEL = gpt-4o | |
| ``` | |
| 这样,上述所有 `/ai/courseware/...` 接口默认都会使用 `gpt-4o`,同时 `meta.model` 字段会反映真实模型名称,便于前端或监控系统做统计。 | |
| --- | |
| ### 5. 错误处理约定 | |
| - 若 OpenAI 调用失败:后端返回 `500`,`detail` 内含错误信息。 | |
| - 若 LLM 返回的内容不是合法 JSON 或缺少关键字段: | |
| - 返回 `422 INVALID_GENERATION`,`detail` 会说明缺失的字段或解析失败原因。 | |
| - 前端封装函数(`apiAi*` 系列)若收到非 2xx,会抛出 `Error`,错误信息来源: | |
| - `data.error` / `data.detail` / `data.message` / 自定义 fallback。 | |
| 前端在捕获异常时可以统一提示“AI 生成失败,请稍后重试”,并记录 `requestId` 以便后端排查。 | |