"""文案生成器 — 模板模式 + AI 模式双模式。""" import re import json import logging logger = logging.getLogger(__name__) class CopyGenerator: """文案生成器。""" def generate_template_copy(self, template_content: str, product_rules: dict, customer_data: dict) -> dict: """模板模式:本地变量替换。 参数: template_content: 含 {{变量}} 占位符的文案模板 product_rules: 产品规则(manual_parsed_rules) customer_data: 客户数据(confirmed_data) 返回: {"headline": "...", "body": "...", "call_to_action": "..."} """ # 构建变量映射 variables = {} # 产品信息 if product_rules: variables["product_name"] = product_rules.get("product_name", "") features = product_rules.get("features", []) for i, feat in enumerate(features[:3], 1): variables[f"feature_{i}_title"] = feat.get("title", "") variables[f"feature_{i}_summary"] = feat.get("summary", "") variables["currency_options"] = ", ".join(product_rules.get("currency_options", [])) # 客户数据 if customer_data: variables["age"] = str(customer_data.get("age", "")) variables["currency"] = customer_data.get("currency", "") variables["sum_assured"] = str(customer_data.get("sum_assured", "")) variables["annual_premium"] = str(customer_data.get("annual_premium", "")) variables["coverage_period"] = customer_data.get("coverage_period", "") # 替换占位符 result = template_content for key, value in variables.items(): result = result.replace("{{" + key + "}}", value) # 尝试按段落拆分为 headline/body/call_to_action lines = [l.strip() for l in result.split("\n") if l.strip()] return { "headline": lines[0] if lines else "", "body": "\n".join(lines[1:-1]) if len(lines) > 2 else lines[1] if len(lines) > 1 else "", "call_to_action": lines[-1] if len(lines) > 1 else "", } async def generate_ai_copy(self, product_rules: dict, customer_data: dict, style: str = "专业") -> dict: """AI 模式:调用 LLM 生成营销文案。 返回: {"headline": "...", "body": "...", "call_to_action": "..."} """ from insurance.ppt.llm_client import poster_llm_client system_prompt = f"""你是一位专业的保险营销文案撰写人。 根据以下产品信息和客户数据,生成一张保险营销海报的文案。 要求: 1. 标题(headline):简短有力,8字以内 2. 正文(body):突出产品亮点与客户需求的匹配,50-100字 3. 行动号召(call_to_action):引导客户咨询,15字以内 4. 风格:{style} 5. 必须基于真实数据,不得虚构收益数字 以 JSON 格式返回(不要包含 markdown 代码块标记)。""" user_prompt = f""" 产品信息:{json.dumps(product_rules, ensure_ascii=False)} 客户数据:{json.dumps(customer_data, ensure_ascii=False)}""" result, _response = await poster_llm_client.structured_output( user_prompt, system_prompt, schema={ "type": "object", "properties": { "headline": {"type": "string"}, "body": {"type": "string"}, "call_to_action": {"type": "string"}, }, "required": ["headline", "body", "call_to_action"], }, ) return result