2025-07-31 15:35:23 +08:00

738 lines
72 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"file_path": "travel-algorithms/travel_algorithms/poster_generation/text_generator.py",
"file_size": 15888,
"line_count": 529,
"functions": [
{
"name": "__init__",
"line_start": 25,
"line_end": 49,
"args": [
{
"name": "self"
},
{
"name": "config",
"type_hint": "AlgorithmConfig"
},
{
"name": "ai_service",
"type_hint": "AIService"
},
{
"name": "prompt_manager",
"type_hint": "PromptManager"
},
{
"name": "json_processor",
"type_hint": "JSONProcessor"
}
],
"return_type": null,
"docstring": "初始化文本生成器\n\nArgs:\n config: 算法配置\n ai_service: AI服务\n prompt_manager: 提示词管理器\n json_processor: JSON处理器",
"is_async": false,
"decorators": [],
"code": " def __init__(\n self, \n config: AlgorithmConfig, \n ai_service: AIService,\n prompt_manager: PromptManager,\n json_processor: JSONProcessor\n ):\n \"\"\"\n 初始化文本生成器\n\n Args:\n config: 算法配置\n ai_service: AI服务\n prompt_manager: 提示词管理器\n json_processor: JSON处理器\n \"\"\"\n self.config = config\n self.ai_service = ai_service\n self.prompt_manager = prompt_manager\n self.json_processor = json_processor\n \n # 获取任务特定的模型配置\n self.task_model_config = config.ai_model.get_task_config(\"poster_generation\")\n \n logger.info(\"海报文本生成器初始化完成\")",
"code_hash": "15b338066890e13ec89a2fd8eda25792"
},
{
"name": "_get_poster_system_prompt",
"line_start": 158,
"line_end": 177,
"args": [
{
"name": "self"
}
],
"return_type": "str",
"docstring": "获取海报生成的系统提示词",
"is_async": false,
"decorators": [],
"code": " def _get_poster_system_prompt(self) -> str:\n \"\"\"获取海报生成的系统提示词\"\"\"\n try:\n # 尝试从文件加载\n return self.prompt_manager.get_prompt(\"poster_generation\", \"system\")\n except:\n # 使用默认提示词\n return \"\"\"你是一个专业的海报文案创作者,专门为旅游、美食、生活方式等主题创作吸引人的海报文案。\n\n你的任务是根据给定的主题信息创作适合海报展示的文案内容包括\n1. 吸引人的标题简洁有力15字以内\n2. 核心内容描述(生动形象,突出亮点)\n3. 相关标签3-5个关键词\n4. 行动召唤语句(激发用户行动)\n\n要求\n- 文案要有感染力和画面感\n- 适合目标受众的语言风格\n- 突出主题的独特价值\n- 符合海报的视觉传达需求\"\"\"",
"code_hash": "020636f01d802e8b218c8759f9900dcb"
},
{
"name": "_get_vibrant_system_prompt",
"line_start": 179,
"line_end": 208,
"args": [
{
"name": "self"
}
],
"return_type": "str",
"docstring": "获取Vibrant模板专用的系统提示词",
"is_async": false,
"decorators": [],
"code": " def _get_vibrant_system_prompt(self) -> str:\n \"\"\"获取Vibrant模板专用的系统提示词\"\"\"\n return \"\"\"你是一名专业的海报设计师专门设计宣传海报。你现在要根据用户提供的信息生成适合Vibrant模板的海报内容。\n\n## Vibrant模板特点\n- 单图背景,毛玻璃渐变效果\n- 两栏布局(左栏内容,右栏价格)\n- 适合展示套餐内容和价格信息\n\n## 你需要生成的数据结构包含以下字段:\n\n**必填字段:**\n1. `title`: 主标题8-12字符体现产品特色\n2. `slogan`: 副标题/宣传语10-20字符吸引人的描述\n3. `price`: 价格数字(纯数字,不含符号),如果材料中没有价格,则用\"欢迎咨询\"替代\n4. `ticket_type`: 票种类型(如\"成人票\"、\"套餐票\"、\"夜场票\"等)\n5. `content_button`: 内容按钮文字(通常为\"套餐内容\"、\"包含项目\"等)\n6. `content_items`: 套餐内容列表3-5个项目每项5-15字符不要只包含项目名称要做合适的美化可以适当省略\n\n**可选字段:**\n7. `remarks`: 备注信息1-3条每条10-20字符\n8. `tag`: 标签1条, 如\"#限时优惠\"等)\n9. `pagination`: 分页信息(如\"1/3\",可为空)\n\n## 内容创作要求:\n1. 套餐内容要具体实用:明确说明包含的服务、时间、数量\n2. 价格要有吸引力:突出性价比和优惠信息\n\n## 输出格式:\n请严格按照JSON格式输出不要有任何额外内容。\"\"\"",
"code_hash": "381b1b84d0827b5b7971483267f67d6a"
},
{
"name": "_build_user_prompt",
"line_start": 210,
"line_end": 249,
"args": [
{
"name": "self"
},
{
"name": "topic_info",
"type_hint": "str"
},
{
"name": "style",
"type_hint": "str"
},
{
"name": "target_audience",
"type_hint": "str"
},
{
"name": "poster_type",
"type_hint": "str"
}
],
"return_type": "str",
"docstring": "构建用户提示词",
"is_async": false,
"decorators": [],
"code": " def _build_user_prompt(\n self,\n topic_info: str,\n style: str,\n target_audience: str,\n poster_type: str,\n **kwargs\n ) -> str:\n \"\"\"构建用户提示词\"\"\"\n \n user_prompt_template = \"\"\"请为以下主题创作海报文案:\n\n### 主题信息\n{topic_info}\n\n### 创作要求\n- 文案风格:{style}\n- 目标受众:{target_audience}\n- 海报类型:{poster_type}\n\n### 额外要求\n{additional_requirements}\n\n请按照以下JSON格式输出\n{\n \"title\": \"海报标题15字以内\",\n \"content\": \"主要内容描述\",\n \"tags\": [\"标签1\", \"标签2\", \"标签3\"],\n \"call_to_action\": \"行动召唤语句\"\n}\"\"\"\n\n additional_requirements = self._format_additional_requirements(kwargs)\n \n return user_prompt_template.format(\n topic_info=topic_info,\n style=style,\n target_audience=target_audience,\n poster_type=poster_type,\n additional_requirements=additional_requirements\n )",
"code_hash": "84412467535b14d3540aec6efdb7b7db"
},
{
"name": "_build_vibrant_user_prompt",
"line_start": 251,
"line_end": 264,
"args": [
{
"name": "self"
},
{
"name": "scenic_info",
"type_hint": "str"
},
{
"name": "product_info",
"type_hint": "str"
},
{
"name": "tweet_info",
"type_hint": "str"
}
],
"return_type": "str",
"docstring": "构建Vibrant模板专用的用户提示词",
"is_async": false,
"decorators": [],
"code": " def _build_vibrant_user_prompt(self, scenic_info: str, product_info: str, tweet_info: str) -> str:\n \"\"\"构建Vibrant模板专用的用户提示词\"\"\"\n return f\"\"\"请根据以下信息,生成适合在旅游海报上展示的文案:\n\n## 景区信息\n{scenic_info}\n\n## 产品信息\n{product_info}\n\n## 推文信息\n{tweet_info if tweet_info else \"无\"}\n\n请提取关键信息并整合成一个JSON对象包含title、slogan、price、ticket_type、content_items、remarks和tag字段。\"\"\"",
"code_hash": "3d5c1619b583f73645577dc7e23ea4c7"
},
{
"name": "_format_additional_requirements",
"line_start": 266,
"line_end": 286,
"args": [
{
"name": "self"
},
{
"name": "kwargs",
"type_hint": "Dict[str, Any]"
}
],
"return_type": "str",
"docstring": "格式化额外要求",
"is_async": false,
"decorators": [],
"code": " def _format_additional_requirements(self, kwargs: Dict[str, Any]) -> str:\n \"\"\"格式化额外要求\"\"\"\n requirements = []\n \n if kwargs.get(\"color_theme\"):\n requirements.append(f\"- 配色主题:{kwargs['color_theme']}\")\n \n if kwargs.get(\"mood\"):\n requirements.append(f\"- 情感氛围:{kwargs['mood']}\")\n \n if kwargs.get(\"key_points\"):\n key_points = kwargs['key_points']\n if isinstance(key_points, list):\n requirements.append(f\"- 重点突出:{', '.join(key_points)}\")\n else:\n requirements.append(f\"- 重点突出:{key_points}\")\n \n if kwargs.get(\"length_preference\"):\n requirements.append(f\"- 文案长度:{kwargs['length_preference']}\")\n\n return \"\\n\".join(requirements) if requirements else \"无特殊要求\"",
"code_hash": "b0a04b1118b2f21e03b4951e75cc6318"
},
{
"name": "_parse_poster_content",
"line_start": 288,
"line_end": 306,
"args": [
{
"name": "self"
},
{
"name": "raw_content",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "解析海报内容生成结果",
"is_async": false,
"decorators": [],
"code": " def _parse_poster_content(self, raw_content: str) -> Dict[str, Any]:\n \"\"\"解析海报内容生成结果\"\"\"\n try:\n # 使用JSON处理器解析\n parsed_data = self.json_processor.parse_llm_output(\n raw_output=raw_content,\n expected_fields=[\"title\", \"content\", \"tags\", \"call_to_action\"],\n required_fields=[\"title\", \"content\"]\n )\n \n if isinstance(parsed_data, dict):\n return parsed_data\n else:\n logger.warning(\"解析结果不是字典格式,使用回退方案\")\n return self._extract_content_from_text(raw_content)\n \n except Exception as e:\n logger.warning(f\"JSON解析失败使用文本提取: {e}\")\n return self._extract_content_from_text(raw_content)",
"code_hash": "efaaad594972eb16fe02238f789cbed1"
},
{
"name": "_parse_vibrant_content",
"line_start": 308,
"line_end": 329,
"args": [
{
"name": "self"
},
{
"name": "raw_content",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "解析Vibrant模板专用内容",
"is_async": false,
"decorators": [],
"code": " def _parse_vibrant_content(self, raw_content: str) -> Dict[str, Any]:\n \"\"\"解析Vibrant模板专用内容\"\"\"\n try:\n # 使用JSON处理器解析指定Vibrant的字段\n expected_fields = [\"title\", \"slogan\", \"price\", \"ticket_type\", \"content_button\", \"content_items\"]\n required_fields = [\"title\", \"slogan\", \"price\", \"ticket_type\", \"content_items\"]\n \n parsed_data = self.json_processor.parse_llm_output(\n raw_output=raw_content,\n expected_fields=expected_fields + [\"remarks\", \"tag\", \"pagination\"],\n required_fields=required_fields\n )\n \n if isinstance(parsed_data, dict):\n return self._normalize_vibrant_content(parsed_data)\n else:\n logger.warning(\"解析结果不是字典格式,使用回退方案\")\n return self._create_fallback_vibrant_content()\n \n except Exception as e:\n logger.warning(f\"Vibrant内容解析失败使用回退方案: {e}\")\n return self._create_fallback_vibrant_content()",
"code_hash": "babcecb24f8b0ec4280825b32ca658c0"
},
{
"name": "_normalize_vibrant_content",
"line_start": 331,
"line_end": 360,
"args": [
{
"name": "self"
},
{
"name": "parsed_data",
"type_hint": "Dict[str, Any]"
}
],
"return_type": "Dict[str, Any]",
"docstring": "标准化Vibrant内容格式",
"is_async": false,
"decorators": [],
"code": " def _normalize_vibrant_content(self, parsed_data: Dict[str, Any]) -> Dict[str, Any]:\n \"\"\"标准化Vibrant内容格式\"\"\"\n normalized = {\n # 必填字段\n \"title\": parsed_data.get(\"title\", \"精彩旅程\"),\n \"slogan\": parsed_data.get(\"slogan\", \"发现世界的美好\"),\n \"price\": str(parsed_data.get(\"price\", \"欢迎咨询\")),\n \"ticket_type\": parsed_data.get(\"ticket_type\", \"门票\"),\n \"content_button\": parsed_data.get(\"content_button\", \"套餐内容\"),\n \"content_items\": parsed_data.get(\"content_items\", [\"精彩体验项目\"]),\n \n # 可选字段\n \"remarks\": parsed_data.get(\"remarks\", []),\n \"tag\": parsed_data.get(\"tag\", \"\"),\n \"pagination\": parsed_data.get(\"pagination\", \"\")\n }\n \n # 确保content_items是列表\n if isinstance(normalized[\"content_items\"], str):\n normalized[\"content_items\"] = [normalized[\"content_items\"]]\n \n # 确保remarks是列表\n if isinstance(normalized[\"remarks\"], str):\n normalized[\"remarks\"] = [normalized[\"remarks\"]]\n \n # 限制列表长度\n normalized[\"content_items\"] = normalized[\"content_items\"][:5]\n normalized[\"remarks\"] = normalized[\"remarks\"][:3]\n \n return normalized",
"code_hash": "d1d0680c8f3c18adea98d7865c839020"
},
{
"name": "_create_fallback_vibrant_content",
"line_start": 362,
"line_end": 378,
"args": [
{
"name": "self"
}
],
"return_type": "Dict[str, Any]",
"docstring": "创建Vibrant模板的回退内容",
"is_async": false,
"decorators": [],
"code": " def _create_fallback_vibrant_content(self) -> Dict[str, Any]:\n \"\"\"创建Vibrant模板的回退内容\"\"\"\n return {\n \"title\": \"精彩旅程体验\",\n \"slogan\": \"探索世界的无限可能\",\n \"price\": \"欢迎咨询\",\n \"ticket_type\": \"体验票\",\n \"content_button\": \"套餐内容\",\n \"content_items\": [\n \"专业导游服务\",\n \"精美旅游纪念品\",\n \"全程保险保障\"\n ],\n \"remarks\": [\"请提前预约\", \"节假日价格另议\"],\n \"tag\": \"#精彩体验\",\n \"pagination\": \"\"\n }",
"code_hash": "8f8b25a2a9eb148e87d59918adb56a03"
},
{
"name": "_extract_content_from_text",
"line_start": 380,
"line_end": 413,
"args": [
{
"name": "self"
},
{
"name": "text",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "从文本中提取海报内容(回退方案)",
"is_async": false,
"decorators": [],
"code": " def _extract_content_from_text(self, text: str) -> Dict[str, Any]:\n \"\"\"从文本中提取海报内容(回退方案)\"\"\"\n lines = text.strip().split('\\n')\n \n # 简单的文本解析逻辑\n title = \"\"\n content = \"\"\n tags = []\n call_to_action = \"\"\n \n for line in lines:\n line = line.strip()\n if not line:\n continue\n \n if len(line) <= 20 and not title:\n # 可能是标题\n title = line\n elif '#' in line:\n # 可能是标签\n tags = [tag.strip() for tag in line.replace('#', '').split() if tag.strip()]\n elif not content and len(line) > 10:\n # 可能是主要内容\n content = line\n elif len(line) <= 15 and ('' in line or '!' in line):\n # 可能是行动召唤\n call_to_action = line\n\n return {\n \"title\": title or \"精彩旅程\",\n \"content\": content or text[:100],\n \"tags\": tags or [\"旅行\", \"探索\"],\n \"call_to_action\": call_to_action or \"立即体验!\"\n }",
"code_hash": "763a2eec02d8d8e087f30dec4b6dac89"
},
{
"name": "_validate_and_enhance_content",
"line_start": 415,
"line_end": 445,
"args": [
{
"name": "self"
},
{
"name": "content",
"type_hint": "Dict[str, Any]"
},
{
"name": "topic_info",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "验证和增强海报内容",
"is_async": false,
"decorators": [],
"code": " def _validate_and_enhance_content(\n self, \n content: Dict[str, Any], \n topic_info: str\n ) -> Dict[str, Any]:\n \"\"\"验证和增强海报内容\"\"\"\n \n # 确保所有必需字段存在\n validated_content = {\n \"title\": content.get(\"title\", \"精彩旅程\")[:15], # 限制标题长度\n \"content\": content.get(\"content\", topic_info),\n \"tags\": content.get(\"tags\", [\"旅行\"]),\n \"call_to_action\": content.get(\"call_to_action\", \"立即体验!\")\n }\n \n # 确保标签是列表格式\n if isinstance(validated_content[\"tags\"], str):\n validated_content[\"tags\"] = [tag.strip() for tag in validated_content[\"tags\"].split(\",\")]\n \n # 限制标签数量\n validated_content[\"tags\"] = validated_content[\"tags\"][:5]\n \n # 添加元数据\n validated_content[\"metadata\"] = {\n \"word_count\": len(validated_content[\"content\"]),\n \"tag_count\": len(validated_content[\"tags\"]),\n \"generated_for\": topic_info,\n \"generation_config\": self.task_model_config\n }\n \n return validated_content",
"code_hash": "563d25f62c01c8605e21730c470242fe"
},
{
"name": "get_style_suggestions",
"line_start": 501,
"line_end": 530,
"args": [
{
"name": "self"
},
{
"name": "poster_type",
"type_hint": "str"
},
{
"name": "target_audience",
"type_hint": "str"
}
],
"return_type": "List[str]",
"docstring": "根据海报类型和目标受众获取风格建议\n\nArgs:\n poster_type: 海报类型\n target_audience: 目标受众\n\nReturns:\n 风格建议列表",
"is_async": false,
"decorators": [],
"code": " def get_style_suggestions(self, poster_type: str, target_audience: str) -> List[str]:\n \"\"\"\n 根据海报类型和目标受众获取风格建议\n\n Args:\n poster_type: 海报类型\n target_audience: 目标受众\n\n Returns:\n 风格建议列表\n \"\"\"\n style_mapping = {\n \"旅游宣传\": {\n \"年轻人\": [\"活泼有趣\", \"激情澎湃\", \"个性时尚\"],\n \"家庭\": [\"温馨感人\", \"亲切自然\", \"安全舒适\"],\n \"商务人士\": [\"优雅文艺\", \"简洁干练\", \"品质生活\"]\n },\n \"美食推荐\": {\n \"年轻人\": [\"诱人美味\", \"时尚潮流\", \"分享快乐\"],\n \"家庭\": [\"家常温馨\", \"营养健康\", \"团圆美好\"],\n \"美食爱好者\": [\"精致品味\", \"传统文化\", \"匠心工艺\"]\n },\n \"活动宣传\": {\n \"年轻人\": [\"活力四射\", \"激情参与\", \"社交互动\"],\n \"全年龄\": [\"欢乐共享\", \"文化体验\", \"意义深远\"],\n \"专业人士\": [\"高端品质\", \"网络建设\", \"知识分享\"]\n }\n }\n \n return style_mapping.get(poster_type, {}).get(target_audience, [\"活泼有趣\", \"简洁明快\"]) ",
"code_hash": "31c20e0f78120979c69d8fbea46d5233"
}
],
"classes": [
{
"name": "TextGenerator",
"line_start": 19,
"line_end": 530,
"bases": [],
"methods": [
{
"name": "__init__",
"line_start": 25,
"line_end": 49,
"args": [
{
"name": "self"
},
{
"name": "config",
"type_hint": "AlgorithmConfig"
},
{
"name": "ai_service",
"type_hint": "AIService"
},
{
"name": "prompt_manager",
"type_hint": "PromptManager"
},
{
"name": "json_processor",
"type_hint": "JSONProcessor"
}
],
"return_type": null,
"docstring": "初始化文本生成器\n\nArgs:\n config: 算法配置\n ai_service: AI服务\n prompt_manager: 提示词管理器\n json_processor: JSON处理器",
"is_async": false,
"decorators": [],
"code": " def __init__(\n self, \n config: AlgorithmConfig, \n ai_service: AIService,\n prompt_manager: PromptManager,\n json_processor: JSONProcessor\n ):\n \"\"\"\n 初始化文本生成器\n\n Args:\n config: 算法配置\n ai_service: AI服务\n prompt_manager: 提示词管理器\n json_processor: JSON处理器\n \"\"\"\n self.config = config\n self.ai_service = ai_service\n self.prompt_manager = prompt_manager\n self.json_processor = json_processor\n \n # 获取任务特定的模型配置\n self.task_model_config = config.ai_model.get_task_config(\"poster_generation\")\n \n logger.info(\"海报文本生成器初始化完成\")",
"code_hash": "15b338066890e13ec89a2fd8eda25792"
},
{
"name": "generate_poster_content",
"line_start": 51,
"line_end": 108,
"args": [
{
"name": "self"
},
{
"name": "topic_info",
"type_hint": "str"
},
{
"name": "style",
"type_hint": "str"
},
{
"name": "target_audience",
"type_hint": "str"
},
{
"name": "poster_type",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "生成海报文案内容\n\nArgs:\n topic_info: 主题信息\n style: 文案风格\n target_audience: 目标受众\n poster_type: 海报类型\n **kwargs: 其他参数\n\nReturns:\n 生成的海报内容字典\n\nRaises:\n ContentGenerationError: 生成失败时抛出",
"is_async": true,
"decorators": [],
"code": " async def generate_poster_content(\n self,\n topic_info: str,\n style: str = \"活泼有趣\",\n target_audience: str = \"年轻旅行者\",\n poster_type: str = \"旅游宣传\",\n **kwargs\n ) -> Dict[str, Any]:\n \"\"\"\n 生成海报文案内容\n\n Args:\n topic_info: 主题信息\n style: 文案风格\n target_audience: 目标受众\n poster_type: 海报类型\n **kwargs: 其他参数\n\n Returns:\n 生成的海报内容字典\n\n Raises:\n ContentGenerationError: 生成失败时抛出\n \"\"\"\n try:\n logger.info(f\"开始生成海报文案,主题: {topic_info}\")\n\n # 1. 构建提示词\n system_prompt = self._get_poster_system_prompt()\n user_prompt = self._build_user_prompt(\n topic_info=topic_info,\n style=style,\n target_audience=target_audience,\n poster_type=poster_type,\n **kwargs\n )\n\n # 2. 调用AI生成\n content, input_tokens, output_tokens, elapsed_time = await self.ai_service.generate_text(\n system_prompt=system_prompt,\n user_prompt=user_prompt,\n stage=\"海报文案生成\",\n **self.task_model_config\n )\n\n # 3. 解析结果\n poster_content = self._parse_poster_content(content)\n\n # 4. 验证和增强内容\n validated_content = self._validate_and_enhance_content(poster_content, topic_info)\n\n logger.info(\"海报文案生成完成\")\n return validated_content\n\n except Exception as e:\n error_msg = f\"海报文案生成失败: {str(e)}\"\n logger.error(error_msg, exc_info=True)\n raise ContentGenerationError(error_msg)",
"code_hash": "331dbb63328ede729ea578c8b5986530"
},
{
"name": "generate_vibrant_content",
"line_start": 110,
"line_end": 156,
"args": [
{
"name": "self"
},
{
"name": "scenic_info",
"type_hint": "str"
},
{
"name": "product_info",
"type_hint": "str"
},
{
"name": "tweet_info",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "专门为Vibrant模板生成内容\n\nArgs:\n scenic_info: 景区信息\n product_info: 产品信息\n tweet_info: 推文信息\n **kwargs: 其他参数\n\nReturns:\n 符合Vibrant模板结构的内容字典\n\nRaises:\n ContentGenerationError: 生成失败时抛出",
"is_async": true,
"decorators": [],
"code": " async def generate_vibrant_content(\n self,\n scenic_info: str,\n product_info: str,\n tweet_info: str = \"\",\n **kwargs\n ) -> Dict[str, Any]:\n \"\"\"\n 专门为Vibrant模板生成内容\n\n Args:\n scenic_info: 景区信息\n product_info: 产品信息\n tweet_info: 推文信息\n **kwargs: 其他参数\n\n Returns:\n 符合Vibrant模板结构的内容字典\n\n Raises:\n ContentGenerationError: 生成失败时抛出\n \"\"\"\n try:\n logger.info(\"开始生成Vibrant模板专用内容\")\n\n # 1. 构建Vibrant专用提示词\n system_prompt = self._get_vibrant_system_prompt()\n user_prompt = self._build_vibrant_user_prompt(scenic_info, product_info, tweet_info)\n\n # 2. 调用AI生成\n content, input_tokens, output_tokens, elapsed_time = await self.ai_service.generate_text(\n system_prompt=system_prompt,\n user_prompt=user_prompt,\n stage=\"Vibrant海报内容生成\",\n **self.task_model_config\n )\n\n # 3. 解析并验证Vibrant格式\n vibrant_content = self._parse_vibrant_content(content)\n\n logger.info(\"Vibrant模板内容生成完成\")\n return vibrant_content\n\n except Exception as e:\n error_msg = f\"Vibrant模板内容生成失败: {str(e)}\"\n logger.error(error_msg, exc_info=True)\n raise ContentGenerationError(error_msg)",
"code_hash": "2f1ed3fc8f7368780c387f77d984a7d4"
},
{
"name": "_get_poster_system_prompt",
"line_start": 158,
"line_end": 177,
"args": [
{
"name": "self"
}
],
"return_type": "str",
"docstring": "获取海报生成的系统提示词",
"is_async": false,
"decorators": [],
"code": " def _get_poster_system_prompt(self) -> str:\n \"\"\"获取海报生成的系统提示词\"\"\"\n try:\n # 尝试从文件加载\n return self.prompt_manager.get_prompt(\"poster_generation\", \"system\")\n except:\n # 使用默认提示词\n return \"\"\"你是一个专业的海报文案创作者,专门为旅游、美食、生活方式等主题创作吸引人的海报文案。\n\n你的任务是根据给定的主题信息创作适合海报展示的文案内容包括\n1. 吸引人的标题简洁有力15字以内\n2. 核心内容描述(生动形象,突出亮点)\n3. 相关标签3-5个关键词\n4. 行动召唤语句(激发用户行动)\n\n要求\n- 文案要有感染力和画面感\n- 适合目标受众的语言风格\n- 突出主题的独特价值\n- 符合海报的视觉传达需求\"\"\"",
"code_hash": "020636f01d802e8b218c8759f9900dcb"
},
{
"name": "_get_vibrant_system_prompt",
"line_start": 179,
"line_end": 208,
"args": [
{
"name": "self"
}
],
"return_type": "str",
"docstring": "获取Vibrant模板专用的系统提示词",
"is_async": false,
"decorators": [],
"code": " def _get_vibrant_system_prompt(self) -> str:\n \"\"\"获取Vibrant模板专用的系统提示词\"\"\"\n return \"\"\"你是一名专业的海报设计师专门设计宣传海报。你现在要根据用户提供的信息生成适合Vibrant模板的海报内容。\n\n## Vibrant模板特点\n- 单图背景,毛玻璃渐变效果\n- 两栏布局(左栏内容,右栏价格)\n- 适合展示套餐内容和价格信息\n\n## 你需要生成的数据结构包含以下字段:\n\n**必填字段:**\n1. `title`: 主标题8-12字符体现产品特色\n2. `slogan`: 副标题/宣传语10-20字符吸引人的描述\n3. `price`: 价格数字(纯数字,不含符号),如果材料中没有价格,则用\"欢迎咨询\"替代\n4. `ticket_type`: 票种类型(如\"成人票\"、\"套餐票\"、\"夜场票\"等)\n5. `content_button`: 内容按钮文字(通常为\"套餐内容\"、\"包含项目\"等)\n6. `content_items`: 套餐内容列表3-5个项目每项5-15字符不要只包含项目名称要做合适的美化可以适当省略\n\n**可选字段:**\n7. `remarks`: 备注信息1-3条每条10-20字符\n8. `tag`: 标签1条, 如\"#限时优惠\"等)\n9. `pagination`: 分页信息(如\"1/3\",可为空)\n\n## 内容创作要求:\n1. 套餐内容要具体实用:明确说明包含的服务、时间、数量\n2. 价格要有吸引力:突出性价比和优惠信息\n\n## 输出格式:\n请严格按照JSON格式输出不要有任何额外内容。\"\"\"",
"code_hash": "381b1b84d0827b5b7971483267f67d6a"
},
{
"name": "_build_user_prompt",
"line_start": 210,
"line_end": 249,
"args": [
{
"name": "self"
},
{
"name": "topic_info",
"type_hint": "str"
},
{
"name": "style",
"type_hint": "str"
},
{
"name": "target_audience",
"type_hint": "str"
},
{
"name": "poster_type",
"type_hint": "str"
}
],
"return_type": "str",
"docstring": "构建用户提示词",
"is_async": false,
"decorators": [],
"code": " def _build_user_prompt(\n self,\n topic_info: str,\n style: str,\n target_audience: str,\n poster_type: str,\n **kwargs\n ) -> str:\n \"\"\"构建用户提示词\"\"\"\n \n user_prompt_template = \"\"\"请为以下主题创作海报文案:\n\n### 主题信息\n{topic_info}\n\n### 创作要求\n- 文案风格:{style}\n- 目标受众:{target_audience}\n- 海报类型:{poster_type}\n\n### 额外要求\n{additional_requirements}\n\n请按照以下JSON格式输出\n{\n \"title\": \"海报标题15字以内\",\n \"content\": \"主要内容描述\",\n \"tags\": [\"标签1\", \"标签2\", \"标签3\"],\n \"call_to_action\": \"行动召唤语句\"\n}\"\"\"\n\n additional_requirements = self._format_additional_requirements(kwargs)\n \n return user_prompt_template.format(\n topic_info=topic_info,\n style=style,\n target_audience=target_audience,\n poster_type=poster_type,\n additional_requirements=additional_requirements\n )",
"code_hash": "84412467535b14d3540aec6efdb7b7db"
},
{
"name": "_build_vibrant_user_prompt",
"line_start": 251,
"line_end": 264,
"args": [
{
"name": "self"
},
{
"name": "scenic_info",
"type_hint": "str"
},
{
"name": "product_info",
"type_hint": "str"
},
{
"name": "tweet_info",
"type_hint": "str"
}
],
"return_type": "str",
"docstring": "构建Vibrant模板专用的用户提示词",
"is_async": false,
"decorators": [],
"code": " def _build_vibrant_user_prompt(self, scenic_info: str, product_info: str, tweet_info: str) -> str:\n \"\"\"构建Vibrant模板专用的用户提示词\"\"\"\n return f\"\"\"请根据以下信息,生成适合在旅游海报上展示的文案:\n\n## 景区信息\n{scenic_info}\n\n## 产品信息\n{product_info}\n\n## 推文信息\n{tweet_info if tweet_info else \"无\"}\n\n请提取关键信息并整合成一个JSON对象包含title、slogan、price、ticket_type、content_items、remarks和tag字段。\"\"\"",
"code_hash": "3d5c1619b583f73645577dc7e23ea4c7"
},
{
"name": "_format_additional_requirements",
"line_start": 266,
"line_end": 286,
"args": [
{
"name": "self"
},
{
"name": "kwargs",
"type_hint": "Dict[str, Any]"
}
],
"return_type": "str",
"docstring": "格式化额外要求",
"is_async": false,
"decorators": [],
"code": " def _format_additional_requirements(self, kwargs: Dict[str, Any]) -> str:\n \"\"\"格式化额外要求\"\"\"\n requirements = []\n \n if kwargs.get(\"color_theme\"):\n requirements.append(f\"- 配色主题:{kwargs['color_theme']}\")\n \n if kwargs.get(\"mood\"):\n requirements.append(f\"- 情感氛围:{kwargs['mood']}\")\n \n if kwargs.get(\"key_points\"):\n key_points = kwargs['key_points']\n if isinstance(key_points, list):\n requirements.append(f\"- 重点突出:{', '.join(key_points)}\")\n else:\n requirements.append(f\"- 重点突出:{key_points}\")\n \n if kwargs.get(\"length_preference\"):\n requirements.append(f\"- 文案长度:{kwargs['length_preference']}\")\n\n return \"\\n\".join(requirements) if requirements else \"无特殊要求\"",
"code_hash": "b0a04b1118b2f21e03b4951e75cc6318"
},
{
"name": "_parse_poster_content",
"line_start": 288,
"line_end": 306,
"args": [
{
"name": "self"
},
{
"name": "raw_content",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "解析海报内容生成结果",
"is_async": false,
"decorators": [],
"code": " def _parse_poster_content(self, raw_content: str) -> Dict[str, Any]:\n \"\"\"解析海报内容生成结果\"\"\"\n try:\n # 使用JSON处理器解析\n parsed_data = self.json_processor.parse_llm_output(\n raw_output=raw_content,\n expected_fields=[\"title\", \"content\", \"tags\", \"call_to_action\"],\n required_fields=[\"title\", \"content\"]\n )\n \n if isinstance(parsed_data, dict):\n return parsed_data\n else:\n logger.warning(\"解析结果不是字典格式,使用回退方案\")\n return self._extract_content_from_text(raw_content)\n \n except Exception as e:\n logger.warning(f\"JSON解析失败使用文本提取: {e}\")\n return self._extract_content_from_text(raw_content)",
"code_hash": "efaaad594972eb16fe02238f789cbed1"
},
{
"name": "_parse_vibrant_content",
"line_start": 308,
"line_end": 329,
"args": [
{
"name": "self"
},
{
"name": "raw_content",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "解析Vibrant模板专用内容",
"is_async": false,
"decorators": [],
"code": " def _parse_vibrant_content(self, raw_content: str) -> Dict[str, Any]:\n \"\"\"解析Vibrant模板专用内容\"\"\"\n try:\n # 使用JSON处理器解析指定Vibrant的字段\n expected_fields = [\"title\", \"slogan\", \"price\", \"ticket_type\", \"content_button\", \"content_items\"]\n required_fields = [\"title\", \"slogan\", \"price\", \"ticket_type\", \"content_items\"]\n \n parsed_data = self.json_processor.parse_llm_output(\n raw_output=raw_content,\n expected_fields=expected_fields + [\"remarks\", \"tag\", \"pagination\"],\n required_fields=required_fields\n )\n \n if isinstance(parsed_data, dict):\n return self._normalize_vibrant_content(parsed_data)\n else:\n logger.warning(\"解析结果不是字典格式,使用回退方案\")\n return self._create_fallback_vibrant_content()\n \n except Exception as e:\n logger.warning(f\"Vibrant内容解析失败使用回退方案: {e}\")\n return self._create_fallback_vibrant_content()",
"code_hash": "babcecb24f8b0ec4280825b32ca658c0"
},
{
"name": "_normalize_vibrant_content",
"line_start": 331,
"line_end": 360,
"args": [
{
"name": "self"
},
{
"name": "parsed_data",
"type_hint": "Dict[str, Any]"
}
],
"return_type": "Dict[str, Any]",
"docstring": "标准化Vibrant内容格式",
"is_async": false,
"decorators": [],
"code": " def _normalize_vibrant_content(self, parsed_data: Dict[str, Any]) -> Dict[str, Any]:\n \"\"\"标准化Vibrant内容格式\"\"\"\n normalized = {\n # 必填字段\n \"title\": parsed_data.get(\"title\", \"精彩旅程\"),\n \"slogan\": parsed_data.get(\"slogan\", \"发现世界的美好\"),\n \"price\": str(parsed_data.get(\"price\", \"欢迎咨询\")),\n \"ticket_type\": parsed_data.get(\"ticket_type\", \"门票\"),\n \"content_button\": parsed_data.get(\"content_button\", \"套餐内容\"),\n \"content_items\": parsed_data.get(\"content_items\", [\"精彩体验项目\"]),\n \n # 可选字段\n \"remarks\": parsed_data.get(\"remarks\", []),\n \"tag\": parsed_data.get(\"tag\", \"\"),\n \"pagination\": parsed_data.get(\"pagination\", \"\")\n }\n \n # 确保content_items是列表\n if isinstance(normalized[\"content_items\"], str):\n normalized[\"content_items\"] = [normalized[\"content_items\"]]\n \n # 确保remarks是列表\n if isinstance(normalized[\"remarks\"], str):\n normalized[\"remarks\"] = [normalized[\"remarks\"]]\n \n # 限制列表长度\n normalized[\"content_items\"] = normalized[\"content_items\"][:5]\n normalized[\"remarks\"] = normalized[\"remarks\"][:3]\n \n return normalized",
"code_hash": "d1d0680c8f3c18adea98d7865c839020"
},
{
"name": "_create_fallback_vibrant_content",
"line_start": 362,
"line_end": 378,
"args": [
{
"name": "self"
}
],
"return_type": "Dict[str, Any]",
"docstring": "创建Vibrant模板的回退内容",
"is_async": false,
"decorators": [],
"code": " def _create_fallback_vibrant_content(self) -> Dict[str, Any]:\n \"\"\"创建Vibrant模板的回退内容\"\"\"\n return {\n \"title\": \"精彩旅程体验\",\n \"slogan\": \"探索世界的无限可能\",\n \"price\": \"欢迎咨询\",\n \"ticket_type\": \"体验票\",\n \"content_button\": \"套餐内容\",\n \"content_items\": [\n \"专业导游服务\",\n \"精美旅游纪念品\",\n \"全程保险保障\"\n ],\n \"remarks\": [\"请提前预约\", \"节假日价格另议\"],\n \"tag\": \"#精彩体验\",\n \"pagination\": \"\"\n }",
"code_hash": "8f8b25a2a9eb148e87d59918adb56a03"
},
{
"name": "_extract_content_from_text",
"line_start": 380,
"line_end": 413,
"args": [
{
"name": "self"
},
{
"name": "text",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "从文本中提取海报内容(回退方案)",
"is_async": false,
"decorators": [],
"code": " def _extract_content_from_text(self, text: str) -> Dict[str, Any]:\n \"\"\"从文本中提取海报内容(回退方案)\"\"\"\n lines = text.strip().split('\\n')\n \n # 简单的文本解析逻辑\n title = \"\"\n content = \"\"\n tags = []\n call_to_action = \"\"\n \n for line in lines:\n line = line.strip()\n if not line:\n continue\n \n if len(line) <= 20 and not title:\n # 可能是标题\n title = line\n elif '#' in line:\n # 可能是标签\n tags = [tag.strip() for tag in line.replace('#', '').split() if tag.strip()]\n elif not content and len(line) > 10:\n # 可能是主要内容\n content = line\n elif len(line) <= 15 and ('' in line or '!' in line):\n # 可能是行动召唤\n call_to_action = line\n\n return {\n \"title\": title or \"精彩旅程\",\n \"content\": content or text[:100],\n \"tags\": tags or [\"旅行\", \"探索\"],\n \"call_to_action\": call_to_action or \"立即体验!\"\n }",
"code_hash": "763a2eec02d8d8e087f30dec4b6dac89"
},
{
"name": "_validate_and_enhance_content",
"line_start": 415,
"line_end": 445,
"args": [
{
"name": "self"
},
{
"name": "content",
"type_hint": "Dict[str, Any]"
},
{
"name": "topic_info",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "验证和增强海报内容",
"is_async": false,
"decorators": [],
"code": " def _validate_and_enhance_content(\n self, \n content: Dict[str, Any], \n topic_info: str\n ) -> Dict[str, Any]:\n \"\"\"验证和增强海报内容\"\"\"\n \n # 确保所有必需字段存在\n validated_content = {\n \"title\": content.get(\"title\", \"精彩旅程\")[:15], # 限制标题长度\n \"content\": content.get(\"content\", topic_info),\n \"tags\": content.get(\"tags\", [\"旅行\"]),\n \"call_to_action\": content.get(\"call_to_action\", \"立即体验!\")\n }\n \n # 确保标签是列表格式\n if isinstance(validated_content[\"tags\"], str):\n validated_content[\"tags\"] = [tag.strip() for tag in validated_content[\"tags\"].split(\",\")]\n \n # 限制标签数量\n validated_content[\"tags\"] = validated_content[\"tags\"][:5]\n \n # 添加元数据\n validated_content[\"metadata\"] = {\n \"word_count\": len(validated_content[\"content\"]),\n \"tag_count\": len(validated_content[\"tags\"]),\n \"generated_for\": topic_info,\n \"generation_config\": self.task_model_config\n }\n \n return validated_content",
"code_hash": "563d25f62c01c8605e21730c470242fe"
},
{
"name": "generate_multiple_variations",
"line_start": 447,
"line_end": 499,
"args": [
{
"name": "self"
},
{
"name": "topic_info",
"type_hint": "str"
},
{
"name": "num_variations",
"type_hint": "int"
},
{
"name": "template_type",
"type_hint": "str"
}
],
"return_type": "List[Dict[str, Any]]",
"docstring": "生成多个文案变体\n\nArgs:\n topic_info: 主题信息\n num_variations: 变体数量\n template_type: 模板类型 (\"general\", \"vibrant\")\n **kwargs: 其他参数\n\nReturns:\n 文案变体列表",
"is_async": true,
"decorators": [],
"code": " async def generate_multiple_variations(\n self,\n topic_info: str,\n num_variations: int = 3,\n template_type: str = \"general\",\n **kwargs\n ) -> List[Dict[str, Any]]:\n \"\"\"\n 生成多个文案变体\n\n Args:\n topic_info: 主题信息\n num_variations: 变体数量\n template_type: 模板类型 (\"general\", \"vibrant\")\n **kwargs: 其他参数\n\n Returns:\n 文案变体列表\n \"\"\"\n variations = []\n \n styles = [\"活泼有趣\", \"温馨感人\", \"激情澎湃\", \"优雅文艺\", \"简洁干练\"]\n \n for i in range(num_variations):\n try:\n # 使用不同的风格\n style = styles[i % len(styles)]\n \n if template_type == \"vibrant\":\n # 为Vibrant模板生成内容\n variation = await self.generate_vibrant_content(\n scenic_info=kwargs.get(\"scenic_info\", topic_info),\n product_info=kwargs.get(\"product_info\", \"\"),\n tweet_info=kwargs.get(\"tweet_info\", \"\"),\n **kwargs\n )\n else:\n # 通用海报内容\n variation = await self.generate_poster_content(\n topic_info=topic_info,\n style=style,\n **kwargs\n )\n \n variation[\"variation_id\"] = i + 1\n variation[\"style_used\"] = style\n variations.append(variation)\n \n except Exception as e:\n logger.error(f\"生成变体 {i+1} 失败: {e}\")\n continue\n \n return variations",
"code_hash": "cbc98eca863ae6528a60314359f69de8"
},
{
"name": "get_style_suggestions",
"line_start": 501,
"line_end": 530,
"args": [
{
"name": "self"
},
{
"name": "poster_type",
"type_hint": "str"
},
{
"name": "target_audience",
"type_hint": "str"
}
],
"return_type": "List[str]",
"docstring": "根据海报类型和目标受众获取风格建议\n\nArgs:\n poster_type: 海报类型\n target_audience: 目标受众\n\nReturns:\n 风格建议列表",
"is_async": false,
"decorators": [],
"code": " def get_style_suggestions(self, poster_type: str, target_audience: str) -> List[str]:\n \"\"\"\n 根据海报类型和目标受众获取风格建议\n\n Args:\n poster_type: 海报类型\n target_audience: 目标受众\n\n Returns:\n 风格建议列表\n \"\"\"\n style_mapping = {\n \"旅游宣传\": {\n \"年轻人\": [\"活泼有趣\", \"激情澎湃\", \"个性时尚\"],\n \"家庭\": [\"温馨感人\", \"亲切自然\", \"安全舒适\"],\n \"商务人士\": [\"优雅文艺\", \"简洁干练\", \"品质生活\"]\n },\n \"美食推荐\": {\n \"年轻人\": [\"诱人美味\", \"时尚潮流\", \"分享快乐\"],\n \"家庭\": [\"家常温馨\", \"营养健康\", \"团圆美好\"],\n \"美食爱好者\": [\"精致品味\", \"传统文化\", \"匠心工艺\"]\n },\n \"活动宣传\": {\n \"年轻人\": [\"活力四射\", \"激情参与\", \"社交互动\"],\n \"全年龄\": [\"欢乐共享\", \"文化体验\", \"意义深远\"],\n \"专业人士\": [\"高端品质\", \"网络建设\", \"知识分享\"]\n }\n }\n \n return style_mapping.get(poster_type, {}).get(target_audience, [\"活泼有趣\", \"简洁明快\"]) ",
"code_hash": "31c20e0f78120979c69d8fbea46d5233"
}
],
"docstring": "海报文本生成器\n使用AI模型为海报生成适合的文案内容特别支持Vibrant模板的字段结构",
"decorators": [],
"code": "class TextGenerator:\n \"\"\"\n 海报文本生成器\n 使用AI模型为海报生成适合的文案内容特别支持Vibrant模板的字段结构\n \"\"\"\n\n def __init__(\n self, \n config: AlgorithmConfig, \n ai_service: AIService,\n prompt_manager: PromptManager,\n json_processor: JSONProcessor\n ):\n \"\"\"\n 初始化文本生成器\n\n Args:\n config: 算法配置\n ai_service: AI服务\n prompt_manager: 提示词管理器\n json_processor: JSON处理器\n \"\"\"\n self.config = config\n self.ai_service = ai_service\n self.prompt_manager = prompt_manager\n self.json_processor = json_processor\n \n # 获取任务特定的模型配置\n self.task_model_config = config.ai_model.get_task_config(\"poster_generation\")\n \n logger.info(\"海报文本生成器初始化完成\")\n\n async def generate_poster_content(\n self,\n topic_info: str,\n style: str = \"活泼有趣\",\n target_audience: str = \"年轻旅行者\",\n poster_type: str = \"旅游宣传\",\n **kwargs\n ) -> Dict[str, Any]:\n \"\"\"\n 生成海报文案内容\n\n Args:\n topic_info: 主题信息\n style: 文案风格\n target_audience: 目标受众\n poster_type: 海报类型\n **kwargs: 其他参数\n\n Returns:\n 生成的海报内容字典\n\n Raises:\n ContentGenerationError: 生成失败时抛出\n \"\"\"\n try:\n logger.info(f\"开始生成海报文案,主题: {topic_info}\")\n\n # 1. 构建提示词\n system_prompt = self._get_poster_system_prompt()\n user_prompt = self._build_user_prompt(\n topic_info=topic_info,\n style=style,\n target_audience=target_audience,\n poster_type=poster_type,\n **kwargs\n )\n\n # 2. 调用AI生成\n content, input_tokens, output_tokens, elapsed_time = await self.ai_service.generate_text(\n system_prompt=system_prompt,\n user_prompt=user_prompt,\n stage=\"海报文案生成\",\n **self.task_model_config\n )\n\n # 3. 解析结果\n poster_content = self._parse_poster_content(content)\n\n # 4. 验证和增强内容\n validated_content = self._validate_and_enhance_content(poster_content, topic_info)\n\n logger.info(\"海报文案生成完成\")\n return validated_content\n\n except Exception as e:\n error_msg = f\"海报文案生成失败: {str(e)}\"\n logger.error(error_msg, exc_info=True)\n raise ContentGenerationError(error_msg)\n\n async def generate_vibrant_content(\n self,\n scenic_info: str,\n product_info: str,\n tweet_info: str = \"\",\n **kwargs\n ) -> Dict[str, Any]:\n \"\"\"\n 专门为Vibrant模板生成内容\n\n Args:\n scenic_info: 景区信息\n product_info: 产品信息\n tweet_info: 推文信息\n **kwargs: 其他参数\n\n Returns:\n 符合Vibrant模板结构的内容字典\n\n Raises:\n ContentGenerationError: 生成失败时抛出\n \"\"\"\n try:\n logger.info(\"开始生成Vibrant模板专用内容\")\n\n # 1. 构建Vibrant专用提示词\n system_prompt = self._get_vibrant_system_prompt()\n user_prompt = self._build_vibrant_user_prompt(scenic_info, product_info, tweet_info)\n\n # 2. 调用AI生成\n content, input_tokens, output_tokens, elapsed_time = await self.ai_service.generate_text(\n system_prompt=system_prompt,\n user_prompt=user_prompt,\n stage=\"Vibrant海报内容生成\",\n **self.task_model_config\n )\n\n # 3. 解析并验证Vibrant格式\n vibrant_content = self._parse_vibrant_content(content)\n\n logger.info(\"Vibrant模板内容生成完成\")\n return vibrant_content\n\n except Exception as e:\n error_msg = f\"Vibrant模板内容生成失败: {str(e)}\"\n logger.error(error_msg, exc_info=True)\n raise ContentGenerationError(error_msg)\n\n def _get_poster_system_prompt(self) -> str:\n \"\"\"获取海报生成的系统提示词\"\"\"\n try:\n # 尝试从文件加载\n return self.prompt_manager.get_prompt(\"poster_generation\", \"system\")\n except:\n # 使用默认提示词\n return \"\"\"你是一个专业的海报文案创作者,专门为旅游、美食、生活方式等主题创作吸引人的海报文案。\n\n你的任务是根据给定的主题信息创作适合海报展示的文案内容包括\n1. 吸引人的标题简洁有力15字以内\n2. 核心内容描述(生动形象,突出亮点)\n3. 相关标签3-5个关键词\n4. 行动召唤语句(激发用户行动)\n\n要求\n- 文案要有感染力和画面感\n- 适合目标受众的语言风格\n- 突出主题的独特价值\n- 符合海报的视觉传达需求\"\"\"\n\n def _get_vibrant_system_prompt(self) -> str:\n \"\"\"获取Vibrant模板专用的系统提示词\"\"\"\n return \"\"\"你是一名专业的海报设计师专门设计宣传海报。你现在要根据用户提供的信息生成适合Vibrant模板的海报内容。\n\n## Vibrant模板特点\n- 单图背景,毛玻璃渐变效果\n- 两栏布局(左栏内容,右栏价格)\n- 适合展示套餐内容和价格信息\n\n## 你需要生成的数据结构包含以下字段:\n\n**必填字段:**\n1. `title`: 主标题8-12字符体现产品特色\n2. `slogan`: 副标题/宣传语10-20字符吸引人的描述\n3. `price`: 价格数字(纯数字,不含符号),如果材料中没有价格,则用\"欢迎咨询\"替代\n4. `ticket_type`: 票种类型(如\"成人票\"、\"套餐票\"、\"夜场票\"等)\n5. `content_button`: 内容按钮文字(通常为\"套餐内容\"、\"包含项目\"等)\n6. `content_items`: 套餐内容列表3-5个项目每项5-15字符不要只包含项目名称要做合适的美化可以适当省略\n\n**可选字段:**\n7. `remarks`: 备注信息1-3条每条10-20字符\n8. `tag`: 标签1条, 如\"#限时优惠\"等)\n9. `pagination`: 分页信息(如\"1/3\",可为空)\n\n## 内容创作要求:\n1. 套餐内容要具体实用:明确说明包含的服务、时间、数量\n2. 价格要有吸引力:突出性价比和优惠信息\n\n## 输出格式:\n请严格按照JSON格式输出不要有任何额外内容。\"\"\"\n\n def _build_user_prompt(\n self,\n topic_info: str,\n style: str,\n target_audience: str,\n poster_type: str,\n **kwargs\n ) -> str:\n \"\"\"构建用户提示词\"\"\"\n \n user_prompt_template = \"\"\"请为以下主题创作海报文案:\n\n### 主题信息\n{topic_info}\n\n### 创作要求\n- 文案风格:{style}\n- 目标受众:{target_audience}\n- 海报类型:{poster_type}\n\n### 额外要求\n{additional_requirements}\n\n请按照以下JSON格式输出\n{\n \"title\": \"海报标题15字以内\",\n \"content\": \"主要内容描述\",\n \"tags\": [\"标签1\", \"标签2\", \"标签3\"],\n \"call_to_action\": \"行动召唤语句\"\n}\"\"\"\n\n additional_requirements = self._format_additional_requirements(kwargs)\n \n return user_prompt_template.format(\n topic_info=topic_info,\n style=style,\n target_audience=target_audience,\n poster_type=poster_type,\n additional_requirements=additional_requirements\n )\n\n def _build_vibrant_user_prompt(self, scenic_info: str, product_info: str, tweet_info: str) -> str:\n \"\"\"构建Vibrant模板专用的用户提示词\"\"\"\n return f\"\"\"请根据以下信息,生成适合在旅游海报上展示的文案:\n\n## 景区信息\n{scenic_info}\n\n## 产品信息\n{product_info}\n\n## 推文信息\n{tweet_info if tweet_info else \"无\"}\n\n请提取关键信息并整合成一个JSON对象包含title、slogan、price、ticket_type、content_items、remarks和tag字段。\"\"\"\n\n def _format_additional_requirements(self, kwargs: Dict[str, Any]) -> str:\n \"\"\"格式化额外要求\"\"\"\n requirements = []\n \n if kwargs.get(\"color_theme\"):\n requirements.append(f\"- 配色主题:{kwargs['color_theme']}\")\n \n if kwargs.get(\"mood\"):\n requirements.append(f\"- 情感氛围:{kwargs['mood']}\")\n \n if kwargs.get(\"key_points\"):\n key_points = kwargs['key_points']\n if isinstance(key_points, list):\n requirements.append(f\"- 重点突出:{', '.join(key_points)}\")\n else:\n requirements.append(f\"- 重点突出:{key_points}\")\n \n if kwargs.get(\"length_preference\"):\n requirements.append(f\"- 文案长度:{kwargs['length_preference']}\")\n\n return \"\\n\".join(requirements) if requirements else \"无特殊要求\"\n\n def _parse_poster_content(self, raw_content: str) -> Dict[str, Any]:\n \"\"\"解析海报内容生成结果\"\"\"\n try:\n # 使用JSON处理器解析\n parsed_data = self.json_processor.parse_llm_output(\n raw_output=raw_content,\n expected_fields=[\"title\", \"content\", \"tags\", \"call_to_action\"],\n required_fields=[\"title\", \"content\"]\n )\n \n if isinstance(parsed_data, dict):\n return parsed_data\n else:\n logger.warning(\"解析结果不是字典格式,使用回退方案\")\n return self._extract_content_from_text(raw_content)\n \n except Exception as e:\n logger.warning(f\"JSON解析失败使用文本提取: {e}\")\n return self._extract_content_from_text(raw_content)\n\n def _parse_vibrant_content(self, raw_content: str) -> Dict[str, Any]:\n \"\"\"解析Vibrant模板专用内容\"\"\"\n try:\n # 使用JSON处理器解析指定Vibrant的字段\n expected_fields = [\"title\", \"slogan\", \"price\", \"ticket_type\", \"content_button\", \"content_items\"]\n required_fields = [\"title\", \"slogan\", \"price\", \"ticket_type\", \"content_items\"]\n \n parsed_data = self.json_processor.parse_llm_output(\n raw_output=raw_content,\n expected_fields=expected_fields + [\"remarks\", \"tag\", \"pagination\"],\n required_fields=required_fields\n )\n \n if isinstance(parsed_data, dict):\n return self._normalize_vibrant_content(parsed_data)\n else:\n logger.warning(\"解析结果不是字典格式,使用回退方案\")\n return self._create_fallback_vibrant_content()\n \n except Exception as e:\n logger.warning(f\"Vibrant内容解析失败使用回退方案: {e}\")\n return self._create_fallback_vibrant_content()\n\n def _normalize_vibrant_content(self, parsed_data: Dict[str, Any]) -> Dict[str, Any]:\n \"\"\"标准化Vibrant内容格式\"\"\"\n normalized = {\n # 必填字段\n \"title\": parsed_data.get(\"title\", \"精彩旅程\"),\n \"slogan\": parsed_data.get(\"slogan\", \"发现世界的美好\"),\n \"price\": str(parsed_data.get(\"price\", \"欢迎咨询\")),\n \"ticket_type\": parsed_data.get(\"ticket_type\", \"门票\"),\n \"content_button\": parsed_data.get(\"content_button\", \"套餐内容\"),\n \"content_items\": parsed_data.get(\"content_items\", [\"精彩体验项目\"]),\n \n # 可选字段\n \"remarks\": parsed_data.get(\"remarks\", []),\n \"tag\": parsed_data.get(\"tag\", \"\"),\n \"pagination\": parsed_data.get(\"pagination\", \"\")\n }\n \n # 确保content_items是列表\n if isinstance(normalized[\"content_items\"], str):\n normalized[\"content_items\"] = [normalized[\"content_items\"]]\n \n # 确保remarks是列表\n if isinstance(normalized[\"remarks\"], str):\n normalized[\"remarks\"] = [normalized[\"remarks\"]]\n \n # 限制列表长度\n normalized[\"content_items\"] = normalized[\"content_items\"][:5]\n normalized[\"remarks\"] = normalized[\"remarks\"][:3]\n \n return normalized\n\n def _create_fallback_vibrant_content(self) -> Dict[str, Any]:\n \"\"\"创建Vibrant模板的回退内容\"\"\"\n return {\n \"title\": \"精彩旅程体验\",\n \"slogan\": \"探索世界的无限可能\",\n \"price\": \"欢迎咨询\",\n \"ticket_type\": \"体验票\",\n \"content_button\": \"套餐内容\",\n \"content_items\": [\n \"专业导游服务\",\n \"精美旅游纪念品\",\n \"全程保险保障\"\n ],\n \"remarks\": [\"请提前预约\", \"节假日价格另议\"],\n \"tag\": \"#精彩体验\",\n \"pagination\": \"\"\n }\n\n def _extract_content_from_text(self, text: str) -> Dict[str, Any]:\n \"\"\"从文本中提取海报内容(回退方案)\"\"\"\n lines = text.strip().split('\\n')\n \n # 简单的文本解析逻辑\n title = \"\"\n content = \"\"\n tags = []\n call_to_action = \"\"\n \n for line in lines:\n line = line.strip()\n if not line:\n continue\n \n if len(line) <= 20 and not title:\n # 可能是标题\n title = line\n elif '#' in line:\n # 可能是标签\n tags = [tag.strip() for tag in line.replace('#', '').split() if tag.strip()]\n elif not content and len(line) > 10:\n # 可能是主要内容\n content = line\n elif len(line) <= 15 and ('' in line or '!' in line):\n # 可能是行动召唤\n call_to_action = line\n\n return {\n \"title\": title or \"精彩旅程\",\n \"content\": content or text[:100],\n \"tags\": tags or [\"旅行\", \"探索\"],\n \"call_to_action\": call_to_action or \"立即体验!\"\n }\n\n def _validate_and_enhance_content(\n self, \n content: Dict[str, Any], \n topic_info: str\n ) -> Dict[str, Any]:\n \"\"\"验证和增强海报内容\"\"\"\n \n # 确保所有必需字段存在\n validated_content = {\n \"title\": content.get(\"title\", \"精彩旅程\")[:15], # 限制标题长度\n \"content\": content.get(\"content\", topic_info),\n \"tags\": content.get(\"tags\", [\"旅行\"]),\n \"call_to_action\": content.get(\"call_to_action\", \"立即体验!\")\n }\n \n # 确保标签是列表格式\n if isinstance(validated_content[\"tags\"], str):\n validated_content[\"tags\"] = [tag.strip() for tag in validated_content[\"tags\"].split(\",\")]\n \n # 限制标签数量\n validated_content[\"tags\"] = validated_content[\"tags\"][:5]\n \n # 添加元数据\n validated_content[\"metadata\"] = {\n \"word_count\": len(validated_content[\"content\"]),\n \"tag_count\": len(validated_content[\"tags\"]),\n \"generated_for\": topic_info,\n \"generation_config\": self.task_model_config\n }\n \n return validated_content\n\n async def generate_multiple_variations(\n self,\n topic_info: str,\n num_variations: int = 3,\n template_type: str = \"general\",\n **kwargs\n ) -> List[Dict[str, Any]]:\n \"\"\"\n 生成多个文案变体\n\n Args:\n topic_info: 主题信息\n num_variations: 变体数量\n template_type: 模板类型 (\"general\", \"vibrant\")\n **kwargs: 其他参数\n\n Returns:\n 文案变体列表\n \"\"\"\n variations = []\n \n styles = [\"活泼有趣\", \"温馨感人\", \"激情澎湃\", \"优雅文艺\", \"简洁干练\"]\n \n for i in range(num_variations):\n try:\n # 使用不同的风格\n style = styles[i % len(styles)]\n \n if template_type == \"vibrant\":\n # 为Vibrant模板生成内容\n variation = await self.generate_vibrant_content(\n scenic_info=kwargs.get(\"scenic_info\", topic_info),\n product_info=kwargs.get(\"product_info\", \"\"),\n tweet_info=kwargs.get(\"tweet_info\", \"\"),\n **kwargs\n )\n else:\n # 通用海报内容\n variation = await self.generate_poster_content(\n topic_info=topic_info,\n style=style,\n **kwargs\n )\n \n variation[\"variation_id\"] = i + 1\n variation[\"style_used\"] = style\n variations.append(variation)\n \n except Exception as e:\n logger.error(f\"生成变体 {i+1} 失败: {e}\")\n continue\n \n return variations\n\n def get_style_suggestions(self, poster_type: str, target_audience: str) -> List[str]:\n \"\"\"\n 根据海报类型和目标受众获取风格建议\n\n Args:\n poster_type: 海报类型\n target_audience: 目标受众\n\n Returns:\n 风格建议列表\n \"\"\"\n style_mapping = {\n \"旅游宣传\": {\n \"年轻人\": [\"活泼有趣\", \"激情澎湃\", \"个性时尚\"],\n \"家庭\": [\"温馨感人\", \"亲切自然\", \"安全舒适\"],\n \"商务人士\": [\"优雅文艺\", \"简洁干练\", \"品质生活\"]\n },\n \"美食推荐\": {\n \"年轻人\": [\"诱人美味\", \"时尚潮流\", \"分享快乐\"],\n \"家庭\": [\"家常温馨\", \"营养健康\", \"团圆美好\"],\n \"美食爱好者\": [\"精致品味\", \"传统文化\", \"匠心工艺\"]\n },\n \"活动宣传\": {\n \"年轻人\": [\"活力四射\", \"激情参与\", \"社交互动\"],\n \"全年龄\": [\"欢乐共享\", \"文化体验\", \"意义深远\"],\n \"专业人士\": [\"高端品质\", \"网络建设\", \"知识分享\"]\n }\n }\n \n return style_mapping.get(poster_type, {}).get(target_audience, [\"活泼有趣\", \"简洁明快\"]) ",
"code_hash": "fefa8ecc6e5c63c9d5cf088dde3fd727"
}
],
"imports": [
{
"type": "import",
"modules": [
"logging"
],
"aliases": []
},
{
"type": "from_import",
"module": "typing",
"names": [
"Dict",
"Any",
"Optional",
"List"
],
"aliases": [],
"level": 0
},
{
"type": "from_import",
"module": "config",
"names": [
"AlgorithmConfig"
],
"aliases": [],
"level": 2
},
{
"type": "from_import",
"module": "core",
"names": [
"AIService",
"PromptManager",
"JSONProcessor"
],
"aliases": [],
"level": 2
},
{
"type": "from_import",
"module": "exceptions",
"names": [
"ContentGenerationError"
],
"aliases": [],
"level": 2
}
],
"constants": [],
"docstring": "Text Generator for Posters\n海报文本生成器 - 负责生成海报所需的文案内容支持Vibrant模板格式",
"content_hash": "089a514f622542e62800299ecacf62c3"
}