LangChain应用指南:构建基于大语言模型的智能应用
LangChain是一个开源框架,专注于将大语言模型(如GPT、LLaMA等)与其他工具和数据源结合,构建端到端的应用。
引言
LangChain是一个强大的框架,旨在帮助开发者更高效地构建基于大语言模型(LLM)的应用。无论是构建聊天机器人、自动化文档处理,还是开发复杂的问答系统,LangChain都提供了丰富的工具和模块。本文将带你深入了解LangChain的核心功能,并通过实际示例展示如何应用它。
一、LangChain简介
LangChain是一个开源框架,专注于将大语言模型(如GPT、LLaMA等)与其他工具和数据源结合,构建端到端的应用。
核心功能:链(Chains)将多个任务串联成高效的工作流;代理(Agents)使模型能够动态选择工具完成任务;记忆(Memory)支持上下文记忆,实现流畅的多轮对话;数据加载(Data Loaders)从多种数据源加载数据,确保信息来源丰富多样;提示模板(Prompt Templates)则标准化提示词设计,提升模型输出的准确性和一致性。这些功能共同构成了 LangChain 强大的开发框架,助力开发者高效构建基于大型语言模型的应用。
适用场景:聊天机器人、文档问答系统、自动化数据处理、知识库构建等。
二、LangChain的核心模块快速概览
1、 模型调用:
首先安装必要的库,这里默认安装最新版:
!pip install langchain # 安装 LangChain 框架本身
!pip install openai # 安装 OpenAI 的 Python SDK(软件开发工具包)
!pip install langchain-openai # 安装 LangChain 的 OpenAI 集成包
安装完成后,需要使用 OpenAI 的模型,从环境变量中获取你的 OpenAI API 密钥,调用ChatOpenAI()进行连接后就可以进行提问。
import os
import openai
from langchain.chat_models import ChatOpenAI
# 从环境变量中读取 API 密钥和基础 URL
openai.api_key = os.environ.get('OPENAI_API_KEY') # 环境变量中储存 API 密钥
openai.api_base = os.environ.get('OPENAI_API_BASE') # 环境变量中储存基础 URL
# 创建 ChatOpenAI 实例
llm = ChatOpenAI() # 默认使用'gpt-3.5-turbo'模型
# 直接提供问题,并调用 llm
response = llm.invoke("你是什么模型")
2、prompt template的使用
我们可以创建prompt template, 并引入一些变量到prompt template中,这样在应用的时候更加灵活。from_messages 是一个类方法,用于从一组消息中创建一个聊天提示模板。这些消息可以是系统消息(system)或用户消息(user),它们定义了聊天的上下文和用户输入。
from langchain_core.prompts import ChatPromptTemplate # 用于构建聊天提示模板的工具
# 创建一个聊天提示模板,定义了聊天的上下文和用户输入
prompt = ChatPromptTemplate.from_messages([
("system", "You are the technical writer"), # 系统消息,定义聊天机器人的角色为“技术作家”
("user", "{input}") # 用户消息,其中"{input}"是一个变量占位符,用于动态插入用户输入的内容
])
# 我们可以把prompt和具体llm的调用和在一起
chain = prompt | llm # 使用管道操作符(|)将prompt和llm连接起来,形成一个链式调用
chain.invoke({"input": "你是什么模型?"}) # # 调用chain,并传入具体的用户输入
我们也可以在链式调用(chain)中加入一个输出解析器(output_parser),以确保最终的输出格式。
from langchain_core.output_parsers import StrOutputParser # 一个输出解析器,用于将语言模型的输出解析为字符串格式。
output_parser = StrOutputParser() # 创建一个字符串输出解析器
chain = prompt | llm | output_parser # 将prompt、llm和output_parser连接起来,形成完整的链式调用
chain.invoke({"input": "你是什么模型?"}) # 调用chain,并传入具体的用户输入
3、实现RAG+Langchain
若大模型对所问问题理解不到位,可基于外部知识,增强大模型回复。
# 结合相关知识的来生成更好地答案,分几步:
# 第一步: 寻找关于相应的一些文库,并抓取内容
# 第二步: 把文库切块(trunks)并存放到向量数据库中
# 第三步: 对于新的问题,我们首选从vector store中提取trunks, 并融合到llm的prompt里
from langchain_community.document_loaders import WebBaseLoader # 一个用于加载网页内容的工具,通常用于从网页中提取文档或数据。
# 创建WebBaseLoader实例,传入网页链接
loader = WebBaseLoader("https://openai.com/research/video-generation-models-as-world-simulators")")
docs = loader.load() # 调用load方法加载网页内容
# 使用openai embedding
from langchain_openai import OpenAIEmbeddings
# 创建 OpenAIEmbeddings 实例
embeddings = OpenAIEmbeddings()
使用 langchain 库中的 RecursiveCharacterTextSplitter 和 FAISS 向量数据库来处理文本数据,并将其存储到向量数据库中。
from langchain_community.vectorstores import FAISS # 导入 FAISS 向量数据库
from langchain.text_splitter import RecursiveCharacterTextSplitter # 导入 RecursiveCharacterTextSplitter
# 用于将长文本递归地分割为较小的片段
text_splitter = RecursiveCharacterTextSplitter()
# 把 docs 切分成 trunks,在这里只有一个 doc,因为我们只抓取了一个页面
documents = text_splitter.split_documents(docs)
# 存放在向量数据库中。把 trunk 转化成向量时候用的 embedding 工具为 OpenAIEmbeddings
vector = FAISS.from_documents(documents, embeddings)
1. 给定input,从vector database搜索相似的documents(trunks)
2. documents加入到prompt里面(prompt template, 变量比如{context})
3. prompt call LLM, LLM返回response(答案)
4. 通过output parser得到格式化完之后的结果
# 这个链式调用会将一个文档列表格式化为一个提示,然后将该提示传递给一个语言模型(LLM)。
from langchain.chains.combine_documents import create_stuff_documents_chain # 用于创建一个链式调用,该链将多个文档组合成一个提示
# 定义一个 ChatPromptTemplate,用于将文档和问题格式化为一个提示
prompt = ChatPromptTemplate.from_template("""Answer the following question based only on the provided context:
<context>
{context}
</context>
Question: {input}""")
# 创建一个链式调用,将文档链和语言模型组合在一起
document_chain = create_stuff_documents_chain(llm, prompt)
from langchain.chains import create_retrieval_chain # 用于从向量数据库中检索相关信息,并生成最终的回答。
# 将向量数据库转换为检索器
retriever = vector.as_retriever()
# 创建检索链,结合检索器和文档链
retrieval_chain = create_retrieval_chain(retriever, document_chain)
# 调用检索链,传入用户输入的查询
response = retrieval_chain.invoke({"input": "什么是deepseek?"})
# 从响应中提取并打印最终的回答
print(response["answer"])
4、Agent
大模型Agent(AI Agent)是一种基于大型语言模型(LLM)构建的智能体,它能够感知环境、进行决策并执行任务以实现特定目标。Agent的核心在于其自主性和主动性,它不仅能够理解用户的需求,还能像人类一样主动完成一系列关联性任务。其基本架构可以总结为:Agent = LLM(大模型) + 记忆 + 规划 + 工具使用。
-
记忆:包括短期记忆(如会话上下文)和长期记忆(如用户偏好、历史任务等),帮助Agent记住信息以便更好地完成任务。
-
规划:将复杂任务分解为多个可执行的子任务,并评估执行策略。
-
工具使用:通过调用外部工具(如API、数据库等)来扩展自身能力。
# 导入一个工具创建函数,用于生成一个能够检索信息的工具。
from langchain.tools.retriever import create_retriever_tool
# 创建一个检索工具
retriever_tool = create_retriever_tool(
retriever, # 检索器对象,负责从数据源中检索信息
"Sora", # 工具的名称,标识这个工具的功能
"Search for information about Sora. For any questions about Sora, you must use this tool!" # 工具的描述,说明其用途和使用场景
)
# 将创建的检索工具放入一个列表中
tools = [retriever_tool]
# 导入LangChain OpenAI模块中的ChatOpenAI类
from langchain_openai import ChatOpenAI
# 导入提供了从 LangChain 社区中拉取预定义的 prompt 模板的功能。
from langchain import hub
# 用于创建一个基于 OpenAI 函数的代理(Agent)以及执行代理的任务,管理工具的调用和结果的处理。
from langchain.agents import create_openai_functions_agent, AgentExecutor
# 从LangChain的hub中拉取一个预定义的prompt模板
prompt = hub.pull("hwchase17/openai-functions-agent")
# 初始化一个OpenAI语言模型
llm = ChatOpenAI(model="gpt-4", temperature=0) # 使用GPT-4模型,设置温度为0(表示输出更确定)
# 创建一个OpenAI函数代理(Agent)
agent = create_openai_functions_agent(llm, tools, prompt) # 将语言模型、工具和prompt传递给代理
# 初始化AgentExecutor
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) # 将代理和工具传递给执行器,并设置为详细模式
# 调用agent_executor的invoke方法,处理用户输入
agent_executor.invoke({"input": "What is the Sora model?"})
补充:PromptTemplate和ChatPromptTemplate的区别。
-
PromptTemplate适用于简单的文本生成任务,如生成描述、解释等。 -
ChatPromptTemplate适用于对话场景,如聊天机器人、问答系统等。
from langchain.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template(
"编写一段关于{主题}的小红书宣传文案,需要采用{风格}语气"
)
prompt_template.format(主题="美国留学", 风格="幽默")
# 输出:'编写一段关于美国留学的小红书宣传文案,需要采用幽默语气'
from langchain_core.prompts import ChatPromptTemplate
chat_template = ChatPromptTemplate.from_messages(
[
("system", "你是AI助教,你的名字是{name}."),
("human", "你好"),
("ai", "你好,有什么可以帮到您?"),
("human", "{user_input}"),
]
)
messages = chat_template.format_messages(name="张三", user_input="你的名字是什么?")
llm.invoke(messages)
# 输出:'你好,我的名字是张三,我是你的AI助教。有什么可以帮你的?'
chain = chat_template | llm
chain.invoke({"name":"张三", "user_input":"你的名字是什么?"})
# 输出:'你好,我是AI助教,我的名字是张三。'
# 流式进行输出
for chunk in llm.stream(messages):
print(chunk.content, end="", flush=True)
对于给定的例子提供简短的prompt:
from langchain.prompts import (
ChatPromptTemplate,
FewShotChatMessagePromptTemplate,
)
# 示例数据:输入和输出的示例对
examples = [
{"input": "2+2", "output": "4"},
{"input": "2+3", "output": "5"},
]
# 定义单个示例的模板
example_prompt = ChatPromptTemplate.from_messages(
[
("human", "{input}"), # 用户输入
("ai", "{output}"), # AI 输出
]
)
# 创建 FewShotChatMessagePromptTemplate,用于将示例数据格式化为提示
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt, # 单个示例的模板
examples=examples, # 示例数据
)
# 打印格式化后的 FewShot 示例提示
print(few_shot_prompt.format())
# 输出:Human: 2+2
# AI: 4
# Human: 2+3
# AI: 5
# 定义最终的提示模板
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "You are a wondrous wizard of math."), # 系统指令
few_shot_prompt, # 少样本示例
("human", "{input}"), # 用户输入
]
)
# 将最终的提示模板与语言模型连接,形成一个链式调用
chain = final_prompt | llm
# 调用链,传入输入并获取响应
chain.invoke({"input": "4+6"})
# 输出:10
5、Cache
对于之前问题的答案,直接从cache中返回,减少成本、提高效率。
%%time
from langchain.cache import InMemoryCache # 简单的内存缓存实现,用于存储语言模型的调用结果。
from langchain.globals import set_llm_cache # 用于设置全局的缓存机制。
set_llm_cache(InMemoryCache()) # 将全局的缓存设置为 InMemoryCache 的实例。这意味着后续的语言模型调用结果将被缓存到内存中。
# 第一次,需要直接调用,需要消耗时间
llm.invoke("讲一个冷笑话")
%%time
# 第二次调用,直接从cache中获取
llm.invoke("讲一个冷笑话")
6、追踪token的使用
from langchain.callbacks import get_openai_callback # 上下文管理器,用于捕获和记录语言模型调用的详细信息
from langchain_openai import ChatOpenAI
# 初始化语言模型
llm = ChatOpenAI(model_name="gpt-4") # 使用 GPT-4 模型
# 进入上下文管理器
with get_openai_callback() as cb:
result = llm.invoke("最近心情怎么样?")
print(cb)
"""输出
Tokens Used: 58
Prompt Tokens: 16
Prompt Tokens Cached: 0
Completion Tokens: 42
Reasoning Tokens: 0
Successful Requests: 1
Total Cost (USD): $0.003
"""
with get_openai_callback() as cb:
result = llm.invoke("Tell me three jokes")
result2 = llm.invoke("Tell me a joke")
print(cb)
"""输出
Tokens Used: 91
Prompt Tokens: 22
Prompt Tokens Cached: 0
Completion Tokens: 69
Reasoning Tokens: 0
Successful Requests: 2
Total Cost (USD): $0.0048000000000000004
"""
三、参考资料
Langchain官方文档
更多推荐




所有评论(0)