当下,人工智能飞速发展,以 ChatGPT 为代表的大预言模型崭露头角后,诸如豆包、月之暗面、通义千问等生成式指令调优AI工具蓬勃发展。AI+各行各业成为了当下不可逆转的趋势,提示词工程(Prompt Engineering)成为了一项关键技能。本篇博客将介绍提示词工程的一些技巧,这些技巧不仅能帮助开发人员快速构建生成式AI应用,还可以帮助其他 AI 应用的使用者,撰写属于自己的提示词模板,调教出更符合自身需求的 AI 助理。
注:本博客主要总结了 DeepLearning AI 的公开课程内容,也可以理解为是该公开课程的笔记。如果你有足够的时间和条件,强烈建议直接访问文末的课程链接亲自学习,因为这样,你还可以在官网的 Jupyter Notebook 上一边听课,一边调试、实践。
0. 为什么要学习提示词工程?
不同于过去的基础大预言模型 Base LLM,当下的指令调优大语言模型 Instruction Tuned LLM,它更聪明,可以遵循用户的指令来进行预测,给出结果。如果你需要它给出一些方案,你可以告知已有的条件、决策方式、希望达成的目的等。如果你想要它撰写文章,除了主题、大纲以外,你还可以指定文字风格、篇幅,要求它阅读哪些参考文献等等。因此,学好提示词的使用,能够帮助我们和 AI 更好地共同完成任务。尤其是一些复杂的场景、要求比较多的任务,更需要我们组织有条理的提示词,来帮助 LLM 理解任务的含义。
学习了提示词工程以后,即使不用做编写基于 LLM 的 AI 软件,你也可以通过抽象出一系列的提示词模板,只需要更换部分词语内容,完成相似的任务,提升你的工作、学习效率。
指导原则 Guidelines
本章节将从最基础的指导原则开始,介绍如何清晰、有效地给 LLM 下达指令。
如果你已经搭建了调用 LLM 应用的环境,那么可以一边阅读一边实践。不同的 LLM 环境需求和接口调用不尽相同,因此,在这里就不给出具体的指令了,只需要参考你使用的 LLM 文档就好。 即使没有环境也没关系,可以去 DeepLearning AI 的官网上使用 Jupyter Notebook,那里已经帮你安装、配置好了环境,还为你准备了 OpenAI 的调用 key,方便你学习。
话不多说,我们开始吧!
首先,指导有两个原则:
- 编写清晰而具体的提示
- 给模型思考的时间
针对这两个原则,分别有对应的提示词技巧。
指导原则1:编写清晰而具体的提示
策略1:使用分隔符
我们可以使用分隔符,将我们想要输入的文本清晰地分割开来,比如下文,使用 ``` 我们想要 LLM 阅读、总结的文本括起来,给 LLM 更清晰的指令。这样,LLM不容易被你提供的大量文本混淆,即使你提供的文本是一段数学应用题目,它也会给出总结,而不是被误导,求解这道应用题的答案。
1 | text = f""" |
防止注入
同时,使用分隔符还可以避免用户注入,防止输入一些危险的、冲突的指令。这在信息安全中常常用到,比如防范SQL注入等。
分隔符的类型
分隔符可以有很多种,只要在提示词中明确指出即可,例如三重双引号”””、单引号’’’、XML<>标记等等。
策略2:结构化的输出
在开发软件的过程中,结构化的输出更有利于我们对返回的结果数据进行进一步的处理,例如以表格、数组、JSON等格式陈列,能够让我们直接输入到下一个函数方法中,又或者只需要复制粘贴就可以放到我们的 PPT 汇报中,而不需要再去整理数据格式。你可以在提示词中指定你想要的结果格式,例如 JSON,同时指定其中 key值的内容。
1 | prompt = f""" |
1 | # 生成结果如下 |
在这里,不得不承认,使用提示词的时候用英文会更合适,因为很多规范化的格式都是英文表达的,如果使用多语言混合的提示词,可能会增加 LLM 的理解成本,何况中文真的是一种非常容易产生歧义的语言。当然,使用国内的一些 LLM,这样的误解或许会少一些。
策略3:要求LLM检查是否满足条件
有时候,我们提供的文本不一定能满足我们希望 LLM 完成的任务条件。因此,可以要求 LLM 在执行任务前,检查是否满足条件,如果满足再执行,不满足的话就停止。这样做可以减少一些算力浪费,还可以避免一些边界情况、意外的错误等。
例如下方提供的两段输入,很显然,只有第一段文本包含了指令步骤,因此,在执行第二段时就会返回 No steps provided.
1 | text_1 = f""" |
策略4:少样本提示 few-shot prompt
如果我们想要 LLM 更精确地理解我们的用意,我们可以提供少量的示例,来告知它,我们期望的回复究竟是什么样的。比如我们想要指定某种风格的回复,就可以先提供一个样本,让 LLM 参考。
1 | prompt = f""" |
1 | <grandparent>: Resilience is like a tree that bends with the wind but never breaks. It is the ability to bounce back from adversity and keep moving forward, even when things get tough. Just like a tree that grows stronger with each storm it weathers, resilience is a quality that can be developed and strengthened over time. |
可以看到,回复也会像我们提供的示例那样,给出很多排比和比喻的内容。
指导原则2:给模型思考的时间
如果一个任务比较复杂、困难,或者需要的回复比较长,例如写一篇篇幅较长的文章,LLM 可能会为了及时响应你的请求,匆匆忙忙就给出结论。而这样匆忙之下得出的结论,往往不尽人意,很有可能是错误的,有失偏颇的。因此,对于一些 LLM 无法短时间内完成的任务,有一定困难的任务,我们可以显式地指示 LLM,花更长的时间进行思考,而不必急于响应。这一点和人类相似,通常来说,花更多的时间去思考,得到的结果总是会相对好一些。
策略1:指定任务的执行步骤
在完成一个复杂或庞大的任务时,我们第一时间想到的,就是任务拆解。对于 LLM,这一方法也同样奏效,我们可以尝试将一个复杂的任务,拆解成一小步、一小步的小任务,指示 LLM 逐步完成。例如下面提供的例子。其中prompt_1 没有要求结构化的输出,prompt_2则在任务拆解的基础上,要求了逐步的结构化输出。
1 | text = f""" |
1 | # Completion for prompt 1: |
虽然的确是逐步完成了我们的指令,但是输出不够结构化,与下方的输出对比,显然,下面的输出更让人一目了然,也更易于通过代码传递。
1 | # Completion for prompt 2: |
策略2:在得出结论前,指示 LLM 先自己寻找解决方案
给出一道应用题,同时给出一位学生的解题思路,LLM很可能就会顺着学生的思路去解决这个问题。就和我们大多数人一样,一不留神就会被隐蔽的、错误的想法带跑。为了保证结果的正确性,我们可以指示 LLM 先判断给出的方法是否正确,如果不正确,则先制定自己的解决方案,然后再对问题进行求解。
例如下面提供的例子。这个例子场景就比较复杂了,因此在提示词中充分应用了分隔符,防止 LLM 误解。
1 | prompt = f""" |
使用数学应用题或许会让你觉得不太实用,怎么会有人提供一个错误的方法,然后又让 LLM 判断,再请它制定一个正确的解决方案呢?但是,其实这个场景在我们的生活中非常常见。例如,编程过程中,你可以告诉它你正在实现的算法或是函数功能,并在 student solution 中提供自己的代码,请求 LLM 对你的代码进行 review。review 的方向也不一定是功能的正确性,还可以让它指点代码的可拓展性、可读性、性能优化等方面。如果是GPT-4的话,不仅代码正确率高,而且还能够提供详细的解析,是一个非常好的 coding pair搭档。
减少 LLM 的幻觉/欺骗
常使用 AI 的各位都知道,AI 常常骗人。比如让它提供某个领域的综述,它会提供一些看上去很逼真但是实际上根本不存在的内容。为了避免这一点,我们可以要求 LLM 在提供内容时,同时提供它的参考出处,这样,即使它想编造参考文献,我们也很容易验证是不是被欺骗了。或者,我们可以在对话过程中,就提供已经经过我们自身确认的文本资料、参考链接等,确保 LLM 不会自己胡编乱造。
Prompt Engineering 提示词工程笔记汇总
- 第一、二章:编写指示的几个指导原则
- 第三章:迭代 Iterative
- 第四章:摘要 Summarizing
- 第五章:推理 Inferring
- 第六章:转化 Transferring
- 第七章:扩充 Expanding
- 第八章:聊天机器人 ChatBot
参考资料
ChatGPT Prompt Engineering for Developers - DeepLearning.AI
B站可以找到搬运翻译的中文版本👆:《吴恩达 x OpenAI Prompt课程》
- 本文作者: Berry
- 本文链接: https://wuxinberry.github.io/2025/01/19/Prompt-tips/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!