扫码打开虎嗅APP
本文来自微信公众号:Mindstorms,作者:艾木三号,题图来自:AI生成
我有一个很好的学习习惯,养成好多年了,它也让我受益好多年。这个习惯叫“追本溯源”。
所谓“追本”就是追问本质。为什么要追问?因为问题是思考的起点。为什么要追问本质?因为枝叶都是表象,知识在接近根的地方相连通。
所谓“溯源”就是回溯源头。为什么要溯源?因为信息在传播过程中会有损失,会损失准确性、完整性。“溯源”这个能力在我们当下这个糟糕的信息环境中变得尤为重要。你可以环顾一下你所处的媒体环境,检视一下你的各种信息源,其中能做到本本分分转述信息的媒体已经是凤毛麟角了。夸大、扭曲是媒体的常态,更恶劣者还会在信息中投毒。长期通过这种媒体接收信息,脑子会坏掉的。
如何在提示词里控制任务流程?
Anthropic 官方有一个提示词工程指南[1],如果你还没有任何提示词编程的基础,可以看一下。
最起码,要掌握这三个最基本的提示词策略:
1. 使用例子[2]
2. 让模型思考[3]
3. 设定系统角色[4]
在第 2 篇教程中,Anthropic 团队分享了三种控制任务流程的方法:
第一种就是最简单的“Think step by step”,大家应该都会用了。
第二种就是我们在提示词中制定好思考步骤,第一步干嘛,第二步干嘛,第三步干嘛……这种方法相比于第一种方法会更可控,同时也更加局限,因为它限制了大模型做其他探索的可能。
第三种方法,比较有意思。你可以用 <thinking>
和 <answer>
这样的 XML 标签去引导大模型的思考流程。
Think step by step
我最近写提示词有一个感受:“Think step by step” 这句提示词的价值被低估了(至少被我低估了)。这是一句元提示词(meta prompt),这类提示词的强大首先在于它的通用性,它并不局限于某一类具体问题。使用这类提示词不是为了“教” 大语言模型解决某个具体问题,而是为了“教”大语言模型如何思考。
“Think step by step” 这句提示词会引导大模型去定位到合适当前任务的流程性知识,然后应用它。所以这句提示词有效需要一个前提,就是在大模型的训练语料中一定是有“一步一步思考”相关的例子。在意识到“一步一步思考”的重要性之后,各大模型厂商在训练模型的时候,必然会增加流程性知识语料。目前做得最极致的就是 OpenAI 的 o1 系列模型,OpenAI 想要把这种“一步一步思考”的能力内化到模型内部。
也就是说,我们目前接触的大部分模型,除了具有丰富的事实性知识(是什么)以外,它们的程序性知识(怎么做)也被丰富了,甚至说策略性知识(在什么情况下应用什么知识)也被增强了。因此我们在写提示词的时候,要尽一切可能利用好大模型的这个能力。
Think before acting
第三种任务流程控制方法乍看上去很简单,好像没什么稀奇的。但我个人认为,它是一个比思维链(CoT)更通用、更实用、也更重要的提示词技巧。它是在让大模型践行一条更一般性的认知原则:思而后行(think-before-acting)。
如果你不显式地让大模型思而后行,它会倾向于先直接给出答案,然后再给出理由(合理化)。它给出的答案可以看作是一种“快思考”的结果,也就是我们常说的“没过脑子”。
Anthropic 团队为我们提供了一个非常好的应用示例,而且是应用在一个非常重要的场景中——Claude 的 Artifacts 功能。在 Claude 的系统提示词[6]中有这样一段:
<artifact_instructions>
...
1. Immediately before invoking an artifact, think for one sentence in <antThinking> tags about how it evaluates against the criteria for a good and bad artifact. Consider if the content would work just fine without an artifact. If it's artifact-worthy, in another sentence determine if it's a new artifact or an update to an existing one (most common). For updates, reuse the prior identifier.
2. Wrap the content in opening and closing `<antArtifact>` tags.
...
</artifact_instructions>
<artifact_instructions>
中第一条就是告诉 Claude 在调用 Artifact 能力之前,用 <antThinking>
标签先思考一下,然后再使用 <antArtifact>
标签去生成 Artifact 的内容。这就是 <thinking>
和 <answer>
的一个更具体的应用。在<thinking>
部分需要思考什么东西,其实很灵活。重要的是,你通过这个标签可以为大模型打开一个思考的空间,让它可以思而后行。
这段提示词中让 Claude 思考了三件事,我觉得第二件事比较有意思。Artifact 本质上是 Claude 的一个工具(或者叫功能/能力),要让 Claude 能熟练地“使用”这个工具就需要利用大模型的 tool use(或者叫 function calling)能力,而大模型的 tool use 能力普遍是很差的,现在也没好到哪里去。“Consider if the content would work just fine without an artifact” 这句提示词的作用就是让 Claude 在调用 Artifact 功能之前,先思考一下有没有这个必要,以减少 false positive 情况发生的概率。
上面只是 think-before-acting 的一个应用案例,这个提示词技巧比你想象的更加通用。在上面这个示例中,<antThinking>
相当于 Artifact 这个功能的一个自适应接口(adaptive interface)。你可以在工作流的任何一个重要的 Action(Function calling、大步骤、小步骤)之前加入这样一个接口,去做一些智能适配工作。
让大模型在<thinking>
标签里思考什么,也是非常灵活的。假设你的任务是“do SOMETHING”,你甚至可以让大模型在 <thinking>
标签里就思考“how to do SOMETHING”。<thinking>
标签还可以配合 “think step by step” 一起使用,用来规范大模型如何思考。当然,也可以配合其他的思维策略一起使用。Just try it,会有惊喜。
激发出大模型的最佳表现
Amanda Askell 是 Anthropic 的 AI 研究员,负责“调教“ Claude 个性和价值观。据说她可能是 Anthropic 内部跟 Claude 聊得最多的人类。
Amanda 在与 Lex Fridman 的访谈中说道[7],一般情况下你只需要跟大模型正常交流就可以了,“只有当你真正想要榨取出模型性能的最后 2% 的潜力时,提示词工程才变得特别重要”。但我觉得,在用大模型很好地完成日常任务与激发出大模型的最佳表现之间,好像还有一个让人很难受的障碍需要跨越。
我有一种很深切的感受:大语言模型似乎有一股很强的奔向平庸的势能,就像重力会将所有河流引向地心一样。尤其是你在让大模型完成一些创造性任务的时候,你会有很明显的感受。比如 Amanda 提到,如果你让 Claude 写一首关于“太阳”的诗,Claude 生成的内容可能乍一看感觉都还不错,但大概率你得到的就是一个平均水准的(average)东西。我有类似的体验,所以非常能共鸣这一点。
大语言模型的这种趋向平均的特性似乎是与生俱来的局限,这是由它的自监督和自回归的学习机制导致的:一个 token 与另一个 token 共现的频率就是最具引导性的 KPI,那些容易“造成不和的”(divisive)token 难逃被平均化的命运。你需要通过各种提示词手段,去鼓励大模型发挥创造性,“让它们摆脱那种标准的、即时的反应(这种反应可能只是大多数人认为还不错的想法的集合)”。所有创造性的工作都有这个特质,“如果你创作的作品只是为了让尽可能多的人喜欢,可能就不会有太多真正热爱它的人”。
从一个”平庸的初始版本”开始,尝试改进到“偶有惊艳的表现”的版本,然后继续迭代,期望它最终能到达一个“能持续稳定地给我惊喜”的状态,要完成这种从平凡(vanilla)到不平凡(non-vanilla)的质变,绝对不是一件轻易的事。因为大模型天然具有趋向平庸的惯性,我甚至认为提示词编程的最大功用和目的就是要抵抗这股平庸之势。不过说抵抗可能不太准确,因为它很难抵抗。准确说,我们所能做的只是因势利导,想尽办法避开一个又一个均值化的深潭,同时期望能顺带在途中采撷一些逻辑之种、想象之花与创造之果。
挑战艰难的任务
在另一个访谈中[8],Anthropic 的工程师 David Hershey 的这段话也引起了我的共鸣。如果你想提升提示词编程技能,你应该去尝试“让模型做一些你认为它可能做不到的事情”。如果你只是想用大模型完成一些日常任务,比如写写邮件,其实不需要提示词编程。
当你让大模型去挑战“最难的事情”的时候,你肯定就需要想尽一切办法,做各种可能的实验,这时候也是你经验增长最快的时候。另外,即使你失败了,你也能学到很多关于模型如何工作的知识,你会比其他人更理解大模型。
如果你在摸索的过程中,能持续收获一些发现的喜悦和攻克难点的成就感,你就会获得心流,进入一种深度投入的(deeply engaged)状态。这种体验是你在用大模型完成简单任务的时候不可能获得的。
追求极致的清晰
Amanda 是学哲学的,她的哲学写作经验为她写提示词带来很大帮助。Amanda 讲到,写提示词和写哲学文章类似,都是要遵循同样的原则:追求极致的清晰(desire for extreme clarity)。你可以想象你的读者是一位受过教育的门外汉(educated layperson),TA 并不熟悉你要讲的话题,但 TA 也不是傻瓜,TA 有智力,有知识储备,而你要做的就是把你脑袋里的想法、那些复杂的概念,以极致清晰的方式传递给读者。无论这个“读者”是人还是大模型,这条经验都同样适用。
为什么要追求极致的清晰?道理很容易理解,因为写提示词实际上就是在跟大模型交流,所以把意思传达清楚是第一要义。
虽然交流看似只是一个外化的过程,但要清晰地表达,前提是表达者要有清晰的内在思考。要让大模型理解你的意图,首先你自己要明确你想要什么。当你理清了自己的想法,任务就已经完成了一半。
压缩还不够,还需要展开
AI 领域有一个说法:压缩即智能。
的确,压缩是智能的一个核心特征。对于人类智能来讲,压缩是发生在经验内化以及内在思考的过程中。如前文所述,清晰的表达依赖于清晰的内在思考。清晰的内在思考会表现出压缩的特性,比如更精准的概念使用。但是要注意,这些内在思考都是属于你个人的,别人不知道你想了什么,大模型更不知道你想了什么。
前文也讲过,编写提示词实际上是一个跟大模型交流的过程。在你跟人的交流过程中,对方可以通过内在思考来理解你所说的内容,这个过程可以看作是一个意义展开的过程。
但是,大模型没有内在思考,你必须让它输出 token 才能模拟人的内在思考。在 Anthropic 的官方提示词教程中[3]清楚地写着这样一条提示:“始终让 Claude 输出它的思考过程。如果不输出思考过程,就等于没有思考!”
从这个视角看,第一部分讲到的“think step by step”、“think-before-action”这些提示词技巧,都是在引导大模型做展开。你可以让大模型自主展开,也可以控制它的展开过程。重要的是要展开,要显式地展开,要高质量地展开。
提示词编程是工程?是艺术?是巫术?
一个计算过程确实很像一种神灵的巫术,它看不见也摸不到,根本就不是由物质组成的。然而它却又是非常真实的,可以完成某些智力性的工作。它可以回答提问,可以通过在银行里支付现金或者在工厂里操纵机器人等等方式影响这个世界。我们用于指挥这种过程的程序就像是巫师的咒语,它们是用一些诡秘而深奥的程序设计语言,通过符号表达式的形式精心编排而成,它们描述了我们希望相应的计算过程去完成的工作。
——计算机程序的构造和解释(第2版)
SICP[9] 的作者把计算机程序比喻成“巫师的咒语”(sorcerer’s spells),这些咒语是由“诡秘而深奥”的编程语言(programming languages)编排而成。巫师通过这些咒语可以唤起寄宿在计算机内的灵能(spirit)——计算过程(computational process),从而利用这种灵能去完成一些智力性的工作或者影响改造这个世界。我们知道这是一种比喻修辞。实际上计算机程序没那么神秘,理论上它的构造和执行过程是完全可解释的。
或许“巫师的咒语”用来比喻提示词更合适?因为大语言模型内部的计算过程神秘而充满未知,而且我们不知道它还有哪些潜在的灵能可以被激发出来。虽然目前在与大语言模型相关的所有领域中,从底层模型到上层应用,我们都还处于一个经验大于科学、实践大于理论的状态,但是我不想把提示词编程这件事给过分神秘化了。
提示词编程使用的并不是另外一种神秘难懂的语言,它就是我们人类言说所使用的语言。它是可见、可听、可感的,它可以被记录、被阅读、被编辑。从出生起,只要我们还活着,还在思考,我们就一直不停地在跟它打交道,我们富于经验。它很普通,完全不神秘,但比任何咒语都强大。
我也不想把提示词编程这件事完全理解成是一种工程技术。即使是最传统的编程活动,也有其艺术性的部分存在。大模型充满未知,我们需要一些更加有想象力的思维方式和不一样的实验风格去探索它的潜力。
如果把提示词编程看作一种艺术,它应该是语言的艺术。按照最朴素的方式理解,大语言模型即“大”、“语言”、“模型”,它是人类利用计算机程序对人类语言现象建立起的一个模型。大语言模型最强大的地方就在于它对人类语言的驾驭,它对语言具有超高的敏感性。
语言在提示词编程中起到了什么作用?语言对于大模型与对人类有一个共同的关键作用,按照维特根斯坦的说法,语言符号相当于路标,指引着大语言模型不要在关键路口转错弯儿。又或者如陈嘉映老师所言,语言作为一种道路系统,同时支持着也规范着语义的传输和流动。
提示词编程会不会被干掉?
经常碰到朋友会有这样的疑问:等模型足够强大了,提示词编程会不会被干掉?类似的问题还有:“等模型足够强大了,Workflow 会不会被干掉“、”等模型足够强大了,Agent 会不会被干掉”等等。
刚开始听到这类问题我还会想一想。现在慢慢意识到了,我好像哪里做得不太对:我为什么要浪费时间去考虑这些完全没有意义的问题?
从某种意义上讲,大语言模型的诞生相当于计算机又重新被发明出来。Anthropic CEO 的这句话送给大家:
参考资料
[1]提示词工程指南: https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/overview
[2]使用例子: https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/multishot-prompting
[3]让模型思考: https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/chain-of-thought
[4]设定系统角色: https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/system-prompts
[5]如何在提示词里控制任务流程: https://xiaobot.net/post/db068c8a-d3be-4152-95d0-2497d0065c0c
[6]Claude 的系统提示词: https://gist.github.com/dedlim/6bf6d81f77c19e20cd40594aa09e3ecd
[7]Amanda 在与 Lex Fridman 的访谈中说道: https://www.youtube.com/watch?v=ugvHCXCOmm4
[8]在另一个访谈中: https://www.youtube.com/watch?v=T9aRN5JkmL8
[9]SICP: https://book.douban.com/subject/1148282/
本文来自微信公众号:Mindstorms,作者:艾木三号