文章目录
- 概要&序論
- 一、提示词编写的世界观
- 二、结构化框架:CO-STAR 方法论
- 2.1 CO-STAR 六大核心模块
- 2.2 实战案例:健康咨询 Prompt 优化
- 2.2.1优化前(模糊、低效):
- 2.2.2优化后(清晰、高效):
- 三、少样本提示 / 多示例提示(Few-Shot Prompting)
- 3.1 基础数值运算与符号隐喻示例
- 3.1.1优化前(零样本提示 / Zero-Shot):
- 3.1.2优化后(少样本提示 / Few-Shot):
- 3.2 结构化数据提取与文本分析示例
- 3.2.1优化前(零样本提示 / Zero-Shot):
- 3.2.2优化后(少样本提示 / Few-Shot):
- 四、思维链提示(Chain-of-Thought, CoT)
- 4.1 传统 Zero-Shot 推理的局限与陷阱
- 4.2 少样本思维链(Few-shot-CoT)
- 4.2.1 Few-shot-CoT 实战演练
- 4.2.2 少样本思维链的本质解析
- 4.3零样本思维链(Zero-Shot-CoT)
- 4.3.1 Zero-Shot-CoT实战案例
- 4.3.2 零样本思维链的本质解析
- 五、自我批判与迭代
- 5.1什么是自我批判迭代
- 5.2 编写代码后进行检查
- 5.2.1优化前
- 5.2.2优化后
- 六、綜合運用以上的提示詞技巧
- 6.1 IDE 中的实战应用:以 AI IDE Rules 为例
概要&序論
Hello大家好,我是此方。从本文开始我将正式开始连载LangChain/LangGraph系列文章,本文介绍大模型的提示词编写技巧。关于“大模型的概念,主流大模型,大模型的能力,大模型的训练方法概念等等一大堆的这个概念的内容”相对不是那么的重要。我会把他们单独放在日后的专栏【主题曲:大模型应用开发】大模型全景概念中。
一、提示词编写的世界观
编写优质提示词(Prompt)的核心宗旨在于:将你的问题限定范围,让 AI 明确知道你要的答案具体要包含什么,提示词效果就会大幅提升。
其核心心态在于换位思考:想象 AI 对你提供的背景信息一无所知的状态下,你需要清晰、具体、无歧义地告诉它你要什么、在什么背景下、以什么方式呈现。善用示例、角色扮演、具体约束和迭代优化,才能最大化激发大模型潜能。
二、结构化框架:CO-STAR 方法论
在目标设定和问题解决的场景下,清晰性和结构性是至关重要的。在众多的 Prompt 编写框架中,由新加坡政府技术局(GovTech)的数据科学与 AI 团队开发的CO-STAR 框架表现尤为出色。
CO-STAR 框架重点在于确保提供给 LLM 的提示词是全面且结构良好的,从而生成更相关和准确的回答。
2.1 CO-STAR 六大核心模块
CO-STAR 框架可以拆解为六个维度:
| 模块 | 说明 | 示例 |
|---|---|---|
| Context | 任务背景与上下文 | “你是电商客服,需解答用户关于 iPhone 17 的咨询,知识库包含最新价格和库存” |
| Objective | 核心目标 | “准确回答价格、发货时间,推荐适配配件” |
| Steps | 执行步骤 | “1. 识别用户问题类型;2. 检索知识库;3. 用亲切语气整理回复” |
| Tone | 语言风格 | “口语化,避免专业术语,使用‘亲~’‘呢’等语气词” |
| Audience | 目标用户 | “20-35岁年轻消费者,对价格敏感,关注性价比” |
| Response | 输出格式 | “价格: XXX元\n库存: XXX件\n推荐配件: XXX (链接)” |
2.2 实战案例:健康咨询 Prompt 优化
假设我们需要进行健康咨询并希望获得针对性的营养建议,下面对比传统提问与运用 CO-STAR 框架优化后的差异:
2.2.1优化前(模糊、低效):
我该怎么吃才能更健康?
2.2.2优化后(清晰、高效):
角色:你是一个基于科学证据的 AI 营养顾问。重要约束:你提供的所有建议都仅为通用信息,不能替代专业医疗诊断。在给出任何具体建议前,必须首先声明此免责条款。 任务:基于以下用户信息,提供一份个性化的每日饮食原则性建议。 用户信息: • 年龄:30岁 • 性别:男性 • 目标:减脂增肌 • 日常活动水平:办公室久坐,每周进行3次力量训练 回答要求: 1. 首先,输出免责声明:“请注意:以下建议为通用健康信息...” 2. 核心原则应围绕“控制总热量摄入,确保充足蛋白质”。 3. 分别对早餐、午餐、晚餐和训练加餐提出各1条核心建议(例如:早餐应包含优质蛋白和复合碳水)。 4. 推荐2种适合该用户的具体健康零食。 5. 避免推荐任何具体的保健品或药物。 输出格式: 【免责声明】 巴拉巴拉。。。 【核心原则】 巴拉巴拉。。。 【分餐建议】 • 早餐:巴拉巴拉。。。 • 午餐:巴拉巴拉。。。 【健康零食推荐】 巴拉巴拉。。。 巴拉巴拉。。。几乎没有人会在写代码时死记硬背 CO-STAR!全靠模板化
# Role & Context {{ context }} # Objective {{ objective }} # Constraints & Tone {{ constraints }} # Response Format {{ output_format }}三、少样本提示 / 多示例提示(Few-Shot Prompting)
少样本提示(Few-Shot Prompting)是通过给 AI 提供一两个“输入-输出”的示例,让它“照葫芦画瓢”。
- 核心思想:你不是单纯在给它下指令,而是在**“教”**它你想要的格式、风格和逻辑。
- 适用场景:格式固定、风格独特、逻辑复杂的任务,如风格仿写、数据提取、复杂格式生成等。
3.1 基础数值运算与符号隐喻示例
3.1.1优化前(零样本提示 / Zero-Shot):
2 # 9等于多少?
3.1.2优化后(少样本提示 / Few-Shot):
根据以下示例,处理问题。
示例1:2 # 3 = 5
示例2:4 # 7 = 11
现在请分析这个:2 # 9等于多少?
3.2 结构化数据提取与文本分析示例
3.2.1优化前(零样本提示 / Zero-Shot):
请分析以下客户反馈,提取产品名称、情感倾向和具体问题。
反馈:“我刚买的耳机,才用了一周左边就没声音了,太让人失望了。”
3.2.2优化后(少样本提示 / Few-Shot):
请根据以下示例,分析后续的客户反馈,并提取产品名称、情感倾向和具体问题。 示例1: • 反馈:“笔记本的电池续航太差了,完全达不到宣传的10小时,最多就4小时。” • 分析: • 产品名称:笔记本电池 • 情感倾向:负面 • 具体问题:续航远低于宣传 示例2: • 反馈:“客服响应很快,非常专业地帮我解决了软件激活问题,点赞!” • 分析: • 产品名称:客服服务 • 情感倾向:正面 • 具体问题:无 现在请分析这个: • 反馈:“我刚买的耳机,才用了一周左边就没声音了,太让人失望了。”通过示例,AI 清晰地学会了“产品名称”如何概括,“情感倾向”的标签是什么,“具体问题”如何简洁描述。这比单纯用文字描述规则要有效得多。
四、思维链提示(Chain-of-Thought, CoT)
提示词工程的关键目标是让 AI 更好地理解复杂语义。这种能力的高低,可以直接通过模型处理复杂逻辑推理题的表现来检验。
当好的提示词能帮助模型解决原本解决不了的难题时,就说明它确实提升了模型的推理水平。并且,提示词设计得越出色,这种提升效果就越显著。通过设置不同难度的推理测试,可以很清晰地验证这一点。
4.1 传统 Zero-Shot 推理的局限与陷阱
在论文Large Language Models are Zero-Shot Reasoners中提出了一个经典的测试例子:
Q: A juggler can juggle 16 balls. Half of the balls are golf balls, and half of the golf balls are blue. How many blue golf balls are there? A: The answer (arabic numerals) is 8. (Output: X)翻译一下问题:
杂耍者可以杂耍16个球。其中一半的球是高尔夫球,其中一半的高尔夫球是蓝色的。请问总共有多少个蓝色高尔夫球?
模型直出结果:
8个蓝色高尔夫球
可以看到,直接让模型输出最终答案会导致计算错误。该逻辑题的数学计算过程并不复杂,但却设计了一个语言陷阱,即“一半的一半”是多少。
为了解决类似的逻辑问题,可以使用思维链提示(Chain-of-Thought, CoT)。思维链提示最常用的两种方式为:
- Few-shot-CoT(少样本思维链)
- Zero-shot-CoT(零样本思维链)
4.2 少样本思维链(Few-shot-CoT)
相比于普通的少样本提示(Few-shot),少样本思维链(Few-shot-CoT)的不同之处在于需要在提示样本中不仅给出问题的答案,还同时需要给出问题推导的过程(即思维链),从而让模型学会思维链的推导过程,并将其应用到新的问题中。此技巧主要用于解决复杂推理问题,如数学、逻辑或多步骤规划。
- 核心思想:要求 AI“展示其工作过程”,而不是直接给出最终答案。这模仿了人类解决问题时的思考方式。
- 适用场景:数学题、逻辑推理、复杂决策、需要解释过程的任务。
4.2.1 Few-shot-CoT 实战演练
我们可以手动编写一个包含思考过程的思维链作为少样本提示的示例:
示例1: Q: “罗杰有五个网球,他又买了两盒网球,每盒有3个网球,请问他现在总共有多少个网球?” A: “罗杰起初有五个网球,又买了两盒网球,每盒3个,所以,他总共买了 2×3=6 个网球,将起始的数量和购买的数量相加,可以得到他现在总共的网球数量:5+6=11,所以罗杰现在总共有11个网球” 问: “食堂总共有23个苹果,如果他们用掉20个苹果,然后又买来了6个苹果,请问现在食堂总共有多少个苹果?”模型推理输出:
食堂起初有23个苹果,用掉20个苹果后,剩余苹果数量为 23-20=3 个。然后又买来了6个苹果,将剩余数量和新买的数量相加,可以得到现在总共的苹果数量:3+6=9个。所以食堂现在总共有9个苹果。4.2.2 少样本思维链的本质解析
通过这个例子可以观察到,这就像是“把答案告诉了 AI”。从某种意义上说,你告诉它的是“回答这个问题正确的方式和步骤”,而不仅仅是最终的答案,AI 会模仿你提供的范本结构和逻辑,来解决新问题。
实际上,Few-shot-CoT 的方式虽然有效,但并不一定是稳定且准确的。如果想要得到稳定的正确答案,需要更高阶的提示方法。你给的例子越详细,它模仿得就越像,这更像是一种“教学”或“格式化”。
当你有一个非常复杂的逻辑流程,或者你希望 AI 严格按照某种格式(比如先分析 A,再对比 B,最后总结 C)来输出时,就可以直接提供一个完美的“思考过程”作为范例。
4.3零样本思维链(Zero-Shot-CoT)
零样本思维链(Zero-shot-CoT)是少样本思维链(Few-shot-CoT)的简化版。只需在提示词末尾加上一句短语,即可激发 AI 的推理能力。
- 核心思想:通过指令“请一步步进行推理并得出结论”,强制 AI 在给出答案前先进行内部推理。
- 适用场景:任何需要一点逻辑思考的问题,即使你不太清楚具体步骤。
4.3.1 Zero-Shot-CoT实战案例
提示词(Prompt):
罗杰有五个网球,他又买了两盒网球,每盒有3个网球,请问他现在总共有多少个网球?请一步步进行推理并得出结论。
AI 的输出可能会变成:
罗杰最初有5个网球。
他买了两盒网球,每盒有3个网球,所以买来的网球数量是:2 × 3 = 6个网球。
因此,他现在总共有网球:5 + 6 = 11个。
答案:11个网球。
4.3.2 零样本思维链的本质解析
“一步步进行推理”这个指令,相当于在引导模型的“注意力机制”。它告诉模型:“在生成最终答案之前,请先在你的‘脑海’里(即生成的文本序列中)模拟出一个缓慢、有序的推理上下文。”
当模型开始输出“第一步…第二步…”时,它实际上是在为自己创造一个更丰富、更逻辑化的上下文。它在这个自己创造的优质上下文中进行推理,最终得出的结论自然比在贫瘠的上下文中(只有原始问题)更准确。
根据《Large Language Models are Zero-Shot Reasoners》论文中的结论,从海量数据的测试结果来看,Few-shot-CoT 比 Zero-shot-CoT 准确率更高。
五、自我批判与迭代
5.1什么是自我批判迭代
要求 AI 在生成答案后,从特定角度对自己的答案进行审查和优化。
- 核心思想:将“生成”和“评审”两个步骤分离,利用 AI 的批判性思维来提升内容质量。
- 适用场景:代码审查、文案优化、论证强化、安全检查。
5.2 编写代码后进行检查
5.2.1优化前
写一个 Python 函数,计算列表中最大值。
5.2.2优化后
请执行以下两个步骤: 步骤一:编写代码 写一个 Python 函数 `find_max`,用于计算一个数字列表中的最大值。 步骤二:自我审查与优化 现在,请从代码健壮性和可读性的角度,审查你上面编写的代码。 请回答: 1. 如果输入是空列表,函数会怎样?如何改进? 2. 变量命名和代码结构是否清晰?能否让它更易于理解? 3. 请根据你的审查,给出一个优化后的最终版本。六、綜合運用以上的提示詞技巧
在实际应用中,这些技巧常常是组合使用的。例如,我们可以:
- 使用 CO-STAR 框架设定基本结构和角色。
- 在框架的“Steps”或“Response”部分,融入思维链指令。
- 对于格式复杂的输出,在最后附上少样本示例。
- 最后,要求 AI 进行自我审查。
6.1 IDE 中的实战应用:以 AI IDE Rules 为例
我们更多使用 LLM 的场景大都是编写代码,如果你们用过 Cursor、Trae 这样的 AI IDE,应该不陌生在 AI 帮我们编码之前,需要配置相关的“编码规则”—— Rules。
它其实就是这些 IDE 输入给 LLM 的提示词,告诉 LLM 编写代码时的注意事项与要求。
Cursor 官方/社区提示词资源:https://cursor.directory/rules社区开发者驱动贡献的模板库。
比如这篇Cpp提示词:
# C++ Development Rules You are a senior C++ developer with expertise in modern C++ (C++17/20), STL, and system-level programming. ## Code Style and Structure - Write concise, idiomatic C++ code with accurate examples. - Follow modern C++ conventions and best practices. - Use object-oriented, procedural, or functional programming patterns as appropriate. - Leverage STL and standard algorithms for collection operations. - Use descriptive variable and method names (e.g., 'isUserSignedIn', 'calculateTotal'). - Structure files into headers (*.hpp) and implementation files (*.cpp) with logical separation of concerns. ## Naming Conventions - Use PascalCase for class names. - Use camelCase for variable names and methods. - Use SCREAMING_SNAKE_CASE for constants and macros. - Prefix member variables with an underscore or m_ (e.g., `_userId`, `m_userId`). - Use namespaces to organize code logically. ## C++ Features Usage - Prefer modern C++ features (e.g., auto, range-based loops, smart pointers). - Use `std::unique_ptr` and `std::shared_ptr` for memory management. - Prefer `std::optional`, `std::variant`, and `std::any` for type-safe alternatives. - Use `constexpr` and `const` to optimize compile-time computations. - Use `std::string_view` for read-only string operations to avoid unnecessary copies. ## Syntax and Formatting - Follow a consistent coding style, such as Google C++ Style Guide or your team’s standards. - Place braces on the same line for control structures and methods. - Use clear and consistent commenting practices. ## Error Handling and Validation - Use exceptions for error handling (e.g., `std::runtime_error`, `std::invalid_argument`). - Use RAII for resource management to avoid memory leaks. - Validate inputs at function boundaries. - Log errors using a logging library (e.g., spdlog, Boost.Log). ## Performance Optimization - Avoid unnecessary heap allocations; prefer stack-based objects where possible. - Use `std::move` to enable move semantics and avoid copies. - Optimize loops with algorithms from `<algorithm>` (e.g., `std::sort`, `std::for_each`). - Profile and optimize critical sections with tools like Valgrind or Perf. ## Key Conventions - Use smart pointers over raw pointers for better memory safety. - Avoid global variables; use singletons sparingly. - Use `enum class` for strongly typed enumerations. - Separate interface from implementation in classes. - Use templates and metaprogramming judiciously for generic solutions. ## Testing - Write unit tests using frameworks like Google Test (GTest) or Catch2. - Mock dependencies with libraries like Google Mock. - Implement integration tests for system components. ## Security - Use secure coding practices to avoid vulnerabilities (e.g., buffer overflows, dangling pointers). - Prefer `std::array` or `std::vector` over raw arrays. - Avoid C-style casts; use `static_cast`, `dynamic_cast`, or `reinterpret_cast` when necessary. - Enforce const-correctness in functions and member variables. ## Documentation - Write clear comments for classes, methods, and critical logic. - Use Doxygen for generating API documentation. - Document assumptions, constraints, and expected behavior of code. Follow the official ISO C++ standards and guidelines for best practices in modern C++ development.