You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
4.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

const axios = require('axios');
const AipSpeechClient = require('baidu-aip-sdk').speech;
const APP_ID = process.env.BAIDU_APP_ID;
const API_KEY = process.env.BAIDU_API_KEY;
const SECRET_KEY = process.env.BAIDU_SECRET_KEY;
const QIANFAN_API_KEY = process.env.QIANFAN_API_KEY;
const QIANFAN_SECRET_KEY = process.env.QIANFAN_SECRET_KEY;
const client = new AipSpeechClient(APP_ID, API_KEY, SECRET_KEY);
async function transcribeAudio(req, res) {
if (!req.file) {
return res.status(400).json({ msg: 'No audio file uploaded.' });
}
const audioBuffer = req.file.buffer;
try {
const result = await client.recognize(audioBuffer, 'wav', 16000, {
dev_pid: 1537,
});
if (result.err_no === 0) {
return res.json({ result: result.result[0] });
}
console.error('Baidu ASR service error:', result);
return res.status(502).json({ msg: 'Baidu ASR service error', error: result });
} catch (error) {
console.error('Error calling Baidu ASR API:', error);
return res.status(500).json({ msg: 'Server error during transcription.' });
}
}
async function getQianfanAccessToken() {
if (!QIANFAN_API_KEY || !QIANFAN_SECRET_KEY) {
throw new Error('QIANFAN credentials are not configured');
}
const url = `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${QIANFAN_API_KEY}&client_secret=${QIANFAN_SECRET_KEY}`;
try {
const response = await axios.get(url);
if (!response.data?.access_token) {
throw new Error('Invalid access token response');
}
return response.data.access_token;
} catch (error) {
const message = error.response?.data || error.message;
console.error('Error getting Qianfan access token:', message);
throw new Error('Failed to get Qianfan access token');
}
}
async function evaluateFeynmanAttempt(req, res) {
const { originalContent, transcribedText } = req.body || {};
if (!originalContent || !transcribedText) {
return res.status(400).json({ msg: 'Original content and transcribed text are required.' });
}
try {
const accessToken = await getQianfanAccessToken();
const url = `https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant?access_token=${accessToken}`;
const prompt = `你是一个严格而友善的计算机科学学习教练。你的任务是评估学生对一个知识点的复述,并给出反馈。
【原始知识点】:
\`\`\`
${originalContent}
\`\`\`
【学生的口头复述文本】:
\`\`\`
${transcribedText}
\`\`\`
请你完成以下三项任务:
1. **文本润色**: 将学生的复述文本润色成一段通顺、专业、书面化的文字。修正明显的语法错误和口语化表达,但保持其核心观点不变。
2. **综合评价**: 基于原始知识点,对学生的复述进行评价。指出其优点和可以改进的地方。
3. **评分**: 综合考虑准确性、完整性、逻辑性和流畅性给出一个0到100的整数分数。
请严格按照以下JSON格式返回你的结果不要包含任何额外的解释或文字。
{
"polishedText": "这里是润色后的文本",
"evaluation": "这里是你的综合评价",
"strengths": ["优点1", "优点2"],
"weaknesses": ["可以改进的地方1", "可以改进的地方2"],
"score": 85
}`;
const response = await axios.post(
url,
{
messages: [
{
role: 'user',
content: prompt,
},
],
},
{
headers: { 'Content-Type': 'application/json' },
timeout: 20_000,
},
);
const rawResult = response.data?.result || response.data?.body?.result;
if (!rawResult) {
throw new Error('Empty result from Qianfan');
}
try {
const parsed = JSON.parse(rawResult);
return res.json(parsed);
} catch (parseError) {
console.error('Failed to parse Qianfan result:', rawResult);
throw new Error('Invalid JSON returned by Qianfan');
}
} catch (error) {
const message = error.response?.data || error.message;
console.error('Error calling LLM API:', message);
return res.status(500).json({ msg: 'AI evaluation failed', detail: message });
}
}
module.exports = {
transcribeAudio,
evaluateFeynmanAttempt,
};