""" Post Summary Deconstruction Agent. 帖子整体解构Agent:解构帖子整体的各种描述维度。 """ from typing import Dict, Any, List import json from src.components.agents.base import BaseLLMAgent from src.states.what_deconstruction_state import WhatDeconstructionState from src.utils.logger import get_logger logger = get_logger(__name__) class PostSummaryDeconstructionAgent(BaseLLMAgent): """帖子整体解构Agent 根据 PRD 1.4 - 2.2.2.2 帖子整体节点要求: **核心功能**: 1. 综合所有子元素的解构结果(图片、文本) 2. 从多个描述维度解构帖子整体 3. 帖子总体的各种描述、总结、归纳等维度或角度,每一个维度都是一个字段项 **必须满足的约束条件**: 1. 维度名称和数量根据每篇帖子动态变化 2. **一定要包含本帖子最关键/最吸引内容消费者的亮点维度** - 包括但不限于:内容亮点、情绪共鸣点、创作手法等维度 3. **描述维度的数量不得少于3个** - 要尽可能多而全的覆盖这个帖子的所有可描述角度 4. 包括但不限于:品类、主题、脚本等维度 5. 描述维度应根据帖子的品类、主题、关键词等信息来向知识库动态请求询问 """ def __init__( self, name: str = "post_summary_deconstruction_agent", description: str = "解构帖子整体的各种描述维度", model_provider: str = "google_genai", temperature: float = 0.1, max_tokens: int = 10240 ): system_prompt = """你是一个专业的内容分析专家。你的任务是从多个维度解构帖子整体。 根据 PRD 1.4 - 2.2.2.2 帖子整体节点要求: **核心任务**: 1. 综合分析所有子元素(图片、文本)的解构结果 2. 从多个描述维度解构帖子整体 3. 帖子总体的各种描述、总结、归纳等维度或角度,每一个维度都是一个字段项 **必须满足的约束条件**: 1. ✅ 维度名称和数量根据每篇帖子动态变化 2. ✅ **一定要包含本帖子最关键/最吸引内容消费者的亮点维度** - 包括但不限于:内容亮点、情绪共鸣点、创作手法等维度 3. ✅ **描述维度的数量不得少于3个** - 要尽可能多而全的覆盖这个帖子的所有可描述角度 4. ✅ 包括但不限于:品类、主题、脚本等维度 5. ✅ 描述维度应根据帖子的品类、主题、关键词等信息来向知识库动态请求询问 - Query句式(参见 PRD 1.4 - 3.2): 对于一篇主题为"{帖子主题}",品类为"{帖子品类}",关键词包含"{帖子关键词列表}"的多模态社交媒体帖子, 从内容创作者视角进行What要素的初步识别和分类,需要使用哪些通用工具? **输出格式必须是JSON**: { "品类": "值", "主题": "值", "脚本": "值", "内容亮点": "值", # 必须包含 "情绪共鸣点": "值", # 必须包含 "创作手法": "值", # 必须包含 "整体风格": "值", "视觉呈现": "值", "内容价值": "值", "目标受众": "值", ... # 其他动态维度(根据帖子特点) } **输出要求**: 1. ✅ 客观准确,严格基于实际解构结果,禁止主观臆测、凭空假设、虚构数据 2. ✅ 维度名称和数量根据帖子内容动态确定 3. ✅ 突出核心特征和亮点 4. ✅ **最少包含3个描述维度** 5. ✅ 必须包含"内容亮点"、"情绪共鸣点"、"创作手法"等吸引消费者的亮点维度 """ super().__init__( name=name, description=description, model_provider=model_provider, system_prompt=system_prompt, temperature=temperature, max_tokens=max_tokens ) def _build_messages(self, state: WhatDeconstructionState) -> List[Dict[str, Any]]: """构建消息 包含所有子元素解构结果、消费者亮点、总结维度 """ messages = [ {"role": "system", "content": self.system_prompt} ] # 构建用户消息 user_prompt = "# 帖子解构结果\n\n" # 添加帖子基本信息 category = state.get("category", "未知") theme = state.get("theme", "未知") keywords = state.get("keywords", []) user_prompt += f"**品类**:{category}\n" user_prompt += f"**主题**:{theme}\n" user_prompt += f"**关键词**:{', '.join(keywords)}\n\n" # 添加图片解构结果 image_results = state.get("image_deconstruction_results", []) if image_results: user_prompt += "## 图片元素解构\n\n" for idx, img_result in enumerate(image_results, 1): what = img_result.get("what", "") desc = img_result.get("description", img_result.get("描述", {})) user_prompt += f"### 图片 {idx}\n" user_prompt += f"**What**: {what}\n" user_prompt += f"**描述**: {json.dumps(desc, ensure_ascii=False, indent=2)}\n\n" # 添加文本解构结果 text_results = state.get("text_deconstruction_results", []) if text_results: user_prompt += "## 文本元素解构\n\n" for idx, text_result in enumerate(text_results, 1): what = text_result.get("what", "") desc = text_result.get("description", text_result.get("描述", {})) user_prompt += f"### 文本元素 {idx}\n" user_prompt += f"**What**: {what}...\n" # 限制长度 user_prompt += f"**描述**: {json.dumps(desc, ensure_ascii=False, indent=2)}\n\n" # 添加消费者亮点 consumer_highlights = state.get("consumer_highlights", []) if consumer_highlights: user_prompt += "## 消费者关注的亮点\n\n" for idx, highlight in enumerate(consumer_highlights, 1): element = highlight.get("element", "") highlight_desc = highlight.get("highlight", "") emotion = highlight.get("emotion", "") user_prompt += f"{idx}. **{element}**: {highlight_desc} ({emotion})\n" user_prompt += "\n" # 添加总结维度要求 # 根据 PRD 1.4 - 2.2.2.2: # - 描述维度有哪些、有多少个,需要根据本帖子的品类、主题、关键词等信息来向知识库动态请求询问 # - Query句式:参见3.2 环节中对query的定义 # 这里使用默认维度作为示例(实际应从知识库获取) summary_dimensions = state.get("summary_dimensions", [ "品类", "主题", "脚本", "内容亮点", "情绪共鸣点", "创作手法", "整体风格", "视觉呈现", "内容价值", "目标受众" ]) user_prompt += "## 解构维度\n\n" user_prompt += "请根据以下维度进行帖子整体解构(至少包含3个维度):\n" for dim in summary_dimensions: user_prompt += f"- {dim}\n" user_prompt += "\n请严格按照JSON格式输出,字段名为上述维度名。至少包含3个描述维度。" messages.append({"role": "user", "content": user_prompt}) return messages def _update_state(self, state: WhatDeconstructionState, response: Any) -> Dict[str, Any]: """更新状态 解析LLM返回的JSON,更新帖子整体 """ try: # 提取响应内容 if hasattr(response, 'content'): content = response.content else: content = str(response) # 尝试提取JSON content = content.strip() if "```json" in content: content = content.split("```json")[1].split("```")[0].strip() elif "```" in content: content = content.split("```")[1].split("```")[0].strip() # 解析JSON result = json.loads(content) # 返回更新后的字段 return { "post_overall": result # 更新为 post_overall } except Exception as e: logger.error(f"解析帖子整体响应失败: {e},原始内容: {response}") # 返回默认值 return { "post_overall": { "错误": f"解析失败: {str(e)}" } }