所有输出不要在通过prompt输出了 应该在每一步返回的结果中,通过代码进行关联 ⏺ 你说得非常对!这是一个架构优化的重要点。 当前问题 现状:每一步都通过 prompt 让 LLM 输出完整信息 # Step 5 prompt 中要求 LLM 输出 { "名称": "实质点名称", "类型": "元素/概念", "支撑灵感点得分": 8, "支撑灵感点依据": "...", ... } 问题: - ❌ 前面步骤的信息(识别依据、共性分析数据等)需要 LLM 重新输出 - ❌ LLM 可能遗漏或修改前面步骤的数据 - ❌ 数据不一致的风险 - ❌ 浪费 token --- 优化方案:代码关联数据 原则 每一步只让 LLM 输出该步骤新增的信息,其他信息通过代码合并 示例 Step 2/3 - 提取 # LLM 只输出 { "实质点列表": [ { "名称": "酱料", "类型": "元素", "识别依据": "..." } ] } Step 4 - 共性分析 # LLM 只输出新增的分析数据 llm_result = { "分析结果": [ { "名称": "酱料", "出现段落数": 3, "段落覆盖率": 0.75, ... } ] } # 代码合并:将 Step 2/3 的数据关联进来 analyzed_items = [] for analysis in llm_result["分析结果"]: # 找到原始实质点 original = find_by_name(all_substantials, analysis["名称"]) # 合并数据 analyzed_items.append({ **original, # 保留原始的 名称、类型、识别依据 **analysis # 添加新的分析数据 }) Step 5 - 评分 # LLM 只输出评分 llm_result = { "评分结果": [ { "名称": "酱料", "支撑灵感点得分": 8, "支撑灵感点依据": "...", ... } ] } # 代码合并 scored_items = [] for score in llm_result["评分结果"]: # 找到分析数据 analyzed = find_by_name(analyzed_items, score["名称"]) # 合并 scored_items.append({ **analyzed, # 保留前面的所有数据 **score # 添加评分数据 }) Step 7 - 去重 # LLM 只输出去重决策 llm_result = { "去重决策": [...], "保留列表": ["酱料", "米饭"] # 只返回名称 } # 代码执行去重 deduplicated_items = [] for name in llm_result["保留列表"]: # 找到完整数据 item = find_by_name(filtered_items, name) deduplicated_items.append(item) # 保留所有历史数据 Step 8 - 整合 # LLM 只输出树状结构(只包含名称和分类) llm_result = { "元素列表": [ { "名称": "调味品", "描述": "...", "子项": [ {"名称": "酱料"} # 只有名称 ] } ] } # 代码填充完整数据 def enrich_tree(node, data_source): if "子项" in node and node["子项"]: for child in node["子项"]: if "名称" in child and "描述" not in child: # 这是叶子节点,填充完整数据 full_data = find_by_name(data_source, child["名称"]) child.update(full_data) else: # 递归处理 enrich_tree(child, data_source) final_result = llm_result enrich_tree(final_result, deduplicated_items) --- 优势 1. ✅ 数据一致性:前面步骤的数据不会被 LLM 修改或遗漏 2. ✅ 节省 token:LLM 只输出新增信息 3. ✅ 职责清晰:LLM 负责判断,代码负责数据管理 4. ✅ 减少依赖:后续步骤不需要传入 text_data/images,因为历史数据已包含上下文 --- 是否要现在重构? 这是一个较大的架构改动,需要修改所有 8 个步骤。 建议: 1. 先确认这个方向是否符合你的需求 2. 如果确认,我可以逐步重构每个步骤 你觉得这个方案如何? > 开始优化吧 ⏺ 好的!我开始优化。让我先创建任务列表,然后逐步重构每个步骤。 ⏺ 现在开始重构 Step 4。让我先读取相关代码: ⏺ Read(src/components/agents/script_element_extraction_agent.py) ⎿ Read 160 lines ⏺ 现在开始重构 Step 4。我将修改为: 1. LLM 只输出新增的共性分析数据(不包含名称、类型、识别依据) 2. 代码合并 Step 2/3 的原始数据 ⏺ Update(src/components/agents/script_element_extraction_agent.py) ⎿ Updated src/components/agents/script_element_extraction_agent.py with 12 additions and 8 removals 681 682 对每个实质点进行**共性定量分析**(统计基础数据)。 683 684 + **重要**:只输出新增的分析数据,不要重复输出名称、类型、识别依据等已有信息。 685 + 686 ## 元素的共性分析(仅针对类型=元素) 687 688 1. **出现段落数**:该元素在多少个段落中出现(整数) ... 700 3. **核心概念识别**:在每个出现的段落中是主要概念还是辅助概念 701 - 主要概念:该概念是段落的核心主题 702 - 辅助概念:该概念是段落的补充说明 703 - 4. **概念强度**:在每个段落中的重要性权重(0-10分) 703 + 4. **概念强度详情**:在每个段落中的重要性权重(0-10分) 704 - 9-10分:段落核心概念,定义段落主题 705 - 7-8分:段落重要概念,有明显作用 706 - 5-6分:段落一般概念,有一定作用 ... 711 712 - 定量指标必须准确计算 713 - 所有分析必须有客观依据 714 + - **只输出名称和对应的分析数据,不要重复已有字段** 715 716 # 输出(JSON) 717 ... 718 "分析结果": [ 719 {{ 720 "名称": "实质点名称", 721 - "类型": "元素/概念", 722 - 723 - // 元素类型的共性分析 721 + // 元素类型只输出以下字段 722 "出现段落数": 3, 723 "段落覆盖率": 0.75, 724 "出现频次": 5, 725 "视觉显著性": 8, 726 - "视觉显著性依据": "在图片中的位置和显著程度描述", 727 - 728 - // 概念类型的共性分析 726 + "视觉显著性依据": "在图片中的位置和显著程度描述" 727 + }}, 728 + {{ 729 + "名称": "实质点名称", 730 + // 概念类型只输出以下字段 731 "出现段落数": 3, 732 "段落覆盖率": 0.75, 733 "核心概念识别": [ ... 749 750 **注意**: 751 - 元素类型的实质点,输出元素相关的共性分析字段 752 - - 概念类型的实质点,输出概念相关的共性分析字段""" 752 + - 概念类型的实质点,输出概念相关的共性分析字段 753 + - 不要输出类型、识别依据等字段,这些会由代码自动合并 754 755 # 构建多模态消息 756 message_content = [{"type": "text", "text": prompt}] ⏺ 现在添加代码合并逻辑: ⏺ Update(src/components/agents/script_element_extraction_agent.py) ⎿ Updated src/components/agents/script_element_extraction_agent.py with 29 additions and 2 removals 771 ] 772 773 # 调用LLM 774 - result = LLMInvoker.safe_invoke( 774 + llm_result = LLMInvoker.safe_invoke( 775 self, 776 "共性定量分析", 777 messages, 778 fallback={"分析结果": []} 779 ) 780 781 + # 代码合并:将原始实质点数据与分析数据合并 782 + analyzed_items = [] 783 + analysis_results = llm_result.get("分析结果", []) 784 + 785 + for analysis in analysis_results: 786 + analysis_name = analysis.get("名称", "") 787 + # 找到对应的原始实质点 788 + original = None 789 + for s in all_substantials: 790 + if s.get("名称") == analysis_name: 791 + original = s 792 + break 793 + 794 + if original: 795 + # 合并数据:原始数据 + 分析数据 796 + merged_item = { 797 + **original, # 保留原始的名称、类型、识别依据 798 + **{k: v for k, v in analysis.items() if k != "名称"} # + 添加分析数据(排除名称) 799 + } 800 + analyzed_items.append(merged_item) 801 + else: 802 + logger.warning(f"⚠️ 未找到实质点 '{analysis_name}' 的原始数据") 803 + # 如果找不到原始数据,仍然保留分析结果 804 + analyzed_items.append(analysis) 805 + 806 + result = {"分析结果": analyzed_items} 807 + 808 # 打印结果 809 import json 810 - logger.info(f"Step 4 - 结果:\n{json.dumps(result, ensure_ascii=False, indent=2)}") 810 + logger.info(f"Step 4 合并后 + 结果:\n{json.dumps(result, ensure_ascii=False, indent=2)}") 811 812 return result 813 ⏺ 完成 Step 4!现在继续 Step 5: ✻ 修改 Step 5… (esc to interrupt · ctrl+t to hide todos · 142s · ↓ 2.9k tokens) ⎿ ☒ Step 4: 修改为只输出新增的共性分析数据,代码合并 Step 2/3 的原始数据 ☐ Step 5: 修改为只输出评分数据,代码合并 Step 4 的分析数据 ☐ Step 6: 修改筛选逻辑,基于完整数据筛选 ☐ Step 7: 修改为只输出去重决策,代码执行去重并保留完整数据,移除 text_data 参数 ☐ Step 8: 修改为只输出树状结构框架,代码填充完整数据,移除 text_data 参数