738 lines
72 KiB
JSON
738 lines
72 KiB
JSON
{
|
||
"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"
|
||
} |