本章涵盖以下内容:
- 提示与提示工程
- 不同类型的提示及其组织结构
- 如何利用单样本、双样本或少样本学习来增强提示响应
- 在 ChatGPT 和 OpenAI API 中使用提示的示例
AI 应用与大语言模型(LLM)的交互,主要是通过提示(prompt) 完成的——提示是用来引导模型行为的结构化输入。这有点像你在给一位很有天赋、但经验尚浅的同事布置任务:你说得越清楚、越具体,结果往往就越好。为了获得准确且相关的输出,提示需要被精心设计,并针对具体任务进行定制。在实际应用中,提示设计往往是决定应用表现优劣的最关键因素之一。
提示工程(prompt engineering) ——也就是通过设计和迭代优化提示来引导 LLM 输出的实践——是构建 LLM 应用的一项核心技能。你会把大量时间花在创建、测试和迭代提示上,以确保系统能够稳定地产出高质量结果。
在本章中,你将从提示设计的基础开始,逐步过渡到更复杂的技术,例如思维链(Chain of Thought,CoT) 。随着你学习如何在应用中充分发挥 LLM 的能力,LangChain 提供的一整套提示工程工具——包括 PromptTemplate 和 FewShotPromptTemplate——将成为你的关键助力。
2.1 以编程方式运行提示
LLM 应用依赖精心设计的提示来生成补全结果(completions),而这些结果会继续传递给链中的下一个组件。与在 ChatGPT 这类界面中手动输入提示不同,LangChain 中的提示通常是作为更大工作流的一部分,以编程方式构建并发送给 LLM 的。接下来的小节将先演示如何直接使用 OpenAI API 来设置和执行提示,然后再探讨如何在 LangChain 中运行和管理提示。在深入之前,请先确保你已经掌握以下基础内容:
- 你已经有一个 OpenAI API key。
- 你知道如何创建 Python 的 Jupyter Notebook 环境。
如果你对这些操作还不熟悉,请参阅附录 A 的说明,并按照附录 B 中关于搭建 Jupyter Notebook 环境的指导进行准备。
2.1.1 为本章搭建环境
假设你已经完成了前置准备,本节将指导你搭建一个用于提示工程的 Jupyter Notebook 环境,本章中的所有示例都会在这个环境中运行。在本章以及本书的其余部分,我将演示如何在 Windows 上搭建 Jupyter。如果你使用的是其他操作系统,请参见附录 B 获取对应平台的说明。
打开你操作系统的终端(这里以 Windows 命令提示符为例),创建一个名为 ch02 的新项目文件夹。你也可以选择克隆本书对应的 GitHub 仓库:
https://mng.bz/YZma
然后进入 ch02 文件夹:
C:\Github\building-llm-applications\ch02>
使用 venv 创建并激活一个虚拟环境:
C:\Github\building-llm-applications\ch02>python -m venv env_ch02
C:\Github\building-llm-applications\ch02>.\env_ch02\Scripts\activate
此时你应该会看到更新后的命令行提示符,前面多出了环境名称 (env_ch02):
(env_ch02) C:\Github\building-llm-applications\ch02>
激活虚拟环境后,你就可以着手实现一个用于调用 OpenAI 模型执行提示的 Jupyter Notebook 了。如果你已经从 GitHub(https://mng.bz/YZma)克隆了仓库,或者从 Manning 网站下载了 zip 格式的代码包,那么你可以按如下方式安装 Jupyter 和 OpenAI 相关包:
(env_ch02) C:\Github\building-llm-applications\ch02>
↪pip install -r requirements.txt
然后你就可以启动 notebook:
(env_ch02) C:\Github\building-llm-applications\ch02>
↪jupyter notebook 02-prompt_examples.ipynb
如果你打算从零开始在本地自己搭建一切,请务必安装 requirements.txt 中列出的相同版本的依赖包——这样有助于避免后续出现版本冲突。接下来在本书余下部分中,我都默认你已经从 GitHub 克隆了项目仓库,或者从 Manning 网站下载了源码。
大约一分钟后,notebook 和 OpenAI 包的安装应当完成。你可以通过执行以下命令启动 Jupyter Notebook:
(env_ch02) C:\Github\building-llm-applications\ch02>jupyter notebook
几秒钟后,你应该会在终端中看到一些输出。接着,浏览器会打开 http://localhost:8888/tree。按照图 2.1 所示,选择 File > New > Notebook 来创建一个 notebook,然后把文件重命名为 prompt_examples.ipynb。
图 2.1 创建一个新的 Jupyter Notebook
创建好 notebook 之后,进入 Jupyter 菜单,选择 File > Rename,将 notebook 文件命名为 02-prompt_examples.ipynb。现在你就可以在 notebook 单元格中输入代码(如果你是从 GitHub 获取的 notebook,也可以直接执行现成代码)。
提示 如果你对 Jupyter Notebook 还不熟悉,请记住:按 Shift-Enter 就可以执行当前单元格中的代码。
在本章余下内容中,我都默认你已经按本节所述完成了以下步骤:创建虚拟环境、安装 OpenAI 库,并启动了一个 Jupyter Notebook 实例。
2.1.2 最小化提示执行示例
在 notebook 的第一个单元格中,导入所需库,并以安全方式获取 OpenAI API key(绝不要把 key 直接硬编码到代码里,否则可能被滥用):
from openai import OpenAI
import getpass
OPENAI_API_KEY = getpass.getpass('Enter your OPENAI_API_KEY')
输入 OpenAI API key 后(这里只需要按 Enter,不需要按 Shift),按如下方式初始化 OpenAI 客户端:
client = OpenAI(api_key=OPENAI_API_KEY)
在 notebook 的下一个单元格中,输入并执行以下代码:
prompt_input = """Write a concise message to remind
users to be vigilant about phishing attacks."""
response = client.chat.completions.create(
model="gpt-5-nano",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt_input}
]
)
print(response)
注意 为了把执行成本控制在较低水平,我们使用 gpt-5-nano,它是 GPT-5 家族中体积最小、价格最便宜的模型。在本书的大多数内容中你都会看到它。不过,如果你更看重准确性,也完全可以改用 gpt-5-mini 或 gpt-5。关于 OpenAI 模型的更多信息,可参见:https://platform.openai.com/docs/models。
输出结果看起来会像下面这样(由于 LLM 的非确定性,具体内容可能略有差异):
ChatCompletion(id='chatcmpl-CFkN43Xs80ohhDJVIDeRUSID8RXNo', choices=[Choice( finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage( content='Be vigilant against phishing: verify the sender, hover over links to check URLs, don’t click suspicious attachments or share passwords, and report anything suspicious to IT.', refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=None))], created=1757869206, model ='gpt-5-nano-2025-08-07', object='chat.completion', service_tier='default', system_fingerprint=None, usage=CompletionUsage(completion_tokens=553, prompt_tokens=32, total_tokens=585, completion_tokens_details= CompletionTokensDetails(accepted_prediction_tokens=0, audio_tokens=0, reasoning_tokens=512, rejected_prediction_tokens=0), prompt_tokens_details=PromptTokensDetails(audio_tokens=0, cached_tokens=0)))
为了获得更清晰的输出,可以进一步查看 response 对象的属性:
print(response.choices[0].message.content)
你会看到类似下面的输出:
Be vigilant against phishing: verify the sender, hover over links to check URLs, don’t click suspicious attachments or share passwords, and report anything suspicious to IT.
注意 如果你不熟悉的话,我这里使用的三个双引号 """ 是为了方便地输入跨多行的文本块,而不必显式写入换行符 \n。这种写法非常适合承载提示文本。
chat.completions.create 函数
chat.completions.create 函数是 OpenAI Completions API 的一部分,也是与 OpenAI LLM 交互的主要方式。理解它的函数签名非常关键:
client.chat.completions.create(
model="gpt-5-nano",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt_input}
]
)
下面是各参数的说明:
model —— 指你要使用的 OpenAI 模型。可选范围从 GPT-5 到 GPT-5-nano:前者最准确,但也最慢、最贵;后者最快、最便宜,但在某些任务上准确性稍逊。GPT-5-mini 则提供了一个不错的折中,在速度、准确性和成本之间取得平衡。
messages —— 提示以消息列表的形式表达,其中每条消息都带有一个角色(如 system、user 或 assistant)和具体内容。这个格式遵循 OpenAI 对会话式输入的标准约定。
尽管如今 Responses API 已经成为 OpenAI 更推荐的接口——尤其是在智能体工作流中——但本书主要使用的还是 Completions API,并且很多时候会通过 LangChain 中的 ChatOpenAI 封装间接调用它。原因在于,Completions 不仅受到 OpenAI 模型支持,也被许多开源 LLM 所采用,因此能给你带来更大的灵活性。等到第 11 章深入 AI 智能体时,我们还会回到 Responses API。
现在你已经掌握了以编程方式提交提示的基础,可以继续学习并处理更复杂的提示了。
2.2 使用 LangChain 运行提示
在进入更高级的提示之前,我先用 LangChain 复现刚才相同的例子,帮助你熟悉它的对象模型。在接下来的小节里,我会演示 LangChain 是如何简化复杂提示的实现的——那些提示如果从零手写,通常会更难完成。
如果你已经按照 2.1 节中的说明安装好了所需 Python 包,那么 langchain 和 langchain-openai 应该都已经装好了。现在你可以使用这些库,并初始化与 LLM 的连接:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY,
model_name="gpt-5-nano")
现在就可以像下面这样实例化并执行刚才的提示:
prompt_input = """Write a concise message to remind
users to be vigilant about phishing attacks."""
response = llm.invoke(prompt_input)
print(response.content)
输出将类似如下:
Stay vigilant against phishing: verify the sender, hover over links to check URLs before clicking, never share passwords, and report suspicious messages.
2.3 提示模板
在构建 LLM 应用时,创建能够通过参数接收用户输入的灵活提示模板是非常重要的。LangChain 通过 PromptTemplate 类让这件事变得更简单,它允许你管理和复用参数化提示,而无需自己编写定制函数。这不仅简化了动态提示的创建,也提高了 LLM 交互的效率和适应性。下面我会做具体演示。
2.3.1 用 Python 函数实现一个提示模板
为了说明模板的概念,我们来创建一个文本摘要模板,它会要求提供:待摘要的文本、期望的摘要长度,以及希望采用的语气。你可以用一个简单的 Python 函数来实现:
def generate_text_summary_prompt(text, num_words, tone):
return f"You are an experienced copywriter. Write a
↪{num_words} words summary of the following text, using a
↪{tone} tone: {text}"
现在用这个提示模板生成一个提示,然后像之前一样通过 LangChain 的 ChatOpenAI 封装执行它:
segovia_aqueduct_text = """The Aqueduct of Segovia (Spanish:
Acueducto de Segovia) is a Roman aqueduct in Segovia, Spain.
It was built around the first century AD to channel water from
springs in the mountains 17 kilometres (11 mi) away to the
city's fountains, public baths and private houses, and was in
use until 1973.
Its elevated section, with its complete arcade of 167 arches,
is one of the best-preserved Roman aqueduct bridges and the
foremost symbol of Segovia, as evidenced by its presence on the
city's coat of arms.
The Old Town of Segovia and the aqueduct, were declared a UNESCO
World Heritage Site in 1985. As the aqueduct lacks a legible
inscription (one was apparently located in the structure's attic,
or top portion[citation needed]), the date of construction cannot be
definitively determined. The general date of the Aqueduct's
construction was long a mystery, although it was thought to have
been during the 1st century AD, during the reigns of the Emperors
Domitian, Nerva, and Trajan. At the end of the 20th century,
Géza Alföldy deciphered the text on the dedication plaque by
studying the anchors that held the now missing bronze letters
in place. He determined that Emperor Domitian (AD 81–96) ordered
its construction[1] and the year 98 AD was proposed as the most
likely date of completion.[2] However, in 2016 archeological
evidence was published which points to a slightly later date,
after 112 AD, during the government of Trajan or in the
beginning of the government of emperor Hadrian,
from 117 AD."""
input_prompt = generate_text_summary_prompt(
text=segovia_aqueduct_text,
num_words=20,
tone="knowledgeable and engaging")
response = llm.invoke(input_prompt)
print(response.content)
你应该会看到类似下面的输出:
The Aqueduct of Segovia, built in the 1st century AD, is a well-preserved Roman structure and a UNESCO World Heritage Site.
2.3.2 使用 LangChain 的 PromptTemplate
有了 LangChain,你就不必手动实现提示模板函数了。你可以直接使用便捷的 PromptTemplate 类来处理参数化模板。写法如下:
from langchain_core.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template(
"""You are an experienced copywriter.
Write a {num_words} words summary of the following text,
using a {tone} tone: {text}""")
要使用这个提示模板,只需先创建一个提示实例,并用参数进行格式化:
prompt = prompt_template.format(
text=segovia_aqueduct_text,
num_words=20,
tone="knowledgeable and engaging")
然后调用 ChatOpenAI 客户端执行这个格式化后的提示:
response = llm.invoke(prompt)
print(response.content)
它会生成与下面类似的输出(正如你现在已经知道的,精确输出可能和书中打印的不完全一致,所以我后面就不再反复强调这一点了):
The Aqueduct of Segovia, a Roman marvel built in the 1st century AD, channels water to Segovia's fountains and baths.
让我们暂时从 LangChain 代码里抽离一下。我想更深入地谈一谈提示工程。接下来的几页中你会看到,一个好的提示可以包含各种不同元素,这取决于你的目标、任务复杂度以及你希望获得的准确性。通过学习不同形式的提示,你将能够同时应对简单提示和复杂提示,并根据具体场景调整它们的复杂程度。
2.4 提示类型
在 LangChain 应用中,要获得最佳结果,创建有效提示至关重要。无论你的应用是做文本分类、情感分析、摘要、文本生成,还是问答,每一种任务都需要经过精心设计的提示。接下来的小节中,我们将深入探讨如何为这些特定任务编写合适的提示,以确保应用按预期工作。
尽管这些提示技术对 LangChain 应用开发非常关键,但为了让概念解释更直观、也更容易上手,我们暂时先用 ChatGPT 来演示。你在这里学到的模式,都会直接迁移到后续章节里我们将使用 LangChain 构建的 LLM 应用中。
2.4.1 文本分类
在分类任务中,目标是把输入文本归入若干预定义类别中的某一个。下面这个提示展示了这一概念——你可以把它输入到 ChatGPT 中试一试,我们在本节都会使用 ChatGPT 来演示:
INSTRUCTION 将以下文本分类到以下类别之一:history、tech、gardening。
TEXT Headphones provide immersive audio experiences for music lovers and gamers alike.
“文本 Headphones provide immersive audio experiences for music lovers and gamers alike. 应该被归类为 tech,因为它讨论的是与技术相关的产品及其功能。”
这个输出过于详细了。我们来修改一下提示,并明确要求它只输出类别。
INSTRUCTION 将以下文本分类到以下类别之一:history、tech、gardening。
TEXT Headphones provide immersive audio experiences for music lovers and gamers alike.
OUTPUT only the category
“Tech
现在,我们只修改文本内容,再用同样的提示对另一句话进行分类:
INSTRUCTION 将以下文本分类到以下类别之一:history、tech、gardening。
TEXT Julius Caesar was a Roman general and statesman who played a pivotal role in the demise of the Roman Republic and the rise of the Roman Empire.
OUTPUT only the category
“History
总结来说,一个标准的文本分类提示通常包含三个组成部分:Instruction(指令) 、输入的 Text(文本) ,以及 Output(输出说明) 。接下来,我们来看一种稍微更专门化的文本分类任务:情感分析。
2.4.2 情感分析
情感分析是文本分类的一种特定形式,其目标是判断给定文本所表达的情感倾向是正面、中性还是负面。下面给出三个示例提示(以及预期回答),你可以自行尝试:
INSTRUCTION Classify the following text as positive, neutral or negative
TEXT Apple has announced stellar quarterly results
“Positive
INSTRUCTION Classify the following text as positive, neutral or negative
TEXT this is the worst movie I have watched this month
“Negative
INSTRUCTION Classify the following text as positive, neutral or negative
TEXT The customer bought a green dress
“Neutral
如果你有一组文本,希望一次性分析它们的情感倾向,也可以把它们全部放进一个提示中:
INSTRUCTION classify the sentiment of following stock reports as positive, neutral or negative
Stock 1: Apple: the launch of the new iPhone has been a success
Stock 2: Nvidia: sales are being propelled by consumer demand on LLMs
Stock 3: GX oil: demand of carbon based energy is dropping thanks to the increase of renewable energy
OUTPUT output a table with the columns “stock name”, “sentiment”
“
| Stock Name | Sentiment |
|---|---|
| Apple | positive |
| Nvidia | positive |
| GX oil | negative |
正如你所看到的,在这个场景里,输出被格式化成了表格,这样一来就很容易再通过程序做后续处理。接下来,我们来编写一个最常见的 LLM 用例之一:文本摘要。
2.4.3 文本摘要
创建一个文本摘要提示非常简单:你只需要要求模型对输入文本生成一个指定长度的摘要即可。
INSTRUCTION write a 30 word summary for the following text
TEXT Home PCs from the 1980s were iconic pioneers of personal computing. Computers like the Apple II, IBM PC, and Commodore 64 revolutionized how we lived and worked. They introduced us to word processing, gaming, and the possibilities of home computing. The graphical user interface, as seen in the Apple Macintosh, changed the way we interacted with machines. These PCs, though less powerful by today’s standards, ignited a digital revolution, shaping the technology landscape we know today. They hold a special place in history, symbolizing the dawn of a new era in computing that laid the foundation for the modern digital age.
“1980s home PCs like Apple II, IBM PC, Commodore 64 pioneered personal computing, introducing word processing, gaming, and GUIs. They shaped today’s tech, symbolizing a digital era’s dawn.
你也可以要求 LLM 对它已经熟知的文本内容进行摘要:
INSTRUCTION Write a one sentence summary of the Lord of the Rings
“The Lord of the Rings follows the epic journey of a diverse group of characters as they seek to destroy a powerful ring and save Middle-earth from the dark lord Sauron.
2.4.4 文本创作
LLM 属于 AI 中所谓的生成式 AI(generative AI) 。虽然 LLM 也可以处理音频和视频,但当输入是文本时,它们尤其擅长基于一组事实生成新的内容,比如一段文章或一句话。举个例子:
Write a piece on the diver watches, mentioning the following facts:
the Rolex Oyster Perpetual was among the first to be water resistant
Omega produced the Seamaster in 1948 as the first purpose designed diver watch was the Seamaster
the Seamaster set a world record of immersion of 62.5m in 1955
Rolex produced the first Submariner in 1953
the Submariner became popular also because of the association with James Bond until 1995
James Bond started to wear the Seamaster in 1995
“Rolex Oyster Perpetual 于 20 世纪早期问世,在潜水表的发展历程中发挥了开创性作用。它最显著的特点之一就是卓越的防水设计,这为真正意义上的防水腕表的发展奠定了基础。这一创新迈出了关键一步,确保手表能够承受水下探索的严苛环境。
Omega 这家备受尊敬的瑞士制表商,则在 1948 年凭借 Seamaster 进入潜水表领域。这款腕表意义重大,因为它是第一款为潜水而专门设计的腕表,兼具风格与功能。Seamaster 不仅设计出色,也展现了其下潜实力。1955 年,它创造了 62.5 米的世界下潜纪录。
不甘落后的 Rolex 在 1953 年推出了第一款 Submariner。这款标志性腕表很快成为水下探险与冒险的代名词。它的成功还因与虚构的英国间谍詹姆斯·邦德的关联而进一步扩大。不过,1995 年潮流发生转变,当由皮尔斯·布鲁斯南饰演的詹姆斯·邦德在《黄金眼》中佩戴上 Omega Seamaster 时,Seamaster 开启了新的时代,也由此成为世界上最著名特工的腕上之选。”
你可能会注意到,ChatGPT 利用有限的信息生成了一篇相当长的文章。而另一方面,你原本可能更期待一段更短的文字,也未必喜欢它使用的复杂词汇或略显正式的语气。在这种情况下,可以尝试更系统地组织提示,让生成文本更符合你想要的长度、措辞和风格:
PERSONA you’re a watch enthusiast, experienced in writing high quality articles for watch magazines for a general audience
INSTRUCTION Write a piece on the diver watches
Facts to mention:
the Rolex Oyster Perpetual was among the first to be water resistant
Omega produced the Seamaster in 1948 as the first purpose designed diver watch was the Seamaster
the Seamaster set a world record of immersion of 62.5m in 1955
Rolex produced the first Submariner in 1953
the Submariner became popular also because of the association with James Bond until 1995
James Bond started to wear the Seamaster in 1995
TONE use a sober, knowledgeable but not too formal tone and use everyday vocabulary
OUTPUT the length of the article should be 150 words at most
“Diver Watches: Timepieces of Exploration and Style
Diver watches have long been cherished for their blend of functionality and aesthetics, a perfect companion for both the adventurous spirit and the style-conscious.
Rolex deserves recognition for pioneering water resistance with the Oyster Perpetual, setting the stage for a new era in watchmaking.
Omega, however, made a significant splash in 1948 with the Seamaster, the world’s first purpose-designed diver watch. Its 1955 record dive of 62.5 meters underlines its prowess in the deep.
Rolex didn’t lag behind, introducing the Submariner in 1953, a watch that became synonymous with exploration, partly due to its affiliation with James Bond on-screen.
Speaking of James Bond, it’s worth noting that in 1995, the iconic secret agent started sporting the Omega Seamaster, a move that reinforced the Seamaster’s reputation as a sophisticated yet rugged timepiece for those who dare to explore both land and sea. These diver watches are more than instruments; they’re symbols of adventure and style.
通过在提示中加入更多细节,文章就几乎完全按照你的要求生成了。
注意 创建一个结构清晰、分区明确的提示(例如 Persona、Instruction、Facts、Tone、Output Format),有助于让 LLM 更好地理解你的要求,并生成符合预期的文本。
2.4.5 问答
LLM 对文本的“理解”能力,使它们不仅适合做摘要,也适合提取特定信息,这就是所谓的问答(question answering) 用例。现在,我们回到前面摘要示例里用过的同一段文本,并针对内容提出聚焦问题。
INSTRUCTION read the following text, and tell me which home computers were popular in the 80s.
TEXT Home PCs from the 1980s were iconic pioneers of personal computing. Computers like the Apple II, IBM PC, and Commodore 64 revolutionized how we lived and worked. They introduced us to word processing, gaming, and the possibilities of home computing. The graphical user interface, as seen in the Apple Macintosh, changed the way we interacted with machines. These PCs, though less powerful by today’s standards, ignited a digital revolution, shaping the technology landscape we know today. They hold a special place in history, symbolizing the dawn of a new era in computing that laid the foundation for the modern digital age.
OUTPUT just output the names of the computers in a list
“1980 年代流行的家用电脑有:
- Apple II
- IBM PC
- Commodore 64
- Apple Macintosh
问答是如此常见的一类用例,以至于大多数 LLM 都能理解 Q and A 是 Question and Answer 的缩写。例如:
TEXT Java is a popular programming language that compiles code into bytecode, which is executed by the Java Virtual Machine (JVM) for platform-independent application development.
Q: Where is Java code executed?
A:
“Java code is executed by the Java Virtual Machine (JVM).
LLM 不仅擅长在文本中找到所需信息,还能够做出逻辑推断。下一节中你将看到这一点。
2.4.6 推理
虽然推理是一项很强大的能力,但这仍然是 LLM 还在持续进步的领域。因此,为了得到你想要的结果,你有时需要更高级的提示工程技巧。来看一个涉及数学推理的简单例子:
INSTRUCTION Add the square numbers in this sequence: 19, 13, 1, 17, 4, 64, 900
“The square numbers in the sequence 19, 13, 1, 17, 4, 64, and 900 are 1, 4, 64, and 900. To find their sum:
1 + 4 + 64 + 900 = 969
So, the sum of the square numbers in this sequence is 969.
ChatGPT 识别出了平方数,把它们挑了出来,然后算出了总和。下一个例子更有挑战性,涉及回文数(palindromes) ——即正着读和反着读都一样的数字,例如 1661 或 27872:
INSTRUCTION Sum the palindromes in this sequence: 13, 1331, 121, 73, 99, 56, 232, 7
我当时得到的输出是:
“The palindromes in the sequence 13, 1331, 121, 73, 99, 56, 232, and 7 are 1331, 121, 232, and 7. To find their sum:
1331 + 121 + 232 + 7 = 1691
So, the sum of the palindromes in this sequence is 1691.
这显然是错的!回文数是正反读取都相同的数字,因此 99 也应该被算作回文数,但它却被遗漏了。
坦率地说,这个输出是我在撰写本书早期阶段时真实遇到的。不过,如果你现在再运行这个提示,你大概率会看到不同的、而且更重要的是正确的输出。尽管如此,我仍然觉得有必要解释一下,在 OpenAI 后来的模型版本修复这一问题之前,我当时是怎样纠正 ChatGPT 错误的。
那么我是怎么修复的?由于早期版本的 LLM 并没有完全理解“回文数”这个概念,我就通过提示“教”ChatGPT 正确识别所有相关情形。下一节我会详细说明。在此之前,先回顾一下到目前为止学过的提示类型,见表 2.1。
表 2.1 提示类型及示例
| 提示类型 | 提示示例 |
|---|---|
| 文本分类 | Classify the following text into one of these categories: history, tech, gardening. |
| 情感分析 | Classify the following text as positive, neutral, or negative. |
| 文本摘要 | Write a 30-word summary for the following text. |
| 文本创作 | Write a piece on the diver watches, mentioning the following facts: • The Rolex Oyster Perpetual was among the first to be water resistant. • Omega produced the Seamaster in 1948 as the first purpose designed diver watch was the Seamaster. |
| 问答 | Read the following text, and tell me which home computers were popular in the 80s. |
| 推理 | Add the square numbers in this sequence: 19, 13, 1, 17, 4, 64, 900. |
2.5 详细理解推理
在开发 LLM 应用时,尤其是那些需要复杂推理能力的应用,理解不同提示技术的局限性非常重要。例如,零样本学习(zero-shot learning) 是指你不给任何示例,而是期望 LLM 仅凭指令本身就理解并完成任务。这个方法在某些场景下表现不错,但对于更复杂的任务——比如教 LLM 识别回文数——并不总能得到准确结果。接下来的几个小节中,我将展示如何超越零样本学习,通过改进提示来让 LLM 在推理任务上表现得更可靠。
2.5.1 单样本学习
当你只在提示中提供一个示例时,这称为单样本学习(one-shot learning) 。下面是我当时尝试解决回文数问题的方法——我给了一个单独示例:
INSTRUCTION Sum the palindromes in this sequence: 13, 1331, 121, 73, 99, 56, 232, 7
EXAMPLE 33 is a palindrome
“I apologize for the previous oversight. Let’s correctly identify and sum the palindromes in this sequence: 13, 1331, 121, 73, 99, 56, 232, and 7.
The palindromes in the sequence are 1331, 121, 232, and 7. To find their sum:
1331 + 121 + 232 + 7 = 1691
So, the sum of the palindromes in this sequence is indeed 1691.
遗憾的是,即便使用了单样本学习,问题依然存在。于是我调整了提示,加入两个示例。
2.5.2 双样本学习
下面是我修改后的提示,以及它生成的输出。这个输出展示了模型是如何理解修订后的指令,并在这个双样本学习示例中应用它们的。
INSTRUCTION Sum the palindromes in this sequence: 13, 1331, 121, 73, 99, 56, 232, 7
Examples:
33 is a palindrome
44 is a palindrome
“Certainly, let’s identify and sum the palindromes in the sequence: 13, 1331, 121, 73, 99, 56, 232, and 7.
The palindromes in this sequence are 1331, 121, 232, and 7. To find their sum:
1331 + 121 + 232 + 7 = 1691
So, the sum of the palindromes in this sequence is 1691.
依然不对:99 再次被遗漏了。在又一次尝试失败之后,我开始寻找其他方法,最终发现了一个标准解法。它建议把问题拆解成几个步骤,并对每一步给出清晰指令。这有点像你在指导一位同事完成某项流程,只不过对方卡在了某个具体步骤上。
2.5.3 提供步骤
下面是我修改后的提示,以及由此生成的输出。这个输出展示了模型如何遵循修订后的指令,并应用逐步推理的方法来解决这个例子。
INSTRUCTION Sum the palindromes in this sequence: 13, 1331, 121, 73, 99, 56 232, 7
Examples:
33 is a palindrome
44 is a palindrome
Steps: 1) identify the palindromes; 2) add them up
“Certainly, let’s follow your instructions step by step:
Step 1: Identify the palindromes in the sequence.
Palindromes in the sequence:
1331
121
99
232
7
Step 2: Add them up.
1331 + 121 + 99 + 232 + 7 = 1790
So, the sum of the palindromes in the sequence is 1790.
终于,这次我成功了!有意思的是,看起来 ChatGPT 后来似乎也经历了类似的“训练过程”(当然规模大得多),从而修复了这个问题。为了说明这一点,如果你现在直接输入最初的原始提示:
INSTRUCTION Sum the palindromes in this sequence: 13, 1331, 121, 73, 99, 56, 232, 7
你现在大概率会看到类似这样的输出:
“Let’s identify the palindromes in the given sequence:
1331 is a palindrome
121 is a palindrome
99 is a palindrome
232 is a palindrome
7 is a palindrome
Now, let’s add these palindromes together:
1331 + 121 + 99 + 232 + 7 = 1790
Therefore, the sum of the palindromes in the sequence is 1790.
看起来,ChatGPT 现在会像我当初那样,按步骤来解决这个问题。像 GPT-5 Thinking 这样的推理模型,经常会自己把问题拆解开来,而不需要你明确告诉它该按什么步骤做。不过,在更复杂的场景中——尤其当步骤本身是确定性的——在提示里把步骤明确写出来仍然很有帮助。这样可以确保 LLM 按照你期望的顺序执行,而不是自己发明一套流程,从而减少出错概率。
我之所以愿意分享一个“已经过时”的例子,是因为这种情况在你与 LLM 打交道时非常真实:你可能花了很多时间,通过高级提示工程技巧教会模型某项任务,结果后来换了一个更新的模型版本,它不需要任何额外“训练”就已经能做好了。比如,OpenAI 的 GPT-5 模型在很多推理任务上,只需要极少的提示就能完成;而这些任务在以前往往需要更复杂的 few-shot 等提示技术。
2.5.4 少样本学习
在某些情况下,只提供两个示例还不足以让 LLM 学会一个新概念。这时你就需要提供多个示例,这就是少样本学习(few-shot learning) 。为了演示这一点,我来构造一个小游戏:把一个数字分类为 Abra、Kadabra 或 Abra Kadabra。先看看当我完全不提供分类规则时会发生什么。
Classify the following numbers as Abra, Kadabra or Abra Kadabra:
3, 5, 8, 2, 7, 12, 13
“The classification of numbers into “Abra,” “Kadabra,” or “Abra Kadabra” doesn’t follow a conventional mathematical pattern. These are just words, not related to numbers. Therefore, it’s not possible to classify the numbers you provided as “Abra,” “Kadabra,” or “Abra Kadabra” based on any mathematical or logical criteria.
这里 ChatGPT 并没有产生幻觉,而是正确指出:你根本没有说明分类规则。现在我给你看一个提示,它并不直接解释规则,而是通过一组与待分类数字不同的示例,让模型自行归纳规则:
Classify the following numbers as Abra, Kadabra or Abra Kadabra:
3, 4, 5, 7, 8, 10, 11, 13, 35
Examples:
6 // not divisible by 5, not divisible by 7 // None
15 // divisible by 5, not divisible by 7 // Abra
12 // not divisible by 5, not divisible by 7 // None
21 // not divisible by 5, divisible by 7 // Kadabra
70 // divisible by 5, divisible by 7 // Abra Kadabra
注意我在每个示例中使用的格式:我用双斜杠 // 来分隔每个字段,但并没有显式说明这些字段各自表示什么。我把这个任务留给 LLM 自己去领会。下面是输出:
“Let’s classify the numbers as Abra, Kadabra, or Abra Kadabra based on whether they are divisible by 5 and/or 7:
3: Not divisible by 5, not divisible by 7 - None
4: Not divisible by 5, not divisible by 7 - None
5: Divisible by 5, not divisible by 7 - Abra
7: Not divisible by 5, divisible by 7 - Kadabra
8: Not divisible by 5, not divisible by 7 - None
10: Divisible by 5, not divisible by 7 - Abra
11: Not divisible by 5, not divisible by 7 - None
13: Not divisible by 5, not divisible by 7 - None
35: Divisible by 5, divisible by 7 - Abra Kadabra
So, here’s the classification:
Abra: 5, 10, 35
Kadabra: 7
Abra Kadabra: 35
None: 3, 4, 8, 11, 13
ChatGPT 不仅给出了正确结果,还解释了背后的推理过程。它成功地从给定示例中归纳出了通用规则,并清楚地表达了出来。是不是很厉害?
注意 你可能会想到一个类似的数字分类游戏,或者说“整除测试算法”(在 Stack Overflow 上常见),其中一个数如果能被 3 整除就标记为 “Foo”,能被 5 整除就标记为 “Bar”,能同时被 3 和 5 整除就标记为 “Foo Bar”。我之所以没有用它做例子,是因为 ChatGPT 早就“认识”这个模式了,不需要示例,仅靠零样本学习就能正确分类。
2.5.5 使用 LangChain 实现少样本学习
下面我们用 LangChain 来实现这个 AbraKadabra 游戏。首先,像前面一样先建立与 LLM 的连接:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY,
model_name="gpt-5-mini")
然后定义并运行你刚才在 ChatGPT 中直接执行过的那段 few-shot 提示:
prompt_input = """Classify the following numbers as Abra, Kadabra
↪or Abra Kadabra:
3, 4, 5, 7, 8, 10, 11, 13, 35
Examples:
6 // not divisible by 5, not divisible by 7 // None
15 // divisible by 5, not divisible by 7 // Abra
12 // not divisible by 5, not divisible by 7 // None
21 // not divisible by 5, divisible by 7 // Kadabra
70 // divisible by 5, divisible by 7 // Abra Kadabra
"""
response = llm.invoke(prompt_input)
print(response.content)
输出如预期所示:
3 // not divisible by 5, not divisible by 7 // None
4 // not divisible by 5, not divisible by 7 // None
5 // divisible by 5, not divisible by 7 // Abra
7 // not divisible by 5, divisible by 7 // Kadabra
8 // not divisible by 5, not divisible by 7 // None
10 // divisible by 5, not divisible by 7 // Abra
11 // not divisible by 5, not divisible by 7 // None
13 // not divisible by 5, not divisible by 7 // None
35 // divisible by 5, divisible by 7 // Abra Kadabra
这个输出是准确的,但实现方式并不理想,因为示例被硬编码进了提示。LangChain 为创建 few-shot 提示提供了更整洁的方案。它允许你把“训练示例”和提示模板分离开,在之后再把示例注入进去,如下面这段代码所示。
代码清单 2.1 使用 FewShotPromptTemplate 构造 few-shot 提示
from langchain_core.prompts.few_shot import FewShotPromptTemplate
from langchain_core.prompts.prompt import PromptTemplate
examples = [
{
"number": 6,
"reasoning": "not divisible by 5 nor by 7",
"result": "None"
},
{
"number": 15,
"reasoning": "divisible by 5 but not by 7",
"result": "Abra"
},
{
"number": 12,
"reasoning": "not divisible by 5 nor by 7",
"result": "None"
},
{
"number": 21,
"reasoning": "divisible by 7 but not by 5",
"result": "Kadabra"
},
{
"number": 70,
"reasoning": "divisible by 5 and by 7",
"result": "Abra Kadabra"
} ]
example_prompt = PromptTemplate(input_variables=["number",
↪"reasoning", "result"],
↪template="{number} \ {reasoning} \ {result}")
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="Classify the following numbers as Abra, Kadabra
↪or Abra Kadabra: {comma_delimited_input_numbers}",
input_variables=["comma_delimited_input_numbers"]
)
prompt_input = few_shot_prompt.format(
↪comma_delimited_input_numbers="3, 4, 5, 7, 8, 10, 11, 13, 35.")
response = llm.invoke(prompt_input)
print(response.content)
结果依然正确:
3 \ not divisible by 5 nor by 7 \ None
4 \ not divisible by 5 nor by 7 \ None
5 \ divisible by 5 but not by 7 \ Abra
7 \ divisible by 7 but not by 5 \ Kadabra
8 \ not divisible by 5 nor by 7 \ None
10 \ divisible by 5 but not by 7 \ Abra
11 \ not divisible by 5 nor by 7 \ None
13 \ not divisible by 5 nor by 7 \ None
35 \ divisible by 5 and by 7 \ Abra Kadabra
2.5.6 思维链(Chain of Thought)
最后,我想向你介绍 CoT(Chain of Thought,思维链) 技术。它结合了“给出逻辑步骤”和“少样本学习”这两种做法。这里我虚构一个新的数学定义:如果一个数字序列中至少包含两个奇数,并且所有奇数之和可以被 3 整除,那么我们就称这个序列是“strange(奇异的)”。一开始,我先验证 LLM 是否确实不了解“奇异序列”的规则:
Is the following sequence “strange”?
3, 4, 5, 7, 10, 18, 22, 24
“The sequence you provided appears to be increasing, but it doesn’t follow a common mathematical pattern like arithmetic or geometric progressions. Whether it’s considered “strange” depends on the context or criteria you’re using to define “strange.” In a mathematical sense, it might be considered an unusual or nonstandard sequence. If you’ve specific criteria or rules that define what a “strange” sequence is, please provide more details for a more precise classification.
不出所料,ChatGPT 并不理解“奇异序列”这个概念,这也再次说明:幸运的是,它还没有发展出读心术。
接着,我会构造一个使用 CoT 技术的提示,正如 Wei 等人的论文中所提出的那样(https://arxiv.org/abs/2201.11903)。这个提示其实是一个 few-shot 提示的扩展,里面会包含:
- 多个示例序列,用于少样本学习
- 对每个示例序列给出判断其是否为 strange 的逻辑步骤说明
Q: Is the following sequence “strange”?
3, 4, 5, 7, 10, 18, 22, 24
Examples:
Q: is the following sequence strange: 1, 4, 6, 8, 20
A: 1 is an odd number; I need at least two odd numbers // Not Strange
Q: is the following sequence strange: 5, 6, 7, 8, 20
A: 5 and 7 are odd numbers; the sum of 5 and 7 is 12; 12 is divisible by 3 // Strange
Q: is the following sequence strange: 1, 5, 6, 7, 8, 20
A: 1, 5 and 7 are odd numbers; the sum of 1, 5 and 7 is 13; 13 is not divisible by 3 // Not Strange
Q: is the following sequence strange: 5, 6, 7, 8, 9, 20
A: 5, 7, 9 are odd numbers; the sum of 5, 7 and 9 is 21; 21 is divisible by 3 // Strange
“Thank you for providing the examples and clarifications. Based on the criteria you’ve presented:
The sequence “3, 4, 5, 7, 10, 18, 22, 24” has 3 odd numbers: 3, 5, and 7. The sum of these odd numbers is 15. 15 is divisible by 3. So, according to the criteria, this sequence is Strange.
ChatGPT 给出了正确答案,并解释了它的思考过程。为了加深理解,你可以试着用类似的提示换一组数字再跑一遍。同时,也可以观察一下当序列中只包含一个奇数时,ChatGPT 会如何回答。
在这一节中,你已经看到:要让 ChatGPT 学会一个新任务,你可以提供多个示例,或者明确列出必须遵循的步骤。这种方法就叫做上下文学习(in-context learning) ,因为你是在借助提示中给出的上下文信息来“教”模型如何完成任务。
定义 上下文学习(in-context learning)是指:针对用户提出的、LLM 原本不熟悉的任务或指令,通过在提示上下文中提供示例来进行引导的方法。常见技术包括单样本、双样本、少样本学习,以及逐步引导(通常称为思维链)。与微调不同——微调是通过在领域数据上继续训练,把一个通用 LLM 变成专用 LLM——上下文学习是一种成本更低、资源要求更少的方法。它不需要 GPU 这类高端硬件,也不要求你深入理解 Transformer 架构。
本节介绍了一系列上下文学习提示,表 2.2 对它们做了总结。
表 2.2 上下文学习提示
| 上下文学习技术 | 说明 |
|---|---|
| 零样本学习 | 提示中不提供任何示例。 |
| 单样本学习 | 提示中提供一个示例。 |
| 双样本学习 | 提示中提供两个示例。 |
| 少样本学习 | 提示中提供若干示例。 |
| 思维链(CoT) | 提示中提供若干示例,并对每个示例清晰解释达成目标所需的全部逻辑步骤。 |
超越思维链
思维链(CoT)通过把问题拆分成更小、更有逻辑的步骤,提升了语言模型处理复杂推理的能力。不过,它也有局限,比如对更深层次探索的支持不足,或者在上下文杂乱时容易失焦。为了解决这些问题,研究者提出了两种更高级的技术:Tree of Thought(ToT) 和 Thread of Thought(ThoT) 。
Tree of Thought(ToT) —— ToT 允许语言模型探索多条推理路径,从而增强问题求解能力。传统模型通常是逐 token 做决策,这限制了它们前瞻性规划和回溯早先选择的能力。ToT 把整个过程组织成连贯的思考步骤,使模型能够在推进过程中评估并修正不同选项(参见 https://arxiv.org/abs/2305.10601)。这种方法在需要策略性思考的任务中尤其有效,例如 Game of 24、创意写作和迷你填字游戏。例如,在 Game of 24 上,ToT 让 GPT-4 的解题率达到 74%,而 CoT 只有 4%。这种方法提升了模型的审慎决策、回溯能力和战略预见性。
Thread of Thought(ThoT) —— ThoT 主要用于应对混乱上下文带来的挑战(参见 https://arxiv.org/abs/2311.08734),在这种场景中,无关细节往往会干扰模型或导致错误。ThoT 的灵感来自人类认知,它通过系统性地拆解和分析大段信息,同时聚焦于相关细节来工作。它可以作为一个模块化的附加层,集成进不同模型和提示方案中。基于 PopQA、EntityQ 以及一个多轮对话响应数据集的实验表明,ThoT 能显著增强推理准确率。它特别擅长在复杂上下文中滤除噪声、维持聚焦。
这两种技术都推动语言模型超越了简单的响应生成,在结构化和混乱两类场景中提升了推理、规划与决策能力。关于技术细节和示例,可以参考相应的研究论文与代码仓库。
在结束本章之前,我们来尝试从前面看到的各种用例中,提炼出一种标准的提示格式。
2.6 提示结构
将前面各节提到的提示元素综合起来,可以得到如下这种通用结构:
Persona(角色) —— 指定你希望 LLM 扮演的身份。无论是资深营销经理、获奖科幻作家,还是计算机杂志的专业文案编辑,都尽量把期望设得明确而高。
Context(上下文) —— 提供详细背景信息,帮助 LLM 理解你请求背后的语境。信息越精确,就越容易让输出贴近你的预期。
Instruction(指令) —— 清楚定义你希望 LLM 对输入文本执行什么动作。无论是翻译、写作、改写、润色、分类、排序还是查找,都要表达得足够明确。
Input(输入) —— 指具体输入内容,可以是一段文本、一个问题,或者一组要点。你也可以根据情况给它贴上标签,例如 “Text” 或 “Question”。
Steps(步骤) —— 列出 LLM 生成输出时应遵循的处理步骤。
Tone(语气) —— 指定回答应采用的语气,例如正式、非正式、机智、热情、克制、友好等,也可以组合多种风格。
Output format(输出格式) —— 可选项,用于指定你期望的输出形式。如果不指定,LLM 默认会输出普通文本。但你也可以要求它输出表格、CSV 文件(包含列名)、JSON(包含属性名)或其他结构化格式。
Examples(示例) —— 在某些任务上,尤其是文本分类和推理任务上,如果 LLM 的训练不足以覆盖你的要求,可以通过示例给它做“内联微训练”。哪怕只提供少量示例,也常常能显著提升答案质量。
这份清单可以看作一份组织提示的指南或检查表。你可以根据自己的需求对它做定制,保留相关部分、删减不必要部分,或进行扩展。下面这个提示就包含了其中许多元素,并且以清晰的分段方式组织:
PERSONA You’re an experienced Large Language Model (LLM) developer and renowned speaker.
CONTEXT You’ve been invited to give a keynote speech for a LLM event.
INSTRUCTION Write the punch lines for the speech.
INPUT Include the following facts:
LLMs have become mainstream with the launch of ChatGPT in November 2022
many popular LLMs and LLM based chatbots have been launched since then, such as LLAMA-2, Falcon180B, Bard.
LLMs becoming as popular as search engines
many companies want to integrate LLMs in their applications
TONE Use a witty but entertaining tone.
OUTPUT FORMAT Present the text in two paragraphs of 5 lines each.
“Ladies and gentlemen, as we embark on this linguistic odyssey, remember this: In November 2022, ChatGPT didn’t just enter the scene; it was the linguistic equivalent of a rockstar’s encore, setting the stage for an epic word-tastic journey! Today, with LLAMA-2, Falcon180B, and Bard, it’s safe to say that LLMs have become the Beatles of the digital era, making search engines feel like yesterday’s news.
But here’s the kicker – companies are now falling over themselves, desperately trying to get these LLMs into their applications. It’s like the gold rush, but instead of panning for precious metal, we’re sifting through bytes of brilliant language. So, my friends, in this age where words wield the power, and LLMs are the mighty pens, we’re not just scripting the future; we’re penning a linguistic saga that’s bound to be a best-seller! Welcome to the age of LLMs, where we’re rewriting the rules, one sentence at a time, and words are the currency of change!
一种更可靠、而且 OpenAI 与 Anthropic 的提示工程指南都推荐的做法,是使用 XML 风格标签 来标记提示中的不同部分。比如,上面那个提示就可以写成这样:
<Persona>
You’re an experienced Large Language Model (LLM) developer and renowned speaker.
</Persona>
<Context>
You’ve been invited to give a keynote speech for a LLM event.
</Context>
<Instruction>
Write the punch lines for the speech.
</Instruction>
<Input>
Include the following facts:
LLMs have become mainstream with the launch of ChatGPT in November 2022
many popular LLMs and LLM based chatbots have been launched since then, such as LLAMA-2, Falcon180B, Bard.
LLMs becoming as popular as search engines
many companies want to integrate LLMs in their applications
</Input>
<Tone>
Use a witty but entertaining tone.
</Tone>
<OutputFormat>
Present the text in two paragraphs of 5 lines each.
</OutputFormat>
注意 研究(例如 The Prompt Report: A Systematic Survey of Prompting Techniques,https://arxiv.org/abs/2406.06608)发现,显式标记提示中不同部分的名称,通常有助于提升效果。不过,这并不意味着你必须给每一部分都命名。大多数 LLM 通常能够自行判断提示中各段文本的用途。因此,你完全可以灵活组合:给某些部分命名(例如 Question 或 Examples),而让另一些部分不带标题(例如 Context 或 Tone)。实践中最好的办法,就是多做实验,观察什么方式最适合你的场景和你想要的结果。
如果你想进一步深入学习提示工程,我非常推荐以下资源:
https://mng.bz/z2aAhttps://mng.bz/0zVvhttps://mng.bz/KwmOhttps://mng.bz/9ynrwww.promptingguide.ai/techniqueshttps://github.com/dair-ai/Prompt-Engineering-Guidehttps://mng.bz/jZ8e
小结
- 提示通过为 LLM 提供指令和上下文(例如领域知识或约束条件)来引导模型行为。清晰、具体的提示通常比模糊提示效果更好。
- 不同的任务适合不同的指令模式。分类提示要求输出类别标签或情感分值;生成类提示要求产出原创内容;抽取类提示则从输入文本中提取特定事实。
- 当提示未能产生预期输出时,原因之一可能是 LLM 缺乏针对该任务格式的训练示例。增加 few-shot 示例,或提升指令清晰度,通常可以解决这个问题。
- 少样本学习展示了期望的回答模式。单样本使用一个示例,双样本使用两个,以此类推——示例越多,一致性通常越高,但 token 成本也会增加。
- 标准提示通常包含:角色(persona)、上下文(context)、指令(instructions)、输入(input)、风格(tone/format)以及示例(examples)。并不是每个任务都必须包含所有部分。
- 你可以省略、重排或扩展提示结构中的各个部分。根据需要加入约束、输出格式说明,或多步骤推理要求。
- 基于 API 的提示自动化会把变量注入提示模板中,并以编程方式批量执行请求。这使提示可以从单次调用扩展到成千上万次变体。例如,你可以把不同产品属性(名称、类别、特性)从数据库或 CSV 中填充进同一个模板,从而批量生成数千条产品描述。
- 提示模板使用占位符(通常是花括号中的
{variable_name}),在运行时替换为实际值。这使提示结构与动态内容彼此分离。 - LangChain 为基础变量替换提供
PromptTemplate。FewShotPromptTemplate可以根据输入相似性动态选择示例,而ChatPromptTemplate则用于组织多轮对话结构。 - 思维链(CoT)提示要求 LLM 在给出最终答案之前,先展示逐步推理过程。常见写法包括加入 “Let’s think step-by-step” 之类的指令,或者直接明确列出所需推理步骤。
- 可以使用 XML 风格标签来强化提示结构,例如
<persona>、<context>、<instruction>、<input>、<examples>。这种做法符合 OpenAI 和 Anthropic 的提示工程指南,能提升清晰度。 - 在 OpenAI API 中,消息通常以带有
role和content的列表形式传入:messages=[{"role": "system", "content": "..."}, {"role": "user", "content": "..."}]。角色通常包括system、user和assistant。