Skip to content

提示工程高级技巧

本文档整理提示工程的高级技巧和模式,补充基础提示词设计文档。

高级模式概览

txt
┌─────────────────────────────────────────────────────┐
│                 提示工程高级模式                     │
├─────────────────────────────────────────────────────┤
│                                                     │
│  结构化模式                                         │
│  ├── XML 标签结构                                  │
│  ├── JSON 输出约束                                 │
│  ├── 表格格式输出                                  │
│  └── 分步推理结构                                  │
│                                                     │
│  推理增强模式                                       │
│  ├── Chain-of-Thought (CoT)                        │
│  ├── Self-Consistency                              │
│  ├── Tree-of-Thought (ToT)                         │
│  └── Least-to-Most                                 │
│                                                     │
│  优化模式                                           │
│  ├── 自动提示优化 (APE)                            │
│  ├── 提示微调 (Soft Prompt)                        │
│  └── 迭代优化                                      │
│                                                     │
│  组合模式                                           │
│  ├── 多轮对话优化                                  │
│  ├── 工具调用模式                                  │
│  └── RAG 增强                                      │
│                                                     │
└─────────────────────────────────────────────────────┘

结构化输出

XML 标签结构

python
# XML 结构化提示模板
XML_STRUCTURED_PROMPT = """
<task>
分析以下产品评论,提取关键信息。
</task>

<input>
{review_text}
</input>

<instructions>
1. 识别产品名称
2. 提取情感倾向(正面/负面/中性)
3. 列出提到的优点
4. 列出提到的缺点
5. 给出评分(1-5星)
</instructions>

<output_format>
<analysis>
    <product_name>产品名称</product_name>
    <sentiment>情感倾向</sentiment>
    <pros>
        <pro>优点1</pro>
        <pro>优点2</pro>
    </pros>
    <cons>
        <con>缺点1</con>
    </cons>
    <rating>评分</rating>
</analysis>
</output_format>

<constraints>
- 所有字段必须填写
- 如果信息缺失,填写"未提及"
- 评分必须是 1-5 的整数
</constraints>
"""

# 使用示例
def analyze_review_with_xml(review_text: str, model) -> dict:
    prompt = XML_STRUCTURED_PROMPT.format(review_text=review_text)
    response = model.generate(prompt)

    # 解析 XML 输出
    import xml.etree.ElementTree as ET
    try:
        root = ET.fromstring(response)
        return {
            "product_name": root.find("product_name").text,
            "sentiment": root.find("sentiment").text,
            "pros": [p.text for p in root.find("pros").findall("pro")],
            "cons": [c.text for c in root.find("cons").findall("con")],
            "rating": int(root.find("rating").text)
        }
    except ET.ParseError:
        return {"error": "解析失败"}

JSON Schema 约束

python
# JSON Schema 约束提示
JSON_SCHEMA_PROMPT = """
你是一个数据分析助手。请分析以下文本,并严格按照提供的 JSON Schema 输出结果。

文本:
{input_text}

请输出符合以下 JSON Schema 的 JSON:
{json_schema}

注意:
1. 严格遵循 Schema 定义的字段和类型
2. 所有必需字段必须存在
3. 枚举值必须在允许范围内
4. 数字必须在指定范围内
"""

# 定义 JSON Schema
PERSON_SCHEMA = {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "required": ["name", "age", "email"],
    "properties": {
        "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "姓名"
        },
        "age": {
            "type": "integer",
            "minimum": 0,
            "maximum": 150,
            "description": "年龄"
        },
        "email": {
            "type": "string",
            "format": "email",
            "description": "邮箱地址"
        },
        "interests": {
            "type": "array",
            "items": {
                "type": "string"
            },
            "description": "兴趣爱好"
        }
    }
}

# 验证 JSON 输出
def validate_json_output(output: str, schema: dict) -> tuple[bool, dict]:
    """验证 JSON 输出是否符合 Schema"""
    import json
    from jsonschema import validate, ValidationError

    try:
        data = json.loads(output)
        validate(instance=data, schema=schema)
        return True, data
    except json.JSONDecodeError as e:
        return False, {"error": f"JSON 解析失败: {e}"}
    except ValidationError as e:
        return False, {"error": f"Schema 验证失败: {e}"}

表格格式输出

python
# 表格格式提示
TABLE_FORMAT_PROMPT = """
请以表格形式整理以下信息。

{content}

输出要求:
1. 使用 Markdown 表格格式
2. 包含表头
3. 对齐列内容
4. 如果信息不足,使用 N/A

表格格式示例:
| 列1 | 列2 | 列3 |
|-----|-----|-----|
| 数据1 | 数据2 | 数据3 |
"""

# 表格解析
def parse_markdown_table(table_text: str) -> list[dict]:
    """解析 Markdown 表格"""
    lines = table_text.strip().split('\n')

    # 跳过空行
    lines = [l for l in lines if l.strip()]

    if len(lines) < 2:
        return []

    # 解析表头
    headers = [h.strip() for h in lines[0].split('|')[1:-1]]

    # 解析数据行(跳过分隔线)
    rows = []
    for line in lines[2:]:
        cells = [c.strip() for c in line.split('|')[1:-1]]
        if len(cells) == len(headers):
            rows.append(dict(zip(headers, cells)))

    return rows

推理增强

Chain-of-Thought (CoT)

python
# Chain-of-Thought 提示模板
COT_PROMPTS = {
    "standard": """
请一步步思考并解决问题:

{question}

请按照以下格式回答:
1. 首先,分析问题...
2. 然后,考虑...
3. 接着,计算/推理...
4. 最后,得出结论...

答案:
""",

    "zero_shot": """
{question}

请一步步思考,展示你的推理过程。
""",

    "few_shot": """
以下是一些示例:

示例 1:
问题:小明有 5 个苹果,给了小红 2 个,又买了 3 个。请问小明现在有几个苹果?
思考过程:
1. 小明初始有 5 个苹果
2. 给了小红 2 个,剩余 5 - 2 = 3 个
3. 又买了 3 个,现在有 3 + 3 = 6 个
答案:6 个苹果

示例 2:
问题:一本书有 200 页,小明第一天读了 1/4,第二天读了剩下的 1/3。请问小明两天共读了多少页?
思考过程:
1. 第一天读了 200 × 1/4 = 50 页
2. 剩余 200 - 50 = 150 页
3. 第二天读了 150 × 1/3 = 50 页
4. 两天共读了 50 + 50 = 100 页
答案:100 页

现在请解决:
问题:{question}
思考过程:
""",

    "self_consistency": """
{question}

请用 5 种不同的方法解决这个问题,然后选择最一致的答案。

方法 1:
[推理过程 1]

方法 2:
[推理过程 2]

方法 3:
[推理过程 3]

方法 4:
[推理过程 4]

方法 5:
[推理过程 5]

一致性分析:
比较这 5 种方法的结果,最一致的答案是:
"""
}

# CoT 使用示例
def solve_with_cot(question: str, model, style: str = "few_shot") -> str:
    prompt = COT_PROMPTS[style].format(question=question)
    return model.generate(prompt)

Tree-of-Thought (ToT)

python
from dataclasses import dataclass
from typing import List, Optional

@dataclass
class Thought:
    """思维节点"""
    content: str
    evaluation: float  # 0-1
    children: List['Thought'] = None

    def __post_init__(self):
        if self.children is None:
            self.children = []

class TreeOfThought:
    """思维树"""

    def __init__(
        self,
        model,
        max_depth: int = 3,
        branch_factor: int = 3,
        beam_width: int = 2
    ):
        self.model = model
        self.max_depth = max_depth
        self.branch_factor = branch_factor
        self.beam_width = beam_width

    def solve(self, problem: str) -> str:
        """使用思维树解决问题"""
        # 生成初始思维
        initial_thoughts = self._generate_thoughts(problem, None, self.branch_factor)

        # 广度优先搜索
        current_thoughts = initial_thoughts

        for depth in range(self.max_depth):
            # 评估当前层的思维
            for thought in current_thoughts:
                thought.evaluation = self._evaluate_thought(problem, thought)

            # 选择最优的思维继续扩展
            current_thoughts.sort(key=lambda t: t.evaluation, reverse=True)
            current_thoughts = current_thoughts[:self.beam_width]

            # 检查是否找到解决方案
            for thought in current_thoughts:
                if self._is_solution(thought):
                    return self._extract_solution(thought)

            # 扩展下一层
            next_thoughts = []
            for thought in current_thoughts:
                children = self._generate_thoughts(problem, thought, self.branch_factor)
                thought.children = children
                next_thoughts.extend(children)

            current_thoughts = next_thoughts

        # 返回最优思维
        return self._extract_best_solution(initial_thoughts)

    def _generate_thoughts(
        self,
        problem: str,
        current_thought: Optional[Thought],
        num_thoughts: int
    ) -> List[Thought]:
        """生成思维"""
        if current_thought is None:
            prompt = f"""
问题:{problem}

请生成 {num_thoughts} 个可能的思考方向或步骤。
每个方向用一行表示,格式为:
1. [思考方向1]
2. [思考方向2]
...
"""
        else:
            prompt = f"""
问题:{problem}
当前思考:{current_thought.content}

请基于当前思考,生成 {num_thoughts} 个可能的下一步。
每个步骤用一行表示。
"""

        response = self.model.generate(prompt)

        # 解析响应
        thoughts = []
        lines = response.strip().split('\n')
        for line in lines[:num_thoughts]:
            # 提取思考内容
            content = line.strip()
            if content and content[0].isdigit():
                content = content.split('.', 1)[1].strip()
            if content:
                thoughts.append(Thought(content=content, evaluation=0.0))

        return thoughts

    def _evaluate_thought(self, problem: str, thought: Thought) -> float:
        """评估思维"""
        prompt = f"""
问题:{problem}
思考:{thought.content}

请评估这个思考方向的有效性(0-10分):
- 是否有助于解决问题?
- 是否有逻辑错误?
- 是否有创新性?

只输出分数(0-10):
"""
        response = self.model.generate(prompt)

        try:
            score = float(response.strip())
            return min(max(score / 10, 0), 1)
        except:
            return 0.5

    def _is_solution(self, thought: Thought) -> bool:
        """检查是否为解决方案"""
        # 简化实现
        return thought.evaluation >= 0.9

    def _extract_solution(self, thought: Thought) -> str:
        """提取解决方案"""
        return thought.content

    def _extract_best_solution(self, thoughts: List[Thought]) -> str:
        """提取最优解决方案"""
        def get_max_evaluation(thoughts: List[Thought]) -> Thought:
            max_thought = thoughts[0]
            for thought in thoughts:
                if thought.evaluation > max_thought.evaluation:
                    max_thought = thought
                if thought.children:
                    child_max = get_max_evaluation(thought.children)
                    if child_max.evaluation > max_thought.evaluation:
                        max_thought = child_max
            return max_thought

        best = get_max_evaluation(thoughts)
        return best.content

# 使用示例
def solve_with_tot(problem: str, model) -> str:
    tot = TreeOfThought(model, max_depth=3, branch_factor=3, beam_width=2)
    return tot.solve(problem)

Least-to-Most Prompting

python
# Least-to-Most 提示
LEAST_TO_MOST_PROMPT = """
复杂问题分解策略:

原始问题:{problem}

第一步:分解问题
请将原始问题分解为一系列简单的子问题,从最简单的开始。

子问题列表:
1. [最简单的子问题]
2. [稍复杂的子问题]
3. ...
n. [最终要解决的原问题]

第二步:逐个解决
从第一个子问题开始,逐步解决:

子问题 1:[问题]
答案 1:[答案]

子问题 2:[问题]
(基于答案 1)答案 2:[答案]

...

最终答案:[原问题的答案]
"""

def solve_with_l2m(problem: str, model) -> str:
    """使用 Least-to-Most 方法解决问题"""
    prompt = LEAST_TO_MOST_PROMPT.format(problem=problem)
    return model.generate(prompt)

自动提示优化

自动提示工程 (APE)

python
from typing import List, Callable
import random

class AutomaticPromptEngineer:
    """自动提示工程"""

    def __init__(
        self,
        model,
        evaluator: Callable,
        num_candidates: int = 10,
        num_iterations: int = 5
    ):
        self.model = model
        self.evaluator = evaluator
        self.num_candidates = num_candidates
        self.num_iterations = num_iterations

    def optimize(
        self,
        task_description: str,
        few_shot_examples: List[dict] = None,
        initial_prompt: str = None
    ) -> str:
        """优化提示"""
        # 生成候选提示
        if initial_prompt:
            candidates = [initial_prompt]
        else:
            candidates = self._generate_initial_prompts(task_description)

        best_prompt = None
        best_score = -1

        for iteration in range(self.num_iterations):
            # 评估候选
            scored_candidates = []
            for candidate in candidates:
                score = self.evaluator(candidate, few_shot_examples)
                scored_candidates.append((candidate, score))

            # 排序
            scored_candidates.sort(key=lambda x: x[1], reverse=True)

            # 更新最佳
            if scored_candidates[0][1] > best_score:
                best_prompt = scored_candidates[0][0]
                best_score = scored_candidates[0][1]

            # 生成新的候选
            top_candidates = [c[0] for c in scored_candidates[:3]]
            new_candidates = self._generate_variations(top_candidates)

            # 更新候选池
            candidates = top_candidates + new_candidates

        return best_prompt

    def _generate_initial_prompts(self, task_description: str) -> List[str]:
        """生成初始提示候选"""
        prompt = f"""
任务描述:{task_description}

请生成 10 个不同的提示词模板,用于指导 AI 完成这个任务。
每个提示词应该:
1. 清晰描述任务目标
2. 提供必要的上下文
3. 指定输出格式
4. 包含约束条件

请按以下格式输出:
1. [提示词1]
2. [提示词2]
...
"""
        response = self.model.generate(prompt)

        # 解析提示词
        candidates = []
        for line in response.strip().split('\n'):
            if line.strip() and line[0].isdigit():
                candidate = line.split('.', 1)[1].strip()
                if candidate:
                    candidates.append(candidate)

        return candidates[:self.num_candidates]

    def _generate_variations(self, top_candidates: List[str]) -> List[str]:
        """生成变体"""
        prompt = f"""
以下是几个表现较好的提示词:

{chr(10).join(f'{i+1}. {c}' for i, c in enumerate(top_candidates))}

请基于这些提示词,生成 5 个改进版本。
每个改进版本应该:
1. 保留优点
2. 修正可能的缺陷
3. 尝试新的表达方式

请按以下格式输出:
1. [改进提示词1]
2. [改进提示词2]
...
"""
        response = self.model.generate(prompt)

        # 解析变体
        variations = []
        for line in response.strip().split('\n'):
            if line.strip() and line[0].isdigit():
                variation = line.split('.', 1)[1].strip()
                if variation:
                    variations.append(variation)

        return variations

# 使用示例
def evaluate_prompt(prompt: str, examples: List[dict]) -> float:
    """评估提示词效果"""
    # 简化实现:使用示例评估
    # 实际应该用验证集评估
    return random.random()  # 返回 0-1 的分数

def optimize_prompt_with_ape(task: str, model) -> str:
    ape = AutomaticPromptEngineer(
        model=model,
        evaluator=evaluate_prompt,
        num_candidates=10,
        num_iterations=5
    )
    return ape.optimize(task)

提示词模板库

通用模板

python
# 通用任务模板
TASK_TEMPLATES = {
    "classification": """
请对以下文本进行分类。

文本:{text}

类别:{categories}

请分析文本内容,并从给定类别中选择最合适的一个。
输出格式:
类别:[选择的类别]
置信度:[0-1]
理由:[简短说明]
""",

    "extraction": """
请从以下文本中提取信息。

文本:{text}

需要提取的字段:
{fields}

输出要求:
- 以 JSON 格式输出
- 如果字段不存在,填写 null
- 数值字段转换为数字类型

输出:
""",

    "summarization": """
请总结以下文本。

文本:{text}

总结要求:
- 长度:{length} 字以内
- 风格:{style}
- 重点:{focus}

总结:
""",

    "translation": """
请将以下文本翻译成{target_language}

源文本({source_language}):
{text}

翻译要求:
- 保持原意
- 语言流畅自然
- 符合目标语言习惯

译文:
""",

    "qa": """
根据以下上下文回答问题。

上下文:
{context}

问题:{question}

回答要求:
- 只使用上下文中的信息
- 如果上下文没有答案,回答"无法确定"
- 简洁明了

答案:
"""
}

# 角色模板
ROLE_TEMPLATES = {
    "expert": """
你是一位{domain}领域的专家,拥有深厚的理论知识和丰富的实践经验。

专业背景:
- {background}
- {experience}

当前任务:{task}

请以专家的角度分析和解决问题。
""",

    "teacher": """
你是一位耐心、善于引导的老师,擅长将复杂概念解释得通俗易懂。

教学风格:
- 循序渐进
- 举例说明
- 鼓励思考

当前教学内容:{content}

请用简单易懂的方式讲解这个概念。
""",

    "reviewer": """
你是一位严格的评审专家,擅长发现问题和提出改进建议。

评审标准:
{criteria}

当前待评审内容:
{content}

请从多个角度进行评审,指出优点和不足。
"""
}

# 使用示例
def apply_template(template_name: str, **kwargs) -> str:
    """应用模板"""
    if template_name in TASK_TEMPLATES:
        return TASK_TEMPLATES[template_name].format(**kwargs)
    elif template_name in ROLE_TEMPLATES:
        return ROLE_TEMPLATES[template_name].format(**kwargs)
    else:
        raise ValueError(f"Unknown template: {template_name}")

最佳实践总结

markdown
## 提示工程高级技巧检查清单

### 结构化输出

- [ ] 使用 XML/JSON 结构约束输出
- [ ] 定义清晰的输出 Schema
- [ ] 验证输出格式
- [ ] 处理解析异常

### 推理增强

- [ ] 使用 Chain-of-Thought
- [ ] 提供 few-shot 示例
- [ ] 引导逐步推理
- [ ] 使用 Self-Consistency 验证

### 提示优化

- [ ] 测试多个提示变体
- [ ] 使用自动提示优化
- [ ] 迭代改进
- [ ] 建立提示词库

### 质量保证

- [ ] 定义评估指标
- [ ] 建立测试集
- [ ] 进行 A/B 测试
- [ ] 监控线上效果