AI/LLM应用开发实战(二):Prompt Engineering 核心技巧与实战
AI/LLM应用开发实战(二):Prompt Engineering 核心技巧与实战
📚 本文是《AI/LLM 应用开发实战》系列第 2 篇。上一篇我们完成了第一个 LLM 对话应用,本篇将深入 Prompt Engineering 的核心技巧。
前言
很多开发者在接入 LLM API 后发现:**同样的模型,提示词写得好不好,输出质量天差地别**。
Prompt Engineering(提示词工程)不是玄学,而是一套有章可循的工程方法。本篇将介绍 5 个最实用的技巧,每个都配有可运行的 Python 代码,让你立刻上手。
一、System Prompt:给模型一个"人设"
System Prompt 是最基础也最重要的提示词技巧。它定义了模型的角色、行为边界和输出风格。
1.1 设计原则
一个好的 System Prompt 应该包含:
- **角色定义**:你是谁,擅长什么
- **行为约束**:什么该做,什么不该做
- **输出格式**:期望的回答风格和结构
-
1.2 实战代码
import os from openai import OpenAI from dotenv import load_dotenv load_dotenv() client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) def ask_with_system_prompt(system_prompt: str, user_query: str) -> str: response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_query} ], temperature=0.7 ) return response.choices[0].message.content # 对比:没有 System Prompt vs 精心设计的 System Prompt query = "解释一下什么是 Docker?" # 普通回答 print("【普通模式】") print(ask_with_system_prompt("你是一个AI助手。", query)) print() # 精心设计的 System Prompt expert_prompt = """你是一位资深 DevOps 工程师,拥有 10 年容器化技术经验。 回答要求: 1. 先用一句话给出核心定义 2. 用生活中的比喻帮助理解 3. 列出 3 个最常见的使用场景 4. 回答控制在 200 字以内 语气:专业但通俗易懂,像在和同事聊天。""" print("【专家模式】") print(ask_with_system_prompt(expert_prompt, query))专家模式的输出会更加结构化、专业且易懂,这就是 System Prompt 的威力。
二、Few-shot Learning:用示例教会模型
Few-shot(少样本学习)是指在提示词中提供几个输入-输出示例,让模型"学会"你期望的模式。
2.1 适用场景
- 特定格式的文本转换
- 分类任务
- 风格统一的内容生成
-
2.2 实战:智能命名转换器
def few_shot_naming_converter(variable_name: str) -> str: """利用 Few-shot 让模型学会变量命名风格转换""" response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": "你是一个编程命名风格转换工具。将输入的变量名转换为所有常见风格。"}, # Few-shot 示例 1 {"role": "user", "content": "user_login_count"}, {"role": "assistant", "content": """camelCase: userLoginCount PascalCase: UserLoginCount kebab-case: user-login-count UPPER_SNAKE: USER_LOGIN_COUNT"""}, # Few-shot 示例 2 {"role": "user", "content": "get_all_items"}, {"role": "assistant", "content": """camelCase: getAllItems PascalCase: GetAllItems kebab-case: get-all-items UPPER_SNAKE: GET_ALL_ITEMS"""}, # 实际输入 {"role": "user", "content": variable_name} ], temperature=0 ) return response.choices[0].message.content # 测试 print(few_shot_naming_converter("create_new_project")) print() print(few_shot_naming_converter("send_email_notification"))通过 2 个示例,模型就能精确地按照我们期望的格式输出,无需复杂的规则描述。
三、Chain-of-Thought(CoT):让模型"思考"
CoT(思维链)是提升模型推理能力的关键技巧。核心思想:**要求模型展示推理过程,而不是直接给答案**。
3.1 三种 CoT 方式
| 方式 | 做法 | 适用场景 |
|------|------|---------|
| Zero-shot CoT | 加一句"请一步步思考" | 简单推理 |
| Few-shot CoT | 提供带推理过程的示例 | 复杂推理 |
| 自动 CoT | 让模型自己生成推理链 | 批量任务 |
3.2 实战:代码 Bug 分析器
def analyze_bug_with_cot(code_snippet: str) -> str: """使用 CoT 技巧分析代码中的 Bug""" system_prompt = """你是一位资深代码审查专家。分析用户提供的代码时,请严格按以下步骤思考: 第一步:逐行阅读代码,理解意图 第二步:检查常见错误类型(边界条件、类型错误、逻辑错误、资源泄漏) 第三步:定位具体的 Bug 位置和原因 第四步:给出修复方案和修复后的代码 请展示完整的思考过程。""" response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": f"请分析以下代码的 Bug:\n\n```python\n{code_snippet}\n```"} ], temperature=0.3 ) return response.choices[0].message.content # 测试:一段有 Bug 的代码 buggy_code = """ def calculate_average(numbers): total = 0 for num in numbers: total += num return total / len(numbers) result = calculate_average([]) print(f"平均值: {result}") """ print(analyze_bug_with_cot(buggy_code))模型会按步骤分析出空列表导致的 `ZeroDivisionError`,并给出防御性编程的修复方案。
四、结构化输出:让 LLM 返回可解析的数据
在实际应用中,我们通常需要 LLM 返回 JSON 等结构化数据,而不是自由文本。
4.1 实战:智能简历解析器
import json def parse_resume(resume_text: str) -> dict: """将非结构化的简历文本解析为结构化 JSON""" system_prompt = """你是一个简历解析引擎。将用户提供的简历文本解析为 JSON 格式。 严格按以下 JSON Schema 输出,不要输出任何其他内容: { "name": "姓名", "email": "邮箱", "phone": "电话", "education": [{"school": "学校", "degree": "学历", "major": "专业", "year": "毕业年份"}], "skills": ["技能1", "技能2"], "experience_years": 数字 } 如果某个字段信息缺失,填 null。只输出 JSON,不要加 markdown 标记。""" response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": resume_text} ], temperature=0, response_format={"type": "json_object"} ) return json.loads(response.choices[0].message.content) # 测试 sample_resume = """ 张三,男,5年Python开发经验 邮箱:[email] 电话:[phone_number] 2018年毕业于北京大学计算机科学与技术专业,硕士学位 熟练掌握 Python、Go、Docker、Kubernetes、MySQL、Redis 曾在字节跳动担任高级后端工程师 """ result = parse_resume(sample_resume) print(json.dumps(result, ensure_ascii=False, indent=2))输出示例:
{ "name": "张三", "email": "[email]", "phone": "[phone_number]", "education": [ { "school": "北京大学", "degree": "硕士", "major": "计算机科学与技术", "year": "2018" } ], "skills": ["Python", "Go", "Docker", "Kubernetes", "MySQL", "Redis"], "experience_years": 5 }💡 **关键技巧**:使用 `response_format={"type": "json_object"}` 可以强制 GPT 输出合法 JSON,大幅降低解析失败率。
五、组合技巧:构建实用的 Prompt 模板引擎
实际项目中,我们需要把上述技巧组合起来,构建可复用的 Prompt 模板。
from dataclasses import dataclass from typing import Optional @dataclass class PromptTemplate: """可复用的 Prompt 模板""" role: str task: str constraints: list[str] output_format: str examples: Optional[list[dict]] = None def build_system_prompt(self) -> str: prompt = f"# 角色\n{self.role}\n\n# 任务\n{self.task}\n" if self.constraints: prompt += "\n# 约束条件\n" for i, c in enumerate(self.constraints, 1): prompt += f"{i}. {c}\n" prompt += f"\n# 输出格式\n{self.output_format}\n" return prompt def build_messages(self, user_input: str) -> list[dict]: messages = [{"role": "system", "content": self.build_system_prompt()}] if self.examples: for ex in self.examples: messages.append({"role": "user", "content": ex["input"]}) messages.append({"role": "assistant", "content": ex["output"]}) messages.append({"role": "user", "content": user_input}) return messages # 使用示例:创建一个 SQL 生成器模板 sql_generator = PromptTemplate( role="你是一位精通 SQL 的数据库专家", task="根据用户的自然语言描述生成对应的 SQL 查询语句", constraints=[ "只生成 SELECT 查询,不生成修改数据的语句", "使用标准 SQL 语法,兼容 MySQL 和 PostgreSQL", "对复杂查询添加注释说明" ], output_format="直接输出 SQL 代码,用 ```sql 包裹", examples=[ { "input": "查询所有年龄大于18岁的用户", "output": "```sql\nSELECT * FROM users WHERE age > 18;\n```" } ] ) messages = sql_generator.build_messages("查询每个部门的平均工资,只显示平均工资超过1万的部门") response = client.chat.completions.create(model="gpt-4o", messages=messages, temperature=0) print(response.choices[0].message.content)总结:Prompt Engineering 核心原则
经过本篇的学习,总结 5 条核心原则:
1. **明确角色**:用 System Prompt 定义清晰的角色和边界
2. **提供示例**:Few-shot 比长篇描述更高效
3. **引导思考**:CoT 让模型的推理更可靠
4. **约束输出**:结构化输出让结果可编程处理
5. **模板复用**:将技巧封装为可复用的模板,提升开发效率
---
📖 **下一篇预告**:《AI/LLM应用开发实战(三):Function Calling 与工具调用——让 LLM 连接真实世界》—— 我们将学习如何让 LLM 调用外部函数和 API,实现查天气、查数据库、执行代码等真实场景的能力扩展!
---
🔔 如果觉得有帮助,欢迎点赞、收藏、关注,后续更新不迷路!
更多推荐


所有评论(0)