LangChain框架各组件详解与实践指南
LangChain是一个强大的框架,旨在简化使用大型语言模型(LLM)构建应用程序的过程。它提供了一系列标准化组件,使开发者能够轻松地将LLM与各种数据源和工具集成在一起。本报告将深入探讨LangChain的核心组件,并提供实际代码示例。
1. LLMs与Chat Models
LangChain中的模型接口分为两种主要类型:LLMs和Chat Models,它们代表了与大型语言模型交互的两种不同方式。
1. LLMs
LLMs接口用于处理纯文本输入并返回纯文本输出的模型。这是与语言模型交互的最基本形式。
python
from langchain_openai import OpenAI
# 初始化一个基本的LLM
llm = OpenAI(temperature=0)
# 使用LLM进行预测
result = llm.invoke("解释量子计算的基本原理")
print(result)
2. Chat Models
Chat Models是一种更高级的模型形式,它的输入和输出是格式化的聊天消息,而不是纯文本[^7]。这种模式更适合构建对话应用。
python
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
# 初始化聊天模型
chat = ChatOpenAI(temperature=0)
# 创建消息列表
messages = [
SystemMessage(content="你是一个有帮助的AI助手"),
HumanMessage(content="写一个简短的诗歌,主题是春天")
]
# 获取回复
response = chat.invoke(messages)
print(response)
2. Messages
在LangChain中,消息是聊天模型的基本输入和输出单位。LangChain提供了几种不同类型的消息[^6]:
1. 消息类型
- AIMessage: 表示AI助手返回的信息
- HumanMessage: 表示用户输入的信息
- SystemMessage: 用于设定AI的行为规则或背景信息
- ChatMessage: 可以自定义角色的通用消息类型
- FunctionMessage/ToolMessage: 用于函数调用结果的消息类型
python
from langchain_core.messages import (
AIMessage,
HumanMessage,
SystemMessage,
ChatMessage,
ToolMessage
)
# 创建不同类型的消息
system_message = SystemMessage(content="你是一个专业的数据科学家")
human_message = HumanMessage(content="解释一下随机森林算法")
ai_message = AIMessage(content="随机森林是一种集成学习方法...")
custom_message = ChatMessage(role="analyst", content="补充一点关于超参数调优的信息")
# 在对话中使用这些消息
chat = ChatOpenAI()
response = chat.invoke([system_message, human_message])
print(response)
3. Prompts
Prompt是与语言模型交互的核心,LangChain提供了多种工具来管理和优化提示[^14][^1]。
PromptTemplate
PromptTemplate允许创建可重用的文本模板,其中包含可动态插入的变量。
python
from langchain_core.prompts import PromptTemplate
# 定义一个简单的提示模板
template = PromptTemplate(
input_variables=["product", "review"],
template="产品:{product}\n评论:{review}\n这个评论的情感是什么?"
)
# 使用模板生成具体的提示
prompt = template.format(
product="无线耳机",
review="音质非常好,但电池续航一般"
)
print(prompt)
# 与LLM结合使用
llm = OpenAI(temperature=0)
result = llm.invoke(prompt)
print(result)
ChatPromptTemplate
类似地,ChatPromptTemplate用于创建聊天模型的提示模板:
python
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate
# 创建消息模板
system_template = "你是一个专家{role}"
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)
human_template = "给我解释{concept},用浅显易懂的语言"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
# 组合成聊天提示模板
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
# 格式化提示
formatted_messages = chat_prompt.format_messages(
role="物理学家",
concept="相对论"
)
# 使用聊天模型
chat = ChatOpenAI()
response = chat.invoke(formatted_messages)
print(response)
from openai import OpenAI
from langchain import PromptTemplate
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage
import os
load_dotenv('.env')
# 设置 API Key 和模型参数
llm = ChatOpenAI(
api_key=os.getenv("apikey"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen-plus" # 替换为需要的模型名称
)
chat_template = ChatPromptTemplate.from_messages([
("system", "你是专业blog作者"), # 这里可以直接用 ("role", content) 形式
("human", "{input}"), # HumanMessage.from_template() 也可以替换为 ("human", "{input}")
])
# 生成填充后的消息
messages = chat_template.format_messages(input="写一篇关于大模型分词原理的文章")
print(messages)
4. Output Parsers
输出解析器帮助将LLM的文本输出转换为结构化的数据格式,使其更易于在应用程序中使用[^3][^9]。
StructuredOutputParser
python
from langchain_core.output_parsers import StructuredOutputParser, ResponseSchema
# 定义响应模式
response_schemas = [
ResponseSchema(name="answer", description="问题的答案"),
ResponseSchema(name="source", description="信息的来源")
]
# 创建解析器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
# 获取格式说明
format_instructions = output_parser.get_format_instructions()
# 创建包含格式说明的提示
prompt = PromptTemplate(
template="请尽可能回答用户的问题。\n{format_instructions}\n问题:{question}",
input_variables=["question"],
partial_variables={"format_instructions": format_instructions}
)
# 生成提示并获取响应
formatted_prompt = prompt.format(question="巴黎的首都是什么?")
model = OpenAI(temperature=0)
response = model.invoke(formatted_prompt)
# 解析响应
parsed_response = output_parser.parse(response)
print(parsed_response)
PydanticOutputParser
PydanticOutputParser使用Pydantic模型来定义输出结构,提供更强大的数据验证功能[^9]。
python
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
# 定义输出数据结构
class Joke(BaseModel):
setup: str = Field(description="笑话的铺垫")
punchline: str = Field(description="笑话的包袱")
# 创建解析器
parser = PydanticOutputParser(pydantic_object=Joke)
# 创建提示
prompt = PromptTemplate(
template="请讲一个笑话。\n{format_instructions}",
input_variables=[],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
# 获取响应
formatted_prompt = prompt.format()
model = OpenAI(temperature=0.7)
response = model.invoke(formatted_prompt)
# 解析输出
joke = parser.parse(response)
print(f"铺垫: {joke.setup}")
print(f"包袱: {joke.punchline}")
5. Vector Stores与Retrievers
这些组件用于存储和检索非结构化数据,如文本,使LLM能够访问外部知识[^4][^10]。
Vector Stores
向量存储是一种特殊的数据库,用于存储文本的向量表示,并支持语义搜索。
python
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
# 创建文档
documents = [
Document(
page_content="机器学习是人工智能的一个子领域",
metadata={"source": "ai-textbook", "page": 15}
),
Document(
page_content="深度学习是基于神经网络的机器学习方法",
metadata={"source": "ai-textbook", "page": 42}
),
Document(
page_content="Python是最流行的编程语言之一",
metadata={"source": "programming-guide", "page": 7}
)
]
# 创建向量存储
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(documents, embeddings)
# 使用相似度搜索
results = vectorstore.similarity_search("什么是机器学习?", k=2)
for doc in results:
print(doc.page_content)
print(doc.metadata)
print("---")
Retrievers
检索器是向量存储的轻量级包装器,提供标准化接口用于检索文档[^4][^10]。
python
# 从向量存储创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
# 检索相关文档
retrieved_docs = retriever.invoke("人工智能的应用")
for doc in retrieved_docs:
print(doc.page_content)
print("---")
# 使用最大边际相关性(MMR)搜索
mmr_retriever = vectorstore.as_retriever(search_type="mmr", search_kwargs={"k": 2})
mmr_docs = mmr_retriever.invoke("编程语言")
for doc in mmr_docs:
print(doc.page_content)
print("---")
6. Agents
Agent(智能体)是LangChain的高级组件,它结合了LLM和一系列工具,使模型能够做出决策并执行复杂任务[^8]。
python
from langchain.agents import Tool, initialize_zero_shot_agent
from langchain.memory import ConversationBufferMemory
from langchain_openai import OpenAI
# 定义工具
class WeatherTool:
def run(self, query):
# 在实际应用中,这里会调用天气API
return "今天天气晴朗,温度25°C"
class CalculatorTool:
def run(self, query):
# 在实际应用中,这里会解析查询并执行计算
try:
return str(eval(query))
except:
return "无法计算该表达式"
# 创建工具列表
tools = [
Tool(
name="Weather",
func=WeatherTool().run,
description="当你需要查询天气信息时使用"
),
Tool(
name="Calculator",
func=CalculatorTool().run,
description="当你需要进行数学计算时使用"
)
]
# 初始化LLM
llm = OpenAI(temperature=0)
# 创建记忆组件
memory = ConversationBufferMemory(memory_key="chat_history")
# 创建Agent
agent = initialize_zero_shot_agent(
tools,
llm,
memory=memory,
verbose=True # 显示Agent的思考过程
)
# 使用Agent
response = agent.run("今天天气怎么样?")
print(response)
response = agent.run("计算23乘以45")
print(response)
7. LangChain Expression Language (LCEL)与Chains
Chains是LangChain中的基本构建块,允许将多个组件组合成一个工作流。LCEL提供了一种声明式语法来创建这些工作流。
python
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# 创建简单的翻译应用
# 1. 定义提示模板
prompt = ChatPromptTemplate.from_template(
"将以下{input_language}文本翻译成{output_language}:\n\n{text}"
)
# 2. 初始化模型
model = ChatOpenAI(temperature=0)
# 3. 定义输出解析器
output_parser = StrOutputParser()
# 4. 使用LCEL创建链
chain = (
{"input_language": RunnablePassthrough(),
"output_language": RunnablePassthrough(),
"text": RunnablePassthrough()}
| prompt
| model
| output_parser
)
# 5. 运行链
result = chain.invoke({
"input_language": "中文",
"output_language": "英语",
"text": "人工智能正在改变世界"
})
print(result)
8.实际应用:构建简单的问答系统
下面是一个结合多个组件的实际应用示例:
python
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# 1. 加载文档
loader = TextLoader("data.txt") # 替换为实际文件路径
documents = loader.load()
# 2. 分割文档
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
splits = text_splitter.split_documents(documents)
# 3. 创建向量存储
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(splits, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
# 4. 创建提示模板
template = """根据以下上下文回答问题:
上下文:
{context}
问题:{question}
请提供详细且准确的回答:"""
prompt = ChatPromptTemplate.from_template(template)
# 5. 设置模型和输出解析器
model = ChatOpenAI(temperature=0)
output_parser = StrOutputParser()
# 6. 定义检索函数
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
# 7. 构建链
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| model
| output_parser
)
# 8. 使用链回答问题
question = "文档中讨论了哪些主题?"
answer = rag_chain.invoke(question)
print(answer)
9. 总结
LangChain提供了一系列强大的组件,使开发者能够轻松构建复杂的LLM应用程序。通过组合这些组件,可以创建各种各样的应用,从简单的问答系统到复杂的智能代理。关键是理解每个组件的功能和相互关系,然后根据具体需求选择和组合适当的组件。
随着LangChain的不断发展,其API可能会有所变化,建议开发者定期查阅官方文档以获取最新信息[^11]。通过实践和探索,你将能够充分发挥这个强大框架的潜力,创建令人印象深刻的AI应用。