Prompt工程深度解析:从Few-Shot到Chain-of-Thought的推理增强技术全流程

举报
柠檬🍋 发表于 2026/08/22 15:36:52 2026/08/22
【摘要】 Prompt工程深度解析:从Few-Shot到Chain-of-Thought的推理增强技术全流程 一、引言:Prompt是大模型时代的编程语言在大模型时代,Prompt(提示)扮演着类似编程语言的角色——通过自然语言指令控制模型行为。同一个模型,不同的Prompt可以产生截然不同的输出质量。Prompt工程(Prompt Engineering)是研究如何设计有效Prompt以激发模型最...

Prompt工程深度解析:从Few-Shot到Chain-of-Thought的推理增强技术全流程

一、引言:Prompt是大模型时代的编程语言

在大模型时代,Prompt(提示)扮演着类似编程语言的角色——通过自然语言指令控制模型行为。同一个模型,不同的Prompt可以产生截然不同的输出质量。Prompt工程(Prompt Engineering)是研究如何设计有效Prompt以激发模型最大能力的实践学科。从简单的指令到复杂的思维链(Chain-of-Thought),从单轮提示到自洽性推理,Prompt工程的发展深刻影响着大模型的应用效果。本文将系统解析Prompt工程的核心技术:Zero-Shot、Few-Shot、Chain-of-Thought、Self-Consistency、Tree of Thoughts等,并提供完整的Python实现和实验对比。

二、Prompt工程基础

Prompt的基本结构包括:角色设定(Role)、任务描述(Task)、上下文信息(Context)、示例(Examples)、约束条件(Constraints)和输出格式(Format)。好的Prompt应当明确、具体、结构化。

import json
import re
from typing import List, Dict, Any, Optional, Tuple
from dataclasses import dataclass, field

@dataclass
class PromptTemplate:
    """Prompt模板"""
    name: str
    template: str
    input_variables: List[str] = field(default_factory=list)
    
    def format(self, **kwargs) -> str:
        return self.template.format(**kwargs)

class PromptEngineer:
    """Prompt工程师"""
    
    @staticmethod
    def zero_shot(task: str, instruction: str = "") -> str:
        """Zero-Shot提示"""
        prompt = f"""{instruction}

Task: {task}

Answer:"""
        return prompt
    
    @staticmethod
    def few_shot(task: str, examples: List[Dict[str, str]], 
                instruction: str = "") -> str:
        """Few-Shot提示"""
        prompt = instruction + "\n\n" if instruction else ""
        
        for ex in examples:
            prompt += f"Input: {ex['input']}\nOutput: {ex['output']}\n\n"
        
        prompt += f"Input: {task}\nOutput:"
        return prompt
    
    @staticmethod
    def chain_of_thought(task: str, examples: List[Dict[str, str]] = None,
                        instruction: str = "") -> str:
        """思维链提示"""
        prompt = instruction + "\n\n" if instruction else ""
        prompt += "Let's think step by step.\n\n"
        
        if examples:
            for ex in examples:
                prompt += f"Question: {ex['question']}\n"
                prompt += f"Reasoning: {ex['reasoning']}\n"
                prompt += f"Answer: {ex['answer']}\n\n"
        
        prompt += f"Question: {task}\nReasoning:"
        return prompt
    
    @staticmethod
    def self_consistency(task: str, n_samples: int = 5,
                        examples: List[Dict] = None) -> List[str]:
        """自洽性提示:生成多个推理路径"""
        prompts = []
        for i in range(n_samples):
            prompt = f"Approach {i+1}:\n"
            if examples:
                ex = examples[i % len(examples)]
                prompt += f"Example: {ex.get('reasoning', '')}\n"
            prompt += f"Question: {task}\nLet's think step by step.\n"
            prompts.append(prompt)
        return prompts
    
    @staticmethod
    def tree_of_thoughts(problem: str, n_branches: int = 3,
                         max_depth: int = 3) -> str:
        """思维树提示"""
        prompt = f"""Problem: {problem}

Generate {n_branches} different approaches to solve this problem.

For each approach, follow this format:
Approach X: [description]
- Step 1: [reasoning]
- Step 2: [reasoning]
- Evaluation: [score 0-10]
- Continue/Prune: [decision]

After exploring all approaches, select the best one and provide the final answer.
"""
        return prompt
    
    @staticmethod
    def role_play(role: str, task: str, 
                 expertise: str = "") -> str:
        """角色扮演提示"""
        prompt = f"""You are a {role}.
{f"Your expertise: {expertise}" if expertise else ""}

Task: {task}

Please respond based on your role and expertise."""
        return prompt
    
    @staticmethod
    def structured_output(task: str, schema: Dict[str, Any]) -> str:
        """结构化输出提示"""
        schema_str = json.dumps(schema, indent=2, ensure_ascii=False)
        prompt = f"""Task: {task}

Please provide the answer in the following JSON format:
{schema_str}

Output:"""
        return prompt
    
    @staticmethod
    def react_prompt(question: str, tools: List[str]) -> str:
        """ReAct提示"""
        tool_desc = '\n'.join([f"- {t}" for t in tools])
        prompt = f"""Answer the following question using the available tools.

Available tools:
{tool_desc}

Format:
Thought: [reasoning about what to do]
Action: [tool name]
Action Input: [input for the tool]
Observation: [tool result]
... (repeat as needed)
Final Answer: [answer]

Question: {question}

Thought:"""
        return prompt

class MockLLM:
    """模拟LLM用于演示"""
    
    def __init__(self):
        self.responses = {}
    
    def set_response(self, prompt_pattern: str, response: str):
        self.responses[prompt_pattern] = response
    
    def generate(self, prompt: str, temperature: float = 0.7) -> str:
        # 模拟不同Prompt产生不同效果
        if "step by step" in prompt.lower():
            return "Step 1: 分析问题要素\nStep 2: 确定计算方法\nStep 3: 执行计算\nAnswer: 42"
        elif "JSON" in prompt:
            return '{"answer": "42", "confidence": 0.95}'
        elif "Approach" in prompt:
            return "Approach 1: 直接计算 -> Answer: 42\nApproach 2: 分步推导 -> Answer: 42"
        elif "Thought:" in prompt:
            return " I need to calculate this.\nAction: calculator\nFinal Answer: 42"
        else:
            return "42"

def test_prompts():
    """测试不同Prompt策略"""
    llm = MockLLM()
    engineer = PromptEngineer()
    
    # Zero-Shot
    print("=== Zero-Shot ===")
    prompt = engineer.zero_shot("What is 6 * 7?", "You are a math assistant.")
    response = llm.generate(prompt)
    print(f"Prompt:\n{prompt}\n")
    print(f"Response: {response}\n")
    
    # Few-Shot
    print("=== Few-Shot ===")
    examples = [
        {"input": "2 + 3", "output": "5"},
        {"input": "4 * 5", "output": "20"},
    ]
    prompt = engineer.few_shot("6 * 7", examples)
    response = llm.generate(prompt)
    print(f"Prompt:\n{prompt[:200]}...\n")
    print(f"Response: {response}\n")
    
    # Chain-of-Thought
    print("=== Chain-of-Thought ===")
    prompt = engineer.chain_of_thought(
        "A train travels 60 km/h for 2 hours, then 80 km/h for 1.5 hours. Total distance?"
    )
    response = llm.generate(prompt)
    print(f"Prompt:\n{prompt[:200]}...\n")
    print(f"Response: {response}\n")
    
    # Structured Output
    print("=== Structured Output ===")
    schema = {"answer": "string", "confidence": "number", "explanation": "string"}
    prompt = engineer.structured_output("What is the capital of France?", schema)
    response = llm.generate(prompt)
    print(f"Response: {response}\n")

if __name__ == "__main__":
    test_prompts()

三、高级Prompt技术

class SelfConsistency:
    """自洽性推理:生成多个推理路径,投票选择最一致的答案"""
    
    def __init__(self, llm, n_samples: int = 5, temperature: float = 0.7):
        self.llm = llm
        self.n_samples = n_samples
        self.temperature = temperature
    
    def solve(self, question: str, examples: List[Dict] = None) -> Dict:
        """解决推理问题"""
        engineer = PromptEngineer()
        prompts = engineer.self_consistency(question, self.n_samples, examples)
        
        # 生成多个推理路径
        answers = []
        reasoning_paths = []
        
        for i, prompt in enumerate(prompts):
            response = self.llm.generate(prompt, temperature=self.temperature)
            # 提取答案
            answer = self._extract_answer(response)
            answers.append(answer)
            reasoning_paths.append({
                'path': i + 1,
                'response': response,
                'answer': answer
            })
        
        # 投票选择最一致的答案
        from collections import Counter
        answer_counts = Counter(answers)
        best_answer, votes = answer_counts.most_common(1)[0]
        
        return {
            'answer': best_answer,
            'confidence': votes / self.n_samples,
            'all_answers': answers,
            'reasoning_paths': reasoning_paths
        }
    
    def _extract_answer(self, response: str) -> str:
        """从响应中提取答案"""
        match = re.search(r'Answer:\s*(.+?)(?:\n|$)', response)
        if match:
            return match.group(1).strip()
        return response.strip().split('\n')[-1]

class TreeOfThoughts:
    """思维树:树形搜索推理路径"""
    
    def __init__(self, llm, max_depth: int = 3, n_branches: int = 3):
        self.llm = llm
        self.max_depth = max_depth
        self.n_branches = n_branches
    
    def solve(self, problem: str) -> Dict:
        """解决复杂推理问题"""
        # 生成初始想法
        thoughts = self._generate_thoughts(problem, depth=0)
        
        # 搜索最佳路径
        best_path = self._search(problem, thoughts, current_path=[], depth=0)
        
        return {
            'problem': problem,
            'best_path': best_path,
            'solution': best_path[-1]['thought'] if best_path else None
        }
    
    def _generate_thoughts(self, context: str, depth: int) -> List[Dict]:
        """生成多个思考分支"""
        prompt = f"""Context: {context}

Generate {self.n_branches} different thoughts/ideas to progress towards solving this problem.

Thought 1: [thought]
Thought 2: [thought]
Thought 3: [thought]
"""
        response = self.llm.generate(prompt)
        
        # 解析想法
        thoughts = []
        for match in re.finditer(r'Thought \d+:\s*(.+?)(?:\n|$)', response):
            thought = match.group(1).strip()
            # 评估想法质量
            score = self._evaluate_thought(context, thought)
            thoughts.append({
                'thought': thought,
                'score': score,
                'depth': depth
            })
        
        return thoughts
    
    def _evaluate_thought(self, context: str, thought: str) -> float:
        """评估想法质量"""
        # 模拟评估(实际中使用LLM评估)
        import random
        return random.uniform(0.5, 1.0)
    
    def _search(self, problem: str, thoughts: List[Dict],
               current_path: List[Dict], depth: int) -> List[Dict]:
        """搜索最佳路径(DFS)"""
        if depth >= self.max_depth or not thoughts:
            return current_path
        
        # 按分数排序
        thoughts.sort(key=lambda x: x['score'], reverse=True)
        
        # 只保留前N个
        top_thoughts = thoughts[:self.n_branches]
        
        best_path = current_path
        best_score = 0
        
        for thought in top_thoughts:
            new_path = current_path + [thought]
            
            # 如果还有深度,继续搜索
            if depth + 1 < self.max_depth:
                next_context = f"{problem}\nPrevious thoughts: {thought['thought']}"
                next_thoughts = self._generate_thoughts(next_context, depth + 1)
                path = self._search(problem, next_thoughts, new_path, depth + 1)
            else:
                path = new_path
            
            # 评估路径
            path_score = sum(t['score'] for t in path) / len(path) if path else 0
            if path_score > best_score:
                best_score = path_score
                best_path = path
        
        return best_path

class PromptOptimizer:
    """Prompt优化器"""
    
    @staticmethod
    def optimize(prompt: str, feedback: str = "") -> str:
        """根据反馈优化Prompt"""
        improvements = []
        
        # 检查是否缺少角色设定
        if not re.search(r'You are|你是一个|你是', prompt):
            improvements.append("添加角色设定")
        
        # 检查是否缺少输出格式
        if not re.search(r'format|格式|JSON|output', prompt, re.I):
            improvements.append("指定输出格式")
        
        # 检查是否缺少示例
        if not re.search(r'Example|示例|e\.g\.', prompt):
            improvements.append("添加示例")
        
        # 检查是否缺少约束
        if not re.search(r'must|should|不要|必须|不超过', prompt):
            improvements.append("添加约束条件")
        
        # 检查是否过长
        if len(prompt) > 2000:
            improvements.append("Prompt过长,建议精简")
        
        return improvements

def test_advanced_prompts():
    """测试高级Prompt技术"""
    llm = MockLLM()
    
    # Self-Consistency
    print("=== Self-Consistency ===")
    sc = SelfConsistency(llm, n_samples=3)
    result = sc.solve("What is 15 * 17?")
    print(f"Answer: {result['answer']}")
    print(f"Confidence: {result['confidence']:.2%}")
    print(f"All answers: {result['all_answers']}")
    
    # Tree of Thoughts
    print("\n=== Tree of Thoughts ===")
    tot = TreeOfThoughts(llm, max_depth=2, n_branches=2)
    result = tot.solve("How to reduce carbon emissions?")
    print(f"Best path length: {len(result['best_path'])}")
    if result['best_path']:
        print(f"Solution: {result['solution'][:100]}...")
    
    # Prompt优化
    print("\n=== Prompt Optimization ===")
    prompt = "Explain machine learning."
    improvements = PromptOptimizer.optimize(prompt)
    print(f"原始Prompt: {prompt}")
    print(f"改进建议: {improvements}")

if __name__ == "__main__":
    test_advanced_prompts()

四、总结

Prompt工程通过精心设计的提示,显著提升大模型的推理和生成能力。Zero-Shot提供最简单的基线;Few-Shot通过示例引导模型理解任务格式;Chain-of-Thought激发模型的逐步推理能力;Self-Consistency通过多路径投票提升答案可靠性;Tree of Thoughts支持复杂的树形搜索。从工程实践角度,好的Prompt应当明确角色、具体描述任务、提供示例、指定输出格式、设置约束条件。随着Prompt工程与Agent技术的融合(如自动Prompt优化、Prompt-as-Program),Prompt不仅是使用大模型的技术,更成为大模型时代的核心编程范式。掌握Prompt工程,是从大模型的使用者进阶为高效开发者的必经之路。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。