随着ChatGPT等大模型的兴起,提示工程(Prompt Engineering)作为与大模型伴生兴起的一门较新的学科,也受到了广大开发者的关注。熟练掌握大模型提示词的开发和优化,可以帮助用户更好的发挥大语言模型(Large Language Model, LLM)的能力并提升处理复杂任务场景的能力,例如问答和算术推理能力。开发人员可通过提示工程设计、研发强大的工程技术,实现和大语言模型或其他生态工具的高效接轨。
接下来我们将介绍一些时下最常用的提示词技术以及优化技巧(以下示例都是基于ChatGPT-3.5-turbo模型给出)。
1、提示词技术
(1)、Zero-shot prompt
零样本提示:最基本的提示方式,通过详尽的语言描述,表达希望模型返回的内容。
(2)、few-shot prompt
少量样本提示:将难以用语言描述的需求,通过样本的方式表达给模型。从而使输出结果包含更多的额外知识,输出的结果样式更加规范。
(3)、CoT prompt
思维链提示:针对复杂问题,按照人类思考的习惯顺序,将复杂问题简化为多个简单子问题,从而让模型逐一进行推理,并做终给出正确答案。
零样本提示示例:
思维链提示示例:
(4)、Zero-shot-CoT prompt
零样本思维连提示:其核心原理同样是将复杂问题拆分,不同之处在于,拆分过程交给模型自己完成。 零样本思维连提示的关键提示词是:Let's think step by step (让我们逐步思考),好的零样本思维链提示词可以达到思维链提示的效果,同时避免了提示词的设计难度。
(5)、Knowledge-Generation prompt
知识生成式提示:将回答问题所需的背景知识放在问题的上下文中,让模型可以基于上下文信息给出答案。
提示词:
你是一个SQL数据专家,现在有两张数据表:
表1:
CREATE
TABLE dev.table_1_tmp
(
product_key string COMMENT '产品词',
attribute string COMMENT '属性词',
attribute_type string COMMENT '属性类型'
)
COMMENT '表1临时数据' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFile;
表2:
CREATE
TABLE dev.table_2_tmp
(
key_word string COMMENT 'query词',
pv_count bigint COMMENT 'pv统计',
sku_count bigint COMMENT '商品统计'
)
COMMENT '表2临时数据' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFile;
现在需要将两个表进行join操作,连接条件为 key_word 字段必须同时包含product_key字段和attribute字段,
请给出sql,并保障sql可以正常执行。
ChatGPT返回结果:
SELECT
*
FROM
dev.table_2_tmp AS log
JOIN dev.table_1_tmp AS info
ON
log.key_word LIKE CONCAT('%', info.product_key, '%')
AND log.key_word LIKE CONCAT('%', info.attribute, '%')
(6)、RAG
检索增强生成:赋予 ChatGPT 访问互联网、在知识库检索背景知识的能力。
直接询问大模型:
llm = OpenAI(temperature=0)
search = GoogleSerperAPIWrapper()
tools = [
Tool(
name="Intermediate Answer",
func=search.run,
description="useful for when you need to ask with search",
)
]
self_ask_with_search = initialize_agent(
tools, llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True
)
result = self_ask_with_search.run(
"北京今天天气怎么样"
)
使用langchain RAG组件提问:
(7)、embedding 提示优化
在基于大模型构建知识库应用时,通常会利用大模型生成embedding,并基于embedding的相关性召回获得与问题相关的文本信息。合理的设计 embedding ,同样可以提高大模型的理解能力,提高召回结果的效果。例如我们构建相似短语的召回: 示例emb prompt如下:
牛仔裙 国风
召回结果如下:
[{'attribute_info': '牛仔裙 国潮风', 'score': 0.9440432190895081}, {'attribute_info': '牛仔裙 可爱风','score': 0.9312511086463928}, {'attribute_info': '牛仔裙 港风', 'score': 0.9289109706878662}]
优化后的emb prompt:
可以体现国风特点牛仔裙的相似产品
召回结果如下:
[{'attribute_info': '牛仔裙 国潮风', 'score': 0.9227373003959656}, {'attribute_info': '牛仔裙 中国风', 'score': 0.921625554561615}, {'attribute_info': '牛仔裙 民族风', 'score': 0.9201935529708862}]
对比优化前后的召回结果,我们可以发现,合理的设计 emb prompt,可以提高大模型对于指令的理解和泛化能力。
2、技巧总结:
- 提供尽可能明确的指令
- 使用特殊符号进行提示词的区域划分
- 明确模型输出的格式
- 设定尽可能详细的约束条件
- 提供一些示例样本
- 以思维链的形式对复杂任务指令进行拆分
实际工程应用中发现,使用单一的提示方式,往往不能获得让我们满意的结果。因此通常情况下,工程上往往会把相对复杂的任务,进行拆分,并结合多种提示技术,生成最终的输出。为了更加便捷的构建大语言模型应用,langchain 框架。langchian的相关介绍详见Langchain入门指南