跳转到内容

提示词设计

Arvid Lunnemark研究

提示词就像网页设计。让我们把它称为提示词设计,并为此构建更好的工具。

我通常不太喜欢那种试图用旧世界的事物来类比新世界现象的通用做法。所以请容忍我也犯一次同样的罪:让我来论证一下,为什么 prompting 应该被称为 prompt design(提示词设计) ,并被类比为网页设计

我把提示词编写看作是在与一个时间受限的人类交流。虽然一些 LLM 特有的技巧(最典型的是 chain-of-thought)确实很有帮助,但我发现,提高效果的最佳方式之一就是给出极其清晰且高质量的指令,就像清晰与简洁能够帮助真实的人类更好地理解一样。

Prompting-as-clear-communication(将提示词视为清晰沟通) 让 prompting 听起来很像写作。不过,我大部分的提示词工作是参数化的:我有若干输入变量,需要根据这些变量动态地调整提示词。

因此,prompting-as-clear-communication-with-dynamic-input(在动态输入下的清晰沟通式提示) 似乎是最准确的刻画。

还有哪个领域是在动态输入的前提下,追求清晰沟通的?网页设计。

我们来列一下所有相似之处。Prompting 和网页设计都:

  1. 需要清晰性,并且以沟通为首要目标;

  2. 需要响应动态内容,不同于写作或杂志排版;以及

  3. 需要将内容适配到不同“尺寸”——网页设计对的是屏幕尺寸,prompting 对的是上下文窗口。

根据我在 prompting 和网页设计上的经验,我还发现,在这两个领域里我有非常类似的开发偏好:

  1. 直接看到实际的提示词 非常重要,就像 直接看到渲染后的网站 非常重要一样。如果让我在脑子里“模拟” HTML 和 CSS 的渲染过程,我根本没法设计网站。同样地,如果不查看填入所有输入变量之后渲染出的完整提示词,要写出既好又清晰的 prompt 也非常困难。

  2. 比如,提示词 "Hi ${username} ${message}" 乍看之下还挺合理,直到你把它渲染出来,才发现用户名和消息混在一起看不清。

  3. 可组合的组件在 prompting 和网页设计中都很有用。

  4. 对二者来说,声明式都优于命令式。一个所有 HTML 元素都通过 document.createElement 创建的网站会非常难以修改。同样,一个由一长串 str += "..." 拼接而成的 prompt,在阅读和修改时也会迅速变得难以管理。

  5. 在这两者里,我有时都想要实现“像素级完美”。在给能力较弱的模型(GPT-3.5 及更早版本)写提示词时,我会尽量确保没有多余的换行或其它格式瑕疵;而在设计网站时,有时候每一个像素都很重要。

对于 LLM 代理来说,我们甚至可以把这个类比推得更远:agent prompting 可以被看作是在为这些代理搭建一个交互式网站,它们可以通过调用函数来“点击按钮”,而且每次函数调用后提示词都会重新渲染,就像网站会在按钮点击后重新渲染一样。

当然,提示词设计和网页设计之间也有差异:

  1. Prompting 目前只处理文本(至少现在是这样!)。

  2. 缓存机制不同:尤其是对代理来说,你希望通过只修改提示词后半部分来让“重新渲染”更加廉价。这里和 Web 也许能勉强类比一下(你也会想对网站做缓存优化),但我认为这本质上是相当不同的挑战。

尽管如此,这些相似之处已经让我相信,prompting 应该被称为 prompt design,而不是 prompt engineering。写提示词 感觉就像是在设计网站,因此也理应用相同的命名方式。

从提示词设计的视角出发,我创建了 Priompt,一个类似 React、基于 JSX 的提示词设计库。

Priompt v0.1:提示词设计库的第一次尝试

Priompt 是我们基于现代网页设计原则打造提示词设计库的一次首次尝试。我们已经在 Cursor 内部使用它,并且非常喜欢。

我觉得它在抽象设计上可能还不完全严谨,但至少我已经很确信,相比字符串模板,用 JSX 来写提示词要顺手得多。哪怕只是能轻松把提示词的一部分注释掉这么简单的一件事,都能让迭代周期快很多。

Priompt 还带了一个(非常仓促拼出来的)预览网站,你可以在上面用真实数据预览你的提示词。在开发应用时,你可以在每一次请求时记录进入组件的序列化 props。然后,当你看到异常行为时,可以打开 Priompt 预览,查看精确的提示词,并修改源码,同时让提示词在与真实请求相同的 props 下更新。我们发现,这让提示词的迭代变得容易了不少。

如果你试用了它,请告诉我你的想法!我很想看到更多类似方向的点子,或者被直接指出我完全错了、提示词设计根本就是个很蠢的东西 :)。

注意事项

模型变化很快,提示相关的技巧也不得不随之演进。在这种背景下,我觉得把这类工作称作 提示设计,还是有一些需要注意的地方:

  1. 对于 GPT-4 来说,像素级精确的设计并不重要,而到了 GPT-4.5 或更强的模型时,很可能会彻底变得无关紧要。

  2. 如果顺着近期长上下文模型的发展趋势往下推演,上下文窗口这个约束有可能会消失。不过,我对此还不是完全信服。

  3. OpenAI 似乎正朝着让开发者对 prompt 掌控力越来越少的方向前进;不排除一年之后,已经不存在“prompt”这个概念,API 调用只需要我们提供原始输入加上一段指令即可。这种“减少控制权”的趋势从聊天对话格式就开始了,并在最近发布的函数调用功能中进一步延续。

  4. 有可能缓存是提示中最重要的方面之一,如果真是这样,那么它听起来就更像是工程问题,而不是设计问题。

  5. 或许提示设计本身层级太低,应该交给更高层的框架或编译器去处理(例如 langchain)。我认为这可能是对的,但鉴于 LLM 发展变化极快,我个人还是更倾向于尽可能贴近原始模型。

惯例性的最后一段

……因为我真心想和你一起工作:在 Cursor,我们正在打造 Cursor,一款以 AI 为核心的代码编辑器。如果你对提示词设计、面向编程的 LLM,或者打造优秀产品感兴趣,请发邮件到 arvid@cursor.com 联系我。我们目前是一支位于旧金山的 5 人小团队,我的每一位同事都非常出色,也希望再找到几位同样出色的人——工程师和设计师——与我们一起构建编程的未来。

归档于: 研究

作者: Arvid Lunnemark

提示词设计 · Cursor