/** * 多模型大纲生成对比测试 - HTTP方式 */ const axios = require('axios'); const fs = require('fs'); // 只测试 MiniMax (使用官方API) const TEST_MODELS = [ { id: 'MiniMax-M2.7', vendor: 'minimax', name: 'MiniMax M2.7' }, ]; // 优化后的提示词 const OPTIMIZED_SYSTEM_PROMPT = `你是一位专业的图书策划编辑,擅长为各类主题设计清晰、严谨、有逻辑递进的书籍大纲。 ## 你的职责 根据用户提供的书名、规模和主题,设计一份完整的书籍大纲。 ## 工作要求 1. 分析主题复杂度,在允许的章节范围内决定最合适的章节数 2. 章节之间必须有清晰的逻辑递进关系(由浅入深、由理论到实践等) 3. 每章的知识点要具体,不能泛泛而谈 4. 预估字数要符合章节内容量 5. 核心知识点应独立成章,不要过度合并 ## ⚠️ 输出格式要求(非常重要) 1. 必须且只能返回纯 JSON,不要任何解释、思考过程或其他文字 2. 不要使用 markdown 代码块标记 3. 不要包含任何标签(如details、think等) 4. 直接从 { 开始,到 } 结束 5. JSON 必须合法,可以被 JSON.parse 解析 ## JSON 格式 { "mainTheme": "主题一句话描述", "structureLogic": "章节组织逻辑说明", "chapters": [ { "number": 1, "title": "章标题", "summary": "本章概述(2-3句话)", "keyPoints": ["知识点1", "知识点2"], "estimatedWords": 10000 } ] }`; async function testModel(model) { console.log(`\n${'='.repeat(80)}`); console.log(`🤖 测试: ${model.name} (${model.vendor})`); console.log(`${'='.repeat(80)}`); // 读取models.json获取配置 const modelsConfig = JSON.parse(fs.readFileSync('./src/config/models.json', 'utf8')); const vendor = Object.values(modelsConfig.vendors).find(v => v.models.some(m => m.id === model.id) ); if (!vendor) { console.log(`❌ 未找到模型配置: ${model.id}`); return null; } const modelConfig = vendor.models.find(m => m.id === model.id); try { const startTime = Date.now(); const response = await axios.post( `${vendor.baseUrl}/chat/completions`, { model: model.id, messages: [ { role: 'system', content: OPTIMIZED_SYSTEM_PROMPT }, { role: 'user', content: '书名:《操作系统引论》\n规模:大学专业教材\n章节范围:10-12章\n\n请生成完整的书籍大纲。' } ], temperature: modelConfig.temperature || 0.7, max_tokens: modelConfig.maxTokens || 4096 }, { headers: { 'Authorization': `Bearer ${vendor.apiKey}`, 'Content-Type': 'application/json' }, timeout: 120000 } ); const duration = ((Date.now() - startTime) / 1000).toFixed(2); const content = response.data.choices[0].message.content; console.log(`⏱️ 耗时: ${duration}秒`); console.log(`\n📝 生成内容:\n`); console.log(content); // 尝试解析 try { let jsonStr = content.trim(); const match = jsonStr.match(/\{[\s\S]*\}/); if (match) jsonStr = match[0]; const outline = JSON.parse(jsonStr); console.log(`\n✅ JSON解析成功`); console.log(`📊 章节数: ${outline.chapters?.length || 0}`); console.log(`📖 主题: ${outline.mainTheme}`); if (outline.chapters) { const totalWords = outline.chapters.reduce((sum, c) => sum + (c.estimatedWords || 0), 0); console.log(`📈 总字数: ${totalWords}`); console.log(`\n📋 章节列表:`); outline.chapters.forEach(ch => { console.log(` ${ch.number}. ${ch.title} (${ch.estimatedWords}字)`); }); } } catch (e) { console.log(`\n⚠️ JSON解析失败: ${e.message}`); } return { model: model.name, vendor: model.vendor, content, success: true, duration }; } catch (error) { console.log(`\n❌ 失败: ${error.response?.data?.message || error.message}`); return { model: model.name, vendor: model.vendor, error: error.message, success: false }; } } async function main() { console.log('🚀 多模型大纲生成对比测试\n'); console.log('📚 测试主题: 操作系统引论'); console.log(`🔢 测试模型: ${TEST_MODELS.length}个\n`); const results = []; for (const model of TEST_MODELS) { const result = await testModel(model); if (result) results.push(result); await new Promise(resolve => setTimeout(resolve, 2000)); } // 汇总 console.log(`\n\n${'='.repeat(80)}`); console.log('📊 测试结果汇总'); console.log(`${'='.repeat(80)}\n`); results.forEach((r, i) => { console.log(`${i + 1}. ${r.model} [${r.vendor}]`); if (r.success) { console.log(` ✅ 成功 | 耗时: ${r.duration}秒`); } else { console.log(` ❌ 失败: ${r.error}`); } console.log(); }); // 保存结果 const fs = require('fs'); const path = require('path'); // 确保目录存在 const resultsDir = path.join(__dirname, 'test-results'); if (!fs.existsSync(resultsDir)) { fs.mkdirSync(resultsDir, { recursive: true }); } const resultFile = path.join(resultsDir, 'outline-comparison.json'); fs.writeFileSync(resultFile, JSON.stringify(results, null, 2), 'utf8'); console.log(`\n💾 结果已保存到: ${resultFile}`); // 同时保存一个可读的文本版本 const textFile = path.join(resultsDir, 'outline-comparison.txt'); let textContent = '=' .repeat(80) + '\n'; textContent += '多模型大纲生成对比测试结果\n'; textContent += '='.repeat(80) + '\n\n'; textContent += `测试主题: 操作系统引论\n`; textContent += `书籍类型: 大学专业教材\n`; textContent += `章节范围: 10-12章\n`; textContent += `测试时间: ${new Date().toLocaleString('zh-CN')}\n\n`; results.forEach((r, i) => { textContent += `${'='.repeat(80)}\n`; textContent += `${i + 1}. ${r.model} [${r.vendor}]\n`; textContent += `${'='.repeat(80)}\n\n`; if (r.success) { textContent += `⏱️ 耗时: ${r.duration}秒\n`; textContent += `✅ 状态: 成功\n\n`; textContent += `📝 生成内容:\n\n`; textContent += r.content + '\n\n'; } else { textContent += `❌ 状态: 失败\n`; textContent += `错误信息: ${r.error}\n\n`; } }); fs.writeFileSync(textFile, textContent, 'utf8'); console.log(`📄 可读版本已保存到: ${textFile}`); } main().catch(console.error);