第 77 章

Fast Mode 实战:2.5x 速度 / 6倍价格 / Opus 4.6 高速推理的适用场景判断

第七十七章:创意写作与内容生成:风格控制、多样性与品牌一致性

77.1 创意写作的工程挑战

创意写作是 LLM 应用中最难被系统化的任务之一。与结构化数据提取或分类不同,创意写作的"正确答案"本质上是模糊的、主观的,且依赖于受众、目的和品牌背景。

工程师面对的核心挑战是:

  1. 风格可控性:如何让 Claude 始终采用特定的风格(品牌语气、特定作者风格)?
  2. 内容多样性:如何避免大量生成时内容同质化、重复感强?
  3. 品牌一致性:当内容需要跨多个平台、多个时间段发布时,如何确保统一的品牌声音?
  4. 质量评估:如何衡量创意内容的"好坏"?

本章将系统性地解答这些问题,提供可落地的工程方案。

77.2 风格控制

77.2.1 风格的组成要素

风格不是一个单一维度,而是多个相互交织的维度的组合:

STYLE_DIMENSIONS = {
    "tone": {
        "options": ["formal", "casual", "playful", "authoritative", "empathetic", "humorous"],
        "description": "整体情感基调"
    },
    "voice": {
        "options": ["first_person", "second_person", "third_person", "collective_we"],
        "description": "叙述视角和人称"
    },
    "sentence_structure": {
        "options": ["short_punchy", "long_flowing", "varied", "parallel"],
        "description": "句式偏好"
    },
    "vocabulary_level": {
        "options": ["simple", "intermediate", "advanced", "technical", "colloquial"],
        "description": "词汇复杂度"
    },
    "rhetoric": {
        "options": ["factual", "storytelling", "persuasive", "descriptive", "instructional"],
        "description": "修辞策略"
    },
    "punctuation_style": {
        "options": ["minimal", "liberal", "em_dash_heavy", "parenthetical"],
        "description": "标点使用风格"
    }
}

77.2.2 风格示例法(Style Exemplars)

最有效的风格控制方法是提供具体示例,而非抽象描述。"像这样写"远比"写得活泼有趣"更有效:

from anthropic import Anthropic

client = Anthropic()

def build_style_prompt(
    task: str,
    style_exemplars: list,
    anti_examples: list = None,
    style_description: str = ""
) -> str:
    """
    构建基于示例的风格控制 Prompt
    
    style_exemplars: 目标风格的示例文本列表(3-5 个最佳)
    anti_examples: 明确不想要的风格示例(可选)
    """
    
    exemplar_section = "\n\n".join([
        f"示例 {i+1}:\n{example}"
        for i, example in enumerate(style_exemplars)
    ])
    
    anti_example_section = ""
    if anti_examples:
        anti_example_section = "\n\n请注意,以下是不希望的风格示例(不要模仿):\n" + "\n\n".join([
            f"反例 {i+1}:\n{example}"
            for i, example in enumerate(anti_examples)
        ])
    
    desc_section = f"\n\n风格说明:{style_description}" if style_description else ""
    
    return f"""请按照以下示例的风格完成写作任务。

目标风格示例:
{exemplar_section}
{anti_example_section}
{desc_section}

分析以上示例,提炼其核心风格特征(句式、语气、词汇选择、节奏等),然后用相同风格完成任务:

{task}"""

77.2.3 品牌声音(Brand Voice)建模

品牌声音是品牌长期积累的、独特的沟通风格。对于内容量大的企业应用,需要将品牌声音系统化地编码到 Prompt 中:

class BrandVoiceProfile:
    """品牌声音档案"""
    
    def __init__(self, brand_name: str):
        self.brand_name = brand_name
        self.profile = {}
    
    @classmethod
    def from_dict(cls, data: dict) -> "BrandVoiceProfile":
        instance = cls(data["brand_name"])
        instance.profile = data
        return instance
    
    def to_system_prompt(self) -> str:
        """将品牌声音档案转换为系统提示"""
        
        voice_attrs = self.profile.get("voice_attributes", {})
        dos = self.profile.get("dos", [])
        donts = self.profile.get("donts", [])
        keywords = self.profile.get("brand_keywords", [])
        signature_phrases = self.profile.get("signature_phrases", [])
        exemplars = self.profile.get("exemplar_texts", [])
        
        dos_text = "\n".join([f"- {item}" for item in dos])
        donts_text = "\n".join([f"- {item}" for item in donts])
        keywords_text = "、".join(keywords) if keywords else ""
        phrases_text = "\n".join([f'- "{p}"' for p in signature_phrases])
        
        exemplar_text = ""
        if exemplars:
            exemplar_text = "\n\n品牌文案示例(请学习这些示例的风格):\n"
            for i, ex in enumerate(exemplars[:3], 1):
                exemplar_text += f"\n示例 {i}:{ex}"
        
        return f"""你是 {self.brand_name} 的内容创作者。

品牌声音特征:
{chr(10).join([f"- {k}: {v}" for k, v in voice_attrs.items()])}

内容创作规范:
✅ 应该做的:
{dos_text}

❌ 不应该做的:
{donts_text}

{f"品牌核心词汇(适当使用):{keywords_text}" if keywords_text else ""}

{f"品牌标志性表达:{chr(10)}{phrases_text}" if signature_phrases else ""}

{exemplar_text}"""


# 使用示例:科技品牌的品牌声音档案
TECH_BRAND_PROFILE = {
    "brand_name": "YiteAI",
    "voice_attributes": {
        "tone": "专业而平易近人",
        "personality": "聪明、好奇、对技术充满热情",
        "formality": "半正式,避免过于学术化"
    },
    "dos": [
        "使用清晰具体的语言,避免空洞的科技术语",
        "用类比和生活场景解释复杂概念",
        "承认技术的局限性,保持诚实",
        "以用户价值为中心,而非技术功能"
    ],
    "donts": [
        "不使用 '颠覆性'、'革命性' 等夸张词汇",
        "不使用被动语态('它被设计用来...')",
        "不堆砌技术术语来显示专业性",
        "不做无法验证的声明"
    ],
    "brand_keywords": ["智能", "高效", "可靠", "简洁"],
    "signature_phrases": [
        "让复杂的事情变简单",
        "AI 为人服务,而不是相反"
    ],
    "exemplar_texts": [
        "你不需要懂机器学习,就像你不需要懂发动机原理才能开车。YiteAI 把复杂的部分藏在引擎盖下。",
        "数据隐私不是功能,而是基础。我们不收集你不需要我们收集的任何东西。"
    ]
}

77.2.4 风格迁移(Style Transfer)

def style_transfer(
    source_text: str,
    target_style_exemplar: str,
    preserve_elements: list = None
) -> str:
    """
    将现有文本的风格迁移为目标风格
    preserve_elements: 必须保留的元素(如数字、品牌名、核心事实)
    """
    preserve_text = ""
    if preserve_elements:
        preserve_text = f"\n\n注意:以下元素必须原样保留,不得修改:\n" + "\n".join([f"- {el}" for el in preserve_elements])
    
    transfer_prompt = f"""请将第一段文本的内容,用第二段文本的风格重新表达。

原始文本(保留内容,调整风格):
{source_text}

目标风格参考(仅用于风格参考,不使用其内容):
{target_style_exemplar}
{preserve_text}

请输出风格迁移后的版本,长度与原文大致相当:"""
    
    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=len(source_text) * 2 + 500,
        messages=[{"role": "user", "content": transfer_prompt}]
    )
    
    return response.content[0].text

77.3 内容多样性

77.3.1 多样性的度量

内容多样性可以从多个角度度量:

import re
from collections import Counter

def compute_content_diversity(texts: list) -> dict:
    """
    计算一组文本的多样性指标
    """
    if len(texts) < 2:
        return {"error": "需要至少2个文本进行多样性评估"}
    
    # 1. 词汇多样性(Type-Token Ratio 的变体)
    all_words = []
    per_text_words = []
    for text in texts:
        words = re.findall(r'\b\w+\b', text.lower())
        all_words.extend(words)
        per_text_words.append(set(words))
    
    vocabulary_size = len(set(all_words))
    avg_unique_words = sum(len(w) for w in per_text_words) / len(per_text_words)
    
    # 2. 开头多样性(前 20 字符)
    openings = [text[:20] for text in texts]
    unique_openings = len(set(openings))
    opening_diversity = unique_openings / len(texts)
    
    # 3. 句式多样性(句子长度方差)
    sentence_lengths = []
    for text in texts:
        sentences = re.split(r'[。!?.!?]', text)
        sentences = [s for s in sentences if s.strip()]
        if sentences:
            lengths = [len(s) for s in sentences]
            sentence_lengths.extend(lengths)
    
    length_variance = 0
    if sentence_lengths:
        mean_len = sum(sentence_lengths) / len(sentence_lengths)
        length_variance = sum((l - mean_len) ** 2 for l in sentence_lengths) / len(sentence_lengths)
    
    return {
        "vocabulary_size": vocabulary_size,
        "avg_unique_words_per_text": avg_unique_words,
        "opening_diversity_ratio": opening_diversity,
        "sentence_length_variance": length_variance,
        "diversity_score": (opening_diversity * 0.4 + min(length_variance / 100, 1) * 0.3 + 
                           min(vocabulary_size / 1000, 1) * 0.3)
    }

77.3.2 多样性增强技术

def generate_diverse_variations(
    base_content: str,
    n_variations: int = 5,
    diversity_axes: list = None
) -> list:
    """
    生成多样化的内容变体
    
    diversity_axes: 多样化的维度
    - "angle": 切入角度(从不同视角展开)
    - "structure": 结构变化(不同的开头/结构方式)
    - "tone": 语气变化(在品牌允许范围内的轻微语气差异)
    - "hook": 钩子(不同的吸引点/开场白)
    """
    if diversity_axes is None:
        diversity_axes = ["angle", "structure", "hook"]
    
    diversity_prompt = f"""基于以下核心内容,生成 {n_variations} 个风格不同但信息等价的变体版本。

核心内容:
{base_content}

多样化要求:
{chr(10).join([f"- 在以下维度上进行变化:{axis}" for axis in diversity_axes])}

重要约束:
- 所有变体必须传达相同的核心信息和价值主张
- 变体之间的差异应该是真实的,而不是细微的措辞调整
- 确保没有任何两个变体的开头相同

请按以下格式输出:

<variation_1>
[变体1]
</variation_1>

<variation_2>
[变体2]
</variation_2>

... 以此类推"""
    
    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=n_variations * (len(base_content) + 200),
        temperature=0.9,  # 提高温度增加多样性
        messages=[{"role": "user", "content": diversity_prompt}]
    )
    
    text = response.content[0].text
    variations = []
    for i in range(1, n_variations + 1):
        tag = f"variation_{i}"
        if f"<{tag}>" in text:
            variation = text.split(f"<{tag}>")[1].split(f"</{tag}>")[0].strip()
            variations.append(variation)
    
    return variations

77.3.3 避免重复模式

Claude 在大量生成时会出现习惯性的开头模式(如"当然,..." 或 "很高兴为您...")。

ANTI_REPETITION_INSTRUCTIONS = """写作多样性要求:
- 不要用"当然"、"当然了"、"很好"、"好的"等确认词开头
- 不要每次都以"首先...其次...最后..."的三段式结构
- 不要在每段末尾都用相同的过渡句
- 不要过度使用感叹号
- 各变体之间,关键词的使用频率应有所变化

如果发现自己在重复某个模式,请主动打破它。"""

77.4 品牌一致性管理

77.4.1 内容质量门控

class ContentQualityGate:
    """内容质量门控系统"""
    
    def __init__(self, brand_profile: BrandVoiceProfile):
        self.brand_profile = brand_profile
    
    def check_brand_consistency(self, content: str) -> dict:
        """
        检查内容是否符合品牌声音
        """
        check_prompt = f"""请检查以下内容是否符合品牌声音规范。

品牌声音规范:
{self.brand_profile.to_system_prompt()}

待检查内容:
{content}

请检查以下方面:
1. 是否违反了"不应该做的"规则?
2. 是否体现了品牌声音特征?
3. 使用的词汇是否与品牌调性匹配?
4. 整体一致性如何?

以 JSON 格式输出:
{{
  "passes": true/false,
  "overall_score": 0-10,
  "violations": [
    {{"rule": "...", "excerpt": "...", "suggestion": "..."}}
  ],
  "strengths": [...],
  "revision_needed": true/false
}}"""
        
        response = client.messages.create(
            model="claude-opus-4-5",
            max_tokens=1000,
            messages=[{"role": "user", "content": check_prompt}]
        )
        
        import json
        try:
            return json.loads(response.content[0].text)
        except:
            return {"raw_check": response.content[0].text}
    
    def auto_revise(self, content: str, violations: list) -> str:
        """
        根据检查结果自动修订内容
        """
        violations_text = "\n".join([
            f"- 问题:{v['rule']};原文:\"{v['excerpt']}\";建议:{v['suggestion']}"
            for v in violations
        ])
        
        revision_prompt = f"""请修订以下内容以解决品牌声音问题。

原始内容:
{content}

需要修复的问题:
{violations_text}

品牌声音规范:
{self.brand_profile.to_system_prompt()}

请直接输出修订后的版本,无需解释:"""
        
        response = client.messages.create(
            model="claude-opus-4-5",
            max_tokens=len(content) * 2,
            messages=[{"role": "user", "content": revision_prompt}]
        )
        
        return response.content[0].text

77.4.2 内容生成流水线

class ContentGenerationPipeline:
    """完整的内容生成流水线"""
    
    def __init__(self, brand_profile: BrandVoiceProfile):
        self.brand = brand_profile
        self.quality_gate = ContentQualityGate(brand_profile)
    
    def generate(
        self,
        content_brief: str,
        content_type: str,  # "social_post", "blog_intro", "product_desc", etc.
        n_variations: int = 3,
        max_revisions: int = 2
    ) -> list:
        """
        完整的内容生成流程:
        1. 生成初版(含品牌声音)
        2. 质量检查
        3. 如不合格,自动修订(最多 max_revisions 次)
        4. 返回通过检查的变体
        """
        system_prompt = self.brand.to_system_prompt()
        
        # Step 1: 生成初版变体
        generation_prompt = f"""请为以下内容简报生成 {n_variations} 个{content_type}变体。

内容简报:
{content_brief}

每个变体应该独特且符合品牌声音。请按以下格式输出:

<variant_1>[内容1]</variant_1>
<variant_2>[内容2]</variant_2>
<variant_3>[内容3]</variant_3>"""
        
        response = client.messages.create(
            model="claude-opus-4-5",
            max_tokens=3000,
            system=system_prompt,
            messages=[{"role": "user", "content": generation_prompt}]
        )
        
        # 解析变体
        variants = self._parse_variants(response.content[0].text, n_variations)
        
        # Step 2-3: 质量检查与修订
        approved_variants = []
        for variant in variants:
            current = variant
            for revision in range(max_revisions + 1):
                check_result = self.quality_gate.check_brand_consistency(current)
                
                if check_result.get("passes", True):
                    approved_variants.append({
                        "content": current,
                        "quality_score": check_result.get("overall_score", 8),
                        "revisions": revision
                    })
                    break
                elif revision < max_revisions:
                    violations = check_result.get("violations", [])
                    if violations:
                        current = self.quality_gate.auto_revise(current, violations)
                else:
                    # 超出修订次数,仍然包含但标记质量问题
                    approved_variants.append({
                        "content": current,
                        "quality_score": check_result.get("overall_score", 5),
                        "revisions": revision,
                        "quality_warnings": check_result.get("violations", [])
                    })
        
        return approved_variants
    
    def _parse_variants(self, text: str, n: int) -> list:
        variants = []
        for i in range(1, n + 1):
            tag = f"variant_{i}"
            if f"<{tag}>" in text:
                variant = text.split(f"<{tag}>")[1].split(f"</{tag}>")[0].strip()
                variants.append(variant)
        return variants

77.5 特殊创意场景

77.5.1 A/B 测试文案生成

def generate_ab_test_copy(
    product_feature: str,
    target_audience: str,
    platform: str,  # "WeChat", "LinkedIn", "Instagram", etc.
    test_hypothesis: str,
    n_variants: int = 4
) -> dict:
    """
    为 A/B 测试生成系统化的文案变体
    每个变体对应不同的核心信息诉求(情感/理性/恐惧/社会证明等)
    """
    
    APPEAL_TYPES = {
        "rational": "理性诉求:强调功能、数据、效率",
        "emotional": "情感诉求:强调感受、体验、归属感",
        "fear_of_missing_out": "FOMO:错失恐惧,强调竞争者已在使用",
        "social_proof": "社会证明:强调用户数量、评价、口碑"
    }
    
    appeals = list(APPEAL_TYPES.items())[:n_variants]
    
    ab_prompt = f"""请为 A/B 测试生成 {n_variants} 个文案变体。

产品特性:{product_feature}
目标受众:{target_audience}
发布平台:{platform}
测试假设:{test_hypothesis}

每个变体使用不同的诉求方式:
{chr(10).join([f"变体{i+1}:{appeal}" for i, (_, appeal) in enumerate(appeals)])}

每个变体需要包含:
- 标题(15字以内)
- 正文(50-80字)
- 行动号召(CTA,10字以内)

请按以下格式输出:
<variant_1>
标题:[标题文字]
正文:[正文内容]
CTA:[行动号召]
诉求类型:[使用的诉求方式]
</variant_1>
...以此类推"""
    
    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=2000,
        messages=[{"role": "user", "content": ab_prompt}]
    )
    
    return {
        "variants": parse_ab_variants(response.content[0].text, n_variants),
        "test_setup": {
            "hypothesis": test_hypothesis,
            "appeal_types": dict(appeals),
            "platform": platform
        }
    }

小结

创意写作的工程化并不是要消除创意,而是为创意提供可靠的基础设施。风格控制的核心是示例法——让模型看到"好的"和"不好的"示例,比抽象描述更有效。多样性管理需要主动监控内容的多样性指标,并通过多维度的变化策略避免同质化。品牌一致性管理则需要将品牌声音系统化地编码为可执行的检查规则,并建立自动修订循环。

这三者共同构成了内容生成工厂的质量控制体系:风格控制确保输出"听起来对了",多样性管理确保大量输出不会让用户产生"都是同一套话"的感觉,品牌一致性管理确保每一条输出都为品牌资产增值而非损耗。

本章评分
4.9  / 5  (3 评分)

💬 留言讨论