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

所有成功响应都遵循统一包装:

{
  "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

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

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

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

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

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

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 控制默认模型:

DEFAULT_MODEL = (os.getenv("CLARE_DEFAULT_MODEL") or "gpt-4.1-mini").strip()

在 Hugging Face Space(或其他部署环境)中:

  • 打开 Settings → Variables and secrets
  • 设置:
CLARE_DEFAULT_MODEL = gpt-4o

这样,上述所有 /ai/courseware/... 接口默认都会使用 gpt-4o,同时 meta.model 字段会反映真实模型名称,便于前端或监控系统做统计。


5. 错误处理约定

  • 若 OpenAI 调用失败:后端返回 500detail 内含错误信息。
  • 若 LLM 返回的内容不是合法 JSON 或缺少关键字段:
    • 返回 422 INVALID_GENERATIONdetail 会说明缺失的字段或解析失败原因。
  • 前端封装函数(apiAi* 系列)若收到非 2xx,会抛出 Error,错误信息来源:
    • data.error / data.detail / data.message / 自定义 fallback。

前端在捕获异常时可以统一提示“AI 生成失败,请稍后重试”,并记录 requestId 以便后端排查。