AI 服务
EduBuddy 的所有 AI 功能集中封装在 backend/src/services/aiService.ts 中,通过 OpenAI Node.js SDK 与大型语言模型交互,支持任何兼容 OpenAI API 格式的服务商。
服务函数总览
| 函数名 | 功能 | 调用方 |
|---|---|---|
chatWithAI() | 通用对话(基础函数) | 所有其他 AI 函数 |
generateLearningPath() | 生成个性化学习路线 | routes/learningPaths |
generateQuestion() | 生成题目(含解析) | routes/questions |
solveQuestion() | 解析题目(解题过程) | routes/questions |
evaluateAnswer() | 批改答案(评分+反馈) | routes/questions |
analyzeWeaknesses() | 分析薄弱环节并生成建议 | routes/progress |
extractQuestionsFromText() | 从文本提取结构化题目 | routes/questions、routes/upload |
generateAssessmentReport() | 生成综合学习评估报告 | routes/progress |
客户端初始化
使用单例模式懒加载 OpenAI 客户端,避免多次实例化:
let openaiClient: OpenAI | null = null;
function getOpenAIClient(): OpenAI {
if (!openaiClient) {
openaiClient = new OpenAI({
apiKey: process.env.OPENAI_API_KEY || 'sk-placeholder',
baseURL: process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1',
});
}
return openaiClient;
}
// 模型名称从环境变量读取,支持运行时切换
const MODEL = () => process.env.OPENAI_MODEL || 'gpt-4o';
核心调用参数
// 通用对话调用配置
await client.chat.completions.create({
model: MODEL(),
messages,
temperature: 0.7, // 适度创意,避免过于随机
max_tokens: 2000, // 限制单次响应长度
});
各功能 Prompt 设计
generateLearningPath — 学习路线生成
系统角色:专业的教育规划专家
输入:科目、年级、当前水平、学习目标
输出 JSON Schema:
{
"title": "学习路线标题",
"description": "路线描述",
"estimated_hours": 数字,
"difficulty": "beginner|intermediate|advanced",
"nodes": [
{
"title": "节点标题",
"description": "节点描述",
"content": "Markdown格式学习内容",
"node_type": "lesson|quiz|project",
"estimated_minutes": 数字,
"order_index": 数字,
"resources": ["学习资源"]
}
]
}
generateQuestion — 题目生成
系统角色:专业的教育工作者
输入:科目、知识点、难度、题型、数量
输出 JSON Schema(数组):
[
{
"title": "题目简标题",
"content": "题目完整内容",
"options": ["A. 选项1", ...] 或 null,
"correct_answer": "正确答案",
"explanation": "详细解析(不少于200字)",
"tags": ["知识点标签"]
}
]
solveQuestion — 解题
系统角色:专业教师
输出内容:解题思路和步骤、关键知识点、常见错误、拓展知识
{
"solution": "详细解题过程(Markdown,不少于300字)",
"keyPoints": ["关键知识点1", "关键知识点2"]
}
evaluateAnswer — 答案评估
系统角色:专业批改老师
输入:题目内容、正确答案、学生答案、科目
{
"isCorrect": true 或 false,
"score": 0-100,
"feedback": "具体反馈(不少于100字)"
}
降级处理:若 AI 返回解析失败,回退为字符串精确匹配:
const isCorrect = userAnswer.trim().toLowerCase()
=== correctAnswer.trim().toLowerCase();
return { isCorrect, score: isCorrect ? 100 : 0, feedback: ... };
analyzeWeaknesses — 薄弱环节分析
系统角色:专业学习顾问
输入:学生知识点掌握度数据(subject、topic、masteryLevel、practiceCount、correctRate)
输出:按优先级排序的建议列表(最多 8 条)
[
{
"type": "weakness_improvement|review|practice_more|new_topic",
"content": "具体建议(不少于80字)",
"priority": "high|medium|low",
"subject": "科目",
"topic": "知识点"
}
]
extractQuestionsFromText — 文本题目提取
系统角色:题目解析专家
输入:原始文本(最多 3000 字符)、科目
AI 自动识别文本中的题目,提取题目内容、题型、答案、解析、知识点等结构化信息。若无可识别题目,返回空数组 []。
generateAssessmentReport — 评估报告
系统角色:教育评估专家
输入:学生名、评估周期、学习时长、平均分、已掌握知识点、薄弱知识点、练习总数
输出:Markdown 格式的专业评估报告,包含 5 个章节:总体评价、优势分析、薄弱环节分析、改进建议、下阶段学习计划。
JSON 解析容错
所有返回 JSON 的 AI 函数都有统一的解析容错处理:
// 1. 清理 AI 返回的 Markdown 代码块包裹
const cleaned = result
.replace(/```json\n?/g, '')
.replace(/```\n?/g, '')
.trim();
// 2. 尝试 JSON.parse
try {
return JSON.parse(cleaned);
} catch {
logger.error('JSON解析失败:', result);
// 3. 降级处理(各函数自行定义)
throw new Error('AI返回格式异常,请重试');
}
多模态能力
图片 OCR(GPT-4 Vision)
图片上传接口直接使用 OpenAI Vision API,将图片转为 Base64 嵌入消息体:
messages: [{
role: 'user',
content: [
{ type: 'text', text: `请识别图片中的题目,科目:${subject}` },
{ type: 'image_url',
image_url: { url: `data:image/${mimeType};base64,${base64Image}` }
}
]
}]
图片 OCR 需要模型支持 Vision 能力。使用 DeepSeek 或部分国内模型时,若不支持 Vision,该功能将返回错误。
语音转文字(Whisper)
语音识别直接调用 OpenAI Whisper API:
const transcription = await client.audio.transcriptions.create({
file: fs.createReadStream(req.file.path),
model: 'whisper-1',
language: 'zh' // 中文识别
});
Whisper API 目前仅 OpenAI 官方提供,使用 DeepSeek 等替代服务时,语音转文字功能不可用。
费用估算参考
| 功能 | 大约 Token 消耗 | 频率 |
|---|---|---|
| 生成 1 道题目 | 约 500-800 tokens | 按需 |
| AI 解题 | 约 800-1200 tokens | 按题目 |
| 批改答案 | 约 300-500 tokens | 每次答题 |
| 薄弱环节分析 | 约 600-1000 tokens | 按需(建议每天最多 1 次) |
| 生成评估报告 | 约 1000-2000 tokens | 按需 |
| 生成学习路线 | 约 1500-3000 tokens | 按需 |