4. 高级提示词技术
在人工智能浪潮中,语言模型的不断进步为构建智能对话系统提供了强大动力。然而,面对多样化的交互场景和用户需求,如何高效利用这些模型,时期在有限的上下文窗口中发挥最大效能,成为了一个重要课题。本章将深入探讨这一问题,介绍一系列创新的方法和策略,通过精心设计的提示词技术,优化模型的理解和生成能力。
本章将从实际应用的角度出发,详细阐述如何通过LengthBaseExampleSelector根据输入长度动态选择示例,利用最大余弦相似度MMR提示示例选择的相关性和多样性,以及如何通过FewShotPromptTemplate实现少样本学习。此外,还将介绍如何使用向量存储和语义相似度优化消息对话系统中的示例选择,以及如何通过MessagesPlaceholder管理和利用对话历史。
本章还将展示如何预设部分提示词变量,以适应用户交互过程中信息的逐步收集,以及如何动态预设提示词变量,根据上下文实时生成响应。
通过本章的学习,读者将掌握一系列实用的工具和方法,不仅能够提升对话系统的行呢, 还能丰富用户的交互体验,构建出更加智能、灵活和人性化的人工智能应用。
4.1 巧用提示词的案例选择器
4.1.1 根据长度优化示例选择器
AI模型应用设计大型语言模型师,经常需要在有限的上下文窗口中提供输入和示例。为了充分利用这一空间,必须精心挑选最能代表人物的示例。过得的示例或者过长的示例可能会占用过多空间,影响模型对当前输入的理解。
为了解决这以问题,LangChain提供了一种解决方案,即LengthBaseExampleSelector,它能根据给定的最大长度限制,自动选择合适数量的示例,以适应不同长度的输入。
-
LengthBaseExampleSelector根据以下参数工作。
-
Examples是一个示例列表,每个示例包含输入和期望的输出。
-
example_prompt是一个PromptTemplate实例,用于格式化示例。
-
max_length是格式化示例允许的最大长度。这个长度限制帮助选择器决定包括多少示例。
-
get_text_length是一个可选函数,用于计算字符串的长度。虽然默认情况下使用基于空格和换行符的分割方法,但用户可以根据需要自定义此函数。
下面将构建一个示例应用,给定一个词语并返回其反义词。一下是如何根据输入的长度动态选择示例的步骤。
(1)创建示例和模版
首先,定义一组反义词示例和一个PromptTemplate格式化示例,示例代码如下。
python
examples = [{
"question": "开心",
"answer": "伤心"
},{
"question": "高",
"answer": "低"
},{
"question": "精力充沛",
"answer": "无精打采"
},{
"question": "粗",
"answer": "细"
}
]
prompt_template = PromptTemplate.from_template("Question: {question}\n{answer}")
(2)初始化选择器
接着,创建LengthBaseExampleSelector实例,指定示例、模版和最大长度,示例代码如下。
python
#计算字符串的长度
def count_chars(text):
return len(text)
#初始化选择器
examples_selector = LengthBasedExampleSelector(
examples= examples,
#用于指定如何格式化每个示例
example_prompt=prompt_template,
#限制提示词总长度
max_length=100, #格式化后的示例允许的最大总长度,这个长度限制帮助选择器决定最终包含哪些示例。
get_text_length=count_chars,
)
(3)动态选择示例
然后,利用FewShotPromptTemplate结合选择器们根据输入长度动态生成提示,示例代码如下。
python
prompt = FewShotPromptTemplate(
#使用之前创建的基于长度的示例选择器来动态选择示例
example_selector=examples_selector,
#使用同样的格式格式化已被选中的示例
example_prompt=prompt_template,
prefix="给出每个输入的反义词",#定义提示的前缀,这部分将在动态生成的示例之前显示
suffix="Question: {input}",#定义提示的后缀,这部分将在动态生成的示例之后显示,用于引导模型生成预期的输出
# input_variables=["input"],
example_separator="\n",#示例分隔符
)
(4)演示
展示短输入和长输入两种情况下的示例选择。根据输入长度,示例选择器会智能地调整包含的示例数量,示例代码如下。
python
print(prompt.format(input="big"))
打印短输入时查看提示词的选择示例情况,示例代码如下。
python
给出每个输入的反义词
Question: 开心
伤心
Question: 高
低
Question: 精力充沛
无精打采
Question: 粗
细
Question: big
当输入内容不长时,选择器将显示所有示例,如果输入的内容非常长,会减少示例的选择,示例代码如下。
python
print(prompt.format(input="big111111111111111111111111111111111111111111111111111111111111111111111"))
打印长输入时查看提示词的选择示例情况,示例代码如下。
python
给出每个输入的反义词
Question: 开心
伤心
Question: 高
低
Question: big111111111111111111111111111111111111111111111111111111111111111111111
最后,创建链,将提示词传入大模型,完整示例代码如下。
python
from langchain.prompts import PromptTemplate
from langchain_core.example_selectors import LengthBasedExampleSelector
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import FewShotPromptTemplate
def count_chars(text):
return len(text)
if __name__ == '__main__':
examples = [{
"question": "开心",
"answer": "伤心"
},{
"question": "高",
"answer": "低"
},{
"question": "精力充沛",
"answer": "无精打采"
},{
"question": "粗",
"answer": "细"
}
]
#prompt_template = PromptTemplate(input_variables=["question", "answer"], template="Question: {question}\n{answer}")
prompt_template = PromptTemplate.from_template("Question: {question}\n{answer}")
#初始化选择器
examples_selector = LengthBasedExampleSelector(
examples= examples,
#用于制定如何格式化每个示例
example_prompt=prompt_template,
#限制提示词总长度
max_length=100, #示例长度 + 分隔符长度 < max_length
get_text_length=count_chars,
)
prompt = FewShotPromptTemplate(
example_selector=examples_selector,
#使用同样的格式格式化选中的示例
example_prompt=prompt_template,
prefix="给出每个输入的反义词",
suffix="Question: {input}",
# input_variables=["input"],
example_separator="\n",
)
#print(prompt.format(input="big111111111111111111111111111111111111111111111111111111111111111111111"))
llm = ChatOpenAI(
temperature=0.9,
model="deepseek-chat",
openai_api_key="",
openai_api_base="https://api.deepseek.com"
)
output_parse = StrOutputParser()
chat = prompt | llm | output_parse
result = chat.invoke({"input": "热情"})
print(result)
打印结果如下。
python
根据您提供的示例,每个输入的反义词如下:
- **Question:** 热情
**Answer:** 冷漠
由于输入内容交缠个,示例选择器只选择或者不选择示例加入到提示词中。因此,使用LengthBaseExampleSelector能够根据长度优化示例的选择,从而在有限的上下文窗口内最大化模型的性能。这种方法对于构建高效且快速响应的LangChain应用至关重要。
长度计算公式 如果只有一个占位符值 示例总长度=len(占位符值) + len(可选择示例长度) 如果有多个占位符值
示例总长度=len(占位符值) + (占位符个数-1) + len(可选择示例长度) 占位符个数-1:
多个占位符值最后是以空格间隔的合并字符串
4.1.2 使用最大余弦相似度嵌入示例
选择合适的示例放入提示词,对于生成高质量的自然语言处理输出至关重要。本小节将深入探讨如何使用最大余弦相似度(max marginal relevance, MMR)嵌入示例选择器来优化示例的选择,以便为特定输入生成最相关和多样化的输出。
1.理解MMR示例选择器的原理
最大余弦相似度嵌入示例选择器是一种高效的方法,旨在从一组预定义的示例中挑选出与给定输入最相关的示例。它通过计算输入和每个示例之间的余弦相似度识别最相关的示例,并在选择后续示例时考虑已选择示例的多样性。这种方法有助于避免选择过于相似的示例,从而提供更全面多元的视角。
2.安装必要的依赖
使用MMR示例选择器需要安装以下Python库。
sentence-transformers,用于生成文本的嵌入表示。
faiss-cpu,一个高效的相似性向量搜索库。
通过一下命令安装这些依赖
python
pip install sentence-transformers faiss-cpu
3.实现步骤
首选,初始化嵌入模型并定义一组示例。示例应以字段形式给出,每个字段包括输入和期望的输出。嵌入模型可以将字符串转为数字向量,并用于计算字符串内容的相似度。
python
examples = [{
"question": "开心",
"answer": "伤心"
},{
"question": "高",
"answer": "低"
},{
"question": "精力充沛",
"answer": "无精打采"
},{
"question": "粗",
"answer": "细"
}
]
bge-large-zh-v1.5是一个高性能的中文语言模型,专为理解和生成中文文本而设计。它在东中自然语言处理(NLP)任务上表现优异,包括不限于文本分类、语义相似度评估、问答系统和文本摘要。利用这种模型生成的文本嵌入,可以极大地提高语义搜索和相似度计算的准确性。
要在LangChain中使用bge-large-zh-v1.5模型,首先需要HuggingFaceEmbeddings类加载模型,制定模型的路径或者名称。
python
#加载模型
embedding_path = "/Users/xx/Documents/LLM/bge-large-zh-v1.5"
embeddings = HuggingFaceEmbeddings(model_name=embedding_path)
如果没有下载bge-large-zh-v1.5嵌入模型,请访问以下链接下载模型
https://model.baai.ac.cn/models
4.1.3 使用MMR选择示例
在自然语言处理和机器学习领域,向量搜索时一项关键技术,用于快速检索高维空间中最相似的项。FAISS(facebook AI similarity search)是由Facebook AI Research开发的库,专门用于高效的相似性搜索和密集向量聚类。它非常适合于待处理大规模向量数据集,是的在数十亿维向量中检索成为肯呢个。本节将深入介绍FAISS的核心概念、特性,以及如何在LangChain中使用它进行向量存储。
FAISS利用先进的算法和数据结构,优化了向量之间相似度的搜索过程。它支持包括余弦相似度和欧氏距离在内的多种距离度量,并提供了CPU和GPU两种计算方式的支持。这使得FAISS在处理大规模数据集时,既能保持高性能,也能提供灵活的硬件配置选项。
在LangChain项目中,FAISS可以用于嵌入向量的存储和相似性搜索。这对于构建基于相似性匹配的功能(如自动问答系统、文档检索等)非常有用,首先需要导入FAISS.
python
from langchain_community.vectorstores import FAISS
接着,使用MaxMarginalRelevanceSelector根据嵌入的相似度以及多样性选择最合适的示例。
python
example_selector = MaxMarginalRelevanceExampleSelector.from_examples(
examples,
embeddings,#用于生成文本嵌入的模型(把人类语言变成计算机能懂的数字),这些嵌入将用于计算势力之间的相似度。()
FAISS,#指定使用FAISS作为向量存储和相似性搜索的工具,以支持高效的相似度查询。
k=1 #代表最终需要选出的示例的个数,同时也等于MMR算法执行的轮数
)
这段代码的主要目的是初始化示例选择器,它能够根据输入文本的语义内容,从一组预定义的实例中选择一个最相关且具有代表性的示例。选择不仅基于语义相似度,还考虑到了所选示例之间的多样性,以提供更全面的信息或响应。
4.1.4 构建和格式化提示
接下来,构建FewShowPromptTemplate,并将MMR示例选择器作为参数传入,以动态选择和格式化示例。
python
#构建和格式化提示
prompt_template = PromptTemplate(input_variables=["question", "answer"], template="Question: {question}\n{answer}")
prompt = FewShotPromptTemplate(
example_selector=example_selector,
#使用同样的格式格式化选中的示例
example_prompt=prompt_template,
prefix="给出每个输入的反义词",
suffix="Question: {input}",
input_variables=["input"],
example_separator="\n",
)
这段代码的作用是构造一个具有定制前缀、示例、后缀的提示模版。通过使用FewShotPromptTemplate和提钱定义的示例选择器它能够针对具体的输入动态选择相关的示例,并根据示例生成一个完整的提示文本,用于引导模型生成特定任务的输出。
输入变量,打印示例选择器生成的提示词。
python
print(prompt.format(input="担心"))
打印结果如下:
python
给出每个输入的反义词
Question: 开心
伤心
Question: 担心
变量输入了"担心",通过相似性搜索在示例中找到"快乐"、"悲伤"最为相似,因此选择了此示例放到提示词中。
4.1.5 调用和解析结果
最后,使用LangChain的链式调用机制,将MMR提示模版与其他组件(如聊天或者输出解析器)组合,以生成和解析输出,示例代码如下。
python
output_parse = StrOutputParser()
llm = ChatOpenAI(
temperature=0.9,
model="deepseek-chat",
openai_api_key="",
openai_api_base="https://api.deepseek.com"
)
result = prompt | llm | output_parse
print(result.invoke({"input" : "担心"}))
打印结果如下:
python
**Question: 担心**
反义词:放心
本小姐介绍使用最大余弦相似度嵌入示例选择器,在LangChain中优化示例选择。这种方法不仅提高了相关性和多样性,还通过引入更加精准和丰富的示例,极大地提升了生成文本的质量。因此,在项目中实践这些技术时,记得调整示例和参数以最佳地适应具体需求。
4.2 消息对话提示词实现少样本学习
在人工智能和机器学习领域中,少样本学习(few-shot learning, FSL)是一种重要的训练方法,它能够是模型在只有很少训练样本的情况下也能学会完成特定任务。本节将深入探讨如何利用LangChain库中的FewShotChatMessagePromptTemplate实现少样本学习,特别是在处理需要将每个示例转为一条或多条消息的对话式任务中的引用。
FewShotChatMessagePromptTemplate是LangChain库提供的一个功能强大的工具,它支持开发者以对话形式呈现少量示例,训练模型解决特定的问题。这种方法特别适合那些自然语言处理任务,其中对话上下文对弈理解问题和生成正确的回答至关重要。
为了有效地使用FewShotChatMessagePromptTemplate,需要准备好示例集。下面示例想让大模型学会如果问题是数学计算,就直接以最简约的形式回复数字即可。
python
examples = [
{"input" : "2+3", "output": "5"},
{"input": "3+3", "output": "6"},
]
接下来,使用ChatPromptTemplate.from_messages方法将每个示例转换为一系列对话消息。这一步骤通过定义一个模板完成,该模板指定了如何将示例中的"input"和"output"转换为对话格式。
python
example_prompt = ChatPromptTemplate.from_messages([
("human", "{input}"), ("ai", "{output}")
])
然后,使用FewShotChatMessagePromptTemplate将这些格式化的示例组装成一个完整的对话提示词,这个过程为模型提供了上下文,帮助它理解如何在接收到新的的输入时生成相应的输出。
这种基于对话提示词的少样本学习方法特别适用于需要模型理解和参与对话的场景。例如,在开发聊天机器人时,可以使用这种方法训练模型理解特定问题并提供准确回答;或者在构建自动回复系统时,利用少量进行挑选的示例来教会模型如何在各种不同的对话情景中做出反应。
最后一步是将组装好的对话提示词与其他提示信息(如模型的角色描述)整合,形成最终的提示。这一步强调了在对话中引入额外上下文的价值,示例如下。
python
few_shot_prompt = FewShotChatMessagePromptTemplate(
examples=examples,
# 使用同样的格式格式化选中的示例
example_prompt=example_prompt
)
final_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个神奇的数学奇才,能通过示例理解特殊符号的语义。"),
few_shot_prompt,
("human", "{input}")
])
在这个例子中,首先向模型介绍了其角色(一位数学天才), 然后引入少样本对话提示,最后提供了待回答的新问题。这种结构化的方法不仅提高了模型的任务理解能力,也优化了其在特定对话场景下的表现。以下是将提示词通过链传递到大模型执行的效果展示。
python
llm = ChatOpenAI(
temperature=0.9,
model="deepseek-chat",
openai_api_key="",
openai_api_base="https://api.deepseek.com"
)
output_parse = StrOutputParser()
chat = final_prompt | llm | output_parse
result = chat.invoke({"input": "30的平方"})
print(result)
打印结果如下。
python
900
再对比一下直接大模型调用的效果。
python
prompt2 = PromptTemplate.from_template("""{input}""")
chat = prompt2 | llm | output_parse
print(chat.invoke({"input": "30的平方"}))
直接调用大模型的结果如下。
python
好的,我们一起来算一下 \(30\) 的平方。
\(30\) 的平方就是 \(30 \times 30\)。
计算过程:
\[
30 \times 30 = 900
\]
所以,30的平方等于 **900**。
如果你还有其他数字需要计算平方,或者想了解平方的概念,随时告诉我。
本节对LangChain的FewShotChatMessagePromptTemplate进行了深入学习。这种方法的应用可以极大地提升模型在对话任务中的表现,是构建高效、智能对话系统的关键技术之一。
4.3 向量存储实现消息对话的示例选择
本节将探索如何利用bge-large-zh-v1.5模型结合CHroma向量存储优化消息对话系统中的示例选择过程。这一过程通过语义相似度实现,能够显著提高对话系统的响应质量和相关性。揭晓来将逐步介绍如何实现这一功能。
4.3.1 引入必要的库
首先,需要引入几个关键的库,以便加载模型、处理文本、并实现语义相似度的计算代码如下。
python
from langchain_huggingface import HuggingFaceEmbeddings
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain_community.vectorstores import Chroma
Chroma是一个高效的向量存储库,专为快速检索大规模数据而设计,它在各种应用中,特别是在实现基于语义的搜索和信息检索系统中,表现出了卓越的性能。
此处也可使用前面所讲的FAISS向量存储。Chroma和FAISS是两个经常被提及的库。虽然它们都旨在解决大规模向量检索问题,但在设计理念、特性和使用场景上存在一些关键差异。选择哪一个取决于具体的项目需求和优先级。吐过需要一个易于使用、快速集成的向量存储方案,并且项目规模适中,Chroma可能是一个更好的选择。相反,如果项目需要处理巨大的数据集,并且对检索速度和精度有极高的要求,FAISS将是更优的选择。
4.3.2 加载模型
接下来加载bge-large-zh-v1.5。该模型基于HuggingFace的transaformer库构建,并专门针对中文文本处理进行了优化。以下是可以初始化模型并准备将文本转换为向量示例代码。
python
# 加载模型
embedding_path = "/Users/xx/Documents/LLM/bge-large-zh-v1.5"
embeddings = HuggingFaceEmbeddings(model_name=embedding_path)
4.3.3 创建示例集合
示例包括简单的数学问题和一些更复杂的文本输入,如编写关于月亮的诗歌,示例代码如下。
python
examples = [
{"input": "2+3", "output": "5"},
{"input": "3+3", "output": "6"},
{"input": "牛对月亮说了什么?", "output": "什么都没有"},
{"input": "给我写一首关于月亮的五言诗", "output": "月儿挂枝头,清辉洒人家。银盘如明镜,着凉夜归人。思绪随风舞,共赏中秋园。"}
]
4.3.4 利用CHroma向量存储和语义相似度选择示例
将上述示例转换为向量,并存储在Chroma向量库中,可以利用向量找到与用户输入醉相思的示例,示例代码如下。
python
#目的是将每个示例的输入和输出合并,以便将整个示例视为一个整体进行向量化
to_verctorize = [" ".join(example.values()) for example in examples]
#用Chroma的form_texts方法根据给定的文本列表to_vectorize创建一个向量存储实例
vectorstore = Chroma.from_texts(
to_verctorize, #前面步骤生成的字符串列表, 包含了要被向量化的文本
embeddings, #模型处理to_vectorize列表中的每个字符串,生成对应的向量
metadatas=examples, # 附加信息列表,与to_vectorize列表中的文本一一对应
)
4.3.5 选择语义相似的示例
借助SemanticSimilarityExampleSelector,可以根据用户的输入找到最相关的示例,这是通过计算输入与存储示例之间的与哟相似度来完成的,示例代码如下。
python
#SemanticSimilarityExampleSelector(语义相似度选择器):追求"最相关"。计算所有示例与问题的向量距离,直接选出距离最近(最相似)的 Top-K 个。任务非常单一、明确,只需要最精准的参考(如:简单的翻译、格式转换
#MaxMarginalRelevanceExampleSelector(最大边际相关性选择器,简称 MMR):追求"相关且多样"。宽泛,需要模型从多个角度理解(如:开放式问答、RAG检索去重、推荐系统)。
example_selector = SemanticSimilarityExampleSelector(
vectorstore=vectorstore,
k=1,
)
这段代码的主要目的是准备数据并初始化一个CHroma向量存储实例,以便后续可以快速检索与给定查询最相似的文本示例。通过这种方式,Chroma能够支持基于语义相似度的搜索,适用于各种需要理解文本内容并找到相关信息的应用场景,
例如,如果用户输入"对牛弹琴",系统会通过语义相似度选择出最相关的示例。
python
print(example_selector.select_examples({"input": "对牛弹琴"}))
运行结果如下。
python
[{'input': '牛对月亮说了什么?', 'output': '什么都没有'}]
4.3.6 应用示例格式化对话
最后一步是将选择的示例格式转化为对话形式,以便可以直接用于消息对话系统。这里定义了一个基于少样本的提示模版。示例代码如下。
python
prompt_template = ChatPromptTemplate.from_messages([
("human", "{input}"), ("ai", "{output}")
])
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_selector=example_selector,
#使用同样的格式格式化选中的示例
example_prompt=prompt_template
)
这个模版将选定的示例转换为格式化的对话形式,特别适用于创建对话式AI应用,如聊天机器人,它可以通过参考与用户输入相似的历史交互提供更加精准和个性化的回答。接下来创建完整消息提示词,示例代码如下。
python
final_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个神奇的数学奇才,能通过示例理解特殊符号的语义。"),
few_shot_prompt,
("human", "{input}")
])
print(final_prompt.format(input="3+3是多少"))
打印结果如下。
python
System: 你是一个神奇的数学奇才,能通过示例理解特殊符号的语义。
Human: 3+3
AI: 6
Human: 2+3
AI: 5
Human: 3+3是多少
输入"3+3是多少",通过向量存储检索到数字计算的示例最为匹配,因此最终生成的提示词中嵌入了数字计算的示例。将提示词结合大模型链式调用,示例代码如下。
python
output_parse = StrOutputParser()
llm = ChatOpenAI(
temperature=0.9,
model="deepseek-chat",
openai_api_key="",
openai_api_base="https://api.deepseek.com"
)
result = final_prompt | llm | output_parse
print(result.invoke({"input": "3+3是多少"}))
运行后可以看到,大模型按照数字计算的示例,直接输出了以下内容。
python
6
通过本节的学习,读者可以掌握如何使用bge-large-zh-v1.5模型和Chroma向量存储优化消息对话系统中的示例选择。这种方法通过计算语义相似度,确保了对话系统能够提供高度相关富有洞察力的回答,从而大幅提升了用户体验。在接下俩的章节中,将进一步探索如何将浙西额技术应用于更广泛的对话场景中。
4.4 管理历史消息
在构建基于对话的人工智能应用时,管理用户和AI之间的交互历史至关重要。这不仅有助于AI更准确地理解上下文,也提供了维持连贯和有意义的对话的机制。LangChain库通过MessagesPlaceholder提供了一种灵活且强大的方式处理历史消息。本节将详细探讨如何使用MessagesPlaceholder实现消息历史的管理,并讨论其在实际使用场景中的应用。
4.4.1 MessagesPlaceholder组件
MessagesPlaceholder是LangChain核心组件之一,它支持开发者在构建对话模版时动态插入用户和AI之间的交互历史。这种方式不仅增强了对话的连贯性,还提高了AI响应的相关性。
4.4.2 如何使用MessagesPlaceholder
在LangChain的对话管理中,MessagesPlaceholder扮演着桥梁的角色,连接了对话历史和即将生成的新消息。下面是一个基本示例,展示了如何在ChatPromptTemplate中使用MessagesPlaceholder。
python
from langchain_core.messages import HumanMessage, AIMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个有用的助手。尽管你能回答所有问题"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}"),
])
在这个模板中,MessagesPlaceholder用于动态插入名为history的对话历史。这意味着,每当需要生成新的AI响应时,可以将之前的对话作为上下文提供给模型,以便生成更加相关和连贯的回答。
4.4.3 实际使用场景
通过一个具体的例子进一步探讨MessagesPlaceholder的使用场景。假设有一个名为小余的用户,他是一名程序员,喜欢吃粤菜。用户和AI之间的对话历史被记录下来,并用作生成吓一条消息的上下文。
python
history = [
HumanMessage(content="你好,我是小余,是一个程序员。在美食方面,我喜欢吃粤菜。"),
AIMessage(content="好的,小余。我现在了解你了,我是你的助手,随时为你服务"),
]
当小余询问关于午餐的建议是,通过将history作为上下文传入,AI可以根据之前的对话提供更加个性化和相关的建议。
python
print(prompt.format(input="能给我推荐中午一些美食吗?", history= history))
运行结果如下。
python
System: 你是一个有用的助手。尽管你能回答所有问题
Human: 你好,我是小余,是一个程序员。在美食方面,我喜欢吃粤菜。
AI: 好的,小余。我现在了解你了,我是你的助手,随时为你服务
Human: 能给我推荐中午一些美食吗?
将提示词通过链传递到大模型执行的效果展示。
python
output_parse = StrOutputParser()
llm = ChatOpenAI(
temperature=0.9,
model="deepseek-chat",
openai_api_key="",
openai_api_base="https://api.deepseek.com"
)
result = prompt | llm | output_parse
print(result.invoke({"history":history, "input":"能给我推荐中午一些美食吗?"}))
示例运行效果如下。
python
当然可以。小余,既然你爱吃粤菜,那么中午推荐你试试以下几样经典又适合一人食或工作餐的粤式美食:
1. **煲仔饭**:这是中午非常棒的选择。腊味煲仔饭、滑鸡煲仔饭或者排骨煲仔饭都很经典。米饭吸收了肉汁和酱香,底下的锅巴焦香酥脆,很有满足感。
2. **干炒牛河**:一道非常考验厨师功底的粤式主食。河粉爽滑,牛肉嫩滑,搭配豆芽和韭黄,香味十足,作为午餐既饱腹又美味。
3. **云吞面**:清汤寡水却鲜美无比。鲜虾云吞皮薄馅大,面条爽口弹牙,加上几颗青菜和一勺红醋,清淡又开胃。
4. **烧腊双拼/三拼饭**:如果附近有正宗的烧腊店,一份烧鸭叉烧双拼饭或者油鸡烧肉三拼饭是绝佳选择。配上酸梅酱和姜葱蓉,非常下饭。
5. **肠粉**:可以选择鲜虾肠粉、牛肉肠粉或者斋肠粉,也可以加蛋。口感滑嫩,配上甜酱油,简单清爽。如果觉得分量不够,可以再加一碗艇仔粥或者皮蛋瘦肉粥。
**根据你的需求,我还可以帮你这样调整:**
* **如果你今天想吃清淡点的**:推荐**云吞面**或**肠粉+粥**的组合。
* **如果你今天想吃点有锅气的**:推荐**干炒牛河**。
* **如果你今天想吃点实在的、有肉的**:推荐**煲仔饭**或**烧腊饭**。
看看有没有你感兴趣的?或者告诉我你更具体的口味偏好(比如喜欢甜口的还是咸香的,想不想吃辣),我可以再为你推荐得更精准一些。
通过这种方式,AI不仅回顾了用户的喜好(粤菜),还能提供具体的菜肴建议,这展现了对话上下文管理的重要性和效果。
MessagePlaceholder提供了一种高效的方式来管理和利用对话历史,这对于构建高质量的对话AI应用只管重要。通过合理使用这一机制,开发者可以创建出能够理解上下文提供连贯对话和个性化建议的AI助手。随着对话历史的积累,AI的响应将变得更加准确和人性化,极大地增强用户体验。
4.5 预设部分提示词变量
在开发人工智能应用时,经常需要根据用户的输入逐步构建对话内容,特别是在需要手机多个数据点来完成一个任务的场景中。prompt.partial方法提供了一种灵活的解决方案,支持开发者预设置部分提示词变量,然后在获取更多信息后补全剩余的部分。这种方法提高了应用的灵活性和用户交互的连贯性。
在对话应用中,用户肯呢个不会一次性提供所有信息。例如,在一个资源推荐系统中,用户可能首先表达他们对某个主题的兴趣,然后在对话的后期制定希望获取资源的类型。在这种情况下,如果在一开始就知道部分信息(如主题),就可以使用prompt.partial方法预先设置这部分已知的变量。
PromptTemplate类提供了partial方法,支持开发者在创建提示模板时预先填充一部分变量。这些部分设置的变量随后可以获取到更多信息时通过调用format方法补全。这种方法极大地提高了代码的可重用性和对话的灵活性。
假设正在开发一个智能教育平台,旨在为用户提供个性化的学习资源推荐。以下是如何使用prompt.partial方法实现这一功能的具体步骤。
(1)初始化提示模版
首先,创建一个包含两个变量topic(主题)哥resourceType(资源类型)的提示模板。
python
prompt_template = PromptTemplate.from_template("为我推荐关于{topic}的{resourceType}")
(2)预先设置部分变量
python
prompt_template = prompt_template.partial(topic="数学")
打印结果如下。
python
text='为我推荐关于数学的视频教程'
(3)补全并生成最终的提示
python
print(prompt_template.invoke({"resourceType": "视频教程"}))
打印结果如下。
最后使用链式调用大模型查看效果,代码如下。
python
output_parse = StrOutputParser()
llm = ChatOpenAI(
temperature=0.9,
model="deepseek-chat",
openai_api_key="",
openai_api_base="https://api.deepseek.com"
)
chain = prompt_template | llm | output_parse
print(chain.invoke({"resourceType": "视频教程"}))
打印结果如下。
python
为您推荐数学视频教程时,需要先明确您的**当前阶段**(如:小学、中学、大学、考研、工作)和**学习目标**(如:提分、竞赛、考研、培养思维、AI基础)。
以下是按不同类别和平台整理的优质数学视频教程推荐,涵盖免费和付费内容:
### 一、 综合类/全阶段(中文顶级资源)
**1. 宋浩老师(B站 / YouTube)**
- **适用人群:** 大学生、专升本、考研党。
- **内容:** 《高等数学》《线性代数》《概率论与数理统计》。
- **特点:** 幽默风趣,讲解非常细致,板书清晰。全网公认的"救星",适合零基础或基础薄弱的同学。视频通常很长,但干货极多。
**2. 李永乐老师(B站 / YouTube)**
- **适用人群:** 中学生、大学生、对科普感兴趣的人。
- **内容:** 高中数学、考研数学、物理科普、数学思维。
- **特点:** 前人大附中名师,讲解深入浅出,能把复杂概念讲得通俗易懂。他的"线性代数"讲解是经典中的经典。
**3. 3Blue1Brown(B站有官方翻译 / 原版YouTube)**
- **适用人群:** 大学生、对数学本质感兴趣的人、工程师。
- **内容:** 微积分、线性代数、神经网络、概率论等核心概念的**可视化**讲解。
- **特点:** **强烈推荐!** 不是教解题技巧,而是用动画展示数学的"直觉"和几何意义。看完《线性代数的本质》和《微积分的本质》,你对数学的理解会上升一个层次。
### 二、 中小学/考试类
**4. 一数(B站)**
- **适用人群:** 初中生、高中生、高考生。
- **内容:** 初中数学、高中数学、高考数学真题讲解。
- **特点:** 系统性强,分专题讲解,配合习题集。适合想打基础或冲刺高分的同学。视频节奏快,效率高。
**5. 乐乐课堂(App / 网站)**
- **适用人群:** 小学生、初中生。
- **内容:** 小学数学、初中数学(物理、化学等)。
- **特点:** "天天练"系列,每集只有几分钟的动画短视频,生动有趣,容易理解。非常适合碎片化学习和预习复习。
### 三、 高阶/专业/竞赛类
**6. MIT OpenCourseWare(麻省理工学院公开课)**
- **适用人群:** 数学专业学生、数据科学/机器学习从业者。
- **推荐课程:**
- **Gilbert Strang 教授的《线性代数》**:经典中的经典,推荐配合他的书《Introduction to Linear Algebra》一起看。(B站有中文字幕版)
- **《单变量微积分》** (David Jerison教授)
- **特点:** 世界顶级大学原汁原味的课程,深度和广度都有保障。需要一定的英文基础(或看字幕)。
**7. 数学竞赛/思维拓展**
- **"本质教学" / "数学之翼" / "于德浩"(B站)**:这些UP主专门讲解数学竞赛题(如CMO、IMO),或者大学数学分析、高等代数等硬核内容。适合数学爱好者或准备参加竞赛的同学。
### 四、 抽象数学/科普类(培养兴趣)
**8. Veritasium 真理元素(B站有翻译)**
- **内容:** 数学史、数学悖论、数学在现实中的应用(如:为什么车轮是圆的?圆周率π的奥秘)。
- **特点:** 制作精良,引人入胜。适合作为数学学习的"开胃菜",让你爱上数学。
**9. Numberphile(B站有翻译)**
- **内容:** 各种有趣的数学谜题、数字、定理和数学家访谈。
- **特点:** 轻松愉快,经常邀请大数学家讲解看似简单但无比深刻的问题。
### 总结建议(按需求选择)
| 您的目标 | 首选推荐 | 备选推荐 |
| :--- | :--- | :--- |
| **初中/高中提分** | **一数** | 李永乐老师、乐乐课堂 |
| **大学考试/考研** | **宋浩老师** | 张宇(考研界名师)、汤家凤 |
| **理解数学本质** | **3Blue1Brown** | MIT公开课 |
| **培养数学思维/兴趣** | **Veritasium**、**Numberphile** | 李永乐老师(科普向) |
| **专业深度学习(AI/ML)** | **3Blue1Brown**(神经网络系列)、**MIT 线性代数** | 吴恩达(机器学习系列中的数学部分) |
**最后的小建议:**
- **B站(Bilibili)是目前中文数学视频教程最全的平台**,几乎所有上述内容都能在B站找到。
- **看视频时最好暂停、记笔记、自己动手推导**。只看视频不思考是学不好数学的。
- **如果基础薄弱,从宋浩或一数开始;如果基础不错想深入,一定要看3Blue1Brown。**
本节示例演示了如何使用prompt.partial方法帮助构建更加智能和用户友好的对话系统。
4.6 动态预设提示词变量
在构建交互式人工智能应用时,根据上下文动态生成响应可以极大地提升用户体验。prompt.partial方法的一个高级用法是传递函数作为变量,这种方式支持在实际需要生成提示时才动态计算变量的值。本节将深入探讨如何利用这一特性,以会议提醒和准备的场景为例,展示其在实际应用中的强大功能。
在对话系统中,用户需求往往随时间而变化,这要求系统能够灵活地根据当前的上下文提供相关信息。通过使用prompt.partial方法接收一个函数作为变量,可以确保只在需要时才进行计算,从而使提示信息尽可能地新鲜和相关。
考虑一个实际应用场景,助手需要根据会议时间动态提供提醒。提醒不仅包括会议的基本信息(如主题、参与人员和地点),还要根据当前时间相对于会议时间的不同阶段(如会议开始前一天、开始前15分钟等)提供不同的提醒消息。
python
from datetime import datetime, timedelta
from langchain.prompts import PromptTemplate
meeting_details = {
"time": datetime.now() + timedelta(hours=1),
"topic": "项目进度更新",
"participants": ["张三", "李四", "王五"],
"location": "在线会议-Zoom",
}
动态生成提醒消息函数
python
def reminder_for_meeting(meeting_time):
now = datetime.now()
if meeting_time - timedelta(minutes=15) <= now < meeting_time:
return "会议将在5分钟后开始"
elif now < meeting_time - timedelta(days=1):
return "明天有一个重要会议"
else:
return "会议即将开始"
在本例中,将reminder_for_meeting函数作为reminder变量的值传递给prompt.partial,这样reminder的实际内容就会在最后生成提示时根据当前时间动态决定。
python
prompt_template = PromptTemplate.from_template("""
{reminder}
会议主题:{topic}
参与人员:{participants}
会议地点:{location}
{input}
""")
prompt_template = prompt_template.partial(reminder=lambda: reminder_for_meeting(meeting_details["time"]), topic=meeting_details["topic"], participants=",".join(meeting_details["participants"]), location=meeting_details["location"])
print(prompt_template.format(input="请帮我列出目前可以做的会议准备"))
打印的最终提示词如下。
python
会议即将开始
会议主题:项目进度更新
参与人员:张三,李四,王五
会议地点:在线会议-Zoom
请帮我列出目前可以做的会议准备
最后使用链式调用大模型查看提示词效果,代码如下。
python
output_parse = StrOutputParser()
llm = ChatOpenAI(
temperature=0.9,
model="deepseek-chat",
openai_api_key="",
openai_api_base="https://api.deepseek.com"
)
result = prompt_template | llm | output_parse
print(result.invoke({"input": "请帮我列出目前可以做的会议准备"}))
运行结果如下。
python
好的,根据您提供的会议信息,以下是您可以在会议开始前做的准备工作,按重要性排序:
### 1. 技术与环境准备
- **检查网络与设备**:确保您的网络连接稳定,摄像头、麦克风及扬声器(或耳机)正常工作。
- **提前进入Zoom会议**:建议提前5-10分钟进入会议,测试音视频效果,避免临时故障。
- **准备共享屏幕内容**:如需展示PPT、文档或项目看板,提前打开并调整好显示比例,关闭不必要的弹窗或通知。
### 2. 会议内容与资料准备
- **回顾上次会议纪要**:如有之前的会议记录,快速浏览确认遗留事项及本次需重点更新的内容。
- **整理项目进度数据**:准备关键里程碑完成度、当前任务状态、风险与问题清单(如张三负责的开发进度、李四的测试情况、王五的资源协调等)。
- **列出待讨论问题**:针对进度延迟、资源冲突或外部依赖,提前梳理3-5个核心议题,确保会议高效。
- **准备汇报要点**:如果您是汇报者,提炼"已完成/进行中/待解决"三栏式要点,避免冗长叙述。
### 3. 参会人员协调
- **提醒参会者**:通过邮件或即时消息(如钉钉/微信)再次发送Zoom链接及会议议程,确认张三、李四、王五已收到。
- **明确角色分工**:如需要,指定记录人或计时员,或提前分配各自的汇报顺序(例如:张三先,李四次之,王五最后)。
### 4. 会议流程与规则
- **设定时间限制**:建议总时长控制在30-45分钟,每个议题分配5-10分钟,避免超时。
- **准备应急方案**:如有人临时无法参会,提前确认是否可录屏,或安排后续简短同步。
### 5. 其他实用建议
- **关闭非必要程序**:关闭浏览器标签、通讯软件弹窗,减少干扰。
- **准备纸笔或数字笔记工具**:用于随时记录关键决策或后续行动项。
- **调整环境**:确保背景整洁或使用Zoom虚拟背景,光线充足。
---
**快速检查清单**:
- [ ] 网络/麦克风/摄像头测试
- [ ] 屏幕共享文档已打开
- [ ] 关键数据/问题清单已整理
- [ ] 已提醒参会者(含链接)
- [ ] 时间分配计划已备
祝会议顺利!
通过本节示例,读者可以掌握如何利用gprompt.partial传递函数动态预设提示词变量的强大能力。这种方法使对话系统能够根据实时上下文提供精确和及时的信息,极大地提升了用户体验。此外,这种技术的应用不仅限于会议提醒场景,还可以扩展到任何需要根据动态条件色号那个侧好难过响应的情境中,展现了prompt.partial在构建复杂对话逻辑中的灵活性和实用性。
4.7 管道提示词
本节将深入探讨如何使用PipelinePrompt有效组合多个提示词,以创建复杂而有组织的对话和任务流。
PipelinePrompt是一个强大的工具,可以重复使用部分提示词,实现更高效的信息传递和任务执行。
在编写脚本或者创建对话式AI引用时,经常需要组合多个提示词,以便根据特定场景或协调的流程实现复杂的对话管理。
PIpelinePrompt主要由最终提示和管道提示两个部分组成。最终提示是最后返回的提示,而管道提示是一个包含字符串名称和提示模版的元组列表。这些提示模板将被格式化并作为变量传递给未来的提示模板,从而创建一个连贯的对话流。
现在通过一个简单的例子说明如何使用PipelinePrompt。假设正在创建一个模拟与Elon Musj对话的应用。这时需要构建一个流程,买寿险介绍你正在扮演的任务(Elon Musk),然后展示一个交互示例,最后提示用户提出他们的问题。
(1)定义提示模板
首先,定义不同的提示模板,分别对应对话的不同阶段。
定义introduction_template介绍扮演的人物,示例代码如下。
python
introduction_template="""你正在扮演{person}"""
定义example_template提供一个交互示例
(2)组合提示模板
(3)格式化和展示