| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999 |
- "use strict";
- /**
- * AI内容生成服务
- * 使用通义千问/DashScope API
- */
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.aiContentService = exports.AIContentService = exports.generateTasks = void 0;
- const axios_1 = __importDefault(require("axios"));
- const config_1 = require("../../config");
- // 存储生成任务
- exports.generateTasks = new Map();
- // 内容类型分类
- const contentTypes = {
- '创作类': ['小说', '故事', '剧本', '诗歌', '散文'],
- '营销类': ['产品介绍', '广告文案', '朋友圈', '小红书', '抖音脚本'],
- '教育类': ['课件', '培训', '教程', '知识科普', '考试辅导'],
- '商务类': ['销售话术', '客服话术', '商务邮件', '合同条款', '方案PPT'],
- '媒体类': ['新闻播报', '天气预报', '体育解说', '财经评论', '娱乐八卦'],
- '生活类': ['生日祝福', '婚礼致辞', '节日问候', '朋友圈文案', '签名设计'],
- '专业类': ['法律文书', '医学说明', '技术文档', '产品手册', '操作指南'],
- };
- // 行业列表
- const industries = [
- '通用', '医疗健康', '教育培训', '金融服务', '电子商务',
- '法律服务', '新闻媒体', '餐饮美食', '房地产', '汽车销售'
- ];
- // 情感选项
- const emotions = ['开心', '悲伤', '激动', '平静', '紧张', '温柔', '愤怒', '恐惧', '惊讶'];
- // 支持的语言
- const languages = ['中文', '英语', '日语', '韩语', '法语', '德语', '西班牙语', '葡萄牙语', '俄语', '阿拉伯语'];
- // 质量评分维度
- const qualityDimensions = ['fluency', 'naturalness', 'emotion_consistency', 'topic_adherence', 'structural_integrity'];
- // 获取可用模型列表
- function getAvailableModels() {
- return config_1.config.models.getModelsByType('text').filter((m) => m.enabled !== false);
- }
- // 随机选择模型
- function getRandomModel() {
- const models = getAvailableModels();
- return models[Math.floor(Math.random() * models.length)].id;
- }
- class AIContentService {
- modelId;
- apiKey;
- baseUrl;
- constructor() {
- this.modelId = getRandomModel();
- const modelConfig = config_1.config.models.getModel(this.modelId);
- this.apiKey = modelConfig?.apiKey || '';
- this.baseUrl = modelConfig?.baseUrl || '';
- }
- /**
- * 调用 LLM API (流式)
- */
- async *streamLLM(prompt, systemPrompt) {
- if (!this.apiKey || !this.baseUrl) {
- throw new Error('未配置 AI API');
- }
- const fullPrompt = systemPrompt ? `${systemPrompt}\n\n${prompt}` : prompt;
- try {
- const response = await axios_1.default.post(`${this.baseUrl}/chat/completions`, {
- model: this.modelId,
- messages: [{ role: 'user', content: fullPrompt }],
- stream: true,
- }, {
- headers: {
- 'Authorization': `Bearer ${this.apiKey}`,
- 'Content-Type': 'application/json',
- },
- timeout: 180000,
- responseType: 'stream',
- });
- let buffer = '';
- for await (const chunk of response.data) {
- buffer += chunk.toString();
- // 解析SSE格式的数据
- const lines = buffer.split('\n');
- buffer = lines.pop() || '';
- for (const line of lines) {
- if (line.startsWith('data:')) {
- const data = line.slice(5).trim();
- if (data && data !== '[DONE]') {
- try {
- const parsed = JSON.parse(data);
- const content = parsed.choices?.[0]?.delta?.content;
- if (content) {
- yield content;
- }
- }
- catch (e) {
- // 忽略解析错误
- }
- }
- }
- }
- }
- }
- catch (error) {
- console.error('❌ LLM 流式调用失败:', error.response?.data || error.message);
- throw new Error(error.message || 'AI 生成失败');
- }
- }
- /**
- * 调用 LLM API
- */
- async callLLM(prompt, systemPrompt) {
- if (!this.apiKey || !this.baseUrl) {
- throw new Error('未配置 AI API');
- }
- const fullPrompt = systemPrompt ? `${systemPrompt}\n\n${prompt}` : prompt;
- try {
- const response = await axios_1.default.post(`${this.baseUrl}/chat/completions`, {
- model: this.modelId,
- messages: [{ role: 'user', content: fullPrompt }],
- }, {
- headers: {
- 'Authorization': `Bearer ${this.apiKey}`,
- 'Content-Type': 'application/json',
- },
- timeout: 120000,
- });
- const data = response.data;
- return data.choices?.[0]?.message?.content || '';
- }
- catch (error) {
- console.error('❌ LLM 调用失败:', error.response?.data || error.message);
- throw new Error(error.message || 'AI 生成失败');
- }
- }
- /**
- * 智能意图识别
- */
- async recognizeIntent(input) {
- const type = this.detectContentType(input);
- const industry = this.detectIndustry(input);
- return {
- type,
- industry,
- style: '正式',
- scale: input.length > 500 ? '长篇' : '短篇',
- confidence: 0.85,
- };
- }
- /**
- * 检测内容类型
- */
- detectContentType(input) {
- const keywords = {
- '小说': ['故事', '主角', '章节', '穿越', '都市', '玄幻'],
- '广告': ['推广', '优惠', '打折', '促销', '产品'],
- '培训': ['培训', '课程', '教学', '学员', '讲师'],
- '销售': ['客户', '订单', '成交', '跟进', '话术'],
- '祝福': ['祝福', '生日快乐', '节日', '贺卡'],
- };
- for (const [type, words] of Object.entries(keywords)) {
- if (words.some(w => input.includes(w))) {
- return { category: type, subType: type };
- }
- }
- return { category: '创作类', subType: '故事' };
- }
- /**
- * 检测行业
- */
- detectIndustry(input) {
- const keywords = {
- '医疗健康': ['医生', '医院', '药品', '健康', '疾病'],
- '教育培训': ['学校', '学生', '老师', '课程', '培训'],
- '金融服务': ['银行', '理财', '投资', '股票', '基金'],
- '电子商务': ['商品', '店铺', '买家', '电商', '快递'],
- '餐饮美食': ['餐厅', '美食', '菜品', '厨师', '食物'],
- };
- for (const [industry, words] of Object.entries(keywords)) {
- if (words.some(w => input.includes(w))) {
- return industry;
- }
- }
- return '通用';
- }
- /**
- * 获取内容类型列表
- */
- getContentTypes() {
- return contentTypes;
- }
- /**
- * 获取所有内容类型(扁平)
- */
- getAllContentTypes() {
- const all = [];
- Object.values(contentTypes).forEach(types => all.push(...types));
- return [...new Set(all)];
- }
- /**
- * 统一内容生成
- */
- async generateContent(prompt, targetLength = 2000) {
- // 系统性知识展开
- const finalPrompt = `你是一位专业的老师。请围绕用户的主题,系统性地讲解这个知识点。
- 用户主题:${prompt}
- 要求:
- 1. 首先分析这个主题涉及的核心领域和知识体系
- 2. 按照"大类 -> 小类 -> 具体知识点"的层次结构展开讲解
- 3. 每个知识点都要讲清楚"是什么"、"为什么"、"怎么用"
- 4. 内容要准确、全面、深入浅出
- 5. 直接返回正文内容,用清晰的章节标题组织结构
- 6. 目标字数:${targetLength}字左右,如果内容有价值可以超出`;
- console.log('🤖 [AI内容生成] 最终Prompt:', finalPrompt);
- console.log('🤖 [AI内容生成] 使用模型:', this.modelId);
- const content = await this.callLLM(finalPrompt);
- return {
- content,
- type: '通用',
- industry: '通用',
- wordCount: content.length,
- debug: {
- model: this.modelId,
- finalPrompt
- }
- };
- }
- /**
- * AI自动判断内容类型和行业
- */
- async detectTypeAndIndustry(prompt) {
- const detectPrompt = `分析以下内容需求,判断其类型和所属行业。
- 需求内容:${prompt}
- 请以JSON格式返回:
- {"type": "内容类型", "industry": "所属行业"}
- 内容类型选项:小说、故事、剧本、诗歌、散文、营销文案、教育内容、商务内容、媒体内容
- 行业选项:通用、医疗健康、教育培训、金融服务、电子商务、餐饮美食、法律服务、新闻媒体
- 只返回JSON,不要其他内容。`;
- try {
- const response = await this.callLLM(detectPrompt);
- const jsonMatch = response.match(/\{[\s\S]*\}/);
- if (jsonMatch) {
- const parsed = JSON.parse(jsonMatch[0]);
- return {
- type: parsed.type || '通用',
- industry: parsed.industry || '通用',
- };
- }
- }
- catch (e) {
- console.log('类型检测失败,使用默认类型');
- }
- return { type: '通用', industry: '通用' };
- }
- /**
- * 生成小说
- */
- async generateNovel(prompt, targetLength) {
- let content = '';
- const chapterCount = Math.ceil(targetLength / 2000);
- const chapters = [];
- const outlinePrompt = `根据以下需求,为小说生成大纲:
- 需求:${prompt}
- 章节数:${chapterCount}章
- 请以JSON格式返回:
- {"chapters": [{"title": "第X章标题", "description": "章节概要"}]}`;
- try {
- const outlineResponse = await this.callLLM(outlinePrompt);
- const jsonMatch = outlineResponse.match(/\{[\s\S]*\}/);
- if (jsonMatch) {
- const parsed = JSON.parse(jsonMatch[0]);
- const chaptersOutline = parsed.chapters || [];
- for (let i = 0; i < chaptersOutline.length; i++) {
- const chapter = chaptersOutline[i];
- const chapterPrompt = `续写小说章节:
- 章节标题:${chapter.title}
- 章节概要:${chapter.description}
- 要求:
- 1. 内容丰富、生动,不少于1500字
- 2. 包含人物对话、心理描写、场景描写
- 3. 情节紧凑,有吸引力
- 4. 直接返回正文内容`;
- try {
- const chapterContent = await this.callLLM(chapterPrompt);
- chapters.push(`【${chapter.title}】\n\n${chapterContent}`);
- }
- catch {
- chapters.push(`【${chapter.title}】\n\n[内容生成失败]`);
- }
- }
- }
- }
- catch {
- // 如果大纲生成失败,直接根据主题生成
- }
- if (chapters.length === 0) {
- // 降级:直接生成单段内容
- const fallbackPrompt = `根据以下主题,写一篇${targetLength}字的小说:
- 主题:${prompt}
- 要求:
- 1. 内容丰富、生动
- 2. 包含人物对话、心理描写、场景描写
- 3. 直接返回正文内容`;
- content = await this.callLLM(fallbackPrompt);
- }
- else {
- content = chapters.join('\n\n');
- }
- return content;
- }
- /**
- * 生成营销文案
- */
- async generateMarketing(prompt, targetLength) {
- const marketingPrompt = `根据以下需求,写一篇营销文案:
- 需求:${prompt}
- 要求:
- 1. 语言生动,有感染力
- 2. 符合目标受众喜好
- 3. 字数:${targetLength}字左右
- 4. 直接返回正文内容,不要其他说明`;
- return await this.callLLM(marketingPrompt);
- }
- /**
- * 生成教育培训内容
- */
- async generateEducation(prompt, targetLength) {
- const educationPrompt = `根据以下需求,生成教育培训内容:
- 需求:${prompt}
- 要求:
- 1. 结构清晰,易于理解
- 2. 实用性强
- 3. 字数:${targetLength}字左右
- 4. 直接返回正文内容`;
- return await this.callLLM(educationPrompt);
- }
- /**
- * 生成商务内容
- */
- async generateBusiness(prompt, targetLength) {
- const businessPrompt = `根据以下需求,生成商务内容:
- 需求:${prompt}
- 要求:
- 1. 语言专业得体
- 2. 目的明确
- 3. 字数:${targetLength}字左右
- 4. 直接返回正文内容`;
- return await this.callLLM(businessPrompt);
- }
- /**
- * 生成媒体内容
- */
- async generateMedia(prompt) {
- const mediaPrompt = `根据以下需求,生成媒体播报内容:
- 需求:${prompt}
- 要求:
- 1. 语言清晰流畅
- 2. 适合朗读或播报
- 3. 直接返回正文内容`;
- return await this.callLLM(mediaPrompt);
- }
- /**
- * 通用生成
- */
- async generateGeneric(prompt, targetLength) {
- const genericPrompt = `请用中文生成内容:${prompt},大约${targetLength}字,直接返回内容不要加标题`;
- return await this.callLLM(genericPrompt);
- }
- /**
- * 获取行业列表
- */
- getIndustries() {
- return industries;
- }
- /**
- * 行业适配
- */
- async adaptContent(content, industry) {
- const industryConfig = {
- '医疗健康': { terminology: true, compliance: '医疗广告法', sensitivity: 'high' },
- '教育培训': { terminology: true, compliance: '教育规范', sensitivity: 'medium' },
- '金融服务': { terminology: true, compliance: '金融监管', sensitivity: 'high' },
- '电子商务': { terminology: false, compliance: '电商法规', sensitivity: 'low' },
- };
- return {
- adapted: content,
- config: industryConfig[industry] || { terminology: false, compliance: '通用', sensitivity: 'low' },
- warnings: industryConfig[industry]?.sensitivity === 'high' ? ['需遵守相关法规'] : [],
- };
- }
- /**
- * 内容规划
- */
- async planContent(type, theme, targetLength) {
- const chapters = Math.ceil(targetLength / 5000);
- const outline = [];
- for (let i = 1; i <= chapters; i++) {
- outline.push({
- chapter: i,
- title: `第${i}章`,
- summary: `${theme} - 章节内容概要`,
- estimatedLength: Math.ceil(targetLength / chapters),
- });
- }
- return {
- type,
- theme,
- totalChapters: chapters,
- estimatedLength: targetLength,
- outline,
- };
- }
- /**
- * 生成大纲 - 使用 LLM
- */
- async generateOutline(type, theme, chapters) {
- const prompt = `请为一部${type}生成大纲。
- 主题:${theme}
- 章节数:${chapters}章
- 请以JSON格式返回,格式如下:
- {
- "outline": [
- {"id": "chapter-1", "title": "第1章:xxx", "description": "本章情节描述", "wordCount": xxx},
- ...
- ]
- }
- 要求:
- 1. 每章标题要体现本章核心情节
- 2. 描述要详细说明本章发生的关键事件
- 3. 每章预估字数3000-5000字
- 4. 章节之间要有逻辑衔接`;
- try {
- const response = await this.callLLM(prompt);
- // 尝试解析JSON
- const jsonMatch = response.match(/\{[\s\S]*\}/);
- if (jsonMatch) {
- const parsed = JSON.parse(jsonMatch[0]);
- return {
- outlineId: `outline-${Date.now()}`,
- outline: parsed.outline || [],
- theme,
- };
- }
- // 如果无法解析JSON,返回模拟数据
- throw new Error('无法解析LLM响应');
- }
- catch (error) {
- console.log('大纲生成失败,使用默认大纲:', error);
- // 返回默认大纲
- const outline = [];
- for (let i = 1; i <= chapters; i++) {
- outline.push({
- id: `chapter-${i}`,
- title: `第${i}章:${theme}的展开`,
- description: `详细描述第${i}章的情节发展,包括人物互动和故事推进`,
- wordCount: 3500 + Math.floor(Math.random() * 1500),
- });
- }
- return { outlineId: `outline-${Date.now()}`, outline, theme };
- }
- }
- /**
- * 生成角色设定 - 使用 LLM
- */
- async generateCharacters(type, genre) {
- const prompt = `为一个${type}项目生成角色设定。
- 题材风格:${genre}
- 请生成2-4个主要角色,以JSON格式返回:
- {
- "characters": [
- {"id": "char-1", "name": "角色名", "age": 年龄, "gender": "男/女", "personality": "性格特点", "role": "主角/配角", "avatar": ""},
- ...
- ]
- }
- 要求:
- 1. 主角性格要鲜明,有成长空间
- 2. 配角要有独特个性
- 3. 人物关系要合理`;
- try {
- const response = await this.callLLM(prompt);
- const jsonMatch = response.match(/\{[\s\S]*\}/);
- if (jsonMatch) {
- const parsed = JSON.parse(jsonMatch[0]);
- return parsed;
- }
- throw new Error('无法解析LLM响应');
- }
- catch (error) {
- console.log('角色生成失败,使用默认角色:', error);
- return {
- characters: [
- { id: 'char-1', name: '林浩', age: 28, gender: '男', personality: '正直勇敢,有责任心', role: '主角', avatar: '' },
- { id: 'char-2', name: '苏晴', age: 26, gender: '女', personality: '聪明机智,温柔体贴', role: '女主', avatar: '' },
- ],
- };
- }
- }
- /**
- * 分步生成内容 - 使用 LLM
- */
- async generateChunk(outlineId, chapterIndex, chapterTitle, previousContent) {
- const prompt = `请续写以下小说内容:
- ${previousContent ? `前文内容:\n${previousContent}\n\n` : ''}
- 请续写第${chapterIndex + 1}章内容。
- ${chapterTitle ? `章节标题:${chapterTitle}` : ''}
- 要求:
- 1. 内容要丰富、生动,不少于2000字
- 2. 包含人物对话、心理描写、场景描写
- 3. 情节要紧凑,有吸引力
- 4. 直接返回正文内容,不需要额外说明`;
- try {
- const content = await this.callLLM(prompt);
- return {
- chunkId: `chunk-${Date.now()}-${chapterIndex}`,
- chapterIndex,
- content: content,
- wordCount: content.length,
- status: 'completed',
- };
- }
- catch (error) {
- console.log('内容生成失败:', error);
- return {
- chunkId: `chunk-${Date.now()}-${chapterIndex}`,
- chapterIndex,
- content: `第${chapterIndex + 1}章内容\n\n[AI生成内容因接口问题暂未返回,请稍后重试...]`,
- wordCount: 0,
- status: 'error',
- };
- }
- }
- /**
- * 流式生成章节内容 - 使用 LLM SSE
- */
- async *streamGenerateChunk(outlineId, chapterIndex, chapterTitle, previousContent) {
- const prompt = `请续写以下小说内容:
- ${previousContent ? `前文内容:\n${previousContent}\n\n` : ''}
- 请续写第${chapterIndex + 1}章内容。
- ${chapterTitle ? `章节标题:${chapterTitle}` : ''}
- 要求:
- 1. 内容要丰富、生动,不少于2000字
- 2. 包含人物对话、心理描写、场景描写
- 3. 情节要紧凑,有吸引力
- 4. 直接返回正文内容,不需要额外说明`;
- const chunkId = `chunk-${Date.now()}-${chapterIndex}`;
- let fullContent = '';
- let charCount = 0;
- // 先发送开始信号
- yield {
- type: 'start',
- chunkId,
- chapterIndex,
- message: '开始生成...',
- };
- try {
- for await (const chunk of this.streamLLM(prompt)) {
- fullContent += chunk;
- charCount += chunk.length;
- // 实时发送内容片段
- yield {
- type: 'content',
- chunkId,
- chapterIndex,
- content: chunk,
- charCount,
- message: `已生成 ${charCount} 字...`,
- };
- }
- // 发送完成信号
- yield {
- type: 'done',
- chunkId,
- chapterIndex,
- content: fullContent,
- charCount: fullContent.length,
- wordCount: this.estimateWordCount(fullContent),
- status: 'completed',
- message: '生成完成!',
- };
- }
- catch (error) {
- console.error('流式生成失败:', error);
- yield {
- type: 'error',
- chunkId,
- chapterIndex,
- message: error.message || '生成失败',
- status: 'error',
- };
- }
- }
- /**
- * 估算字数(中文按字符,英文按单词)
- */
- estimateWordCount(text) {
- const chineseChars = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
- const englishWords = (text.match(/[a-zA-Z]+/g) || []).length;
- return chineseChars + Math.floor(englishWords * 0.5);
- }
- /**
- * 流式生成(模拟SSE)
- */
- async *streamGenerate(outlineId) {
- const chunks = ['内容开始...', '情节发展...', '高潮迭起...', '最终结局...'];
- for (const chunk of chunks) {
- await new Promise(resolve => setTimeout(resolve, 500));
- yield { type: 'chunk', content: chunk };
- }
- yield { type: 'done', content: '' };
- }
- /**
- * 创建生成任务
- */
- createTask(type, title) {
- return {
- taskId: `task-${Date.now()}`,
- type,
- title,
- status: 'pending',
- progress: 0,
- createdAt: new Date().toISOString(),
- };
- }
- /**
- * 获取任务列表
- */
- getTasks() {
- return [];
- }
- /**
- * 章节连贯性检查
- */
- async checkCoherence(chapter1, chapter2) {
- return {
- score: 0.8 + Math.random() * 0.15,
- issues: [],
- suggestions: [],
- };
- }
- /**
- * 生成衔接段
- */
- async generateContinuity(previousChapter, nextTopic) {
- return {
- content: `[衔接段] 时光飞逝,转眼间来到了${nextTopic}...`,
- wordCount: 200,
- };
- }
- /**
- * 敏感词检测
- */
- async checkSensitive(text) {
- const sensitiveWords = ['敏感词1', '敏感词2', '违规词'];
- const found = sensitiveWords.filter(w => text.includes(w));
- return {
- isClean: found.length === 0,
- foundWords: found,
- positions: found.map((w, i) => ({ word: w, index: text.indexOf(w) })),
- suggestions: found.length > 0 ? ['建议替换敏感词'] : [],
- };
- }
- /**
- * 质量评分
- */
- async scoreQuality(text) {
- const dimensions = {};
- qualityDimensions.forEach(dim => {
- dimensions[dim] = 70 + Math.random() * 25;
- });
- const overall = Object.values(dimensions).reduce((a, b) => a + b, 0) / Object.values(dimensions).length;
- return {
- overall: Math.round(overall),
- dimensions,
- report: '内容质量分析报告...',
- };
- }
- /**
- * 内容优化
- */
- async optimizeContent(text, target) {
- const prompt = `请优化以下内容,使其${target}:
- 原文:
- ${text}
- 要求:
- 1. 保持原文核心意思
- 2. 语言更加生动、流畅
- 3. 直接返回优化后的内容`;
- try {
- const optimized = await this.callLLM(prompt);
- return {
- original: text,
- optimized: optimized,
- improvements: ['语言更生动', '结构更清晰'],
- };
- }
- catch (error) {
- return {
- original: text,
- optimized: `[优化后] ${text}`,
- improvements: ['语言更生动', '结构更清晰'],
- };
- }
- }
- /**
- * 获取支持的语言
- */
- getLanguages() {
- return languages;
- }
- /**
- * 翻译并生成
- */
- async translateAndGenerate(text, targetLang, voiceStyle) {
- return {
- translated: `[${targetLang}] ${text}`,
- voiceStyle,
- audioUrl: `https://example.com/audio/translated-${Date.now()}.mp3`,
- };
- }
- /**
- * 智能匹配BGM
- */
- async matchBGM(contentType, mood, genre) {
- return {
- bgmId: `bgm-${Date.now()}`,
- name: `${mood}${genre}风格音乐`,
- url: 'https://example.com/bgm/matched.mp3',
- duration: 180,
- };
- }
- /**
- * 获取音效列表
- */
- getSounds() {
- return [
- { id: 'sound-1', name: '新闻开场', type: '转场' },
- { id: 'sound-2', name: '轻快背景', type: '氛围' },
- { id: 'sound-3', name: '紧张时刻', type: '情感' },
- ];
- }
- /**
- * 情感调节
- */
- async adjustEmotion(text, targetEmotion) {
- const prompt = `请将以下内容的情感调整为${targetEmotion}风格:
- 原文:
- ${text}
- 要求:
- 1. 保持原文核心意思
- 2. 情感表达更加${targetEmotion}
- 3. 直接返回调整后的内容`;
- try {
- const adjusted = await this.callLLM(prompt);
- return {
- original: text,
- adjusted: adjusted,
- emotion: targetEmotion,
- intensity: 0.8,
- };
- }
- catch (error) {
- return {
- original: text,
- adjusted: `[${targetEmotion}风格] ${text}`,
- emotion: targetEmotion,
- intensity: 0.8,
- };
- }
- }
- /**
- * 获取情感选项
- */
- getEmotions() {
- return emotions;
- }
- /**
- * 多角色对话生成
- */
- async generateDialogue(characters, scenario) {
- const charactersDesc = characters.map(c => `${c.name}(音色:${c.voice})`).join('、');
- const prompt = `请为以下角色生成一段对话:
- 角色:${charactersDesc}
- 场景:${scenario}
- 要求:
- 1. 对话自然流畅,符合各角色性格
- 2. 推动情节发展
- 3. 直接返回对话内容`;
- try {
- const dialogue = await this.callLLM(prompt);
- const lines = dialogue.split('\n').filter(line => line.trim());
- return {
- lines: lines.map((line, i) => ({
- character: characters[i % characters.length]?.name || '未知',
- voice: characters[i % characters.length]?.voice || '',
- dialogue: line,
- })),
- scenario,
- };
- }
- catch (error) {
- const lines = characters.map((char, i) => ({
- character: char.name,
- voice: char.voice,
- dialogue: `这是${char.name}的对话内容...`,
- }));
- return { lines, scenario };
- }
- }
- /**
- * SEO优化
- */
- async optimizeSEO(title, content, platform) {
- const prompt = `请为以下内容进行SEO优化:
- 标题:${title}
- 内容:${content.slice(0, 500)}...
- 目标平台:${platform}
- 请以JSON格式返回:
- {
- "optimizedTitle": "优化后的标题",
- "keywords": ["关键词1", "关键词2", "关键词3"],
- "suggestions": ["优化建议1", "优化建议2"]
- }`;
- try {
- const response = await this.callLLM(prompt);
- const jsonMatch = response.match(/\{[\s\S]*\}/);
- if (jsonMatch) {
- return JSON.parse(jsonMatch[0]);
- }
- }
- catch (error) { }
- return {
- optimizedTitle: `[SEO优化] ${title}`,
- keywords: ['关键词1', '关键词2', '关键词3'],
- suggestions: ['标题添加数字', '内容分段优化'],
- };
- }
- /**
- * 合规检查
- */
- async checkCompliance(text, industry) {
- return {
- passed: true,
- issues: [],
- warnings: industry === '医疗健康' ? ['注意医疗广告法规'] : [],
- };
- }
- /**
- * 内容分析报告
- */
- async generateAnalytics(contentId) {
- return {
- contentId,
- wordCount: 5000,
- readingTime: 15,
- emotionCurve: [0.3, 0.5, 0.8, 0.6, 0.4],
- keywords: ['关键词1', '关键词2', '关键词3'],
- reportUrl: `https://example.com/analytics/${contentId}`,
- };
- }
- /**
- * 智能续写
- */
- async continueContent(text, direction) {
- const prompt = `请续写以下内容,方向:${direction}:
- 原文:
- ${text}
- 要求:
- 1. 保持原文风格
- 2. 情节自然发展
- 3. 提供2-3个不同的续写方向
- 4. 以JSON格式返回:
- {
- "continuations": [
- {"content": "续写方向1", "score": 0.9},
- {"content": "续写方向2", "score": 0.8}
- ],
- "selected": 0
- }`;
- try {
- const response = await this.callLLM(prompt);
- const jsonMatch = response.match(/\{[\s\S]*\}/);
- if (jsonMatch) {
- return JSON.parse(jsonMatch[0]);
- }
- }
- catch (error) { }
- return {
- continuations: [
- { content: `续写方向1: ${text}...`, score: 0.9 },
- { content: `续写方向2: ${text}...`, score: 0.8 },
- ],
- selected: 0,
- };
- }
- /**
- * 异步内容生成(支持进度更新)
- */
- async generateContentAsync(taskId, prompt, targetLength = 2000) {
- const updateTask = (updates) => {
- const task = exports.generateTasks.get(taskId);
- if (task) {
- Object.assign(task, updates);
- }
- };
- try {
- // 阶段1:分析需求
- updateTask({ progress: 10, message: '正在分析需求...' });
- await new Promise(resolve => setTimeout(resolve, 500));
- // 阶段2:构建Prompt
- updateTask({ progress: 20, message: '正在构建生成Prompt...' });
- await new Promise(resolve => setTimeout(resolve, 300));
- // 系统性知识展开
- const finalPrompt = `你是一位专业的老师。请围绕用户的主题,系统性地讲解这个知识点。
- 用户主题:${prompt}
- 要求:
- 1. 首先分析这个主题涉及的核心领域和知识体系
- 2. 按照"大类 -> 小类 -> 具体知识点"的层次结构展开讲解
- 3. 每个知识点都要讲清楚"是什么"、"为什么"、"怎么用"
- 4. 内容要准确、全面、深入浅出
- 5. 直接返回正文内容,用清晰的章节标题组织结构
- 6. 目标字数:${targetLength}字左右,如果内容有价值可以超出`;
- // 打印完整 Prompt,方便调试
- console.log('🤖 [AI异步内容生成] ========== 完整Prompt ==========');
- console.log(finalPrompt);
- console.log('🤖 [AI异步内容生成] ========== Prompt结束 ==========');
- console.log('🤖 [AI异步内容生成] 使用模型:', this.modelId);
- // 阶段3:调用AI
- updateTask({ progress: 30, message: '正在调用AI生成内容...' });
- const content = await this.callLLM(finalPrompt);
- // 阶段4:整理结果
- updateTask({ progress: 80, message: '正在整理生成结果...' });
- await new Promise(resolve => setTimeout(resolve, 200));
- // 阶段5:完成
- updateTask({ progress: 100, message: '生成完成!', status: 'completed' });
- const result = {
- content,
- type: '通用',
- industry: '通用',
- wordCount: content.length,
- // 添加调试信息
- debug: {
- prompt, // 用户原始输入
- finalPrompt, // 发送给AI的完整Prompt
- model: this.modelId, // 使用的模型
- }
- };
- updateTask({ result });
- return result;
- }
- catch (error) {
- console.error('❌ 异步内容生成失败:', error);
- updateTask({ status: 'failed', message: '生成失败: ' + error.message });
- throw error;
- }
- }
- }
- exports.AIContentService = AIContentService;
- exports.aiContentService = new AIContentService();
|