在大语言模型时代,如何与模型"对话"成了一门艺术。同样的模型,不同的提示(
Prompt)可能产生截然不同的结果。提示工程( Prompt
Engineering)正是研究如何设计有效的输入,让模型发挥出最佳性能的技术。从简单的零样本提示到复杂的思维链推理,从角色设定到模板设计,提示工程已经成为使用大模型的核心技能。
In-Context
Learning(上下文学习)是提示工程的理论基础。它揭示了模型如何通过示例学习,如何在推理时动态调整行为,以及为什么少样本提示往往比零样本提示效果更好。理解这些机制不仅能帮助我们写出更好的提示,更能深入理解大语言模型的工作方式。
本文将系统介绍提示工程的核心概念与实践技巧,包括零样本、少样本、思维链提示,角色设定与格式化技巧,提示模板设计,
Self-Consistency 和 ReAct
等高级技术,并通过实战案例展示如何构建高效的提示系统。
提示工程基础与原则
提示工程的基本思路:通过精心设计的输入文本,引导模型产生期望的输出。一个好的提示应该清晰、具体、包含必要的上下文信息。
提示工程的基本原则
1. 清晰性( Clarity)
提示应该明确表达任务要求,避免歧义。对比以下两个提示:
- ❌ 差:
"分析这个文本"
- ✅
好:
"请分析以下文本的情感倾向,并给出积极、消极或中性的判断"
2. 具体性( Specificity)
提供具体的输出格式要求,让模型知道如何组织答案:
1 2 3 4 5 6 7 8 9 10
| prompt = """ 请分析以下产品的优缺点,并按照以下格式输出: 优点: 1. ... 2. ...
缺点: 1. ... 2. ... """
|
3. 上下文完整性( Context Completeness)
确保提示包含完成任务所需的所有信息:
1 2 3 4 5 6 7 8 9
| prompt1 = "翻译这句话"
prompt2 = """ 请将以下英文句子翻译成中文,保持原意和语气: 英文: The quick brown fox jumps over the lazy dog. 中文: """
|
4. 角色设定( Role Assignment)
为模型设定明确的角色,可以显著提升输出质量:
1 2 3 4 5
| prompt = """ 你是一位经验丰富的 Python 编程专家,擅长编写清晰、高效的代码。 请为以下需求编写 Python 函数: 需求:实现一个快速排序算法 """
|
提示的组成要素
一个完整的提示通常包含以下部分:
- 指令( Instruction):明确告诉模型要做什么
- 上下文( Context):提供背景信息
- 输入数据( Input Data):需要处理的具体内容
- 输出格式( Output Format):期望的输出结构
- 示例(
Examples):可选的示例,用于演示期望行为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| def build_prompt(instruction, context, input_data, output_format=None, examples=None): prompt_parts = [] prompt_parts.append("你是一位专业的数据分析师。") prompt_parts.append(f"任务:{instruction}") if context: prompt_parts.append(f"背景信息:{context}") if examples: prompt_parts.append("示例:") for ex in examples: prompt_parts.append(f"输入:{ex['input']}") prompt_parts.append(f"输出:{ex['output']}") if output_format: prompt_parts.append(f"输出格式:{output_format}") prompt_parts.append(f"请处理以下数据:\n{input_data}") return "\n\n".join(prompt_parts)
|
零样本、少样本与思维链提示
零样本提示( Zero-shot
Prompting)
零样本提示是最简单的提示方式:直接给出任务描述,不提供任何示例。
1 2 3 4 5
| zero_shot_prompt = """ 请判断以下句子的情感倾向: 句子:这部电影的剧情非常精彩,演员表演也很出色。 情感: """
|
适用场景: - 模型对任务有较好的先验知识 -
任务相对简单直接 - 需要快速测试模型能力
局限性: - 对于复杂任务,模型可能理解偏差 -
输出格式可能不符合预期 - 难以处理需要多步推理的任务
少样本提示( Few-shot
Prompting)
少样本提示通过提供少量示例,让模型学习任务模式。这是 In-Context
Learning 的核心体现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| few_shot_prompt = """ 请判断以下句子的情感倾向(积极/消极/中性):
示例 1: 句子:今天天气真好,阳光明媚。 情感:积极
示例 2: 句子:这个产品质量很差,完全不值这个价格。 情感:消极
示例 3: 句子:明天会下雨。 情感:中性
现在请判断: 句子:这家餐厅的服务态度让人印象深刻。 情感: """
|
少样本提示的优势:
- 模式学习:模型通过示例学习任务模式
- 格式对齐:示例展示了期望的输出格式
- 任务适应:即使模型未专门训练,也能快速适应新任务
示例选择原则:
- 多样性:覆盖不同类型的输入
- 代表性:选择典型的、边界清晰的示例
- 相关性:示例应该与目标任务高度相关
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| def create_few_shot_prompt(task_description, examples, query): prompt = f"{task_description}\n\n" prompt += "示例:\n" for i, ex in enumerate(examples, 1): prompt += f"示例{i}:\n" prompt += f"输入:{ex['input']}\n" prompt += f"输出:{ex['output']}\n\n" prompt += f"现在请处理:\n 输入:{query}\n 输出:" return prompt
examples = [ {"input": "今天天气真好", "output": "积极"}, {"input": "这个产品质量很差", "output": "消极"}, {"input": "明天会下雨", "output": "中性"} ]
prompt = create_few_shot_prompt( "请判断句子的情感倾向", examples, "这家餐厅的服务态度让人印象深刻" )
|
思维链提示( Chain-of-Thought,
CoT)
思维链提示要求模型展示推理过程,逐步思考问题。这对于复杂推理任务特别有效。
标准 CoT 提示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| cot_prompt = """ 请解决以下数学问题,并展示你的推理过程:
问题:小明有 15 个苹果,他给了小红 3 个,又给了小华 5 个,最后自己吃了 2 个。请问小明还剩多少个苹果?
推理过程: 1. 小明最初有 15 个苹果 2. 给小红 3 个后,剩余: 15 - 3 = 12 个 3. 给小华 5 个后,剩余: 12 - 5 = 7 个 4. 自己吃了 2 个后,剩余: 7 - 2 = 5 个
答案: 5 个
现在请解决: 问题:一本书有 120 页,第一天读了 30 页,第二天读了第一天的 2 倍,第三天读了剩余页数的一半。请问第三天读了多少页? """
|
少样本 CoT:
1 2 3 4 5 6 7 8 9 10 11 12 13
| few_shot_cot = """ 请解决以下问题,展示推理步骤:
问题 1:一个篮子里有 8 个苹果,拿走了 3 个,又放回了 2 个。现在有多少个? 推理:最初 8 个,拿走 3 个后剩 5 个,放回 2 个后是 7 个。 答案: 7 个
问题 2:商店有 20 件商品,卖出了 12 件,又进货了 8 件。现在有多少件? 推理:最初 20 件,卖出 12 件后剩 8 件,进货 8 件后是 16 件。 答案: 16 件
问题 3:班级有 30 个学生,转走了 5 个,又转来了 7 个。现在有多少个学生? """
|
CoT 的数学表达:
对于问题 , CoT
提示引导模型生成推理步骤序列 ,最终得到答案 :
$$
P(A | Q) = {i=1}^{k+1} P(R_i | Q, R{<i}) $$
其中
是最终答案。
CoT 的优势:
- 提升准确性:展示推理过程有助于模型避免错误
- 可解释性:用户可以理解模型的思考过程
- 复杂推理:对于多步推理任务效果显著
角色设定与格式化技巧
角色设定( Role Assignment)
为模型设定明确的角色可以显著改变输出风格和质量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| role_prompts = { "expert": """ 你是一位拥有 20 年经验的 Python 高级工程师,擅长编写高效、可维护的代码。 请为以下需求编写代码: """, "teacher": """ 你是一位耐心的编程老师,擅长用简单易懂的方式解释复杂概念。 请解释以下概念: """, "analyst": """ 你是一位资深数据分析师,擅长从数据中发现洞察。 请分析以下数据: """, "creative": """ 你是一位富有创意的文案写手,擅长撰写吸引人的文案。 请为以下产品撰写文案: """ }
|
角色设定的效果:
- 专业性:专家角色产生更专业、技术性更强的输出
- 风格一致性:角色设定确保输出风格符合预期
- 领域适应:不同角色适应不同领域的任务
格式化技巧
1. 结构化输出
使用明确的格式标记,引导模型输出结构化内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| structured_prompt = """ 请分析以下文章,并按照以下格式输出:
## 文章摘要 [摘要内容]
## 关键观点 1. [观点 1] 2. [观点 2] 3. [观点 3]
## 情感分析 - 整体情感:[积极/消极/中性] - 情感强度:[1-10 分]
文章内容: [文章内容] """
|
2. JSON 格式输出
对于需要程序化处理的情况,要求 JSON 格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| json_prompt = """ 请分析以下文本,并以 JSON 格式输出结果:
要求: - 字段名: title, summary, keywords, sentiment - sentiment 的值: positive, negative, neutral
文本:[文本内容]
输出格式: { "title": "...", "summary": "...", "keywords": ["...", "..."], "sentiment": "..." } """
|
3. 分步骤输出
对于复杂任务,要求分步骤展示:
1 2 3 4 5 6 7 8 9 10 11
| step_by_step_prompt = """ 请解决以下问题,分步骤展示:
步骤 1:[第一步] 步骤 2:[第二步] 步骤 3:[第三步] ... 最终答案:[答案]
问题:[问题内容] """
|
4. 使用分隔符
使用清晰的分隔符区分不同部分:
1 2 3 4 5 6 7 8 9 10 11 12
| delimiter_prompt = """ === 任务说明 === [任务描述]
=== 输入数据 === [数据内容]
=== 输出要求 === [格式要求]
=== 开始处理 === """
|
提示模板设计
提示模板是可复用的提示框架,适用于特定类型的任务。
分类任务模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| classification_template = """ 你是一位专业的文本分类专家。
任务:将文本分类到以下类别之一:{categories}
分类规则: {rules}
示例: {examples}
待分类文本: {text}
请输出: 类别:[类别名称] 置信度:[0-1 之间的数值] 理由:[简要说明分类理由] """
|
生成任务模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| generation_template = """ 你是一位专业的{domain}内容创作者。
任务:{task_description}
要求: - 长度:{length}字左右 - 风格:{style} - 目标受众:{audience}
参考信息: {reference}
请生成内容: """
|
问答任务模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| qa_template = """ 基于以下文档回答问题。
文档: {document}
问题:{question}
要求: 1. 答案必须基于文档内容 2. 如果文档中没有相关信息,请回答"文档中未找到相关信息" 3. 引用文档中的具体内容支持你的答案
答案: """
|
代码生成模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| code_generation_template = """ 你是一位经验丰富的{language}程序员。
需求:{requirement}
技术要求: - 编程语言:{language} - 代码风格:{style} - 需要包含:{features}
示例输入/输出: {examples}
请编写代码: ```{language} [代码]
|
代码说明: [简要说明代码逻辑] """ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| ### 模板参数化实现
```python class PromptTemplate: def __init__(self, template: str): self.template = template def format(self, **kwargs) -> str: """格式化模板,填充参数""" return self.template.format(**kwargs) def format_safe(self, **kwargs) -> str: """安全格式化,处理缺失参数""" try: return self.template.format(**kwargs) except KeyError as e: raise ValueError(f"缺少必需的模板参数: {e}")
# 使用示例 template = PromptTemplate(classification_template) prompt = template.format( categories="积极, 消极, 中性", rules="根据文本的情感倾向进行分类", examples="示例 1:今天天气真好 → 积极", text="这部电影真的很棒" )
|
Self-Consistency:一致性采样
Self-Consistency 是一种提升 CoT
推理准确性的技术。基本思路:对同一个问题生成多个推理路径,然后选择最一致的答案。
Self-Consistency 原理
传统 CoT 只生成一条推理路径, Self-Consistency 生成
条路径,然后通过投票选择最终答案。
算法流程:
- 使用 CoT 提示生成 个不同的推理路径
- 从每条路径中提取答案
- 选择出现频率最高的答案(多数投票)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import random from collections import Counter
def self_consistency_sample(model, prompt, k=5, temperature=0.7): """ 使用 Self-Consistency 采样多个推理路径 Args: model: 语言模型 prompt: CoT 提示 k: 采样数量 temperature: 采样温度(较高温度增加多样性) Returns: 最终答案 """ answers = [] for _ in range(k): response = model.generate( prompt, temperature=temperature, max_tokens=500 ) answer = extract_answer(response) answers.append(answer) answer_counts = Counter(answers) final_answer = answer_counts.most_common(1)[0][0] return final_answer, answer_counts
def extract_answer(response): """从响应中提取答案""" if "答案:" in response: return response.split("答案:")[-1].strip() import re numbers = re.findall(r'\d+', response) return numbers[-1] if numbers else response
|
Self-Consistency 的数学表达
对于问题 ,生成 条推理路径
,每条路径对应答案 。
最终答案通过多数投票选择:
$$
A^{*} = {a} {i=1}^{k} [A_i = a] $$
其中
是指示函数。
实现示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| class SelfConsistency: def __init__(self, model, k=5, temperature=0.7): self.model = model self.k = k self.temperature = temperature def solve(self, question, cot_prompt_template): """使用 Self-Consistency 解决问题""" prompt = cot_prompt_template.format(question=question) answers = [] reasoning_paths = [] for i in range(self.k): response = self.model.generate( prompt, temperature=self.temperature, max_tokens=500 ) answer = self._extract_answer(response) answers.append(answer) reasoning_paths.append(response) answer_counts = Counter(answers) final_answer = answer_counts.most_common(1)[0][0] confidence = answer_counts[final_answer] / self.k return { "answer": final_answer, "confidence": confidence, "answer_distribution": dict(answer_counts), "reasoning_paths": reasoning_paths } def _extract_answer(self, response): """提取答案(需要根据具体任务定制)""" import re numbers = re.findall(r'\d+', response) return numbers[-1] if numbers else response.split()[-1]
sc = SelfConsistency(model, k=5) result = sc.solve( "小明有 15 个苹果,给了小红 3 个,又给了小华 5 个,还剩多少个?", cot_prompt_template ) print(f"答案:{result['answer']}") print(f"置信度:{result['confidence']:.2%}")
|
Self-Consistency 的优势
- 提升准确性:通过多数投票减少错误
- 鲁棒性:对单次采样错误不敏感
- 置信度估计:答案分布提供置信度信息
ReAct:推理与行动的结合
ReAct( Reasoning +
Acting)是一种将推理和行动结合的方法,特别适用于需要工具使用的任务。
ReAct 框架
ReAct
的基本思路:模型在推理过程中可以调用外部工具,通过观察工具结果来指导下一步推理。
基本循环:
- 思考( Thought):分析当前情况,决定下一步行动
- 行动( Action):调用工具或执行操作
- 观察( Observation):获取行动结果
- 重复直到得到最终答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| react_prompt = """ 可以使用以下工具: - search(query): 搜索信息 - calculator(expression): 计算数学表达式 - get_weather(city): 获取天气信息
请按照以下格式回答:
思考:[你的思考过程] 行动:[工具名称(参数)] 观察:[工具返回的结果] ...(重复思考-行动-观察循环) 思考:[最终思考] 答案:[最终答案]
问题:{question} """
|
ReAct 实现示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| class ReActAgent: def __init__(self, model, tools): self.model = model self.tools = tools def solve(self, question): """使用 ReAct 方法解决问题""" prompt = self._build_initial_prompt(question) max_iterations = 10 for i in range(max_iterations): response = self.model.generate(prompt, max_tokens=200) thought, action = self._parse_response(response) if action is None: answer = self._extract_answer(response) return answer observation = self._execute_action(action) prompt += f"\n 思考:{thought}\n 行动:{action}\n 观察:{observation}\n" return "达到最大迭代次数" def _build_initial_prompt(self, question): """构建初始提示""" tool_descriptions = "\n".join([ f"- {name}: {desc}" for name, desc in self.tools.items() ]) return f""" 可以使用以下工具: {tool_descriptions}
请按照以下格式回答: 思考:[你的思考过程] 行动:[工具名称(参数)] 观察:[工具返回的结果] ...(重复思考-行动-观察循环) 思考:[最终思考] 答案:[最终答案]
问题:{question} """ def _parse_response(self, response): """解析响应,提取思考和行动""" import re thought_match = re.search(r'思考:(.*?)(?=行动:|答案:|$)', response, re.DOTALL) action_match = re.search(r'行动:(\w+)\((.*?)\)', response) thought = thought_match.group(1).strip() if thought_match else "" action = None if action_match: tool_name = action_match.group(1) tool_args = action_match.group(2).strip() action = (tool_name, tool_args) return thought, action def _execute_action(self, action): """执行行动""" tool_name, tool_args = action if tool_name not in self.tools: return f"错误:工具 {tool_name} 不存在" tool_func = self.tools[tool_name] try: result = tool_func(tool_args) return str(result) except Exception as e: return f"错误:{str(e)}" def _extract_answer(self, response): """提取最终答案""" import re answer_match = re.search(r'答案:(.*?)$', response, re.DOTALL) return answer_match.group(1).strip() if answer_match else response
def search_tool(query): """模拟搜索工具""" return f"搜索结果:关于'{query}'的信息..."
def calculator_tool(expression): """计算器工具""" try: result = eval(expression) return result except: return "计算错误"
tools = { "search": search_tool, "calculator": calculator_tool }
agent = ReActAgent(model, tools) answer = agent.solve("北京今天的天气如何?如果温度高于 20 度,计算 15 * 3 的结果")
|
ReAct 的优势
- 工具集成:可以调用外部工具扩展能力
- 动态适应:根据观察结果调整策略
- 可解释性:思考过程清晰可见
- 复杂任务:适合需要多步推理和工具使用的任务
构建高效的提示系统
提示系统架构
一个完整的提示系统应该包含以下组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class PromptSystem: def __init__(self): self.templates = {} self.examples = {} self.metrics = {} def register_template(self, name, template): """注册提示模板""" self.templates[name] = template def build_prompt(self, template_name, **kwargs): """构建提示""" if template_name not in self.templates: raise ValueError(f"模板 {template_name} 不存在") template = self.templates[template_name] return template.format(**kwargs) def evaluate(self, prompt, test_cases): """评估提示效果""" results = [] for case in test_cases: full_prompt = prompt + "\n\n" + case['input'] output = self.model.generate(full_prompt) results.append({ 'input': case['input'], 'expected': case['expected'], 'actual': output, 'match': output.strip() == case['expected'].strip() }) accuracy = sum(r['match'] for r in results) / len(results) return { 'accuracy': accuracy, 'results': results }
|
提示优化策略
1. A/B 测试
对比不同提示版本的效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| def ab_test_prompts(prompt_a, prompt_b, test_cases, model): """A/B 测试两个提示""" results_a = evaluate_prompt(prompt_a, test_cases, model) results_b = evaluate_prompt(prompt_b, test_cases, model) return { 'prompt_a': { 'accuracy': results_a['accuracy'], 'avg_length': np.mean([len(r['actual']) for r in results_a['results']]) }, 'prompt_b': { 'accuracy': results_b['accuracy'], 'avg_length': np.mean([len(r['actual']) for r in results_b['results']]) } }
|
2. 迭代优化
基于反馈不断改进提示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| def iterative_optimization(initial_prompt, test_cases, model, max_iterations=5): """迭代优化提示""" current_prompt = initial_prompt best_accuracy = 0 best_prompt = initial_prompt for iteration in range(max_iterations): results = evaluate_prompt(current_prompt, test_cases, model) accuracy = results['accuracy'] if accuracy > best_accuracy: best_accuracy = accuracy best_prompt = current_prompt errors = [r for r in results['results'] if not r['match']] if not errors: break current_prompt = refine_prompt(current_prompt, errors) return best_prompt, best_accuracy
|
3. 提示组合
组合多个提示技术:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| def build_advanced_prompt(question, examples, use_cot=True, use_role=True): """构建高级提示,组合多种技术""" prompt_parts = [] if use_role: prompt_parts.append("你是一位专业的问题解决专家。") prompt_parts.append("请解决以下问题:") if examples: prompt_parts.append("示例:") for ex in examples: prompt_parts.append(f"问题:{ex['question']}") if use_cot: prompt_parts.append(f"推理:{ex['reasoning']}") prompt_parts.append(f"答案:{ex['answer']}") if use_cot: prompt_parts.append("\n 请展示你的推理过程,然后给出答案。") prompt_parts.append(f"\n 问题:{question}") return "\n".join(prompt_parts)
|
实战案例
案例 1:情感分析系统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| class SentimentAnalyzer: def __init__(self, model): self.model = model self.prompt_template = """ 你是一位专业的情感分析专家。
任务:分析文本的情感倾向
分类标准: - 积极:表达正面情感、满意、赞扬等 - 消极:表达负面情感、不满、批评等 - 中性:无明显情感倾向
示例: 文本 1:这部电影真的很棒,演员表演出色,剧情紧凑。 情感:积极 理由:使用了"很棒"、"出色"等正面词汇
文本 2:产品质量太差了,完全不值这个价格。 情感:消极 理由:使用了"太差"、"不值"等负面词汇
文本 3:明天会下雨。 情感:中性 理由:只是陈述事实,无情感色彩
请分析以下文本: 文本:{text}
输出格式: 情感:[积极/消极/中性] 置信度:[0-1 之间的数值] 理由:[简要说明] """ def analyze(self, text): """分析文本情感""" prompt = self.prompt_template.format(text=text) response = self.model.generate(prompt) return self._parse_response(response) def _parse_response(self, response): """解析响应""" import re sentiment_match = re.search(r'情感:(\w+)', response) confidence_match = re.search(r'置信度:([\d.]+)', response) reason_match = re.search(r'理由:(.*?)(?=\n|$)', response, re.DOTALL) return { 'sentiment': sentiment_match.group(1) if sentiment_match else None, 'confidence': float(confidence_match.group(1)) if confidence_match else None, 'reason': reason_match.group(1).strip() if reason_match else None }
|
案例 2:代码生成助手
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class CodeGenerator: def __init__(self, model): self.model = model self.prompt_template = """ 你是一位经验丰富的 Python 程序员,擅长编写清晰、高效、可维护的代码。
任务:根据需求生成 Python 代码
要求: 1. 代码必须可以直接运行 2. 包含必要的注释 3. 遵循 PEP 8 代码规范 4. 处理边界情况
示例: 需求:实现一个函数,计算列表中所有偶数的和 代码: ```python def sum_even_numbers(numbers): \"\"\" 计算列表中所有偶数的和 Args: numbers: 数字列表 Returns: 偶数的和 \"\"\" return sum(num for num in numbers if num % 2 == 0)
|
请为以下需求生成代码: 需求:{requirement}
代码: """
def generate(self, requirement):
"""生成代码"""
prompt = self.prompt_template.format(requirement=requirement)
response = self.model.generate(prompt)
return self._extract_code(response)
def _extract_code(self, response):
"""提取代码块"""
import re
code_match = re.search(r'```python\n(.*?)```', response, re.DOTALL)
if code_match:
return code_match.group(1).strip()
return response
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| ### 案例 3:智能问答系统
```python class QASystem: def __init__(self, model): self.model = model self.knowledge_base = {} # 知识库 def add_knowledge(self, doc_id, content): """添加知识""" self.knowledge_base[doc_id] = content def answer(self, question, doc_ids=None): """回答问题""" if doc_ids is None: doc_ids = list(self.knowledge_base.keys()) # 检索相关文档 relevant_docs = self._retrieve_docs(question, doc_ids) # 构建提示 prompt = self._build_qa_prompt(question, relevant_docs) # 生成答案 response = self.model.generate(prompt) return self._extract_answer(response) def _retrieve_docs(self, question, doc_ids, top_k=3): """检索相关文档(简化实现)""" # 实际实现中可以使用向量检索 return [self.knowledge_base[did] for did in doc_ids[:top_k]] def _build_qa_prompt(self, question, docs): """构建 QA 提示""" doc_text = "\n\n".join([ f"文档{i+1}:{doc}" for i, doc in enumerate(docs) ]) return f""" 基于以下文档回答问题。
文档: {doc_text}
问题:{question}
要求: 1. 答案必须基于文档内容 2. 如果文档中没有相关信息,请回答"文档中未找到相关信息" 3. 引用文档中的具体内容支持你的答案 4. 如果文档间有冲突,请说明
答案: """ def _extract_answer(self, response): """提取答案""" if "答案:" in response: return response.split("答案:")[-1].strip() return response.strip()
|
❓ Q&A: 提示工程常见问题
Q1: 提示越长越好吗?
不一定。提示应该包含完成任务所需的所有信息,但过长可能: -
增加计算成本 - 分散模型注意力 - 超出上下文窗口限制
最佳实践是:先写简洁版本,如果效果不佳再逐步添加细节。
Q2: 少样本提示需要多少个示例?
通常 2-5 个示例效果较好。太少可能无法学习模式,太多可能: - 浪费
token - 增加混淆 - 降低效率
建议:从 2-3 个示例开始,根据效果调整。
Q3: CoT 对所有任务都有效吗?
不是。 CoT 主要适用于: - 需要多步推理的任务(数学问题、逻辑推理) -
复杂决策任务
对于简单分类、直接问答等任务, CoT 可能反而增加噪声。
Q4: 如何选择合适的温度参数?
- 低温度(
0.1-0.3):确定性输出,适合需要准确性的任务
- 中等温度( 0.5-0.7):平衡创造性和准确性
- 高温度( 0.8-1.0):创造性输出,适合生成任务
对于 Self-Consistency,通常使用较高温度( 0.7-0.9)增加多样性。
Q5: 提示工程可以替代微调吗?
在某些场景下可以,但各有优势:
- 提示工程:快速、灵活、无需训练数据
- 微调:更专业、更稳定、适合特定领域
最佳实践:先用提示工程快速验证,需要更高性能时再考虑微调。
Q6: 如何处理模型的幻觉( Hallucination)问题?
- 要求模型引用来源
- 使用少样本示例展示期望行为
- 要求模型标注不确定的部分
- 结合外部知识库验证
Q7: 提示中的示例顺序重要吗?
是的。模型可能对: - 第一个示例给予更多权重 - 最近的示例记忆更深
建议:将最典型、最清晰的示例放在前面。
Q8: 如何评估提示效果?
- 准确性:在测试集上评估正确率
- 一致性:多次运行结果的一致性
- 相关性:输出与任务的匹配度
- 效率: token 使用量和响应时间
Q9: 可以组合多种提示技术吗?
可以。常见组合: - 角色设定 + 少样本 + CoT - Few-shot +
Self-Consistency - ReAct + 工具调用
注意:组合可能增加复杂度,需要权衡效果和成本。
Q10: 提示工程有哪些局限性?
- 依赖模型能力:基础模型能力有限
- 上下文窗口限制:无法处理过长输入
- 不稳定:相同提示可能产生不同结果
- 需要人工调试:优化过程耗时
未来方向:自动化提示优化、更好的评估指标、与微调结合。