Menu

提示词链是什么:把任务拆成多个步骤

提示词链(prompt chaining)把一项工作拆成一串更小的提示词,每一步的输出都成为下一步的输入。每一步只做一件事,你可以在下一步运行之前先检查它的结果。

下面的每条提示词都可以编辑:改好后,在 ChatGPT、Claude 或其他 AI 应用中打开。

提示词链就是把一项工作拆成一串提示词,一个提示词的输出成为下一个提示词输入的一部分。你不再要求模型一口气读完五十条评论、找出问题、排好序再写一份报告,而是按顺序逐一提出这些要求。每个提示词只有一项工作,而在步骤之间,你(或你的代码)可以查看结果、修正它,或者停下来。

下面是一个三步的提示词链,它把客户评论变成一份给产品团队的说明。每个标签页是一步。第 2 步的输入是第 1 步的回复,直接粘贴进去;第 3 步的输入是第 2 步的回复。

Fill in
列出 <reviews> 标签内评论中的每一条抱怨。忽略好评。返回一个由对象组成的 JSON 数组,键为 "review"(评论编号)和 "complaint"(最多十个字)。只返回 JSON。 <reviews> 1. 电池 4 小时就没电了,而且充电线太短。 2. 音质很棒。不过 App 老是把我登出。 3. 很喜欢,但电池勉强撑到我下班回家。 4. 配对时 App 崩溃了两次,而且电池掉电很快。 5. 线太短了,我在办公桌前充电时根本没法用。 </reviews>
Try it
Example replyReplies vary between models and runs.
[
  {"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,以及代码可以解析的结构化输出。写作这一步可以更自由。在代码中,你甚至可以把不同的步骤交给不同的模型,比如用一个又小又快的模型来做提取。

失败只影响局部。 当提示词链出错时,你知道是哪一步出了错,只需重新运行那一步。

代价也是实实在在的。提示词链要调用更多次,所以比一个提示词更慢、更贵。而且早期步骤中漏过的错误会被带进后面的每一步,这就是为什么值得检查中间的步骤。

如何设计提示词链

  1. 写下你手工完成时会走的步骤。 如果你会先列一个清单,再排序,再整理成文,那就是三个提示词。需要不同思考方式的步骤,就是天然的拆分点。
  2. 在写每一步的提示词之前,先确定它的输出格式。 下一步要用的东西应该容易读、容易检查:JSON 数组、编号列表、表格。只有最后一步才适合用自由的文字。
  3. 只传下一步需要的内容。 上面的第 2 步收到的是抱怨列表,而不是评论。输入越少,能让模型分心的东西就越少,每一步也能单独测试。
  4. 在步骤之间加一道检查。 在代码中,解析 JSON 并确认字段存在。对于需要判断的事情,检查本身也可以是一个提示词:“这个列表是否包含了这些评论中的每一条抱怨?回答是或否,然后列出缺失的条目。”
  5. 把粘贴的材料标记清楚。 每一步的输入都是前面步骤生成的文字,而分隔符能防止模型把它当成新的指令。

下面是为上面这条链写的一个检查步骤,运行在一个漏掉了一条抱怨的第 1 步输出上。这样的检查是一个只问一个具体问题的独立提示词,所以比提取本身更容易做对。

先检查这一步,再往下传
把 <reviews> 标签中的评论和 <complaints> 标签中的抱怨列表进行比较。这个列表是否包含了评论中的每一条抱怨?第一行回答“完整”或“不完整”。如果不完整,列出每一条缺失的抱怨及其评论编号。 <reviews> 1. 电池 4 小时就没电了,而且充电线太短。 2. 音质很棒。不过 App 老是把我登出。 3. 很喜欢,但电池勉强撑到我下班回家。 4. 配对时 App 崩溃了两次,而且电池掉电很快。 5. 线太短了,我在办公桌前充电时根本没法用。 </reviews> <complaints> 评论 1:电池 4 小时就没电 评论 1:充电线太短 评论 2:App 老是登出 评论 3:电池撑不过通勤 评论 4:配对时 App 崩溃 评论 5:线太短,充电时没法用 </complaints>
Try it
Example replyReplies vary between models and runs.

不完整

  • 评论 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 里使用提示词链吗?

能。运行第一个提示词,检查回答,然后把它粘贴到下一个提示词里,可以在同一个对话中,也可以在新对话中。每一步都开一个新对话,可以避免之前的草稿和指令影响后面的步骤。

什么时候该用提示词链,而不是一个提示词?

当一个提示词要求完成几种不同的工作(比如提取、分析和写作),或者你需要检查、复用某个中间结果时,就用提示词链。如果一个提示词已经能给出可靠的答案,提示词链只会增加调用次数、成本和等待时间。

Coddy 编程语言插图

和 Coddy 一起学编程

开始