$npx -y skills add Supreme-Ultimate/novel-to-script-team --skill one-by-one-comparison-skill逐一对比技能。将生成剧本与每个参考剧本逐一对比,按照剧本评价标准给出详细批判和改进建议。
| 1 | # 逐一对比技能 |
| 2 | |
| 3 | ## 必读 |
| 4 | 1. `../../references/00-first-principles.md` |
| 5 | 2. `../../references/03-script-writing-standard.md` |
| 6 | 3. `../../references/04-review-gates.md` |
| 7 | |
| 8 | ## 技能说明 |
| 9 | |
| 10 | 将生成剧本与检索到的Top 5参考剧本逐一对比,每次对比都按照统一的评价标准进行深度分析,给出具体的批判和改进建议。 |
| 11 | |
| 12 | ## 评价标准(100分制) |
| 13 | |
| 14 | ### 1. 节奏控制(20分) |
| 15 | |
| 16 | **评分细则**: |
| 17 | - 场景数量(5分):与参考剧本相差±2个场景内得满分 |
| 18 | - 场景时长分配(5分):时长分布合理,有快有慢 |
| 19 | - 冲突密度(5分):冲突次数/总字数 ≥ 0.03 |
| 20 | - 节奏变化(5分):有明显的节奏起伏 |
| 21 | |
| 22 | **对比方法**: |
| 23 | ```python |
| 24 | # 统计生成剧本 |
| 25 | gen_scenes = count_scenes(generated_script) |
| 26 | gen_conflicts = count_conflicts(generated_script) |
| 27 | gen_conflict_density = gen_conflicts / len(generated_script) |
| 28 | |
| 29 | # 统计参考剧本 |
| 30 | ref_scenes = count_scenes(reference_script) |
| 31 | ref_conflicts = count_conflicts(reference_script) |
| 32 | ref_conflict_density = ref_conflicts / len(reference_script) |
| 33 | |
| 34 | # 评分 |
| 35 | scene_score = 5 if abs(gen_scenes - ref_scenes) <= 2 else max(0, 5 - abs(gen_scenes - ref_scenes)) |
| 36 | conflict_score = 5 if gen_conflict_density >= 0.03 else gen_conflict_density / 0.03 * 5 |
| 37 | ``` |
| 38 | |
| 39 | ### 2. 对话风格(25分) |
| 40 | |
| 41 | **评分细则**: |
| 42 | - 对话比例(10分):70%+ 得满分,每低5%扣2分 |
| 43 | - 句长控制(8分):平均10-14字符得满分 |
| 44 | - 短句比例(4分):30-40%得满分 |
| 45 | - 对话自然度(3分):人物区分度、口语化程度 |
| 46 | |
| 47 | **对比方法**: |
| 48 | ```python |
| 49 | # 对话比例 |
| 50 | gen_dialogue_ratio = calculate_dialogue_ratio(generated_script) |
| 51 | ref_dialogue_ratio = calculate_dialogue_ratio(reference_script) |
| 52 | |
| 53 | dialogue_score = 10 if gen_dialogue_ratio >= 0.7 else gen_dialogue_ratio / 0.7 * 10 |
| 54 | |
| 55 | # 句长 |
| 56 | gen_avg_length = calculate_avg_sentence_length(generated_script) |
| 57 | ref_avg_length = calculate_avg_sentence_length(reference_script) |
| 58 | |
| 59 | if 10 <= gen_avg_length <= 14: |
| 60 | length_score = 8 |
| 61 | else: |
| 62 | length_score = max(0, 8 - abs(gen_avg_length - 12) * 0.5) |
| 63 | ``` |
| 64 | |
| 65 | ### 3. 视觉化表达(20分) |
| 66 | |
| 67 | **评分细则**: |
| 68 | - 视觉标记密度(10分):3-5个/100字得满分 |
| 69 | - 表情描写(4分):冷笑、嗤笑、冷哼等 |
| 70 | - 眼神描写(3分):眼神一冷、眸光一沉等 |
| 71 | - 动作描写(3分):嘴角勾起、挑眉、转身等 |
| 72 | |
| 73 | **对比方法**: |
| 74 | ```python |
| 75 | visual_markers = ['冷笑', '嗤笑', '冷哼', '眼神一冷', '眸光一沉', '嘴角勾起', '挑眉', '转身'] |
| 76 | |
| 77 | gen_marker_density = count_markers(generated_script, visual_markers) / (len(generated_script) / 100) |
| 78 | ref_marker_density = count_markers(reference_script, visual_markers) / (len(reference_script) / 100) |
| 79 | |
| 80 | if 3 <= gen_marker_density <= 5: |
| 81 | marker_score = 10 |
| 82 | else: |
| 83 | marker_score = max(0, 10 - abs(gen_marker_density - 4) * 2) |
| 84 | ``` |
| 85 | |
| 86 | ### 4. 网文感(20分) |
| 87 | |
| 88 | **评分细则**: |
| 89 | - 网文感关键词密度(10分):1.5-2.5个/100字得满分 |
| 90 | - 情绪强化词(4分):冷笑、嗤笑、冷哼、冷声等 |
| 91 | - 态度词(3分):不屑、轻蔑、讥讽、嘲讽等 |
| 92 | - 打脸节奏(3分):打脸场景数量和质量 |
| 93 | |
| 94 | **对比方法**: |
| 95 | ```python |
| 96 | wanwen_keywords = { |
| 97 | '情绪强化': ['冷笑', '嗤笑', '冷哼', '冷声', '冷冷地'], |
| 98 | '态度词': ['不屑', '轻蔑', '讥讽', '嘲讽', '鄙夷'], |
| 99 | '气场词': ['霸气', '强势', '凌厉', '锐利', '凛然'], |
| 100 | '打脸词': ['啪啪打脸', '狠狠打脸', '当场打脸', '脸色一变'] |
| 101 | } |
| 102 | |
| 103 | gen_keyword_density = count_all_keywords(generated_script, wanwen_keywords) / (len(generated_script) / 100) |
| 104 | ref_keyword_density = count_all_keywords(reference_script, wanwen_keywords) / (len(reference_script) / 100) |
| 105 | |
| 106 | if 1.5 <= gen_keyword_density <= 2.5: |
| 107 | keyword_score = 10 |
| 108 | else: |
| 109 | keyword_score = max(0, 10 - abs(gen_keyword_density - 2) * 3) |
| 110 | ``` |
| 111 | |
| 112 | ### 5. 结构完整性(15分) |
| 113 | |
| 114 | **评分细则**: |
| 115 | - 开局钩子(3分):前10%是否有强冲突 |
| 116 | - 中段冲突(4分):中间60%是否持续有冲突 |
| 117 | - 高潮设计(3分):是否有明显高潮点 |
| 118 | - 反转设置(3分):是否有意外反转 |
| 119 | - 结尾悬念(2分):是否有强钩子 |
| 120 | |
| 121 | **对比方法**: |
| 122 | ```python |
| 123 | structure_elements = { |
| 124 | 'hook': check_opening_hook(script), # True/False |
| 125 | 'development': check_continuous_conflict(script), |
| 126 | 'climax': check_climax(script), |
| 127 | 'twist': check_twist(script), |
| 128 | 'ending': check_ending_hook(script) |
| 129 | } |
| 130 | |
| 131 | structure_score = sum([ |
| 132 | 3 if structure_elements['hook'] else 0, |
| 133 | 4 if structure_elements['development'] else 0, |
| 134 | 3 if structure_elements['climax'] else 0, |
| 135 | 3 if structure_elements['twist'] else 0, |
| 136 | 2 if structure_elements['ending'] else 0 |
| 137 | ]) |
| 138 | ``` |
| 139 | |
| 140 | ## 执行流程 |
| 141 | |
| 142 | ### Step 1: 加载剧本 |
| 143 | |
| 144 | ```python |
| 145 | # 加载生成剧本 |
| 146 | with open(f'outputs/{剧本名}/scripts/ep{N}.md', 'r') as f: |
| 147 | generated_script = f.read() |
| 148 | |
| 149 | # 加载参考剧本列表(从检索结果或style-analysis报告中获取) |
| 150 | reference_files = [ |
| 151 | 'knowledge/hit-scripts-md/参考剧本1.md', |
| 152 | 'knowledge/hit-scripts-md/参考剧本2.md', |
| 153 | 'knowledge/hit-scripts-md/参考剧本3.md', |
| 154 | 'knowledge/hit-scripts-md/参考剧本4.md', |
| 155 | 'knowledge/hit-scripts-md/参考剧本5.md' |
| 156 | ] |
| 157 | |
| 158 | reference_scripts = [] |
| 159 | for ref_file in reference_files: |
| 160 | with open(ref_file, 'r') as f: |
| 161 | reference_scripts.append({ |
| 162 | 'filename': os.path.basename(ref_file), |
| 163 | 'content': f.read() |
| 164 | }) |
| 165 | ``` |
| 166 | |
| 167 | ### Step 2: 逐个对比 |
| 168 | |
| 169 | ```python |
| 170 | comparison_results = [] |
| 171 | |
| 172 | for i, ref in enumerate(reference_scripts, 1): |
| 173 | print(f"\n{'='*80}") |
| 174 | print(f"对比 {i}/5: 生成剧本 vs {ref['filename']}") |
| 175 | print(f"{'='*80}\n") |
| 176 | |
| 177 | # 五大维度评分 |
| 178 | rhythm_score = compare_rhythm(generated_script, ref['content']) |
| 179 | dialogue_score = compare_dialogue(generated_script, ref['content']) |
| 180 | visual_score = compare_visual(generated_script, ref['content']) |
| 181 | wanwen_score = compare_wanwen(generated_script, ref['content']) |
| 182 | structure_score = compare_structure(generated_script, ref['content']) |
| 183 | |
| 184 | total_score = rhythm_score + dialogue_score + visual_score + wanwen_score + structure_score |
| 185 | |
| 186 | # 识别具体问题 |
| 187 | issues = identify_issues(generated_script, ref['content']) |
| 188 | |
| 189 | # 提取参考示例 |
| 190 | examples = extract_examples(ref['content'], issues) |
| 191 | |
| 192 | # 生 |