Browse Source

重新生成整集分段剧本的提示词和参数调优

lh 3 weeks ago
parent
commit
8f2ba4c61f
1 changed files with 37 additions and 11 deletions
  1. 37 11
      app/Services/DeepSeek/DeepSeekService.php

+ 37 - 11
app/Services/DeepSeek/DeepSeekService.php

@@ -807,6 +807,7 @@ class DeepSeekService
         // 如果提供了script_id,从数据库获取剧本内容作为原文
         $originalContent = '';
         $hasValidScript = false;
+        $rawPrompt = $prompt; // 保存用户原始输入,供模板一致性判断
         if ($script_id > 0) {
             $script = DB::table('mp_scripts')
                 ->where('id', $script_id)
@@ -838,7 +839,14 @@ class DeepSeekService
             }
             $templatePrompt = $template->template_prompt ?? '';
             if (!empty($templatePrompt)) {
-                if (!empty($prompt)) {
+                // 模板提示词与用户输入基本一致时只保留一个,避免重复提示词
+                // 剧本模式下当前 prompt 含原文内容需保留,其余情况以模板内容为准
+                $trimmedRawPrompt = trim((string)$rawPrompt);
+                if ($trimmedRawPrompt !== '' && mb_strtolower($trimmedRawPrompt) === mb_strtolower(trim($templatePrompt))) {
+                    if (!$hasValidScript) {
+                        $prompt = $templatePrompt;
+                    }
+                } elseif (!empty($prompt)) {
                     $prompt = $templatePrompt . "\n\n" . $prompt;
                 } else {
                     $prompt = $templatePrompt;
@@ -1174,6 +1182,7 @@ class DeepSeekService
         // 新增: 如果提供了script_id,从数据库获取剧本内容作为原文
         $originalContent = '';
         $hasValidScript = false; // 是否已加载到有效剧本(存在且内容非空)
+        $rawPrompt = $prompt; // 保存用户原始输入,供模板一致性判断
         if ($script_id > 0) {
             $script = DB::table('mp_scripts')
                 ->where('id', $script_id)
@@ -1216,8 +1225,15 @@ class DeepSeekService
             
             // 将模板提示词和用户输入的prompt组合
             // 模板为准,用户输入作为补充要求
+            // 模板提示词与用户输入基本一致时只保留一个,避免重复提示词
+            // 剧本模式下当前 prompt 含原文内容需保留,其余情况以模板内容为准
             if (!empty($templatePrompt)) {
-                if (!empty($prompt)) {
+                $trimmedRawPrompt = trim((string)$rawPrompt);
+                if ($trimmedRawPrompt !== '' && mb_strtolower($trimmedRawPrompt) === mb_strtolower(trim($templatePrompt))) {
+                    if (!$hasValidScript) {
+                        $prompt = $templatePrompt;
+                    }
+                } elseif (!empty($prompt)) {
                     $prompt = $templatePrompt . "\n\n" . $prompt;
                 } else {
                     $prompt = $templatePrompt;
@@ -12307,12 +12323,16 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
             $template_prompt = $template->template_prompt ?? '';
         }
         
-        // 合并用户提示词和模板提示词
+        // 合并用户提示词和模板提示词(模板提示词与用户输入基本一致时只保留一个,避免重复提示词)
         $final_prompt = '';
         if (!empty($template_prompt)) {
-            $final_prompt = $template_prompt;
-            if (!empty($prompt)) {
-                $final_prompt .= "\n\n补充要求:" . $prompt;
+            $trimmedPrompt = trim((string)$prompt);
+            if ($trimmedPrompt !== '' && mb_strtolower($trimmedPrompt) === mb_strtolower(trim($template_prompt))) {
+                $final_prompt = $template_prompt;
+            } elseif (!empty($prompt)) {
+                $final_prompt = $template_prompt . "\n\n补充要求:" . $prompt;
+            } else {
+                $final_prompt = $template_prompt;
             }
         } else {
             $final_prompt = $prompt;
@@ -12383,7 +12403,7 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
 
             $episode_content = DB::table('mp_anime_episodes')->where('id', $episode_id)->value('content');
             if ($episode_content) {
-                $reference_content = "\n\n【本集原始内容】\n{$episode_content}\n\n【本集生成剧本内容】\n{$reference_content}";
+                $reference_content = "\n\n【本集原始内容】\n{$episode_content}\n\n【原分段剧本内容】\n{$reference_content}";
                 //$reference_content = "\n\n【本集原始内容】\n{$episode_content}";
             }else {
                 $reference_content = "\n\n【原分段剧本内容】\n{$reference_content}";
@@ -12494,6 +12514,7 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
         $user_prompt .= $intro_ref;
         $user_prompt .= $art_style_ref;
         $user_prompt .= $reference_content;
+        $user_prompt .= "\n\n【生成要求】\n- 请以【原分段剧本内容】为蓝本,保留剧情脉络、角色、场景与分段结构,但必须围绕【用户要求】对相关片段进行实质性修改;若【用户要求】未指定具体修改点,也需对画面、运镜、台词等描述进行改写,禁止整段原样复制。\n";
         // $user_prompt .= $roles_ref;
         // $user_prompt .= $scenes_ref;
 
@@ -12527,8 +12548,10 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
         $system_prompt .= "- 输出前检查:若缺少##片段N标题或时长行,视为输出无效,必须修正后输出\n\n";
 
         $system_prompt .= "【强制要求】\n";
-        $system_prompt .= "- 请仅生成<分段剧本>部分,不要生成其他任何内容:";
-        $system_prompt .= "- 第一优先级:片段时长上限(单个片段不超过15秒,超过必须切为新片段)";
+        // $system_prompt .= "- 请严格参考【本集原始内容】或【原分段剧本内容】进行本次生成,注意新生成的分段剧本内容一定不要跟【原分段剧本内容】一致,要进行一定程度调整\n";
+        $system_prompt .= "- 【重要】必须参考【本集原始内容】与【原分段剧本内容】中的剧情脉络、角色、场景、道具和分段结构,但严禁原样复制或几乎照抄原文;必须围绕【用户要求】对相关内容进行实质性修改,若生成结果与【原分段剧本内容】完全一致或未体现用户要求,视为生成失败\n";
+        $system_prompt .= "- 请仅生成<分段剧本>部分,不要生成其他任何内容:\n";
+        $system_prompt .= "- 第一优先级:片段时长上限(单个片段不超过15秒,超过必须切为新片段)\n";
         $system_prompt .= "- 每个分镜包含:分镜序号、出场角色、场景、出场道具、画面、运镜、配音台词、背景音效\n";
         $system_prompt .= "- 场景必须从【场景列表参考】中选择(如果提供了场景列表),场景名必须精确匹配【场景列表参考】中的名称(如需匹配“酒店会客室-景池筹备会版”,而不是“酒店会客室”,不得缺少“-”前后和“:”前面的任何内容,不能自创,不能自创){$scenes_ref}\n";
         $system_prompt .= "- 出场角色(如果有出现在本分镜)必须从【主体列表参考】中选择(如果提供了主体列表),角色名必须精准匹配【主体列表参考】中的名称(如需匹配“沈秋岚-程家居家围裙造型”,而不是“沈秋岚”,不得缺少“-”前后和“:”前面的任何内容,不能自创,不能自创){$roles_ref}\n";
@@ -12585,8 +12608,8 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
         $post_data = [
             'model' => $model,
             'messages' => $messages,
-            'temperature' => (float)env('TEXT_TEMPERATURE'),
-            'frequency_penalty' => 0,
+            'temperature' => 1.35,
+            'frequency_penalty' => 0.3,
             'presence_penalty' => 0,
             'response_format' => ['type' => 'text'],
             'thinking' => ['type' => $thinkingMode],
@@ -12618,6 +12641,9 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
             
             $generated_content = $fullContent;
             
+            // 归一化"场景:"标签换行格式:场景:\n场景名\n => 场景:场景名\n,保证场景字段为一行
+            $generated_content = preg_replace('/场景[::]\s*\n\s*([^\n]+)/u', '场景:$1', $generated_content);
+            
             if (empty($generated_content)) {
                 Utils::throwError('20003:AI生成内容为空,请重试');
             }