教学视频1:
9. 关于Langchain,看懂这个就行了(上)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1j5KKeJETZ/
教学视频2:
9. 关于Langchain,看懂这个就行了(下)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV155KKeJEZR/
Ads:大模型中转平台,一个key调用国内外四十家公司上千大模型,相应快速,价格优惠,点击链接注册使用
1.
了解
Langchain
LangChain
是一个用于开发由大型语言模型 (LLM
) 提供支持的应用程序的框架,可简化创建由 大型语言模型 (LLM)
和聊天模型提供支持的应用程序 的过程
LangChain
这个框架为用户或者开发者带来了两大核心优势或好处
- 组件:
LangChain
设计了一些模块化的组件,它 把复杂的任务拆分成更小、更易使用的部分。
- 链:
“
链
”
就像是一个完整的解决方案,它把各个工具(组件)串联起来,形成一套流程,使得即使是初学者也能快速上手解决具体的问题。
LangChain
库本身由几个不同的包组成。
- langchain
:构成应用程序认知架构的链、代理和检索策略。
- langchain
-
core
:
langchain
的核心包。
- langchain
-
community
:第三方集成。
2. Langchain
的核心组件
- Models ->
各种类型的模型和模型集成
- Prompts -> prompt
模板封装
- Indexes ->
索引,用来结构化文档,以便和模型交互
- Chains ->
链,一系列对各种组件的调用
- Agents ->
代理,决定模型采取哪些行动,执行并且 观察流程,直到完成为止
- Memory ->
记忆,用来保存和模型交互时的上下文 状态
3. Langchain
的组件使用
3.1 Models_module
- LLMs (
大语言模型
)
- Chat Models (
聊天模型
)
- Embeddings Models(
嵌入模型
)
- OutputParser(
模型的解析输出
)
3.1 Models_module
3.1.1 LLMs
LLM是将字符串作为输入并返回字符串作为输出的语言模型。
from langchain_openai import ChatOpenAI
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
chat = ChatOpenAI(
model=ai_model
)
print(chat.invoke("请默写鹅鹅鹅").content)
3.1.2 Chat Models
聊天模型是使用一系列消息作为输入并返回消息作为输出的语言模型。
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
# 假设已经正确导入了必要的模块
from langchain_openai import ChatOpenAI
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage,
ChatMessage
)
# 创建一个 ChatOpenAI 实例,指定使用的模型为"gpt-4o-mini"
llm = ChatOpenAI(model=ai_model)
# 定义消息列表
messages = [
SystemMessage(content="描述一个顾客进入饭店并点餐的场景。你是一个幽默风趣的服务员。"), # 系统消息
HumanMessage(content="我进入饭店吃饭。"), # 用户消息
ChatMessage(role="assistant", content="欢迎光临,请问您几位?"), # 迎宾
HumanMessage(content="就我一位,我点菜。"), # 用户消息
ChatMessage(role="assistant", content="好的,这边请"), # 迎宾回应
HumanMessage(content="我想点一份牛肉炒饭,还有一份糖醋排骨。另外,我注意到糖醋排骨的价格比其他菜品要高一些,为什么呢?"), # 用户询问
AIMessage(content="?"), # AI 生成的服务员回应
]
# 调用 llm 对象的 invoke 方法,传入消息列表并打印响应内容
print(llm.invoke(messages).content)
给你瞅瞅机智的DeepSeek的回答
3.1.3 Embedding Models
嵌入模型创建一段文本的矢量表示
embed_query
:适用于单个文档
embed_documents
:适用于多个文档
下面是使用智谱清言的embed模型生成的文本矢量
import os
from dotenv import load_dotenv
load_dotenv()
base_url = os.getenv("ZHIPU_BASE_URL")
api_key = os.getenv("ZHIPU_API_KEY");
embed_model = os.getenv("EMBEDDING_MODEL")
from langchain_community.embeddings import ZhipuAIEmbeddings
# 创建一个 OpenAIEmbeddings 实例,指定使用的模型为 "text-embedding-3-large"
embed = ZhipuAIEmbeddings(
api_key=api_key,
model=embed_model,
)
# 使用 embed 对象嵌入查询文本并保存结果
result1 = embed.embed_query("我是A文档")
print(result1)
print(len(result1)) # 打印嵌入结果的长度
# 使用 embed 对象嵌入多个文档并保存结果
result2 = embed.embed_documents([
"我是A文档",
"我是B文档"
])
print(result2) # 打印嵌入的文档结果
print(len(result2)) # 打印嵌入文档的数量
print(len(result2[0])) # 打印第一个文档嵌入结果的长度
print(len(result2[1])) # 打印第二个文档嵌入结果的长度
3.2 Prompt
3.2.1 OutputParser
输出解析器
=>
当您想要返回以逗号分隔的项目列表时,可以使用此输出解析器
获取解析格式
from langchain.output_parsers import CommaSeparatedListOutputParser
# 创建 CommaSeparatedListOutputParser 实例
output_parser = CommaSeparatedListOutputParser()
# 获取格式说明并打印
print(output_parser.get_format_instructions())
# 定义一个包含逗号分隔值的回复
reply ='foo,bar,baz'
# 解析回复并打印解析结果
print(output_parser.parse(reply)) # 打印解析后的结果
给你瞅瞅提示词
解析日期时间格式。
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
from langchain_openai import ChatOpenAI
from langchain.output_parsers import DatetimeOutputParser
# 创建一个 DatetimeOutputParser 实例
output_parser = DatetimeOutputParser()
# 创建一个 ChatOpenAI 实例,使用 DeepSeek 模型
llm = ChatOpenAI(
model_name=ai_model
)
# 构造请求字符串
request = "中华人民共和国是什么时候成立的"
format_instructions = output_parser.get_format_instructions()
# 构造消息字典
messages = [{"role": "user", "content": f"{request}\n{format_instructions}"}]
# 使用构造的消息调用模型
result = llm.invoke(messages)
# 打印模型的响应内容
print("模型响应:", result)
# 假设 result 有 content 属性
response_text = result.content
parsed_result = output_parser.parse(response_text)
print("解析结果:", parsed_result)
输出
3.2.2 Prompts_module
prompt
基本使用
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
from langchain_openai import ChatOpenAI
from langchain.prompts.chat import HumanMessagePromptTemplate
from langchain_core.prompts import ChatPromptTemplate
from langchain.output_parsers import DatetimeOutputParser
# 创建一个 DatetimeOutputParser 实例
output_parser = DatetimeOutputParser()
# 创建一个 ChatOpenAI 实例,使用 gpt-4o-mini模型
llm = ChatOpenAI(
model_name=ai_model
)
# 创建聊天提示模板,包含用户消息的模板
chat_prompt = ChatPromptTemplate.from_messages(
[
HumanMessagePromptTemplate.from_template("{request}\n{format_instructions}"), # 用户请求和格式说明
]
)
# 格式化聊天提示,填充请求和格式说明
model_request = chat_prompt.format_prompt(
request="中华人民共和国是什么时候成立的", #用户请求的内容
format_instructions=output_parser.get_format_instructions() # 获取输出解析器的格式说明
)
# print(model_request) # 可以打印model_request 以查看格式化后的请求
result = llm.invoke(model_request) # 调用模型处理请求
print(result.content) # 打印模型的响应内容
print("------") # 分隔符
print(output_parser.parse(result.content))# 解析模型的响应内容并打印结果
prompt
使用变量
单变量
prompt
from langchain.prompts import PromptTemplate
# 创建一个包含{name}变量占位符的提示模板
template = PromptTemplate.from_template("给我讲个关于{name}的笑话")
print(template) # 打印提示模板对象
print("-------")
print(template.format(name=input("请输入一个名字")))
多角色自定义变量的
prompt
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.prompts.chat import SystemMessagePromptTemplate, HumanMessagePromptTemplate
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
llm = ChatOpenAI(
model=ai_model
)
template = ChatPromptTemplate.from_messages(
[
SystemMessagePromptTemplate.from_template("你是{product}的客服助手。你的名字叫{name}"),
HumanMessagePromptTemplate.from_template("{query}"),
]
)
# 格式化提示消息,填充产品名、助手名和用户查询
prompt = template.format_messages(
product="人工智能课堂",
name="方海亮",
query="你是谁"
)
# 打印格式化后的提示消息
print(prompt)
print("--------------")
print(llm.invoke(prompt).content)
解析模型的响应内容
import os
from dotenv import load_dotenv
from langchain.prompts.chat import HumanMessagePromptTemplate
from langchain_core.prompts import ChatPromptTemplate
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain_openai import ChatOpenAI
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
# 创建一个逗号分隔列表的输出解析器
output_parser = CommaSeparatedListOutputParser()
# 创建一个 ChatOpenAI 实例
llm = ChatOpenAI(
model_name=ai_model
)
# 创建一个聊天提示模板,包含人类消息的格式
chat_prompt = ChatPromptTemplate.from_messages(
[
HumanMessagePromptTemplate.from_template("{request}\n{format_instructions}") # 人类消息模板,包含请求和格式说明
]
)
# 格式化模型请求,传入具体请求和格式说明
model_request = chat_prompt.format_prompt(
request="给我5个性格特征", # 用户请求
format_instructions=output_parser.get_format_instructions() # 获取格式说明
)
# 使用 LLM 调用模型并获取结果
result = llm.invoke(model_request)
# 打印模型的响应结果
print(result)
print("-------")
# 解析模型的响应内容并打印解析后的结果
print(output_parser.parse(result.content))
看看DeepSeek返回的什么
3.2.3 prompt外部加载
加载
JSON
文件
json文件内容
{
"_type": "prompt",
"input_variables": ["adjective", "content"],
"template": "Tell me a {adjective} joke about {content}."
}
# 从文档当中加载prompt
from langchain.prompts import load_prompt
prompt = load_prompt("simple_prompt1.json")
print(prompt.format(adjective="funny", content="James"))
中文版的解决方案
json内容
{
"_type": "prompt",
"input_variables": ["讲述者", "听众", "形容词", "内容", "时间段"],
"template": "{讲述者} 给 {听众} 讲述了一个{形容词} 的关于 {内容} 的故事,在 {时间段} 期间。"
}
import codecs
import json
# 定义文件路径
file_path = "simple_prompt2.json"
# 读取文件并确保使用 UTF-8 编码
with codecs.open(file_path, "r", encoding="utf-8") as f:
content = f.read()
# 输出转码之后的内容
print(content)
# 解析 JSON 内容
print("---------")
prompt_data = json.loads(content)
# 获取模板字符串
template = prompt_data["template"]
print(template)
print("---------")
# 格式化输出
formatted_prompt = template.format(
讲述者="张三",
听众="李四",
形容词="有趣",
内容="猫",
时间段="文艺复兴时期"
)
# 打印格式化后的提示
print(formatted_prompt)
3.2.4 prompt zero_shot
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
# 导入必要的类库
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
# 创建一个提示模板,其中包含一个输入变量 "sample",它将被替换为实际值。
template = "请说一下{sample}的概念"
prompt = PromptTemplate(
input_variables=["sample"],
template=template
)
# 使用format方法来填充模板中的 "sample" 变量,并将其设置为 "零样本"
prompt_text = prompt.format(sample="零样本")
# 输出格式化的提示文本
print(prompt_text) # 输出: "请说一下零样本的概念"
llm = ChatOpenAI(
model=ai_model
)
result = llm.invoke(prompt_text)
print(result.content)
3.2.5 prompt few_shot
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_openai import ChatOpenAI
# 1.实例化模型
llm = ChatOpenAI(
model=ai_model
)
# 2.给出部分示例
examples = [
{"word": "明亮", "antonym": "黑暗"},
{"word": "新", "antonym": "旧"}
]
# 3.设置example_prompt
example_template = """
单词: {word}
反义词: {antonym}
"""
# 4.实例化example_prompt
example_prompt = PromptTemplate(
input_variables=["word", "antonym"],
template=example_template
)
# 5.实例化few-shot-prompt
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="给出每个单词的反义词",
suffix="单词:{input}反义词",
input_variables=["input"]
)
# 6.指定模型的输入
prompt_text = few_shot_prompt.format(input="漂亮")
print(prompt_text)
print("---------------")
# 7.将prompt_text输入模型
result = llm.invoke(prompt_text)
print(result.content)
3.3 Indexes_module
3.3.1 Loaders
loader txt
from langchain_community.document_loaders import TextLoader
# 创建一个TextLoader实例,指定要加载的文本文件路径及编码格式为utf-8
loader = TextLoader("./医疗数据.txt", encoding='utf8')
# 使用loader加载文档内容
doc = loader.load()
# 打印加载的文档内容
print(doc)
print("---------")
# 输出文档内容的长度
print(len(doc))
print("---------")
# 打印文档第一页内容的前10个字符
print(doc[0].page_content[:10])
loader pdf
from langchain_community.document_loaders import PyPDFLoader
# 创建一个PyPDFLoader实例,指定要加载的PDF文件路径
loader = PyPDFLoader("RAG.pdf")
# 加载并PDF
pages = loader.load()
# 加载并拆分PDF文件内容为多个页面对象
# pages = loader.load_and_split()
print(pages)
print("----------")
# 打印第14页的内容(因为列表索引从0开始,所以pages[13]对应的是第14页)
print(pages[7].page_content)
loader csv
from langchain_community.document_loaders import CSVLoader
# 创建一个CSVLoader实例,指定要加载的CSV文件路径及编码格式为utf-8
loader = CSVLoader("data.csv", encoding="utf-8")
# 加载CSV文件内容到一个包含多个记录的对象列表中
pages = loader.load()
# pages = loader.load_and_split()
# 打印pages的类型和长度
print(type(pages), len(pages))
# 打印第一个记录的类型
print(type(pages[0]))
# 打印第一个记录的内容
print(pages[0].page_content)
3.3.2 Splitters
create_documents
from langchain.text_splitter import CharacterTextSplitter
# 分割器实例化对象
# separator => 分割文本的字符或字符串
# chunk_size => 每个文本块的最大长度
# chunk_overlap => 文本块之间的重叠字符数
text_spliter = CharacterTextSplitter(
separator='',
chunk_size=10,
chunk_overlap=2,
)
# 对一句话进行分割
result = text_spliter.split_text("今天天气好晴朗,处处好风光啊好风光蝴蝶儿忙啊,蜜蜂也忙,小鸟儿忙着,白云也忙")
print(result)
print("**********")
# 对多个句子也就是文档切分
texts = text_spliter.create_documents(
[
"今天天气好晴朗,处处好风光啊好风光蝴蝶儿忙啊,蜜蜂也忙,小鸟儿忙着,白云也忙",
"分割文本的字符或字符串,每个文本块的最大长度,文本块之间的重叠字符数"
]
)
print(texts)
from langchain.text_splitter import RecursiveCharacterTextSplitter # 分割文本
from langchain_community.document_loaders import PyPDFLoader # 加载PDF文档
# 创建一个PyPDFLoader实例,参数是PDF文件的路径
loader = PyPDFLoader("RAG.pdf")
pages = loader.load()
# 创建一个RecursiveCharacterTextSplitter实例,定义文本分割规则
"""
separators =>
"\n\n": 表示两个连续的换行符,分割
"\n": 表示单个换行符,分割。
" ": 表示单个空格,分割。
"": 表示如果没有其他更好的分割点,可以在任意位置分割。
"""
text_splitter = RecursiveCharacterTextSplitter(
separators=["\n\n", "\n", " ", ""],
# 每个文本块的最大字符数
chunk_size=200,
# 文本块之间的重叠字符数
chunk_overlap=50,
# 是否在分割后的每个块中添加起始索引,便于后续追踪原文位置
add_start_index=True,
)
print([pages[2].page_content])
print("---------")
# 使用创建的文本分割器,对特定页的内容进行分割,此处以第13页为例
paragraphs = text_splitter.create_documents([pages[2].page_content])
# 遍历分割后的所有段落,并打印它们的内容
for para in paragraphs:
print(para.page_content)
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 创建一个PyPDFLoader实例,参数是PDF文件的路径
loader = PyPDFLoader("RAG.pdf")
pages = loader.load()
# 创建一个RecursiveCharacterTextSplitter实例,定义文本分割规则,使用tiktoken编码器进行分割
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
# 每个文本块的最大字符数
chunk_size=200,
# 文本块之间的重叠字符数
chunk_overlap=50,
)
# 打印第13页的内容(实际上是第14页,因为索引从0开始)
print(pages[3].page_content)
print("------------")
# 使用创建的文本分割器,对特定页的内容进行分割,此处以第13页为例
texts = text_splitter.split_text(pages[3].page_content)
# 打印分割后的所有段落及其数量
print(texts)
print(len(texts))
3.3.3 Embedding
txt
import os
from dotenv import load_dotenv
load_dotenv()
base_url = os.getenv("ZHIPU_BASE_URL")
api_key = os.getenv("ZHIPU_API_KEY");
embed_model = os.getenv("EMBEDDING_MODEL")
from langchain_community.embeddings import ZhipuAIEmbeddings
embeddings = ZhipuAIEmbeddings(
base_url=base_url,
api_key=api_key,
model=embed_model,
)
from langchain_community.document_loaders import CSVLoader
# 创建一个CSVLoader实例来加载指定路径的CSV文件,并指定编码为utf-8
loader = CSVLoader("data.csv", encoding="utf-8")
# 加载
pages = loader.load()
print(pages)
# 存放的是每一个trunk的embeding。
embeded_docs = embeddings.embed_documents([i.page_content for i in pages])
print(embeded_docs)
# 表示的是每一个trunk的embeding的维度
print(len(embeded_docs[0]))
示例:把embed数据存入chroma向量数据库并检索
import os
from dotenv import load_dotenv
load_dotenv()
base_url = os.getenv("ZHIPU_BASE_URL")
api_key = os.getenv("ZHIPU_API_KEY");
embed_model = os.getenv("EMBEDDING_MODEL")
import chromadb
chroma_client = chromadb.HttpClient(
host="127.0.0.1",
port=5333,
)
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain_community.embeddings import ZhipuAIEmbeddings
from langchain_chroma import Chroma
# 创建一个TextLoader实例来加载指定路径的文本文件,并指定编码为utf-8
loader = TextLoader("./医疗数据.txt", encoding='utf-8')
# 加载文本数据
pku_str = loader.load()
# 如果加载的数据是一个列表,则将其转换为字符串
if isinstance(pku_str, list):
# 使用列表推导式从Document对象中提取page_content属性,并用换行符连接成一个字符串
pku_str = "\n".join([doc.page_content for doc in pku_str])
# 创建一个CharacterTextSplitter实例来分割文本
text_splitter = CharacterTextSplitter(
chunk_size=100,
chunk_overlap=5
)
# 使用text_splitter来分割文本
texts = text_splitter.split_text(pku_str)
# 创建OpenAIEmbeddings实例用于文本嵌入
embedd = ZhipuAIEmbeddings(
api_key=api_key,
model=embed_model,
)
# 使用Chroma将分割后的文本向量化,并使用之前创建的embedd实例
docsearch = Chroma.from_texts(texts, embedd, client=chroma_client)
# 设置查询条件
query = "咽喉症状:咽干,打喷嚏:频繁打喷嚏,头部症状:头痛,是什么症状,需要吃什么药"
# 使用相似度搜索方法在向量数据库中查找与查询条件最相似的文档
result = docsearch.similarity_search(query)
# 打印搜索结果
print(result)
# 打印搜索结果的数量
print(len(result))
import os
from dotenv import load_dotenv
load_dotenv()
base_url = os.getenv("ZHIPU_BASE_URL")
api_key = os.getenv("ZHIPU_API_KEY");
embed_model = os.getenv("EMBEDDING_MODEL")
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain_community.embeddings import ZhipuAIEmbeddings
from langchain_chroma import Chroma
# 创建一个TextLoader实例来加载指定路径的文本文件,并指定编码为utf-8
loader = TextLoader("./医疗数据.txt", encoding='utf-8')
# 加载文本数据
pku_str = loader.load()
# 如果加载的数据是一个列表,则将其转换为字符串
if isinstance(pku_str, list):
# 使用列表推导式从Document对象中提取page_content属性,并用换行符连接成一个字符串
pku_str = "\n".join([doc.page_content for doc in pku_str])
# 创建一个CharacterTextSplitter实例来分割文本
text_splitter = CharacterTextSplitter(
chunk_size=20,
chunk_overlap=5
)
# 使用text_splitter来分割文本
texts = text_splitter.split_text(pku_str)
# 创建OpenAIEmbeddings实例用于文本嵌入
embeddings = ZhipuAIEmbeddings(
api_key=api_key,
model=embed_model,
)
# 使用Chroma将分割后的文本向量化,并使用之前创建的embedd实例
db = Chroma.from_texts(texts, embeddings, persist_directory='./new_db2')
db_new_connection = Chroma(persist_directory='./new_db2', embedding_function=embeddings)
# 设置查询条件
query = "咽喉症状:咽干,打喷嚏:频繁打喷嚏,头部症状:头痛,是什么症状,需要吃什么药"
# 使用相似度搜索方法在向量数据库中查找与查询条件最相似的文档
result = db_new_connection.similarity_search(query)
# 打印搜索结果
print(result)
# 打印搜索结果的数量
print(len(result))
3.3.4 Retrievers
import os
from dotenv import load_dotenv
load_dotenv()
base_url = os.getenv("ZHIPU_BASE_URL")
api_key = os.getenv("ZHIPU_API_KEY");
embed_model = os.getenv("EMBEDDING_MODEL")
from langchain_community.embeddings import ZhipuAIEmbeddings
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS
from langchain.text_splitter import CharacterTextSplitter
# 加载文档
loader = TextLoader('./医疗数据.txt', encoding='utf8')
docments = loader.load()
# 切分文档
text_spliter = CharacterTextSplitter(chunk_size=100,chunk_overlap=5)
texts = text_spliter.split_documents(docments)
print(texts)
# 实例化embedding模型
embed = ZhipuAIEmbeddings(
api_key=api_key,
model=embed_model,
)
db = FAISS.from_documents(texts, embed)
# 文档检索器
retriever = db.as_retriever(search_kwargs={"k": 1})
result = retriever.invoke("过敏性鼻炎用什么药物好?")
# 假设 result 是你的文档列表
print("结果")
for doc in result:
content = doc.page_content # 获取文档内容
print(content) # 打印文档内容
3.4 Memory_module
3.4.1 Chat Message
记忆存储
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain.schema import messages_from_dict, messages_to_dict
# 实例化对象
history = ChatMessageHistory()
# 添加历史信息
history.add_user_message("吃完了吗?")
history.add_ai_message("你说啥?")
# 保存历史信息到字典里
dicts = messages_to_dict(history.messages)
print(dicts)
print("****")
# 从字典转换成列表
new_message = messages_from_dict(dicts)
print(new_message)
3.4.2 Memory classes
序列号存储到文件
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
import pickle
from langchain.schema import messages_from_dict, messages_to_dict
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
# 初始化ChatOpenAI模型实例
llm = ChatOpenAI(
model=ai_model
)
# 创建一个对话链实例,使用上面初始化的ChatOpenAI模型,并设置verbose为True,这样可以在运行时输出更多的调试信息
conversation = ConversationChain(
llm=llm,
verbose=False # 设置了verbose=True以便查看提示。
)
# 使用对话链的predict方法来获取对输入"小明有4个苹果"的回答
result1 = conversation.predict(input="小明有4个苹果")
# 使用对话链的predict方法来获取对输入"小张有5个苹果"的回答
result2 = conversation.predict(input="小张有5个苹果")
# 使用对话链的predict方法来获取对输入"小明和小张一共有多少个苹果"的回答
result3 = conversation.predict(input="小明和小张一共有多少个苹果")
conversation.invoke(input="请通俗一点进行回答")
# 转换成字典
dicts = messages_to_dict(conversation.memory.chat_memory.messages)
print(dicts)
# 存储到文件
f = open("./memory", 'wb')
pickle.dump(dicts,f)
f.close()
再次添加对话
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
import pickle
from langchain.chains import ConversationChain
from langchain.schema import messages_from_dict
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain.memory import ConversationBufferMemory
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model=ai_model
)
# 使用pickle加载之前保存的内存数据
dicts_load = pickle.load(open("./memory", "rb"))
print(dicts_load)
print("-----------")
# 将加载的字典转换成消息列表
new_messages = messages_from_dict(dicts_load)
# 创建一个包含历史消息的聊天历史记录对象
retrieved_chat_history = ChatMessageHistory(messages=new_messages)
# 创建一个对话缓冲内存对象,并传入聊天历史记录
retrieved_memory = ConversationBufferMemory(
chat_memory=retrieved_chat_history
)
# 重新加载之前的对话链,并设置语言模型和对话内存
conversation_reload = ConversationChain(
llm=llm,
memory=retrieved_memory
)
# 向对话链输入新的话语
conversation_reload.predict(input="我回来了")
# 打印出对话链中的当前对话内存
print(conversation_reload.memory.buffer)
3.4.3 ConversationBufferWindowMemory
from langchain.memory import ConversationBufferWindowMemory
# 将历史记录作为消息列表获取
window = ConversationBufferWindowMemory(k=2)
window.save_context({"input": "第一轮问"}, {"output": "第一轮答"})
window.save_context({"input": "第二轮问"}, {"output": "第二轮答"})
window.save_context({"input": "第三轮问"}, {"output": "第三轮答"})
# 调用load_memory_variables方法,加载当前存储的记忆变量,并打印出来。
# 需要传递一个空字典 {}
print(window.load_memory_variables({}))
3.4.4 ConversationSummaryMemory
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
llm = ChatOpenAI(
model=ai_model
)
# 初始化对话链
conversation = ConversationChain(
llm=llm,
memory=ConversationSummaryMemory(
llm=llm,
buffer="以中文表示"
),
)
# 回合1
result = conversation("我明天要去北京,需要买车票。")
print(result)
print("1111111111111111111111111")
# 回合2
result = conversation("我是去北京看升旗仪式,听说天安门广场的升旗很有气势。")
print(result)
print("2222222222222222222222222")
# 回合3
result = conversation("我今天来到了售票站,我是来干嘛的呢?")
print(result)
3.5 Chains_module
3.5.1 single
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
from langchain_core.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain_openai import ChatOpenAI
# 定义模板
template = "{name}开了一个早餐店, 帮我取一个有吸引力的店名"
# 参数一 => 包含模板中所有变量的名称。
# 参数二 => 表示提示模板的字符串,待填充的变量位置
prompt = PromptTemplate(input_variables=["name"], template=template)
print(prompt)
# 实例化模型
llm = ChatOpenAI(model_name=ai_model)
# 构造Chain,将大模型与prompt组合在一起
chain = LLMChain(llm=llm, prompt=prompt)
# 执行Chain
result = chain.invoke({"name": "先知"})
print(f'result-->{result}')
3.5.2 llmchains
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
from langchain_core.prompts import PromptTemplate
from langchain.chains import LLMChain, SimpleSequentialChain
from langchain_openai import ChatOpenAI
# 创建第一条链
# 定义模板
template = "{name}开了一个早餐店, 帮我取一个有吸引力的点名"
prompt = PromptTemplate(input_variables=["name"], template=template)
llm = ChatOpenAI(model_name=ai_model)
# 构造Chain:第一条链
first_chain = LLMChain(llm=llm, prompt=prompt)
# 创建第二条链
# 定义模板
second_prompt = PromptTemplate(input_variables=["name"],template="{name}开店赚钱了,然后又开了一个公司,帮我取一个有吸引力的公司名")
# 创建第二条链
second_chain = LLMChain(llm=llm, prompt=second_prompt)
# 融合两条链:verbose为True的时候,显示模型推理过程,否则不显示
overall_chain = SimpleSequentialChain(
chains=[first_chain, second_chain],
verbose=True
)
# 使用链
result = overall_chain.invoke("亮神")
print(result)
3.6 Agents_module
import os
from dotenv import load_dotenv
load_dotenv()
ai_model = os.getenv("OPENAI_MODEL")
from langchain import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain.agents import load_tools, initialize_agent, AgentType
llm = ChatOpenAI(model=ai_model)
# 工具加载函数:利用工具来增强模型:llm-math计算,wikipedia
# 参数一 => 要加载的工具名称
# 参数二 => 语言模型
tools = load_tools(["llm-math", "wikipedia"], llm=llm)
# 初始化一个智能体(agent)
# 参数一 => 之前加载的工具
# 参数二 => 语言模型
# 参数三 => 智能体的类型,不需要针对特定任务进行训练
# 参数四 => 智能体在执行任务时是否输出详细的日志信息
# 参数五 => 智能体在处理输入时是否应该处理解析错误
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
handle_parsing_errors=True
)
prompt_template = "明朝建立什么时候,皇帝是谁?"
prompt = PromptTemplate.from_template(prompt_template)
res = agent.run(prompt)
print(res)