生产环境的提示词是程序的输出,不是一句妙语
Berryman 与 Ziegler 这本书的价值在于讲透一件事:为每个请求收集、筛选并排列上下文。

要点速览
- Berryman 和 Ziegler 把提示词内容分为静态和动态两类,动态部分在每次请求时重新组装。
- 信息越靠近提示词末尾,影响越大;中间部分被称为“Valley of Meh”(平庸之谷)。
- 上下文选择是一个循环:结合 token 长度和依赖关系选出最佳元素,重复直到没有剩余元素。
运行在生产环境中的提示词,很少是写好一次就不再改动的一段话。
每来一个新请求,系统都要从头重建提示词,从大得多的上下文池里挑出几块。John Berryman 和 Albert Ziegler 合著的 Prompt Engineering for LLMs 教的正是这项技能,而它也正是区分演示原型和能在客户真实数据上跑通的系统的那项技能。
本书由 O’Reilly Media 出版,完整副标题为 The Art and Science of Building Large Language Model–Based Applications。Helion 书店标注电子书于 2024 年 11 月 4 日发布,并注明纸质版日期可能不同;另一家书商的页面写的是 2025 年。
书中涵盖少样本提示、思维链和检索增强生成(RAG),但按照其简介,核心任务是收集、排序并呈现上下文片段,以构建有效的提示词。
对前线部署工程师(FDE)来说,读这本书最有用的方式,是不再把提示词当作一条巧妙的指令,而是把它看作一个程序的输出:有输入,有约束,有执行顺序。作者并没有这样表述,但书中把提示词拆成若干部分,先收集、再筛选、最后组装,顺着这个思路自然会得出这一结论。
作者出身搜索领域,书里处处可见
Helion 介绍 Berryman 是 GitHub Copilot 最早的工程师之一,专攻语言模型和信息检索系统。他的 Arcturus Labs 网站也提到他参与了 Copilot 的早期工作,并做过每天服务数百万人的搜索和推荐系统。
这样的背景解释了为什么书中把提示词当作排序问题来处理:候选很多,空间有限,必须取舍。每当需要找出正确的合同、正确的工单或正确的文档段落,再按精心安排的顺序摆到模型面前时,这种思路就能派上用场。
Arcturus Labs 目前提供一项服务,把 AI 专家直接嵌入客户团队。网站没有使用 FDE 这个说法,但这种工作模式与 FDE 岗位非常接近。
观点一:区分静态与动态
根据 Strick van Linschoten 对第 5 章的笔记,书中把提示词内容分为两类:静态和动态。动态部分随每个请求变化。
设想为一家保险客户构建一个回复投诉的助手。语气风格和“只依据保单条款作答”这条规则是静态的;争议保单的条款和投诉人的工单历史是动态的。
一开始就把两者分开,就能分别测试:静态部分按带版本的配置来管理,动态部分按查询结果来管理。Helion 上的目录也把 RAG 以及词法检索、神经检索放在讲提示词内容的第 5 章,也就是说,检索是获取动态部分的一种方式。
观点二:在提示词中的位置有分量
Gigazine 对第 6 章的摘要指出,信息越靠近提示词末尾,对模型的影响越大。中间部分被称为“Valley of Meh”(平庸之谷),模型在这里处理信息很吃力。
回到保险的例子。第一版很容易犯的错误,是只在提示词开头写规则,然后在后面倒入五段保单条款和工单历史。
这样一来,最重要的指令被整块上下文推到离模型开始作答处很远的地方。顺着这个观察,成本最低的修正办法是在末尾、紧挨着回答之前,重申任务和约束。
除了位置,还要选择格式。同样根据 Gigazine 的摘要,JSON、XML 或 YAML 这类结构化文档效果很好,尤其是模型在训练中已经习惯这种结构时。
在真实项目中,从发票中抽取字段适合用结构化格式。如果选择散文式写法,很可能最后还得额外写代码,专门修补偏离预期格式的输出。
观点三:上下文组装是一个有预算的算法
这是全书最像编程书的部分。Strick van Linschoten 对第 6 章的笔记写道,这一章讲的是如何组织提示词结构、组装各个元素,以及选择放入哪些上下文。
根据 Gigazine 的摘要,这个过程分为若干步骤,其中一步是结合 token 长度和依赖关系选出最佳元素,然后重复,直到没有剩余元素。
这个循环要防止的错误,是把检索到的每个分块都塞进提示词。提示词因此膨胀,成本和延迟上升,真正关键的片段也很容易滑到中间,恰好落在模型处理得最差的位置。
套用到保险的例子:保单条款价值最高;最新工单价值也高,但依赖客户信息已经在提示词中;通用 FAQ 价值低。如果客户要求快速响应,就需要调低 token 预算,最先被砍掉的就是 FAQ。
下面是这个循环的一个草稿,足够短,可以直接复制到项目里再完善:
def assemble_prompt(task, elements, token_budget):
# elements:[{"id", "text", "value", "tokens", "depends_on", "order"}]
remaining = sorted(elements, key=lambda e: e["value"], reverse=True)
chosen, chosen_ids, used = [], set(), 0
while remaining: # 没有剩余元素时停止
e = remaining.pop(0) # 剩余元素中价值最高的一个
if used + e["tokens"] > token_budget:
continue # 超出预算则跳过
if not set(e["depends_on"]) <= chosen_ids:
continue # 依赖缺失则跳过
chosen.append(e)
chosen_ids.add(e["id"])
used += e["tokens"]
chosen.sort(key=lambda e: e["order"]) # 排序,然后组装
context = "\n\n".join(e["text"] for e in chosen)
return f"{task}\n\n{context}\n\n重申任务:{task}"
这个版本刻意写得很简单:因依赖缺失被跳过的元素不会再被重新考虑。但它已经把“砍掉什么”的决定移进了代码:可以测试,可以按延迟要求调整 token_budget,也可以向客户解释,而不是让这个决定只存在于写提示词那个人的记忆里。
该按什么顺序读?
以下建议只基于 Helion 上的章节标题和一位读者对第 5、6 章的笔记,并非基于完整目录或全书正文。
如果你调用过 LLM API,但还没把系统推上生产环境,先读讲提示词内容的第 5 章,掌握静态/动态的划分和几类检索方式,再读第 6 章 Assembling the Prompt。
如果你已经在为客户运行 RAG,可以直接读第 6 章。正是在这一章,一堆检索来的上下文变成了顺序清晰、限制明确的提示词。
从职业发展看,这项技能应该用技术语言写进简历。“设计了一个按 token 预算和延迟要求选择上下文的提示词组装器”,远比“精通提示工程”更有说服力。
看岗位描述时,留意那些在 LLM 之外还提到上下文、检索或延迟的岗位。在这类岗位的面试中,面试官会想听你决定砍掉了哪些信息,以及为什么。
提示词技巧会随着每一代模型过时。选择放入什么、放在哪里的这套方法始终有用,这才是这本书最值得留下的东西。
这篇文章对你有帮助吗?
感谢你的反馈!
6 个信源
- Prompt Engineering for LLMs - John Berryman, Albert Ziegler (Helion) · 2024-11-04
- Prompt Engineering for LLMs: The Art and Science of Building Large Language Model–Based Applications 1st Edition
- Arcturus Labs – John Berryman
- Prompt Content: Notes on 'Prompt Engineering for LLMs' ch 5 · 2025-01-11
- Assembling the Prompt: Notes on ‘Prompt Engineering for LLMs’ ch 6 · 2025-01-12
- Prompt Engineering for LLMs (Gigazine) · 2025-08-19