引用自:Prompt Engineering Guide
背景 提示工程(Prompt Engineering)是一门较新的学科,关注提示词开发和优化,帮助用户将大语言模型(Large Language Model, LLM)用于各场景和研究领域。
提示工程不仅仅是关于设计和研发提示词。它包含了与大语言模型交互和研发的各种技能和技术。
例如:在一些应用场景中,具备特定领域的知识(如编程、医学、法律等)可以帮助设计更有效的提示和任务
模型参数 使用提示词时,我们通常会通过 API 或直接与大语言模型进行交互,而它支持配置多种参数以获得不同的提示结果。
OpenAI投喂的语料中涉及到了markdown文档,使用md格式文本进行投喂训练效果可能很好!
调整这些设置对于提高响应的可靠性非常重要,可能需要进行一些实验才能找出适合您的用例的正确设置。
实验可以包括多种形式,例如在 Playground 中直接输入不同的提示词、调整参数,观察模型生成的响应;或者模型在与用户的交互中逐步优化提示。
以下是使用不同LLM提供程序时会遇到的常见设置:
Temperature :简单来说,temperature
的参数值越小,模型就会返回越确定的一个结果。如果调高该参数值,大语言模型可能会返回更随机的结果,也就是说这可能会带来更多样化或更具创造性的产出。(调小temperature
)实质上,你是在增加其他可能的 token 的权重。在实际应用方面,对于质量保障(QA)等任务,我们可以设置更低的 temperature
值,以促使模型基于事实返回更真实和简洁的结果。 对于诗歌生成或其他创造性任务,适度地调高 temperature
参数值可能会更好。
Top_p :同样,使用 top_p
(与 temperature
一起称为核采样(nucleus sampling)的技术),可以用来控制模型返回结果的确定性。如果你需要准确和事实的答案,就把参数值调低。如果你在寻找更多样化的响应,可以将其值调高点。
使用Top P意味着只有词元集合(tokens)中包含top_p
概率质量的才会被考虑用于响应,因此较低的top_p
值会选择最有信心的响应。这意味着较高的top_p
值将使模型考虑更多可能的词语,包括不太可能的词语,从而导致更多样化的输出。
一般建议是改变Temperature
和Top P
其中一个参数就行,不用两个都调整。
Max Length :可以通过调整 max length
来控制大模型生成的 token 数。指定 Max Length 有助于防止大模型生成冗长或不相关的响应并控制成本。
Stop Sequences :stop sequence
是一个字符串,可以阻止模型生成 token,指定 stop sequences
是控制大模型响应长度和结构的另一种方法。例如,您可以通过添加 “11” 作为 stop sequence
来告诉模型生成不超过 10 个项的列表。
Frequency Penalty :frequency penalty
是对下一个生成的 token 进行惩罚,这个惩罚和 token 在响应和提示中已出现的次数成比例, frequency penalty
越高,某个词再次出现的可能性就越小,这个设置通过给 重复数量多的 Token 设置更高的惩罚来减少响应中单词的重复。
Presence Penalty :presence penalty
也是对重复的 token 施加惩罚,但与 frequency penalty
不同的是,惩罚对于所有重复 token 都是相同的。出现两次的 token 和出现 10 次的 token 会受到相同的惩罚。 此设置可防止模型在响应中过于频繁地生成重复的词。 如果您希望模型生成多样化或创造性的文本,您可以设置更高的 presence penalty
,如果您希望模型生成更专注的内容,您可以设置更低的 presence penalty
。
与 temperature
和 top_p
一样,一般建议是改变 frequency penalty
和 presence penalty
其中一个参数就行,不要同时调整两个。
ChatGPT模型的文本生成实践 当使用 OpenAI 的 gpt-4
或者 gpt-3.5-turbo
等聊天模型时,你可以使用三个不同的角色来构建 prompt: system
、user
和 assistant
。他们共同构建了一个对话的意图与身份,表名了聊天机器人在其中的背景、语气风格以及响应。
不过从o1-2024-12-17
开始,o1模型支持developer
消息而不是system
消息,详见https://cdn.openai.com/spec/model-spec-2024-05-08.html#follow-the-chain-of-command
也可以参考阿里云的提示词实践
多轮对话 这个示例实践中,使用一系列聊天消息作为输入,并使用这些消息生成响应。
输入:
1 2 3 4 系统:你是一个AI研究助手。你使用技术和科学的语气。 用户:你好,你是谁? 助手:问候!我是AI研究助手。我今天能帮你什么忙吗? 用户:你能告诉我黑洞的形成吗?
输出:
1 助手:当一个巨大的恒星耗尽燃料并在自身的引力下坍塌时,就会形成黑洞。这种坍塌使星体变得极其密集,具有极强的引力场,甚至连光都无法逃脱。这个无法逆转的点被称为事件视界。一旦一颗恒星穿过事件视界,它就被认为是一个黑洞...
如图:
代码为:
1 2 3 4 5 6 7 8 9 10 11 import openai openai.ChatCompletion.create( model="gpt-3.5-turbo" , messages=[ {"role" : "system" , "content" : "You are an AI research assistant. You use a tone that is technical and scientific." }, {"role" : "user" , "content" : "Hello, who are you?" }, {"role" : "assistant" , "content" : "Greeting! I am an AI research assistant. How can I help you today?" }, {"role" : "user" , "content" : "Can you tell me about the creation of black holes?" } ] )
单轮任务 输入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 系统: 用户: 下面为demo参考代码,使用~~~标记开始和结束。请基于下面demo代码以及API文档示例,输出bound method(保留self)。如有多个示例请输出多个方法。 请勿输出示例代码中的class_name_demo、__init__、session_init_demo,以及__name__=='__main__' 部分,仅输出根据API文档自定义的函数。 确保保留的自定义函数中,入参arguments中包含self参数,并且不输出上述类函数。注意不要进行代码解释,仅生成代码块。 ~~~ class class_name_demo(): def __init__(self, assets): self.host = assets['host' ] self.port = assets['port' ] self.apikey = assets['apikey' ] self.username = username self.password = password self.session = self.session_init_demo(self.api_key) @staticmethod def session_init_demo(api_key): session = requests.session() session.verify = False session.headers['User-Agent' ] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36' session.headers['custom_authorization' ] = ... return session def custom_action_demo(self, ...): url = f"self.host/v1/..." data = ... try: self.session.method(url=url, data=data) return ... except Exception as e: raise Exception(...) ~~~
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 助手:def send_task (self, task_type, params ): url = f"{self.host} :{self.port} /api/edr/v3/task?token={self.apikey} " data = { "type" : task_type, "params" : params } try : response = self.session.post(url, json=data) return response.json() except Exception as e: raise Exception(f"Failed to send task: {str (e)} " )def query_task_state (self, task_type, params ): url = f"{self.host} :{self.port} /api/edr/v3/task/taskstate?_method=GET&token={self.apikey} " data = { "type" : task_type, "params" : params } try : response = self.session.post(url, json=data) return response.json() except Exception as e: raise Exception(f"Failed to query task state: {str (e)} " )def query_task_result (self, task_type, params ): url = f"{self.host} :{self.port} /api/edr/v3/task/taskresult?_method=GET&token={self.apikey} " data = { "type" : task_type, "params" : params } try : response = self.session.post(url, json=data) return response.json() except Exception as e: raise Exception(f"Failed to query task result: {str (e)} " )def cancel_task (self, task_type, task_ids, uuid=None ): url = f"{self.host} :{self.port} /api/edr/v3/task?_method=DELETE&token={self.apikey} " data = { "type" : task_type, "taskId" : task_ids } if uuid: data["uuid" ] = uuid try : response = self.session.post(url, json=data) return response.json() except Exception as e: raise Exception(f"Failed to cancel task: {str (e)} " )
对话中实践 如果你平时经常使用国内各镜像站提供的GPT-3.5对话站点,你可以针对自己的需求在对话中添加属于本次自己的prompt,以及控制对话时是否继承上下文(开启时 国内大部分镜像站框架提供的对话继承,通常只会继承上一轮的对话 ) ,为避免自己输入简短内容如make([]T)
时被大模型误解,或者输出为你不希望的语言,你可以添加属于本轮对话的system。
例如你正在学习golang 相关的知识点,并且希望参考你之前的技能经验进行输出,你可以这样设计提示词:
1 2 3 4 5 6 7 你是一个GO语言助手,你可以根据输入的信息给出相应的简要解释。# 背景 面向正在初学go语言的初学者,且具有python开发能力、javascript开发能力、typescript开发能力的用户进行阐述和解释,使得他们可以更好的学习go语言。# 风格 使用中文,必要时列举python中的例子。# 输出 用户询问函数使用时只输出简要用法,不要输出较长代码块的示例。
这样就可以使得你在输出简短英文短句时,避免AI输出英文或者其他语言的代码,使得可以达成期望效果。