AI 工程中的语言艺术:Prompt Engineering

文摘   2024-09-03 10:47   浙江  

当今的人工智能领域,最热门的话题莫过于 LLM(大语言模型)和 Prompt Engineering(提示工程)的讨论。在以 GPT 为代表的 LLM 加持下,似乎人人都可以称为作家,画家,软件工程师...... 人们要做的事情也非常简单:打开聊天框,用简单朴素的自然语言告诉 LLM 你的要求,然后就可以等待它为你搞定一切。然而,在人们惊叹于 LLM 智慧的同时,LLM 在大型工程中却表现得并不那么“聪明”,以至于产生了一个新兴职业——Prompt Engineer,来专门研究工程领域中的 Prompt 使用。


本文将以 GPT 作为代表模型,向读者深入浅出地介绍工程中的 Prompt Engineering。


01

工程中的 Prompt Engineering



不同于个人级 LLM 应用的简单 Prompt,在企业级 LLM 应用工程中,Prompt 往往是规模巨大且逻辑复杂的,以至于 LLM 在执行 Prompt 的具体要求时,经常出现满足规律1却忽略了规则2这种顾此失彼的现象。另外,性能和开销也是大型 LLM 工程中必须要考虑的因素。


在 NLP 领域,token 是文本拆解的最小单位,可以是一个词、一部分词甚至是一个标点。OpenAI 也是以 token 为基础单位进行输入输出和收费的。常见 GPT 模型的最大 token 限制及计费标准如下表所示:



另外,GPT 输出的 token 数也会直接影响到产品性能。以 gpt-4 模型为例,每一个输出 token 会占用约80ms。


综上所述,一方面,大型工程的复杂性决定了它的 Prompt 规模;另一方面,处于对准确率、性能以及成本的考虑,Prompt 又必须是精简而有效的,这个是摆在每一个 AI 工程师面前的问题。


02

Function Call:自定义 LLM 外部调用



Function Call 是最先由 OpenAI 提出的概念,其本质是由开发者自定义函数,并且向 LLM 规定调用该函数的情景。LLM 检测用户的输入,当用户输入符合开发者预定义情景时,调用开发者自定义的函数。在工程中使用 Function Call 可以减少 LLM 输出格式的随机性,提高 AI 工程的可信度


下面以一个简单的示例,说明 Function Call 的使用。


#你需要实现一个电影语音订票系统

对于用户输入:请帮我预定两张10月1日下午3点的《泰坦尼克号》电影票。


开发者希望 LLM 给出如下参数取值:

"date":"10/01/2024"“time”:"15:00:00""film":"泰坦尼克号""ticketNumber":2


可以通过规定如下函数来实现该功能:

func = {        "name": "bookTicket",        "description": "预订电影票",        "parameters": {            "type": "object",            "properties": {                "date": {                    "type": "string",                    "description": "预订日期,格式为MM/DD/YYYY"                },                "time": {                    "type": "string",                    "description": "预订时间,24小时制,格式为HH:MM:SS"                },                "film": {                    "type": "string",                    "description": "电影名称,取值范围["泰坦尼克号",“罗马假日”,“海上钢琴师”,“未匹配”],默认值“未匹配”"                },                "ticketNumber": {                    "type": "number",                    "description": "预订数量"                },            },            "required": ["date", "time",“film”,“ticketNumber”]        }    }

以上定义在函数的 description 中规定了 bookTicket 函数的调用场景,在每个参数的域中规定了参数类型以及参数取值范围,开发者可以在 bookTicket 函数中实现电影票预定和异常处理。类似的,可以实现电影票取消,电影票改签等功能。当 LLM 检测到用户输入匹配某个函数的 description 时,会调用开发者提供的相应函数来实现电影票预定/取消/改签功能。


03

LLM 的取舍:无招胜有招



在一些情况下,开发者会陷入对于 LLM 的过度依赖。由于 LLM 的不确定性,以及有限的理解能力,在大规模 AI 工程中,LLM 有时候对于复杂指令的理解并不理想,甚至于产生一些超出开发者本意的输出


仍然以上述电影票预定系统为例:


#假如你希望针对《泰坦尼克号》电影新增一个参数 price,当用户问题中提到座位位置时,按照不同座位由 LLM 生成不同的单张电影票价格。


于是,你在 price 的描述中增加了以下的例子用来解释 price 的取值:

当film取值为“泰坦尼克号”时:当用户要求前排座位时,price为50当用户要求中间座位时,price为70当用户要求后排座位时,price为60当用户没有座位要求时,默认price为60当film取值为其他时,默认price为50


上述 Prompt 示例的本意,是希望为《泰坦尼克号》电影实现一个随座位位置定制化的价格。这样的 Prompt 在小规模应用中或许是有效的,然而到大规模 Prompt 应用场景时,往往产生意想不到的输出,例如:在用户需要订《罗马假日》后排票时,输出 price=60。


对于上述案例,读者很容易想到,price 这个参数不是必须的,由于它可以通过座位位置和电影名称推导出来,因此上述参数设计存在很明显的不合理性。显然对于上述需求,直接引入一个座位位置的参数,由代码层面去实现 price 的计算,才是更合理的设计方案。


另外,当 price 的生成规则变得更为复杂,并且对于用户输入信息有更强依赖,无法通过代码来完成这个任务的时候,比起在主流程中加入大段的 Prompt 来描述仅针对“泰坦尼克号”生效的规则,也可以考虑在检测到 film 为“泰坦尼克号”时,新起一个 LLM 调用来针对性实现 price 的赋值。这样做的好处,一方面可以避免在主流程中插入大段 Prompt 导致 LLM 理解能力的下降,另一方面由于单独的 LLM 调用少了上下文无用信息的干扰,也可以提高 price 取值的准确率。


04

博学的幼子



在 Prompt Engineering 中,开发者往往对 GPT 的理解能力抱有非常大的期待,然而在一次又一次的实践中,我们应该要明白,GPT 更像一个拥有广泛知识背景,但理解能力尚处在幼年时期的智慧体。对于复杂的问题,如果 GPT 难以一次性理解,开发者在 Prompt 中除了规定问题本身,也需要引导 GPT 分步解决问题


#你所在的电影院因为你的优异表现,业务得到了新的扩张,准备加入基于 LLM 的线上影评系统。希望利用 GPT 根据用户的影评来向用户提供与用户输入同语言的100字以内的电影推荐功能,简单介绍电影和推荐理由。例如,针对对该电影持有好评的用户,推荐同系列或者相似题材的电影;对于持差评的用户,推荐不同题材的电影。在经过一段时间的测试之后,你发现推荐效果并不理想,对于同一部电影的不同倾向的用户,不能进行有效的区别性推荐。


这类问题往往时由于不清晰的 Prompt 指令造成的。上述任务事实是由多个子任务组成的:

  1. 用户影评判断用户对于某部电影的情感倾向

  2. 判断用户输入语言

  3. 基于用户对该电影的情感倾向和输入语言提供电影推荐

  4. 检查推荐内容是否在100字以内,如否,精简到100字以内

因此,在 Prompt 中,应该显示地说明上述解题步骤,要求 GPT 依次判断用户的情感倾向、用户输入语言、写电影推荐、检查字数。


如果上述分步规则依然让 GPT 产生困惑,有一种更为有效的方式:要求 GPT 显示地先输出用户的情感倾向、用户语言,然后再进行推荐,并输出字数检查的结果。实践表明,让 GPT 自己输出中间结果,能够在很大程度上提高 GPT 输出的准确度。


总结来说,由于经验的积累和人脑处理能力的强大,人往往习惯于将多个简单步骤合并成一个步骤去思考,这是一个非常影响 Prompt Engineering 输出效果的思维定式。作为一个开发者,需要尝试从 GPT 的角度去理解和分解问题,这一点非常重要。当你无论如何调整 Prompt 都无法得到想要的输出时,不放从一个幼儿园小朋友的角度去思考,或许会有一些收获。


Prompt Engineering 实践中还有非常多值得研究和探讨的问题,比如 GPT 在数学计算上的弱势问题,langchain 等工具的使用,Prompt 中的举例和副作用等等。由于 GPT 兴起并不久,很多问题的解决方案都还需要在实践中探索和积累。不同于传统程序员依靠代码保障产品质量,Prompt Engineer 意在通过简洁,逻辑性强,指令明确无歧义的 Prompt,来提高 LLM 输出的准确性,进而提高 AI 产品的质量。


微策略 商业智能
微策略 MicroStrategy (Nasdaq: MSTR) 是企业级分析和移动应用软件行业的佼佼者。关注我们了解行业资讯、技术干货和程序员日常。
 最新文章