EduForge AI API 文档
本文档面向学校平台研发团队、运维人员与集成合作方,完整说明 EduForge AI 的鉴权方式、请求与响应信封、异步任务模型、资源与教材接口、管理员治理接口、文件与图片资产规则、错误码、环境变量和部署注意事项。
概览
默认 API 基址为 http://localhost:8000。所有业务接口统一返回 JSON 响应信封;生成类接口采用“提交任务 + 查询状态 / SSE 订阅”的异步模型;资源和教材接口则提供同步查询能力,适合工作台页面和校内平台直接接入。
平台支持两类主要调用身份:一类是登录工作台后的教师或管理员,通过 Bearer Token 调用;另一类是第三方系统或自动化服务,通过 X-API-Key 调用。当前公开资源列表不要求鉴权,但工作台生成和管理员治理接口必须校验身份。
从路由组织方式看,接口按业务域划分为认证、生成、资源、教材和管理员治理五大类。集成时建议把“读取元数据”和“触发生成任务”视作两套不同能力:前者偏同步查询,后者偏异步编排,这样更容易在校内平台中设计稳定的交互链路。
对于正式接入,推荐采用统一的错误处理与日志策略:浏览器侧和第三方系统都应首先校验 success,再结合 message、data 或 detail 字段判断后续分支;对异步任务则必须记录 job_id,以便后续查询、审计和问题定位。
响应信封
所有接口统一采用三段式响应结构:
{
"success": true,
"message": "任务状态",
"data": { ... }
}其中 success 表示调用是否成功,message 提供当前响应语义,data 存放业务数据。对于校内平台集成而言,推荐始终先判断 success,再按 message 和 data 做业务分流。
需要注意的是,校验失败、权限不足或对象不存在等异常场景可能由 FastAPI 直接返回 detail 字段,而不是 success/message/data 结构。因此调用方应同时兼容两类返回体,而不是假定所有错误都落在同一信封中。
{
"detail": "章节不存在"
}鉴权方式
Authorization: Bearer <access_token>
X-API-Key: efa_xxxxxxxxxxxxxxxxxxxxxxxxBearer Token 适用于教师和管理员在工作台中的请求,由 /api/v1/auth/login 和 /api/v1/auth/register 返回。X-API-Key 适用于自动化系统、校内服务中台或脚本工具,可通过 /api/v1/auth/api-key/regenerate 更新。
当前注册接口会默认创建教师角色账号,并为其生成 API Key。管理员接口则要求管理员身份,因此如果第三方系统需要调用治理能力,建议通过受控后台或中间服务代理,而不是直接暴露管理员凭证。
curl -X POST http://localhost:8000/api/v1/auth/login -H "Content-Type: application/json" -d '{
"email": "teacher@example.com",
"password": "your_password"
}'核心数据模型
平台的核心模型包括用户、生成任务、资源、教材版本和章节。用户包含 role、plan、api_key 等字段;生成任务包含 job_id、status、progress、result_url、result_metadata 和 error_message;资源记录则包含 chapter_id、resource_type、title、file_url、view_count 和 download_count 等字段。
章节模型是平台最重要的业务锚点。无论是教师生成任务、资源列表还是管理员上传文件,都最终归属于某一章节。因此集成侧如果希望形成长期可治理的资源库,必须把章节 ID 作为正式参数在业务系统中保留。
| 模型 | 核心字段 | 用途说明 |
|---|---|---|
| RegisterSchema | email, password, name, school_name, subject, grade_range | 教师注册请求体,初始化基础身份信息与 API Key 绑定主体。 |
| PptGenerateSchema | grade, subject, topic, version, slides, style, inclusions, output_format, chapter_id | PPT 生成请求,适合备课场景与结构化演示。 |
| ReactCoursewareSchema | grade, subject, topic, features, platform, code_style, chapter_id | React 课件请求,适合互动演示与前端运行预览。 |
| ExamPdfSchema | grade, subject, scope, version, total_questions, difficulty, question_types, include_answers, include_rubric, include_knowledge_index, output_format, chapter_id | 试卷生成请求,适合测评与讲评材料准备。 |
| GenerationJobResponse | job_id, status, result_url, progress, result_metadata, error_message, created_at, completed_at | 三类生成任务统一状态载荷,也是 SSE 与状态查询的核心参照。 |
| ResourceSchema | id, chapter_id, resource_type, title, description, file_url, thumbnail_url, view_count, download_count, created_at | 资源列表、章节资源和管理员上传后的正式资源记录。 |
如果需要在校内系统中保留完整上下文,建议至少存储 user.id、chapter_id、job_id 和 file_url 四类字段。这样既能支撑后续回查,也能为资源复用、任务审计和治理统计提供可靠主键。
| job_id | 生成任务唯一标识 | 用于状态查询、SSE 订阅、审计留痕与故障定位。 |
| status | 任务状态值,支持 pending、processing、completed、failed | 前端与第三方系统都应以此驱动状态机。 |
| progress | 任务进度整数值 | 适合直接绑定进度条和超时告警。 |
| result_url | 主产物文件地址 | 完成后可直接进入下载、预览或二次分发。 |
| result_metadata | 扩展结果元数据 | 可包含 title、artifacts 等结构化补充字段。 |
| error_message | 失败原因描述 | 用于用户提示、重试策略与运维定位。 |
| created_at / completed_at | 任务起止时间 | 适合统计任务耗时和成功率。 |
| id | 资源唯一标识 | 管理员替换截图、治理资源和公开展示时的主键。 |
| chapter_id | 所属章节 ID | 是资源长期治理和筛选的核心锚点。 |
| resource_type | 资源类型 | 当前支持 ppt、react_courseware、exam_pdf、video、other。 |
| file_url | 文件访问地址 | 调用方应以该字段作为下载或预览入口。 |
| thumbnail_url | 截图地址 | 建议资源列表优先展示截图而不是直接展示文件名。 |
| is_ai_generated | 是否由 AI 自动生成 | 可用于资源来源区分与治理统计。 |
| view_count / download_count | 浏览与下载计数 | 适合做资源复用分析与运营评估。 |
异步任务模型
| 状态值 | 含义 | 集成建议 |
|---|---|---|
| pending | 任务已写入 generation_jobs,等待后台开始处理。 | 前端可以立即展示占位状态,并开始轮询或建立 SSE 订阅。 |
| processing | 后台已开始调用生成器并写入进度。 | 界面应展示 progress,并避免同一内容被重复提交。 |
| completed | 产物文件和 result_metadata 已生成;若请求带 chapter_id,会继续尝试自动入库资源。 | 可跳转预览、展示下载入口,并读取 artifacts 扩展产物。 |
| failed | 任务执行失败,error_message 写入具体原因。 | 应引导用户修正参数、模板或外部依赖后重试。 |
curl -X POST http://localhost:8000/api/v1/generate/react-courseware -H "Content-Type: application/json" -H "Authorization: Bearer <token>" -d '{
"grade": "七年级",
"subject": "数学",
"topic": "一元一次方程",
"features": ["slider", "animation", "chart"],
"platform": "standalone",
"code_style": "typescript",
"chapter_id": "<chapter_uuid>"
}'当请求体包含 chapter_id 时,任务完成后会尝试自动创建对应章节资源记录,并进一步生成资源截图。因此对于希望形成长期资源库的接入场景,强烈建议在生成时始终传递章节标识,而不是只保留 topic 或 scope 文字。
接口目录
以下目录按业务域给出平台当前主要接口。建议集成方先完成认证、教材元数据和资源查询接入,再根据具体业务场景接入生成任务与管理员治理接口,这样更容易形成渐进式上线节奏。
| POST /api/v1/auth/register | 注册教师账号并返回 access token、用户信息与 API Key。 |
| POST /api/v1/auth/login | 使用邮箱和密码登录,返回 access token 与用户信息。 |
| GET /api/v1/auth/me | 读取当前登录用户信息,适用于工作台初始化。 |
| POST /api/v1/auth/api-key/regenerate | 重新生成当前用户的 API Key。 |
| POST /api/v1/generate/ppt | 提交教学 PPT 生成任务。 |
| POST /api/v1/generate/react-courseware | 提交 React 课件生成任务。 |
| POST /api/v1/generate/exam-pdf | 提交 PDF 试卷生成任务。 |
| GET /api/v1/generate/status/{job_id} | 读取任务当前状态。 |
| GET /api/v1/generate/history | 读取当前用户最近生成记录。 |
| GET /api/v1/generate/stream/{job_id} | 通过 SSE 订阅任务进度。 |
| GET /api/v1/resources | 按章节、学期、年级、学科与版本筛选资源列表。 |
| GET /api/v1/resources/chapters/{chapter_id} | 读取某一章节下的全部资源。 |
| GET /api/v1/resources/presentation | 按需把站内 PPTX 渲染为逐页 WebP 幻灯片,供站内预览使用。 |
| GET /api/v1/textbook/grades | 读取年级列表。 |
| GET /api/v1/textbook/{grade_id}/subjects | 按年级读取学科列表。 |
| GET /api/v1/textbook/{grade_id}/{subject_id}/versions | 按年级与学科读取教材版本。 |
| GET /api/v1/textbook/chapters | 按版本读取章节列表。 |
| GET /api/v1/textbook/chapters/{chapter_id}/resources | 读取章节资源明细。 |
| GET /api/v1/admin/textbook/overview | 管理员读取教材、章节与资源治理总览。 |
| POST /api/v1/admin/textbook/chapters | 管理员新增章节。 |
| PUT /api/v1/admin/textbook/chapters/{chapter_id} | 管理员更新章节标题、顺序与知识点。 |
| POST /api/v1/admin/resources/upload | 管理员上传资源文件和截图。 |
| POST /api/v1/admin/resources/{resource_id}/thumbnail | 为指定资源生成或替换截图。 |
| POST /api/v1/admin/site-gallery/generate | 批量生成站点案例图和首页展示图。 |
| 参数名 | 位置 | 取值说明 | 典型用途 |
|---|---|---|---|
| semester | query | 可选,整型学期号 | 资源筛选和教材维度限定。 |
| grade_id | query | 资源接口可选,教材章节接口必填 | 确定年级层级。 |
| subject_id | query | 资源接口可选,教材章节接口必填 | 确定学科范围。 |
| version_id | query | 资源接口可选,教材章节接口必填 | 锁定教材版本。 |
| chapter_id | query | 可选,章节 UUID | 将资源查询精确到单章节。 |
| resource_type | query | 可选,支持 ppt、react_courseware、exam_pdf、video、other | 按资源类型过滤正式资源。 |
curl "http://localhost:8000/api/v1/resources?grade_id=7&subject_id=1&version_id=3&resource_type=ppt"curl -X POST http://localhost:8000/api/v1/admin/resources/upload -H "Authorization: Bearer <admin_token>" -F "chapter_id=<chapter_uuid>" -F "resource_type=other" -F "title=校本活动案例" -F "description=用于教研共享" -F "file=@./case-study.pdf"创建教师账号,初始化基础用户信息,并同步获得 Bearer Token 和 API Key。
{
"email": "teacher@example.com",
"password": "StrongPass123",
"name": "王老师",
"school_name": "示范中学",
"subject": "数学",
"grade_range": "七年级"
}{
"success": true,
"message": "注册成功",
"data": {
"access_token": "<jwt>",
"token_type": "bearer",
"user": {
"id": "<user_uuid>",
"email": "teacher@example.com",
"role": "teacher",
"plan": "free",
"api_key": "efa_xxxxxxxxx"
}
}
}围绕章节与教学主题提交 PPT 生成请求,并立即获得 job_id。
{
"grade": "七年级",
"subject": "数学",
"topic": "有理数加减法",
"version": "人教版",
"slides": 12,
"style": "interactive",
"inclusions": ["objectives", "content", "examples", "exercises"],
"output_format": ["pptx"],
"chapter_id": "<chapter_uuid>"
}{
"success": true,
"message": "PPT 生成任务已提交",
"data": {
"job_id": "<job_uuid>",
"status": "pending",
"progress": 0,
"result_url": null,
"error_message": null
}
}按知识点范围、题量和难度配置测评任务,用于单元测评与讲评准备。
{
"grade": "八年级",
"subject": "物理",
"scope": "压强与浮力",
"version": "人教版",
"total_questions": 24,
"difficulty": "balanced",
"question_types": {
"single_choice": 10,
"fill_blank": 8,
"short_answer": 6
},
"include_answers": true,
"include_rubric": true,
"include_knowledge_index": true,
"output_format": "pdf",
"chapter_id": "<chapter_uuid>"
}{
"success": true,
"message": "试卷生成任务已提交",
"data": {
"job_id": "<job_uuid>",
"status": "pending",
"progress": 0
}
}在任务处理中轮询最新状态,并在完成后读取主文件和扩展产物地址。
GET /api/v1/generate/status/<job_uuid>
Authorization: Bearer <access_token>{
"success": true,
"message": "任务状态",
"data": {
"job_id": "<job_uuid>",
"status": "completed",
"progress": 100,
"result_url": "/storage/ppt/demo.pptx",
"result_metadata": {
"title": "有理数加减法",
"artifacts": ["/storage/ppt/demo.pptx"]
},
"completed_at": "2026-05-06T09:00:00Z"
}
}结合年级、学科、版本、章节和资源类型读取资源库,用于公开页和工作台筛选。
GET /api/v1/resources?grade_id=7&subject_id=1&version_id=3&chapter_id=<chapter_uuid>&resource_type=ppt{
"success": true,
"message": "资源列表",
"data": [
{
"id": "<resource_uuid>",
"chapter_id": "<chapter_uuid>",
"resource_type": "ppt",
"title": "有理数加减法课堂演示",
"file_url": "/storage/ppt/demo.pptx",
"thumbnail_url": "/storage/resource-thumbnails/<resource_uuid>.png"
}
]
}按年级、学科和教材版本读取章节顺序、知识点和资源数量,用于前端联动筛选。
GET /api/v1/textbook/chapters?grade_id=7&subject_id=1&version_id=3&semester=1{
"success": true,
"message": "章节列表",
"data": [
{
"id": "<chapter_uuid>",
"title": "有理数加减法",
"short_title": "有理数加减法",
"order": 3,
"knowledge_points": ["相反数", "绝对值"],
"resource_count": 4,
"semester": 1,
"publisher": "人教版"
}
]
}把线下已有文件或校本成果正式纳入章节资源库,并同步生成或上传截图。
chapter_id=<chapter_uuid>
resource_type=other
title=校本案例汇编
description=用于教研共享
thumbnail_prompt=现代简洁的教学资源封面
file=@./case-study.pdf{
"success": true,
"message": "资源已上传",
"data": {
"id": "<resource_uuid>",
"resource_type": "other",
"title": "校本案例汇编",
"file_url": "/storage/resource-library/other/case-study.pdf",
"thumbnail_url": "/storage/resource-thumbnails/<resource_uuid>.png"
}
}认证接口详解
认证接口负责建立教师或管理员的正式身份上下文。对于学校接入场景,建议把登录态获取、当前用户读取和 API Key 生命周期管理明确拆开,避免在同一条调用链中混用用户会话和服务凭证。
| 接口 | 参数位置 | 参数说明 | 返回与约束 |
|---|---|---|---|
| POST /api/v1/auth/register | 请求体 | email、password、name 必填;school_name、subject、grade_range 可选。password 长度需在 8 到 64 之间。 | 无须鉴权。成功后返回 access_token、token_type 与完整 user 信息。 |
| POST /api/v1/auth/login | 请求体 | email、password 必填。email 必须是合法邮箱格式。 | 无须鉴权。成功后返回 access_token 和 user 信息。 |
| GET /api/v1/auth/me | 请求头 | Authorization: Bearer <access_token>。用于工作台初始化当前用户上下文。 | 必须携带登录态。成功后返回当前用户资料。 |
| POST /api/v1/auth/api-key/regenerate | 请求头 | Authorization: Bearer <access_token>。建议仅在受控界面中触发。 | 必须携带登录态。成功后仅返回新的 api_key。 |
推荐做法是:用户进入工作台时使用 Bearer Token,服务到服务接入时再单独使用 API Key,并把 API Key 再生动作限制在受控后台或管理员审批流程中。
生成接口详解
生成接口全部采用异步任务模型。调用方不应把提交成功等同于生成成功,而应把 job_id 视作正式流程主键,贯穿状态追踪、产物读取、异常告警和后续资源治理。
| 接口 | 参数位置 | 参数说明 | 返回与约束 |
|---|---|---|---|
| POST /api/v1/generate/ppt | 请求体 | grade、subject、topic 必填;slides 取值范围 8 到 20;style 支持 lecture、story、interactive、visual;可附带 chapter_id。 | 需 Bearer Token。成功只代表任务受理,真实结果需继续查询 status 或 SSE。 |
| POST /api/v1/generate/react-courseware | 请求体 | grade、subject、topic 必填;features 为字符串数组;code_style 支持 typescript、javascript;可附带 chapter_id。 | 需 Bearer Token。成功后返回 pending 任务。 |
| POST /api/v1/generate/exam-pdf | 请求体 | grade、subject、scope 必填;total_questions 范围 15 到 40;difficulty 支持 easy、balanced、hard;可附带 question_types 和 chapter_id。 | 需 Bearer Token。成功后返回 pending 任务。 |
| GET /api/v1/generate/status/{job_id} | 路径 + 请求头 | job_id 为任务 UUID;需携带 Bearer Token;仅允许访问当前用户自己的任务。 | 返回任务最新状态、进度、主文件地址与错误信息。 |
| GET /api/v1/generate/history | 请求头 | 需携带 Bearer Token;默认返回最近 20 条当前用户记录。 | 适用于工作台历史任务列表。 |
| GET /api/v1/generate/stream/{job_id} | 路径 | job_id 为任务 UUID;返回 text/event-stream;客户端应自行处理断流与结束条件。 | 适合前端实时进度展示,不应替代最终状态兜底查询。 |
如果目标是形成长期资源资产,建议在所有生成请求中都传入 chapter_id。这样任务完成后平台可以继续尝试自动入库资源,并接续缩略图生成与公开展示链路。
资源与教材详解
资源与教材接口承担两个职责:一是为前端筛选器和集成系统提供稳定的章节元数据;二是让正式资源库能按教材维度被检索、展示和复用。实际接入时,建议先接教材接口,再把资源查询接到选中的章节上下文上。
| 接口 | 参数位置 | 参数说明 | 返回与约束 |
|---|---|---|---|
| GET /api/v1/resources | 查询参数 | 支持 semester、grade_id、subject_id、version_id、chapter_id、resource_type 组合筛选;resource_type 支持 ppt、react_courseware、exam_pdf、video、other。 | 公开资源查询接口,适合公开页、资源库和筛选面板。 |
| GET /api/v1/resources/chapters/{chapter_id} | 路径参数 | chapter_id 为章节 UUID;返回章节标题、短标题和该章节下的资源数组。 | 适合章节详情页或资源分组展示。 |
| GET /api/v1/resources/presentation | 查询参数 | file_url 必填,且必须是站内可解析的 PPTX 文件地址。首次请求会触发 LibreOffice 渲染与 WebP 缓存。 | 返回逐页幻灯片图片地址、页码、标题和分辨率,用于站内演示预览。 |
| GET /api/v1/textbook/grades | 无参数 | 按顺序返回全部年级列表。 | 用于级联筛选起点。 |
| GET /api/v1/textbook/{grade_id}/subjects | 路径参数 | grade_id 为整数;仅返回当前年级下实际存在版本数据的学科。 | 用于按年级过滤学科。 |
| GET /api/v1/textbook/{grade_id}/{subject_id}/versions | 路径参数 | grade_id、subject_id 均为整数;按学期和版本顺序返回教材版本。 | 用于版本选择器。 |
| GET /api/v1/textbook/chapters | 查询参数 | grade_id、subject_id、version_id 必填;semester 可选;返回章节顺序、知识点和 resource_count。 | 是任务提交前绑定章节的重要数据源。 |
| GET /api/v1/textbook/chapters/{chapter_id}/resources | 路径参数 | chapter_id 为章节 UUID;返回该章节全部资源列表。 | 适用于章节资源详情或后台核查。 |
对于资源展示,建议统一以 file_url 和 thumbnail_url 为准,不要在外部系统中硬编码具体目录结构。这样能够同时兼容 AI 自动生成产物和管理员手工上传的长期资源。
管理员接口详解
管理员接口直接决定章节结构、正式资源、截图质量和站点视觉资产的治理水平。由于这些接口带有明显的发布和维护属性,建议仅向管理员角色或受控中间层开放,不建议直接暴露给普通用户端。
| 接口 | 参数位置 | 参数说明 | 返回与约束 |
|---|---|---|---|
| GET /api/v1/admin/textbook/overview | 查询参数 + 请求头 | recent_limit 可选,范围 1 到 48;必须由管理员携带 Bearer Token 调用。 | 返回统计数据、版本列表、章节列表和最近资源,是管理员首页核心接口。 |
| POST /api/v1/admin/textbook/chapters | 请求体 + 请求头 | textbook_version_id、title 必填;short_title、order 可选;knowledge_points 为字符串数组。 | 仅管理员可调用。成功后返回新建章节。 |
| PUT /api/v1/admin/textbook/chapters/{chapter_id} | 路径参数 + 请求体 + 请求头 | chapter_id 为章节 UUID;title、short_title、order、knowledge_points 均支持局部更新。 | 仅管理员可调用。成功后返回更新后的章节与资源统计。 |
| POST /api/v1/admin/resources/upload | 表单 + 文件 + 请求头 | chapter_id、resource_type、title、file 必填;description、thumbnail_prompt、thumbnail 可选。resource_type 按 ResourceType 枚举传值。 | 仅管理员可调用。成功后返回正式资源记录和截图地址。 |
| POST /api/v1/admin/resources/{resource_id}/thumbnail | 路径参数 + 表单/文件 + 请求头 | resource_id 为资源 UUID;可上传 thumbnail 文件,也可只传 prompt 触发生成。 | 适合人工替换封面或按提示词重生成截图。 |
| POST /api/v1/admin/site-gallery/generate | 请求体 + 请求头 | keys 为可选字符串数组;为空时按默认规格批量生成站点图库。 | 仅管理员可调用。适用于首页和案例区视觉资产重建。 |
对于资源上传链路,建议在校内制度上同步明确命名规范、截图标准、公开发布责任与审计要求。这样管理员接口才不仅是“可用”,而是真正变成学校资源治理流程的执行入口。
SSE 与状态流
GET /api/v1/generate/stream/{job_id} 采用 text/event-stream 返回任务状态。当前事件体包含 success、status、progress、result_url、metadata 和 error_message 六个核心字段,适合工作台前端或第三方系统做进度条、错误提示和完成后自动下载。
data: {
"success": true,
"status": "processing",
"progress": 56,
"result_url": null,
"metadata": null,
"error_message": null
}当前服务端会按约 0.6 秒频率推送一次状态,并在任务进入 completed 或 failed 后结束流。客户端实现上建议同时设置超时与兜底轮询逻辑,避免因浏览器休眠、网络代理或 EventSource 中断造成前端状态停滞。
const source = new EventSource('/api/v1/generate/stream/<job_id>')
source.onmessage = (event) => {
const payload = JSON.parse(event.data)
if (payload.status === 'completed' || payload.status === 'failed') {
source.close()
}
}文件与图片资产
平台所有文件资产统一落在 /storage 挂载目录下,通过相对路径回传,例如 /storage/ppt/xxx.pptx、/storage/react-courseware/xxx.tsx、/storage/exam/xxx.pdf。站点案例图、首页展示图和资源截图则统一归档到图片目录,由本地图像 API 或管理员上传生成。
对于资源卡片展示,建议始终优先使用截图或案例图,再暴露下载入口。这样既便于教师快速识别资源内容,也便于管理员在资源库治理时完成视觉审查。PPTX 资产支持调用本机 PowerPoint 协议直接打开,React 课件支持站内运行预览。
| 路径或字段 | 资产类型 | 说明 |
|---|---|---|
| /storage/ppt/... | PPT 主文件 | 由 PPT 生成任务输出,可下载,并可继续经站内预览接口转换为逐页 WebP 演示。 |
| /storage/react-courseware/... | React TSX 课件 | 由 React 课件任务输出,可供站内预览页面加载。 |
| /storage/exam/... | 试卷 PDF 或 DOCX | 由试卷生成任务输出,适合打印或归档。 |
| /storage/resource-library/{resource_type}/... | 管理员上传的正式资源 | 由资源上传接口写入,用于长期治理与公开展示。 |
| thumbnail_url | 资源截图访问地址 | 由资源列表、章节资源或管理员上传结果直接返回,前端应优先使用该字段。 |
调用方不应假定所有资源都来自同一目录,而应以 file_url 和 thumbnail_url 为准进行展示与下载。这样既能兼容 AI 自动生成资源,也能兼容管理员手工上传的长期资产。
错误码
| 状态码 | 含义 | 处理建议 |
|---|---|---|
| 400 | 请求参数不合法、文件类型不支持、章节字段缺失或资源不可解析。 | 检查 JSON 结构、文件扩展名、章节 ID 与查询参数。 |
| 401 | 缺少 access token 或 API Key,或认证信息失效。 | 刷新登录态,重新获取 Bearer Token 或 API Key。 |
| 403 | 当前用户无权访问目标任务或管理员接口。 | 检查账号角色、任务归属和调用头部。 |
| 404 | 任务、章节、资源或存储文件不存在。 | 检查 job_id、chapter_id、resource_id 与 file_url。 |
| 422 | FastAPI 请求体验证失败。 | 按照接口文档补齐字段和字段类型。 |
| 500 | 模型生成异常、图片生成异常、文件存储失败或数据库内部错误。 | 查看任务错误信息、后端日志和外部依赖健康状态。 |
对于生成类接口,除 HTTP 状态码外,还应重点关注任务成功创建后返回的 error_message。也就是说,接口层返回 200 只代表任务已被受理,并不意味着最终生成必定成功,真正的业务结果需要通过状态接口或 SSE 继续确认。
环境变量与部署
NEXTAUTH_SECRET=...
NEXTAUTH_URL=http://localhost:3000
SECRET_KEY=...
DATABASE_URL=mysql+aiomysql://root:***@localhost:3306/eduforge
LLM_PROVIDER=tongyi
LLM_API_KEY=...
LLM_API_URL=https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation
LLM_MODEL=qwen-plus
LOCAL_IMAGE_API_URL=http://localhost:3002
LOCAL_IMAGE_DEFAULT_SIZE=1024*1536
NEXT_PUBLIC_API_URL=http://localhost:8000
INTERNAL_API_URL=http://localhost:8000其中 LOCAL_IMAGE_API_URL 指向本地图像生成服务,用于首页图片、案例图和资源截图生成;NEXT_PUBLIC_API_URL 与 INTERNAL_API_URL 分别供浏览器侧与服务器侧请求使用。生产环境建议把前后端、数据库、模型密钥和图片服务地址统一交由学校信息中心管理。
| 变量 | 作用 | 部署建议 |
|---|---|---|
| NEXT_PUBLIC_API_URL | 浏览器侧访问 API 的公开基址 | 前端页面请求后端接口时使用。 |
| INTERNAL_API_URL | 服务端请求 API 的内部基址 | 适用于服务器组件或内部代理调用。 |
| DATABASE_URL | MySQL 连接串 | 核心业务数据持久化,影响用户、任务、教材、章节与资源。 |
| SECRET_KEY / NEXTAUTH_SECRET | 身份签名与认证安全 | 必须在正式环境中安全保管。 |
| LLM_PROVIDER / LLM_API_KEY / LLM_API_URL / LLM_MODEL | 文本生成模型配置 | 控制 Tongyi/Qwen 接入方式与模型版本。 |
| LOCAL_IMAGE_API_URL / LOCAL_IMAGE_DEFAULT_SIZE | 本地图像生成配置 | 用于站点图、案例图和资源截图生产。 |
如果学校采用前后端分离或反向代理部署,建议先固定 API 基址和静态资源访问策略,再开放给教师和第三方系统使用。这样可以减少前端地址变更、跨域策略调整和外部回调不一致带来的运维成本。
速率限制与配额
所有受 API Key 调用的接口共享一组配额计数器,按 1 分钟 / 1 小时 / 1 天 / 月度四个维度滚动统计。当任一维度达到阈值时,服务端返回 HTTP 429 与 {"detail": "rate_limited"},并在响应头 Retry-After 中给出建议重试间隔。
| 套餐 | 每分钟 | 每小时 | 每月生成额度 | 并发任务 |
|---|---|---|---|---|
| 个人免费版 | 20 | 200 | 500 | 2 |
| 专业版 | 60 | 1500 | 5000 | 6 |
| 校园版 | 协商 | 协商 | 不少于 30000 | 协商 |
所有响应均会附带以下响应头帮助客户端做退避:X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset (Unix 秒)。建议客户端在收到 429 时使用指数退避,初始 2 秒,最多 5 次重试,并在第 3 次重试时检查是否需要切换备用 API Key。
版本与兼容策略
所有 HTTP 路径以 /api/v1/ 开头。我们承诺在 v1 大版本生命周期内保持以下兼容性:
- 不会移除已有字段;废弃字段会先标记
deprecated至少 6 个月并在响应头Sunset中通告下线时间。 - 不会改变现有字段的类型;仅会新增字段或新增可选请求参数。
- 新增端点会在 API 文档与白皮书的同一日同步发布;破坏性更改将进入下一个大版本 (
/api/v2/)。 - SSE 事件名只增不删;新增事件名前会在文档中以 Beta 标记不少于 30 天。
客户端建议在请求头中显式声明可接受的版本范围,例如 Accept: application/vnd.eduforge.v1+json,以便服务端在未来切换默认版本时仍能向后兼容。
Webhook (规划中)
下一阶段计划提供 Webhook 推送,便于把生成完成、资源入库、章节调整等关键事件回调到学校自有平台。当前版本仍以 SSE + 轮询为主,下表给出规划中的事件清单与签名机制,便于平台集成方提前规划接入方案。
| 事件名 | 触发时机 | 关键 Payload 字段 |
|---|---|---|
| job.completed | 任意生成任务进入 completed 状态 | job_id, job_type, user_id, resource_id, artifact_url |
| job.failed | 任意生成任务进入 failed 状态 | job_id, job_type, user_id, error_code, error_message |
| resource.published | 管理员将资源切换为 published | resource_id, chapter_id, published_by, published_at |
| resource.uploaded | 教师通过 /resources/upload 上传新资源 | resource_id, chapter_id, owner_id, file_url, thumbnail_url |
| question.created | 题库新增题目 (含手动 / 生成入库) | question_id, chapter_id, knowledge_points, difficulty, created_by |
Webhook 会在请求头中附带 X-EduForge-Signature,使用 HMAC-SHA256 对原始 body 做签名,密钥为接入方在管理员后台登记的 webhook secret。建议接入方对超过 5 分钟的请求视为重放并拒绝处理。
SDK 与调用示例
当前版本不强制使用 SDK,所有接口都可使用任意支持 HTTP 与 SSE 的客户端调用。以下示例覆盖最常用的三个动作:申请并使用 API Key、提交 PPT 生成任务、订阅 SSE 进度。
curl -X POST "$API/api/v1/generate/ppt" \
-H "X-API-Key: $EDUFORGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chapter_id": "ch_human_geography_01",
"topic": "城市化与产业升级",
"objectives": ["理解城市化阶段差异", "掌握产业升级评价指标"],
"slide_count": 18,
"language": "zh-CN"
}'import httpx
with httpx.stream(
"GET",
f"{API}/api/v1/generate/stream/{job_id}",
headers={"X-API-Key": api_key},
timeout=None,
) as response:
for line in response.iter_lines():
if line.startswith("data:"):
print(line.removeprefix("data:").strip())const form = new FormData()
form.append('chapter_id', chapterId)
form.append('resource_type', 'exam_pdf')
form.append('title', '高一地理 · 期中模拟卷')
form.append('file', file)
const created = await fetch(`${API}/api/v1/resources/upload`, {
method: 'POST',
headers: { 'X-API-Key': apiKey },
body: form,
}).then((r) => r.json())
// 缩略图由 LibreOffice + PyMuPDF 异步生成,通常 5 ~ 30 秒可用
const detail = await fetch(`${API}/api/v1/resources/${created.id}`).then((r) => r.json())如果计划在校内做更深入的二次开发,建议封装统一的请求层,集中处理 API Key 注入、429 退避、SSE 重连和文件下载校验,避免业务模块各自实现造成维护成本上升。
支持信息
| 产品主体 | 武汉市瀚普斯科技有限公司 |
|---|---|
| 联系邮箱 | 17300766401@163.com |
| 联系电话 | 17300766401 |
| 建议支持流程 | 先确认环境变量与依赖健康,再核查任务错误信息、SSE 状态流与资源目录,最后定位具体路由或管理员操作链。 |
提交技术问题时,建议同时附上请求路径、请求参数、HTTP 状态码、job_id、error_message、目标章节 ID 和相关存储地址。对于管理员治理问题,还应附上资源 ID 或截图更新链路,这样能够显著缩短定位时间。