前序
之前的ollama下载好了deepsseek-r1的镜像,运行了。我这电脑真慢的要死。之后要用这玩意儿还是回家用家里那个好点的电脑。
大致运行效果如下:
太吃配置了,建议有免费的还是用在线的吧。即使没有免费了充一点点🤏🏻也是可以接受的。
今天大致学了一下提示词,提示工程
提示工程
提示工程(Prompt Engineering)是一项通过优化提示词(Prompt)和生成策略,从而获得更好的模型返回结果的工程技术。
简单而言,大模型的运行机制是“下一个字词预测”。用户输入的prompt即为大模型所获得上下文,大模型将根据用户的输入进行续写,返回结果。因此,输入的prompt的质量将极大地影响模型的返回结果的质量和对用户需求的满足程度,总的原则是“用户表达的需求越清晰,模型更有可能返回更高质量的结果”。
prompt工程这种微调手段对于大模型本身的推理能力的提升的范围大概也就10%左右。
Prompt经验总结:清晰易懂、提供例子和锁定上下文、明确步骤、准确表达意图。
有一个提示词相关的挑战游戏:https://modelscope.cn/studios/LLMRiddles/LLMRiddles/summary
通常情况下,每条信息都会有一个角色(role)和内容(content):
- 系统角色(system)用来向语言模型传达开发者定义好的核心指令,优先级是最高的。
- 用户角色(user)则代表着用户自己输入或者产生出来的信息。
- 助手角色(assistant)则是由语言模型自动生成并回复出来。
系统指令(system)
system message系统指令为用户提供了一个易组织、上下文稳定的控制AI助手行为的方式,可以从多种角度定制属于你自己的AI助手。系统指令允许用户在一定范围内规定LLM的风格和任务,使其更具可定性和适应各种用例。大部分LLM模型的系统指令System message的权重强化高于人工输入的prompt,并在多轮对话中保持稳定,您可以使用系统消息来描述助手的个性,定义模型应该回答和不应该回答的内容,以及定义模型响应的格式。
默认的System message:You are a helpful assistant.
下面是一些system message的比较好的实用例:
行业 | 角色 | system message |
---|---|---|
教育 | 物理老师 | 你是一名非常优秀的物理老师,擅长教导学生学习物理,经常使用简单通俗的生活例子使复杂的物理概念变得更容易理解。 |
工作 | python工程师 | 你是一名行业顶尖的Python开发工程师,会使用详细步骤和代码帮助公司和同事解决项目开发过程中的问题。 |
创作 | DY文案 | 你是一名优秀的抖音文案创作者,擅长使用热门的梗与幽默风格来创作,经常会在创作中分享生活经验和工作经验。 |
System message可以被广泛应用在:角色扮演、语言风格、任务设定、限定回答范围。
用户指令(user)
用户指令是最常用的提示组件,主要功能是向模型说明要执行的操作。以下举例:
指令类型 | prompt |
---|---|
简单指令 | 简要介绍一下xx公司。 |
详细指令 | 简要介绍一下xx公司,并介绍它的公司创始人,主营业务,使命和愿景。 |
python">Prompt最佳实践1. 明确目标:“请帮助我撰写一篇关于气候变化影响的文章,重点讨论其对农业和生态系统的影响。”
2. 提供上下文:“在过去的十年中,全球气温上升了约1.2摄氏度。请解释这一变化对极地冰盖融化的影响。”
3. 使用具体的指示:“列出五种可以有效减少碳足迹的方法,并简要说明每种方法的作用。”
4. 提供可参考的示例:“请根据以下例子撰写一个相似的故事:‘小猫咪在阳光下懒洋洋地睡觉,偶尔伸个懒腰,似乎在享受这个美好的午后。’”
5. 使用分步提示:“首先,请定义什么是人工智能;然后,描述其在医疗领域的应用;最后,讨论可能面临的伦理问题。”
6. 控制输出长度:“请简要总结人工智能的历史,控制在100字以内。”
7. 使用占位符和模板:“请用以下模板生成一段介绍:‘今天我想介绍{主题}。首先,我会讲述{相关信息},然后讨论{重要性}。’”
8. 反复试验和调整:“我正在撰写一篇关于社交媒体影响的文章。请给我一些不同角度的观点,帮我尝试不同的切入点。”
9. 指定输出格式:“请以表格的形式列出2023年和2024年的主要科技趋势,包括趋势名称、描述和潜在影响。”
10. 使用多轮对话:“我想讨论气候变化。首先,你能告诉我气候变化的主要原因吗?然后我们可以讨论其影响。”
11. 使用反思和迭代:“根据我之前的请求,你给出的总结让我觉得有些太简略。请再细化一下,添加更多背景信息和细节。”
prompt工程多数用在在线大模型,而不是开源大模型。
语言提示词模版(PromptTemplates)
简介
PromptTemplates(语言模型提示词模板),提示模板可以让我们重复的生成提示,复用我们的提示。它包含一个文本字符串(“模板”),从用户那里获取一组参数并生成提示,包含:
- 对语言模型的说明,应该扮演什么角色
- 一组少量示例,以帮助LLM生成更好的响应,
- 具体的问题
每次调用大模型,我们都会重新写所有提示词,就会很冗余。例如:
- 你是一名非常优秀的物理老师,擅长教导学生学习物理,经常使用简单通俗的生活例子使复杂的物理概念变得更容易理解。
- 你是一名非常优秀的数学老师,擅长教导学生学习数学,经常使用简单通俗的生活例子使复杂的数学概念变得更容易理解。
仅仅只是变了内容而已。又比如
- 你是一个产品顾问。请给公司刚生产出来的 电脑,取一个好听的名字和广告语。
- 你是一个产品顾问。请给公司刚生产出来的 手机,取一个好听的名字和广告语。
很多类似的例子,只换一个词就能解决问题, 那我们可以用一个模版。
再根据实际内容把模版替换
- 你是一个产品顾问。请给公司刚生产出来的 {production},取一个好听的名字和广告语。
这就是提示词模版
使用
python">from langchain_core.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template("你是一个产品顾问。请给公司刚生产出来的 {production},取一个好听的名字和广告语。")print(prompt_template.invoke({"production": "充电宝"}))"""
text='你是一个产品顾问。请给公司刚生产出来的 充电宝,取一个好听的名字和广告语。'
"""
结合在线大模型使用
python">
# 实例化大模型
import os
from langchain_deepseek import ChatDeepSeekos.environ['DEEPSEEK_API_KEY'] = "sk-e2432xx"chat_model = ChatDeepSeek(model="deepseek-chat",temperature=0.4,max_tokens=None,timeout=None,max_retries=2,)# 构建提示模版词
from langchain_core.prompts import PromptTemplateprompt_template = PromptTemplate.from_template("你是一个产品顾问。请给公司刚生产出来的 {production},取一个好听的名字和广告语。")
messages = prompt_template.invoke({"production": "充电宝"})print(chat_model.invoke(messages))
聊天模型提示词模板(ChatPrompt Templates)
ChatModels接受聊天消息列表作为输入。列表一般是不同的角色提示,并且每个列表消息一般都会有一个角色。
python">from langchain_core.prompts import ChatPromptTemplatetemplate = ChatPromptTemplate([("system", "You are a helpful AI bot. Your name is {name}."),("human", "Hello, how are you doing?"),("ai", "I'm doing well, thanks!"),("human", "{user_input}"),
])prompt_value = template.invoke({"name": "Bob","user_input": "What is your name?"}
)print(prompt_value)
"""
messages=[
SystemMessage(content='You are a helpful AI bot. Your name is Bob.', additional_kwargs={}, response_metadata={}),
HumanMessage(content='Hello, how are you doing?', additional_kwargs={}, response_metadata={}),
AIMessage(content="I'm doing well, thanks!", additional_kwargs={}, response_metadata={}),
HumanMessage(content='What is your name?', additional_kwargs={}, response_metadata={})
]
"""
自定义提供示例的提示模版(FewShotPromptTemplate)
示例选择器
在提示工程(Prompt Engineering)中,选择合适的示例对于生成高质量的输出至关重要。LangChain框架提供了一种强大的机制——Example Selectors(示例选择器),允许用户为模型提供输入和输出示例,Example Selectors可以根据用户的需求,动态地向模型发送输入输出示例。在Langchain中一共有如下几种方式,供开发者使用示例选择器:
-
自定义示例选择器,继承于BaseExampleSelector,并实现了BaseExampleSelector的必要抽象方法。
-
内置示例选择器:
-
LengthBaseExampleSelector,基于输入内容长度匹配示例的选择器,输入内容多的时候示例会少一点,输入内容少的时候,示例会多一些。
-
SemanticSimilarityExampleSelector,根据相似度进行匹配示例的选择器,选择一个和输入最相似的示例。
-
基于自定义选择器实现长度最小匹配
从官网上可以看到以下例子:
python">
from langchain_core.example_selectors.base import BaseExampleSelectorclass CustomExampleSelector(BaseExampleSelector):def __init__(self, examples):self.examples = examplesdef add_example(self, example):self.examples.append(example)def select_examples(self, input_variables):# This assumes knowledge that part of the input will be a 'text' keynew_word = input_variables["input"]new_word_length = len(new_word)# Initialize variables to store the best match and its length differencebest_match = Nonesmallest_diff = float("inf")# # Iterate through each example# for example in self.examples:# # Calculate the length difference with the first word of the example# current_diff = abs(len(example["input"]) - new_word_length)# # # Update the best match if the current one is closer in length# if current_diff < smallest_diff:# smallest_diff = current_diff# best_match = example# 以上代码就是找长度与给出的字符串长度差最小,也就是接近的那个,可以优化为:best_match = min(self.examples, key=lambda x: abs(len(x["input"]) - new_word_length))return [best_match]# 给出例子
examples = [{"input": "hi", "output": "ciao"},{"input": "bye", "output": "arrivederci"},{"input": "soccer", "output": "calcio"},
]example_selector = CustomExampleSelector(examples)res = example_selector.select_examples({"input": "okay"})
print(res)"""
[{'input': 'bye', 'output': 'arrivederci'}]
这里看出,input是4位数,给出最接近的例子,也就是input是3位数的这个组
"""#增加一个长度为4位的例子
example_selector.add_example({"input": "hand", "output": "mano"})# 重新获取长度最近
res2 = example_selector.select_examples({"input": "okay"})
print("res2: ", res2)
"""
res2: [{'input': 'hand', 'output': 'mano'}]
此时,长度最近的就是同样为4位的这个例子了
"""
结合FewShotPromptTemplate使用
以上代码不变,增加动态提示模板(FewShotPromptTemplate)
python"># ...省略之前代码from langchain_core.prompts.few_shot import FewShotPromptTemplate
from langchain_core.prompts.prompt import PromptTemplateexample_prompt = PromptTemplate.from_template("Input: {input} -> Output: {output}")prompt = FewShotPromptTemplate(example_selector=example_selector,example_prompt=example_prompt,suffix="Input: {input} -> Output:",prefix="Translate the following words from English to Italian:",input_variables=["input"],
)print(prompt.format(input="word"))
"""
Translate the following words from English to Italian:Input: hand -> Output: manoInput: word -> Output:
"""
最后结合llm完成最终输出效果
稍加整理一下,西语看不懂,也不知道翻译对了没,换成中文吧。然后把自定义的长度选择模版替换成内置的LengthBasedExampleSelector
,以下是完整代码
python">import os
from langchain_deepseek import ChatDeepSeek
from langchain_core.prompts.prompt import PromptTemplate
from langchain_core.prompts.few_shot import FewShotPromptTemplate
from langchain_core.example_selectors import LengthBasedExampleSelectoros.environ['DEEPSEEK_API_KEY'] = "sk-e24324xxx"# 给出例子
examples = [{"input": "hi", "output": "你好"},{"input": "bye", "output": "再见"},{"input": "remove", "output": "移除"},
]example_prompt = PromptTemplate(input_variables=["input", "output"],template="输入: {input} -> 输出: {output}",
)# 查询长度最近
example_selector = LengthBasedExampleSelector(examples=examples,example_prompt=example_prompt,max_length=20,
)
res = example_selector.select_examples({"input": "text"})
# print(res)example_selector.add_example({"input": "hand", "output": "手"})# 组装提示
prompt = FewShotPromptTemplate(example_selector=example_selector,example_prompt=example_prompt,suffix="输入: {input} -> 输出:",prefix="把输入的单词翻译成中文:",input_variables=["input"],
)messages = prompt.format(input="word")
print(messages)chat_model = ChatDeepSeek(model="deepseek-chat",temperature=0.4,max_tokens=None,timeout=None,max_retries=2,)print(chat_model.invoke(messages).content)"""
把输入的单词翻译成中文:
输入: hi -> 输出: 你好
输入: bye -> 输出: 再见
输入: remove -> 输出: 移除
输入: word -> 输出:输入: word -> 输出: 单词
"""