讲解 prompt 工程核心概念和实战技巧(867 条讨论)。帮助程序员更高效地与 AI 引擎交互。
AI 已经席卷而来!放眼望去,生活中的方方面面几乎都有某种新的人工智能工具。在 ChatGPT、AutoGPT、Midjourney、DALL-E 和 GitHub Copilot 的帮助下,你可以构建产品、编写代码、获取答案,还能创作精美的艺术作品……至少有些人可以。
为什么在使用生成式 AI 时,有些人得到的结果就是比其他人好?为什么有些人能创作出足以陈列在卢浮宫的艺术品,而另一些人得到的却是一团糟?
归根结底,差别在于你使用的输入。这种输入叫作「prompt」。prompt 可以是你提出的问题,也可以是你用来生成某种内容的文字。那些会精心设计 prompt、讲究输入策略的人,把这种做法称为「prompt engineering」。
prompt engineering,是指以特定方式设计 prompt,从而让 AI 给出更好的结果。
OpenAI、Google 等许多 AI 系统的开发者,甚至会聘请「prompt engineer」来帮助训练模型。有些「创作者」甚至会在 Etsy 之类的平台上出售自己的 Midjourney prompt。
简单来说,AI 系统和数据处理一样:垃圾进,垃圾出。如果输入很糟,得到的结果多半也不会好。prompt engineering 在很大程度上取决于上下文。
上下文是影响结果的最大问题之一。举个例子,如果我在 Google 中搜索「donut」(或者「doughnut」🍩),可能会得到五花八门的结果:甜甜圈食谱、甜甜圈图片,或者哪里可以买到这种美味的甜点。这是因为我没有给搜索引擎提供更多上下文。当然,Google 会参考我之前的搜索记录和所在位置来判断应该展示什么结果,但也仅此而已。
对于搜索引擎来说,「donuts」可能代表任何东西:一种形状、一个 Slack 插件、一款应用,或者 GitHub Universe 2022 上供应的这些美味 GitHub 甜甜圈。
比如说,如果我想找一个使用 Blender 创建甜甜圈 3D 模型的教程,那么只输入「donut」很可能看不到我想要的搜索结果。我必须说得更具体一些。像「tutorial for donut Blender3D」这样的搜索词,就能更准确地找到我需要的内容。
AI 也是如此。你需要为 AI 提供足够的上下文,才能针对自己的需求得到更好的结果。
很多人都向我们展示过 ChatGPT 生成的一些令人惊叹的结果。尽管这些结果并不总是准确,但 ChatGPT 有一件事非常擅长:写文章。它特别擅长写出结构良好、衔接流畅的句子。生成的内容读起来毫不费力,听上去也很不错。但要得到准确的回答,则完全是另一回事。例如,有人尝试使用 ChatGPT 撰写历史论文。虽然文章可能读起来很好,但内容未必符合史实。比如,如果你要求 ChatGPT「写一篇 2000 字的中国衰落史论文」,它确实会给你写一篇 2000 字的中国衰落史论文,但里面的事实未必正确。
有些内容虽然读起来很像那么回事,事实却未必正确。提示:我可没有博士学位 😉
这是因为 ChatGPT 会从各种来源中提取信息,再把它们拼凑到一起,而这些信息来源本身可能就不准确。ChatGPT 也不知道你所说的「中国衰落」具体指哪一段历史,因此很容易错误地关联不同年代的信息。如果你先以对话的方式向 ChatGPT 提供信息,然后再要求它写一篇 2000 字的论文,得到的结果会好得多。
这究竟是什么意思?有些人认为 ChatGPT 是一种单向对话、只需输入一次就能获取信息的工具,但事实并非如此。它之所以叫「chat」是有原因的。你应该和它展开对话,不断完善问题,并为回答提供上下文。
例如,如果我要为一份出差报告写一段关于「NDC Conferences」的文字,不会一上来就对 ChatGPT 说「帮我写一段关于 NDC 的出差报告」。相反,我会先弄清楚 ChatGPT 对 NDC 了解多少,同时逐步补充上下文。你提供的输入会在很大程度上决定最终输出。这就是为什么有些人能获得非常好的结果,而另一些人却做不到。
如果没有任何上下文,ChatGPT 并不知道我指的是哪个 NDC。
再举一个例子:如果你要参加求职面试,希望得到一些建议,那么向 ChatGPT 提问「给我一些准备求职面试的建议」,确实能得到一些不错的回答,但这些回答不会太有针对性。相比之下,「我要去一家 AI 初创公司面试软件开发工程师职位,可以给我一些准备这场面试的建议吗?」这样的提问,会得到更加贴合个人情况、更有针对性的结果。
这就像请一位站在台上的专家回答现场 1000 名观众的问题。他很可能会给出比较通用的回答,好让每个人都能有所收获。但如果你和同一位专家一对一交流,他多半会先追问几个问题,以便了解你的具体情况,进而提供更加个性化、更有针对性的回答。
你可能已经看过一些人使用 Stable Diffusion 应用创作出的精美艺术作品。当然,也有些作品看起来就是「不太对劲」。其中很大一部分差异依然来自上下文。比如,我使用自己最喜欢的生成器之一 NightCafe,只输入「dog」这个词,得到了下面的结果:
使用 NightCafe 和 prompt「dog」生成的图片。
画面中有个标牌,莫名其妙地写着「dog」;前景里有一只看起来很奇怪的狗,配色也诡异得出奇。如果我脑海中想象的是一张照片般真实的画面:阳光明媚的日子里,一只成年德国牧羊犬待在公园中——那么最终生成的结果大概不会是我想要的样子。因为 AI 并不知道这些上下文,它还不能读懂我的心思(至少现在还不能!)。
当你想创作艺术作品时,需要像描述脑海中的画面一样描述图像。提供的细节越多,输出效果就越好。麻烦也正在这里:很多 Stable Diffusion 应用都有字符数限制,因此你必须有意义、有策略地设计 prompt。
和使用 ChatGPT 类似,你需要不断重新设计和完善 prompt。不过,聊天式 AI 有一个优势:你可以延续对话,继续为 AI 提供更多信息、提出不同问题,直到得到满意的回答。有些艺术生成器虽然允许你对输出结果进行「remix」,但这仍然需要一个新的 prompt。因此,你要不断等待输出、观察哪些地方不对,再提交调整过的新 prompt。
有些用户会在 Midjourney 上花费数小时,不断查看输出结果、重新设计 prompt,最终创作出令人叹为观止的作品。这一切都需要练习。也正因如此,一些创作者才会在 Etsy 上出售自己的 prompt!
我的朋友 Jean 使用 Midjourney 生成的艺术作品。
有一点可以确定:如果你想创作出高质量的艺术作品,就不要指望只花几秒钟写个 prompt、点击「create」按钮,然后立刻看到一幅莫奈级别的作品。不可能!你需要投入时间(以及金钱),创作数百幅作品,并在每次迭代中调整 prompt,最终才能打造出自己的杰作。
关于如何为 GitHub Copilot 之类的工具设计优秀的 prompt,我不打算花太多时间讨论。我的同事 Rizel 写过一篇很棒的博客文章,深入介绍了 GitHub Copilot 的 prompt engineering:
《GitHub Copilot prompt engineering 初学者指南》
Rizèl Scarlett 为 GitHub 撰写・2023 年 4 月 3 日
我想说的是,与 ChatGPT 类似,GitHub Copilot 同样依赖上下文。代码仓库中还编写了哪些代码?当前文件的扩展名是什么,使用的又是哪种语言?GitHub Copilot 之前还为你生成过什么内容?你在代码中写了哪些注释?所有这些信息,都能帮助 GitHub Copilot 为你生成更加准确的代码。
可以这样理解:如果你写下一条注释,表示自己想创建一个复杂函数,要求它使用后端数据并解决某个特定问题,那么仅凭这一条注释,你很可能得不到理想的结果。你的代码——至少应该如此——会被拆分成许多函数,而且(希望)包含大量有用的注释。同样,GitHub Copilot 在问题被拆解之后,也能表现得更好。
与其直接要求 GitHub Copilot://reverse a sentence (using JavaScript)
不如想一想,如何从逻辑上拆解这个问题。例如,如果有人真的递给我一张写有一句话的纸,并要求我把这句话倒过来,我会怎么做?像这样逐步写出注释,会有用得多。这样一来,GitHub Copilot 就能获得更多上下文,更好地理解你的需求。
与 ChatGPT 这类工具相比,GitHub Copilot 还有一个不同之处:它会考虑你提供的全部上下文,也就是我前面提到的所有内容:
ChatGPT 和其他聊天应用,会给予你最后发送的那条消息更高的权重,也就是你最近一次添加到对话中的信息。而 GitHub Copilot 会始终结合上下文,以生成更好的代码结果。
归根结底,能否从任何一种生成式 AI 中获得好结果,取决于你——也就是提供输入的人。正如我在开头所说:垃圾进,垃圾出。因此,在设计 prompt 时,请记住以下重要建议:
最后,一定、一定要验证从 AI 那里得到的信息。对于艺术作品生成器来说,这一点没那么重要;但涉及代码和信息时,验证就非常关键。检查得到的代码能否按照预期运行,也要核实 AI 提供的文字信息是否准确。
请记住,无论发生什么,你仍然是掌舵者。决定权仍然在你手中:使用和分享哪些艺术作品、哪些代码片段以及哪些信息,最终都由你说了算。
如果还需要采取进一步行动,你可以考虑屏蔽此人和/或举报滥用行为。