ClareCourseWare / docs /AI_COURSEWARE_API_USAGE.md
claudqunwang's picture
Add structured AI courseware APIs
2a4f012
## 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` 以便后端排查。