提示词链就是把一项工作拆成一串提示词,一个提示词的输出成为下一个提示词输入的一部分。你不再要求模型一口气读完五十条评论、找出问题、排好序再写一份报告,而是按顺序逐一提出这些要求。每个提示词只有一项工作,而在步骤之间,你(或你的代码)可以查看结果、修正它,或者停下来。
下面是一个三步的提示词链,它把客户评论变成一份给产品团队的说明。每个标签页是一步。第 2 步的输入是第 1 步的回复,直接粘贴进去;第 3 步的输入是第 2 步的回复。
[
{"review": 1, "complaint": "电池 4 小时就没电"},
{"review": 1, "complaint": "充电线太短"},
{"review": 2, "complaint": "App 老是登出"},
{"review": 3, "complaint": "电池撑不过通勤"},
{"review": 4, "complaint": "配对时 App 崩溃"},
{"review": 4, "complaint": "电池掉电快"},
{"review": 5, "complaint": "线太短,充电时没法用"}
]
第 1 步只负责阅读和提取。第 2 步从来看不到评论,只能看到列表,所以它不会又跑回去总结评论。第 3 步只负责写作。如果第 3 步的语气不对,你只需重新运行第 3 步,提取和归类的结果保持不变。
注意第 3 步没有说的内容:有一块电池 4 小时就没电了,或者 App 的问题是登出和崩溃。第 3 步只收到了主题名称,所以这些细节根本不在它的输入里。决定每一步收到什么,是设计提示词链时最主要的选择;你想在最终答案里出现的细节,必须一路传下去。
为什么用提示词链,而不是写一个大提示词
每一步只有一项工作、一个标准。 一个同时要求提取、分析和精心写作的提示词,要在三个目标之间取舍,而你无从得知它在哪一个上偷了工。只有一项工作的提示词,可以准确说明这项工作的好结果是什么样子,你也能据此评判回复。
你可以检查中间结果。 在单个提示词里,一条漏掉的抱怨会消失在一段写得漂亮的文字里,你永远看不到。在提示词链中,第 1 步的列表就摆在那里。检查它只需几秒钟,而在第 2 步之前修正,比在最终报告里才发现错误要省事得多。
每一步可以用自己的设置。 提取和归类适合用较低的 temperature,以及代码可以解析的结构化输出。写作这一步可以更自由。在代码中,你甚至可以把不同的步骤交给不同的模型,比如用一个又小又快的模型来做提取。
失败只影响局部。 当提示词链出错时,你知道是哪一步出了错,只需重新运行那一步。
代价也是实实在在的。提示词链要调用更多次,所以比一个提示词更慢、更贵。而且早期步骤中漏过的错误会被带进后面的每一步,这就是为什么值得检查中间的步骤。
如何设计提示词链
- 写下你手工完成时会走的步骤。 如果你会先列一个清单,再排序,再整理成文,那就是三个提示词。需要不同思考方式的步骤,就是天然的拆分点。
- 在写每一步的提示词之前,先确定它的输出格式。 下一步要用的东西应该容易读、容易检查:JSON 数组、编号列表、表格。只有最后一步才适合用自由的文字。
- 只传下一步需要的内容。 上面的第 2 步收到的是抱怨列表,而不是评论。输入越少,能让模型分心的东西就越少,每一步也能单独测试。
- 在步骤之间加一道检查。 在代码中,解析 JSON 并确认字段存在。对于需要判断的事情,检查本身也可以是一个提示词:“这个列表是否包含了这些评论中的每一条抱怨?回答是或否,然后列出缺失的条目。”
- 把粘贴的材料标记清楚。 每一步的输入都是前面步骤生成的文字,而分隔符能防止模型把它当成新的指令。
下面是为上面这条链写的一个检查步骤,运行在一个漏掉了一条抱怨的第 1 步输出上。这样的检查是一个只问一个具体问题的独立提示词,所以比提取本身更容易做对。
不完整
- 评论 4:电池掉电快
如果检查结果是“不完整”,就在第 2 步运行之前重新运行第 1 步,或者手动补上缺失的条目。
用代码实现提示词链
在代码中,提示词链就是一连串调用,每个提示词都由上一次的回答构建而成。这个版本使用 Anthropic 的 Python SDK,换成任何服务商,结构都一样。
import json
import anthropic
client = anthropic.Anthropic()
MODEL = "your-model-id" # e.g. from your provider's model list
def ask(prompt):
response = client.messages.create(
model=MODEL,
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return response.content[0].text
reviews = open("reviews.txt", encoding="utf-8").read()
complaints = ask(
"List every complaint in the reviews inside the <reviews> tags. Ignore praise. "
'Return a JSON array of objects with the keys "review" and "complaint". '
"Return only the JSON, with no code fence.\n\n"
f"<reviews>\n{reviews}\n</reviews>"
)
json.loads(complaints) # raises an error here if step 1 did not return valid JSON
themes = ask(
"Group these complaints into themes. Return only a JSON array with the keys "
'"theme", "count" and "reviews", sorted by count, highest first.\n\n'
f"<complaints>\n{complaints}\n</complaints>"
)
note = ask(
"Write a note of at most four sentences to the product team based on these "
f"themes. Lead with the most common one.\n\n<themes>\n{themes}\n</themes>"
)
print(note)
json.loads 这一行是最简单的检查:如果第 1 步回答的是一段文字,提示词链就会停在那里,而不是把错误的输入传下去。生产环境中的提示词链还会检查字段、对失败的步骤重试一次,并记录每个中间结果,这样一个糟糕的最终答案就能追溯到导致它的那一步。
在聊天应用中使用提示词链
使用提示词链不一定要写代码。运行第 1 步,阅读回答,改正其中的错误,再把它粘贴进第 2 步的提示词。每一步都在新对话中进行,可以让之前的对话不进入上下文,这样为某一步写的指令就不会影响下一步。待在同一个对话里更快,在步骤之间联系紧密时也行得通,但整个历史记录会随着每条新消息一起发送。
提示词链与相关技术的比较
思维链是在一次回复内写出的推理;提示词链则是多次回复,由你控制它们之间传递什么。两者可以很好地结合:链中的任何一步都可以要求模型一步一步地推理。
在提示词链中,步骤是由你事先固定好的。如果由模型自己决定下一步做什么,比如搜索、读取结果,再选择另一个动作,那这种模式就是智能体循环,见 ReAct 提示。固定的提示词链更容易测试和预测,所以只要你已经知道步骤,它就是更好的起点。
常见问题
提示词链是什么?
提示词链是一种技术:把一个任务拆成几个依次运行的提示词,并把每个提示词的输出插入到下一个提示词中。比如,第一个提示词从评论中提取抱怨,第二个把它们归纳成主题,第三个根据这些主题写一份报告。
提示词链和思维链有什么区别?
思维链发生在一次回复之内:模型在给出答案之前先写出推理过程。提示词链使用多次独立的调用,由你或你的代码把一次调用的结果传给下一次。你可以检查、修正或重新运行链中的任何一步,而对一次回复内部的推理,你做不到这一点。
不写代码,能在 ChatGPT 或 Claude 里使用提示词链吗?
能。运行第一个提示词,检查回答,然后把它粘贴到下一个提示词里,可以在同一个对话中,也可以在新对话中。每一步都开一个新对话,可以避免之前的草稿和指令影响后面的步骤。
什么时候该用提示词链,而不是一个提示词?
当一个提示词要求完成几种不同的工作(比如提取、分析和写作),或者你需要检查、复用某个中间结果时,就用提示词链。如果一个提示词已经能给出可靠的答案,提示词链只会增加调用次数、成本和等待时间。