主要学习了关于提示工程、链和记忆的相关知识,其中发现由于版本问题会一直出现一些警告,按照警告知识了解了一下关于使用|来构建链的方式,此时发现链的调用方式减少为只能使用invoke来进行调用,且记录的笔记代码都经过了化简
# 创建LLMChain
llm_chain = PromptTemplate.from_template(template) | llm | StrOutputParser() # RunnableSequence
result = llm_chain.invoke({"xxx": "hello"})
以下为教材以及老版本中的创建LLMChain方式以及包含多个调用方式,后续的学习还是主要以下面老版本方式为主
llm_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(template))
result = llm_chain("hello") # 老版本返回json格式
提示工程
提示框架,LangChain中提供String(StringPromptTemplate)和Chat(BaseChatPromptTemplate)两种基本类型模板
- 指令instruction:告诉模型任务做啥,怎么做
- 上下文context:额外知识来源
- 提示输入prompt input:具体问题变量
- 输出指示器output indicator:标记要生成的文本的开始
提示模版类型
① PromptTemplate
from langchain import PromptTemplate
# 常用String提示模版
template = """xx{product}xxx"""
prompt = PromptTemplate.from_template(template)
print(prompt.format(product="input_something"))
# 提示模板类的构造函数
prompt = PromptTemplate(
input_variables=["test1", "test2"],
template="你是xxx, 对于{test1}的{test2}, xxx?"
)
print(prompt.format(test1="xx", test2="xx"))
② ChatPromptTemplate
# 常用Chat提示模板, 组合各种角色消息模板
# 模板的构建
system_template = "xx{product}xx"
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)
human_template = "xxx{product_detail}。"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
prompt_template = ChatPromptTemplate.from_messages(
[system_message_prompt, human_message_prompt]
)
# 格式化提示消息生成提示
prompt = prompt_template.format_prompt(
product="xxx", product_detail="xxx"
).to_messages()
③ FewShotPromptTemplate
- 少样本提示模板,模仿示例写出新文案
- Few-Shot(少样本)、One-Shot(单样本)、 Zero-Shot(零样本):让机器学习模型在极少量甚至无示例情况下学习到新概念或类别
# 创建示例样本
samples = [
{
"key1": "xx",
"key2": "yy"
},
{
"key1": "zz",
"key2": "qq"
}
]
# 创建提示模板
template="键1: {key1}\n 键2: {key2}"
prompt_sample = PromptTemplate(input_variables=["key1", "key2"], template = template)
# 创建FewShotPromptTemplate对象
prompt = FewShotPromptTemplate(
examples = samples,
example_prompt=prompt_sample,
suffix="{key1}{key2}",
input_variables=["key1", "key2"]
)
CoT
- 思维链,Chain of Thought,用于引导模型推理
- Few-Shot CoT提示中提供CoT示例,Zero-Shot CoT让模型一步一步思考
cot_template = """将包含一些对话推导示例"""
system_prompt_cot = SystemMessagePromptTemplate.from_template(cot_template)
TOT
- 思维树,Tree of Thoughts
- 为任务定义具体思维步骤及每个步骤候选项数量
链
个人觉得就是嵌套了多个链,感觉后续要学习的话,需要尽可能去学习相关的源码,收获应该会更大
调用
老版本存在多种调用
result = llm_chain(dict) # __call__直接调用
llm_chain.run() # run调用
result = llm_chain.predict(xx="xx") # predict调用
result = llm_chain.apply([{dict},{dict},{dict}])# 针对输入列表apply调用, 返回字符串
result = llm_chain.generate(input_list)# 返回LLMResult对象
LLMChain
将提示词模板、语言模型、输出解析封装成链接口
from langchain_core.output_parsers import StrOutputParser
template = "{xxx}是?"
llm = OpenAI(temperature=0)
# 创建LLMChain
llm_chain = PromptTemplate.from_template(template) | llm | StrOutputParser() # RunnableSequence
result = llm_chain.invoke({"xxx": "hello"}) # 只能使用invoke调用
#llm_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(template))
#result = llm_chain("hello") 老版本返回json格式
print(result)
顺序链
Sequential Chain,将多个链串联
# 创建多个LLMChain
first_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="c") # 生成c作为后续输入
# 这是总的链,我们按顺序运行这三个链
overall_chain = SequentialChain(
chains=[first_chain, second_chain, third_chain],
input_variables=["a", "b"], # 直接输入
output_variables=["c","d","e"], # 由chat生成输入后续链中
verbose=True)
result = overall_chain({"a":"x", "b": "y"})
路由链
- 动态选择用于给定输入的下一个链,否则发入默认链
- 构建两个场景的模板
a_case_template = """你是a, 需要你回答:{input}"""
b_case_template = """你是b, 需要你回答:{input}"""
# 提示信息
prompt_infos = [
{"key": "a", "description": "a问题", "template": a_case_template,},
{"key": "b", "description": "b问题", "template": b_case_template,}]
- 每个场景构建目标链
chain_map = {}
for info in prompt_infos:
prompt = ...
chain = ...
chain_map[info["key"]] = chain
- 构建路由链
from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import (
MULTI_PROMPT_ROUTER_TEMPLATE as RounterTemplate,
)
destinations = [f"{p['key']}: {p['description']}" for p in prompt_infos]
# 路由模板
router_template = RounterTemplate.format(destinations="\n".join(destinations))
# 根据模板生成路由提示
router_prompt = PromptTemplate(
template=router_template,
input_variables=["input"],
output_parser=RouterOutputParser(),
)
router_chain = LLMRouterChain.from_llm(llm, router_prompt, verbose=True)
- 构建默认对话链
from langchain.chains import ConversationChain
default_chain = ConversationChain(llm=llm,
output_key="text",
verbose=True)
- 构建多提示链
from langchain.chains.router import MultiPromptChain
chain = MultiPromptChain(
router_chain=router_chain,
destination_chains=chain_map,
default_chain=default_chain,
verbose=True,
)
运行
chain.run("如何xxx?")
记忆
- 通过{history}参数将历史对话信息存储在提示模板中,作为新的提示内容
conversation = ConversationChain(llm=llm, memory=ConversationBufferMemory())
# 缓冲记忆 conversation.memory.buffer 中存储
缓冲窗口记忆
ConversationBufferWindowMemory,只保存最近窗口值的互动,限制使用的Token数
conversation = ConversationChain(
llm=llm,
memory=ConversationBufferWindowMemory(k=1)
)
对话总结记忆
ConversationSummaryMemory,由另一个llm汇总传递给history
conversation = ConversationChain(
llm=llm,
memory=ConversationSummaryMemory(llm=llm)
)
对话总结缓冲记忆
ConversationSummaryBufferMemory,混合记忆,总结早期互动,保留最近互动
conversation = ConversationChain(llm=llm, memory=ConversationBufferWindowMemory(k=1))