随着大型语言模型(LLM)技术的飞速发展,如何高效、灵活地构建基于LLM的应用程序成为了开发者面临的重要课题。LangChain作为一个开源框架,应运而生,旨在简化LLM应用的开发流程,将LLM的强大能力与外部数据源和计算资源无缝结合。本文将深入探讨LangChain的应用架构和核心组件,并通过代码案例展示其在实际开发中的应用,帮助读者更好地理解和利用LangChain构建强大的LLM应用。
LangChain 作为一个专业的大语言模型开发框架,在 LLM 应用架构中占据重要地位。它为基于语言模型的应用程序提供了完整的设计和开发架构,如同大厦的蓝图,决定了整个应用的结构和功能。
LangChain 的核心优势在于其强大的集成能力,能够将 LLM 模型、向量数据库、提示词管理、外部知识源和工具等组件有机整合。通过这种统一的架构设计,开发者可以灵活构建各种 LLM 应用。LangChain 使得应用程序具备两大核心能力:
LangChain 采用分布式架构设计,支持高效、可扩展的语言数据处理。其基于微服务的设计理念,将每个处理链作为独立服务运行,实现了:
此架构天然支持与外部数据源和工具的集成,显著增强了 LLM 的实际应用能力。
总之,LangChain 可以将 LLM 模型、向量数据库、交互层 Prompt、外部知识、外部工具整合到一起,进而可以自由构建 LLM 应用。
LangChain 框架的核心在于其模块化的设计,它将构建 LLM 应用所需的各种功能分解为独立的组件,这些组件可以灵活组合,以满足不同的应用需求。LangChain 包含六个主要组成部分:Models、Prompts、Indexes、Memory、Chains 和 Agents [1]。
Models 是 LangChain 与各种语言模型交互的接口,是整个框架的基础。它抽象了不同类型模型的调用方式,使得开发者可以使用统一的接口来操作不同的 LLM。在 LangChain 中,Models 主要包括 ChatModels、Embeddings 和 LLMs。
聊天模型是 LangChain 中专门用于处理对话式交互的语言模型接口。与传统的文本输入/文本输出模型不同,聊天模型以"聊天消息"作为输入和输出,这使得它们更适合构建多轮对话系统。LangChain 定义了以下几种核心消息类型:
这些消息类型有助于开发者更好地组织和管理对话内容,特别是在使用大型语言模型(如 GPT-3)时,能够区分用户输入、AI 响应和系统信息,从而更有效地处理用户请求、生成适当的响应,并维护对话的上下文和状态。
聊天模型使用场景:
上下文缓存:为了优化成本和提高响应速度,LangChain 提供了缓存功能。当用户问同一个问题时,如果结果已被缓存,就可以直接返回,减少对 LLM API 的调用。LangChain 支持内存缓存和多种数据库缓存方案。
流式响应:流式响应允许模型逐步生成响应内容并实时返回给用户,而不是等待整个响应生成完毕。这显著提升了用户体验,尤其是在处理长文本生成任务时,用户可以即时看到部分结果,减少等待焦虑。LangChain 提供了多种工具和组件,可以轻松集成和实现流式响应这一功能。
LangChain 支持与多种模型提供商的集成,包括但不限于:
在使用聊天模型时,可以配置多种参数来控制模型行为:
LangChain 支持异步调用和批处理操作,提高处理效率:
ainvoke()
方法进行非阻塞调用batch()
方法同时处理多个请求stream()
方法获取流式响应嵌入模型是一种将离散的高维数据(如单词、句子、图片等)映射到连续的低维向量空间的技术。这个低维向量空间中的点称为"嵌入"(embedding)。嵌入模型的主要目的是捕捉输入数据中的语义或特征信息,使得相似的输入在嵌入空间中距离更近。它在文档、文本或大量数据的总结、问答场景中尤为重要,通常与向量数据库结合使用,实现高效的向量匹配和信息检索。
特点:
应用场景:文本相似度计算、信息检索、分类和聚类。
文本嵌入模型:
多模态嵌入模型:
大型语言模型(Large Language Models, LLMs)是一种深度学习模型,通常基于 Transformer 架构,具有数以亿计甚至数以百亿计的参数。LLM 通过在大规模文本语料库上进行训练,能够生成、理解和处理自然语言文本。
特点:
应用场景:对话系统、文本生成、问答系统。
LangChain 和 LLMs 的关系:LangChain 是一个开源框架,旨在将大型语言模型(如 GPT-4)与外部数据源和计算资源结合起来,以实现复杂的 NLP 应用。LangChain 提供了一个框架,使开发者可以轻松地集成和扩展大型语言模型,通过组件化设计增强交互性,并提升性能和效率。可以说,LLMs 是 LangChain 的核心,LangChain 继承并支持了众多大语言模型。
嵌入模型(Embedding Model)和大语言模型(Large Language Model, LLM)是自然语言处理(NLP)领域中的两类重要模型,它们在设计目的、功能和应用场景上有明显的区别。
特性 | 嵌入模型(Embedding Model) | 大语言模型(Large Language Model, LLM) |
---|---|---|
目的 | 将离散数据映射到低维向量空间,捕捉语义或特征信息 | 生成、理解和处理自然语言文本 |
功能 | 向量化、相似度计算、信息检索、分类、聚类 | 文本生成、对话、翻译、摘要、问答等 |
核心优势 | 无需训练即可实时添加新内容,成本较低,适用于相似性搜索 | 强大的自然语言生成和理解能力,适用于复杂 NLP 任务 |
应用场景 | 文本相似度计算、信息检索、分类和聚类 | 对话系统、文本生成、问答系统 |
嵌入模型相比大语言模型的 fine-tuning 最大的优势就是,不用进行训练,并且可以实时添加新的内容,而不用加一次新的内容就训练一次,并且各方面成本要比 fine-tuning 低很多。
基础语言模型是指只在大规模文本语料中进行了预训练的模型,未经过指令和下游任务微调、以及人类反馈等任何对齐优化。当前绝大部分的大语言模型都是 Decoder-only 的模型结构。
基础语言模型的特点:
一个提示词(Prompt)指的是输入模型的内容,通常由多个组件构成。LangChain 提供了多个类和函数,使构建和处理提示变得简单。提示词是引导语言模型生成特定类型输出的关键。除了直接编写聊天模型的消息类型外,LangChain 还提供了通过提示词间接实现聊天模型的新方式。
提示词模板是一种预定义的文本结构,其中包含变量和固定文本部分,用于引导语言模型生成特定类型的输出。这些模板可以帮助模型更准确地理解上下文,并生成符合预期的响应。当用户需要输入多个类似的 prompt 时,生成一个 prompt 模板是一个很好的解决方案,可以节省用户的时间和精力。提示模板可以接受任意数量的输入变量,并可以格式化生成提示。
提示词模板的类型:
通过 PipelinePrompt
可以将多个 PromptTemplate
提示模板进行组合,组合的优点是可以很方便地进行复用。例如,常见的系统角色提示词通常遵循 {introduction} {example} {start}
这样的结构。
清晰性和具体性:
上下文设置:
示例驱动:
基于用户输入的动态提示:
多语言提示词支持:
迭代优化:
安全考虑:
Indexes 在 LangChain 中扮演着连接语言模型与外部数据的关键角色,尤其是在处理大量非结构化数据时。它允许 LLM 访问和理解其训练数据之外的信息,从而增强其回答特定问题或执行特定任务的能力。Indexes 通常与向量数据库结合使用,以实现高效的数据检索和管理。
核心功能:
支持的文档格式:
高级加载功能:
分割方法:
分割参数优化:
本地向量存储:
云端向量存储:
性能考虑:
相似性搜索:
高级检索技术:
应用场景:
Memory 是 LangChain 中用于管理和维护对话历史的关键组件。在 LLM 应用中,尤其是对话式应用,模型需要记住之前的对话内容才能进行连贯的交流。Memory 模块提供了多种机制来存储和检索对话的上下文信息。
核心功能:
ConversationBufferMemory:
ConversationBufferWindowMemory:
ConversationSummaryMemory:
ConversationKGMemory:
Token管理:
性能优化:
应用场景:
Chains 是 LangChain 中用于将多个组件(如 LLM、Prompts、Parsers 等)组合在一起,以实现特定任务的强大工具。它们允许开发者定义一系列操作步骤,将一个组件的输出作为另一个组件的输入,从而构建复杂的工作流。Chains 是 LangChain 灵活性的核心体现,它使得开发者能够以模块化的方式构建复杂的 LLM 应用。
核心功能:
基础链:
文档处理链:
高级链:
管道模式:
条件执行:
继承基类:
组合现有链:
应用场景:
Agents 是 LangChain 中最强大的组件之一,它赋予了语言模型"决策"和"行动"的能力。Agent 不仅仅是简单地执行预定义的 Chain,而是能够根据用户的输入和当前环境,自主地选择并执行一系列工具(Tools)来完成任务。这使得 LLM 应用能够与外部世界进行更复杂的交互,解决更开放式的问题。
核心功能:
决策循环:
推理模式:
零样本Agent:
专用Agent:
多模态Agent:
预置工具:
自定义工具开发:
from langchain.tools import Tool
def custom_calculator(expression: str) -> str:
"""安全的数学表达式计算器"""
try:
result = eval(expression)
return f"计算结果: {result}"
except:
return "无效的数学表达式"
calculator_tool = Tool(
name="Calculator",
func=custom_calculator,
description="用于计算数学表达式"
)
工具安全考虑:
性能优化:
可靠性提升:
核心概念:
多Agent协作:
学习型Agent:
应用场景:
以下是使用 LangChain 聊天模型的示例,展示了如何发送单条消息、多条消息以及批量处理消息。
import os
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
# 设置您的OpenAI API Key
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY"
# 初始化聊天对象
chat = ChatOpenAI(openai_api_key="YOUR_API_KEY")
# 1. 发送单条HumanMessage
print("\n--- 单条HumanMessage示例 ---")
response_single = chat.invoke([HumanMessage(content="Translate this sentence from English to French: I love programming.")])
print(response_single.content)
# 2. 发送多条消息(SystemMessage 和 HumanMessage)
print("\n--- 多条消息示例 ---")
messages_multi = [
SystemMessage(content="You are a helpful assistant that translates English to French."),
HumanMessage(content="I love programming.")
]
response_multi = chat.invoke(messages_multi)
print(response_multi.content)
# 3. 批量处理消息
print("\n--- 批量处理消息示例 ---")
batch_messages = [
[
SystemMessage(content="You are a helpful assistant that translates English to French."),
HumanMessage(content="I love programming.")
],
[
SystemMessage(content="You are a helpful assistant that translates English to French."),
HumanMessage(content="I love artificial intelligence.")
],
]
# 使用generate方法进行批量处理
# 注意:LangChain 0.2.x 版本中,ChatOpenAI 的 generate 方法可能已被 invoke 或 batch 替代,
# 或者需要更复杂的处理方式。这里为了与PDF文档保持一致,保留generate的描述,
# 但实际代码可能需要调整为循环调用invoke或使用RunnableParallel等。
# 鉴于实际环境和API版本差异,此处仅为概念性示例,实际运行可能需要根据LangChain版本调整。
# 假设的批量处理逻辑 (实际可能需要循环调用 invoke 或使用更高级的并行处理)
results_batch = []
for msg_list in batch_messages:
results_batch.append(chat.invoke(msg_list))
for i, res in enumerate(results_batch):
print(f"Batch {i+1} Result: {res.content}")
LangChain 提供了缓存功能,可以减少对 LLM API 的调用,从而节省成本并加快响应速度。以下是使用 SQLiteCache 进行缓存的示例:
import langchain
from langchain_openai import ChatOpenAI
from langchain_community.cache import SQLiteCache
# 设置语言模型的缓存数据存储的地址
langchain.llm_cache = SQLiteCache(database_path=".langchain.db")
# 加载 llm 模型
# 请替换为您的实际API Key和base_url
llm = ChatOpenAI(
model="gpt-4",
openai_api_key="YOUR_API_KEY",
base_url="https://api.openai.com/v1/" # 替换为您的实际API Base URL
)
# 第一次向模型提问
print("\n--- 第一次提问 (会进行API调用并缓存) ---")
result1 = llm.invoke('tell me a joke')
print(result1.content)
print ('\n******************* 缓存验证 *************************\n')
# 第二次向模型提问同样的问题 (会从缓存中获取,不会进行API调用)
print("\n--- 第二次提问 (会从缓存中获取) ---")
result2 = llm.invoke('tell me a joke')
print(result2.content)
# 清理缓存(可选)
# import os
# if os.path.exists(".langchain.db"):
# os.remove(".langchain.db")
# print("\n缓存文件 .langchain.db 已删除。")
流式响应可以提供即时反馈,提升用户体验。以下是一个概念性的示例,展示了 LangChain 如何与 FastAPI 结合实现流式响应。请注意,此示例需要安装 fastapi
和 uvicorn
,并且 ConversationalRetrievalChain
的 generate_responses
方法在最新版本中可能有所不同,这里仅为演示概念。
# 由于此代码涉及 FastAPI 和复杂的链调用,且PDF中提供的代码片段可能与最新LangChain版本不完全兼容,
# 故此处提供一个简化版的流式输出概念示例,不依赖FastAPI,仅展示LLM的stream方法。
# 实际生产环境请参考LangChain官方文档中关于Streaming和FastAPI的最新集成方式。
import os
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
# 设置您的OpenAI API Key
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY"
llm = ChatOpenAI(
model="gpt-4",
openai_api_key="YOUR_API_KEY",
base_url="https://api.openai.com/v1/", # 替换为您的实际API Base URL
streaming=True # 开启流式传输
)
print("\n--- 流式响应示例 ---")
print("AI 回复 (流式输出): ")
# 使用stream方法获取流式响应
for chunk in llm.stream([HumanMessage(content="Tell me a long story about a brave knight.")]):
print(chunk.content, end="", flush=True)
print("\n")
# 原始PDF中FastAPI示例的伪代码结构(仅供参考,不直接运行)
'''
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import time
from langchain.chains import ConversationalRetrievalChain
from langchain.llms import OpenAI
app = FastAPI()
# 初始化 Langchain 模型 (此处为伪代码,实际需要更复杂的初始化)
# llm = OpenAI(api_key='your-api-key')
# chain = ConversationalRetrievalChain(llm)
def generate_stream_response(prompt):
# 使用 Langchain 生成响应 (伪代码,实际需要调用链或LLM的流式方法)
# responses = chain.generate_responses(prompt)
# for response in responses:
# yield response
# time.sleep(0.1) # 模拟生成过程中的延迟
yield "This is a simulated stream response part 1. "
time.sleep(0.5)
yield "This is part 2. "
time.sleep(0.5)
yield "And this is the final part."
@app.post("/chat")
async def chat(prompt: str):
return StreamingResponse(generate_stream_response(prompt), media_type="text/plain")
# 运行应用程序:uvicorn example:app --reload
'''
以下是使用 OpenAIEmbeddings 将文本转换为嵌入向量的示例:
import os
from langchain_openai import OpenAIEmbeddings
# 设置您的OpenAI API Key
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY"
# 初始化嵌入模型
embeddings = OpenAIEmbeddings(openai_api_key="YOUR_API_KEY")
# 把文本通过嵌入模型向量化
text_to_embed = 'hello world'
res = embeddings.embed_query(text_to_embed)
print(f"\n--- 嵌入模型示例 ---")
print(f"文本: '{text_to_embed}'")
print(f"嵌入向量的前5个维度: {res[:5]}")
print(f"嵌入向量的长度: {len(res)}")
以下是使用 LangChain 定义和调用 LLM 的示例,包括阻塞式获取结果和流式响应。
import os
from langchain_openai import OpenAI
# 设置您的OpenAI API Key
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY"
# 实例化一个LLM模型
# 注意:text-davinci-002 等旧模型可能已被弃用,建议使用 gpt-3.5-turbo-instruct 或其他新模型
llm = OpenAI(
openai_api_key="YOUR_API_KEY",
model_name="gpt-3.5-turbo-instruct", # 建议使用此模型或更新的模型
temperature=0.7, # 发散度,0-1之间,越高越随机
max_tokens=50, # 最大生成token数
# max_retries=10, # 发生错误后重试次数
# max_concurrency=5, # 最大并发请求次数
# cache=True # 开启缓存,需要配置llm_cache,如2.1.4节所示
)
# 1. 使用 invoke 方法获取阻塞式结果
print("\n--- LLM invoke 示例 (阻塞式) ---")
response_invoke = llm.invoke("Tell me a short, funny joke.")
print(response_invoke)
# 2. 使用 stream 方法获取流式响应
print("\n--- LLM stream 示例 (流式) ---")
print("AI 回复 (流式输出): ")
for chunk in llm.stream("Tell me a long story about a magical forest."):
print(chunk, end="", flush=True)
print("\n")
# 3. 使用 batch 方法进行批量处理 (LangChain 0.2.x 推荐使用 invoke 的列表输入)
print("\n--- LLM batch 示例 (批量处理) ---")
# 在LangChain 0.2.x中,通常直接将一个列表的输入传递给invoke方法即可实现批量处理
questions = [
"What is the capital of France?",
"What is 2+2?"
]
batch_responses = llm.batch(questions)
for i, res in enumerate(batch_responses):
print(f"Question {i+1}: {questions[i]}")
print(f"Answer {i+1}: {res}")
print("-" * 20)
以下示例展示了如何使用 ChatPromptTemplate
和 PromptTemplate
创建和格式化提示词模板。
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage
# --- ChatPromptTemplate 示例 ---
print("\n--- ChatPromptTemplate 示例 ---")
template = "You are a helpful assistant that translates {input_language} to {output_language}."
human_template = "{text}"
chat_prompt = ChatPromptTemplate.from_messages([
("system", template),
("human", human_template),
])
mes1 = chat_prompt.format_messages(input_language="English", output_language="French", text="I love programming.")
for e in mes1:
print(e)
print("\n--- ChatPromptTemplate 多个变量示例 ---")
chat_template_multi_var = ChatPromptTemplate.from_messages(
[
("system", "You are a helpful AI bot. Your name is {name}."),
("human", "Hello, how are you doing? My name is {user_name}."),
("ai", "I'm doing well, thanks! How can I help you today?"),
("human", "{user_input}"),
]
)
messages_multi_var = chat_template_multi_var.format_messages(name="Bob", user_name="Alice", user_input="What is your name?")
for msg in messages_multi_var:
print(msg)
# --- PromptTemplate 示例 ---
print("\n--- PromptTemplate 示例 ---")
prompt_template = PromptTemplate.from_template(
"Tell me a {adjective} joke about {content}."
)
message_formatted = prompt_template.format(adjective="funny", content="chickens")
print(f"===message== {message_formatted}")
print("\n--- PromptTemplate 自动推断 input_variables 示例 ---")
prompt_template_auto_infer = PromptTemplate.from_template(
"Tell me a {adjective} joke about {content}."
)
print(f"=====input_variables======= {prompt_template_auto_infer.input_variables}")
message_auto_infer = prompt_template_auto_infer.format(adjective="silly", content="ducks")
print(f"===message== {message_auto_infer}")
PipelinePrompt
在 LangChain 0.2.x 版本中可能不再直接作为独立类存在,其功能通常通过 RunnableSequence
或自定义链来实现。这里提供一个概念性的示例,展示如何通过组合 PromptTemplate
来构建更复杂的提示逻辑。
from langchain_core.prompts import PromptTemplate
# 定义第一个提示模板:介绍
introduction_template = PromptTemplate.from_template(
"You are an expert interviewer. Your task is to interview a famous person.\nIntroduction: {introduction_text}"
)
# 定义第二个提示模板:示例
example_template = PromptTemplate.from_template(
"Example dialogue:\nInterviewer: {interviewer_example}\nFamous Person: {person_example}"
)
# 定义第三个提示模板:开始对话
start_template = PromptTemplate.from_template(
"Start the interview now. Interviewer: {start_question}"
)
# 组合这些模板 (概念性组合,实际可能通过RunnableSequence或自定义链实现)
# 假设我们有一个函数或链来按顺序组合这些部分
def combine_prompts(intro, example, start):
return f"{intro}\n\n{example}\n\n{start}"
# 格式化各个部分
intro_formatted = introduction_template.format(introduction_text="Today we have the honor of speaking with a renowned scientist.")
example_formatted = example_template.format(interviewer_example="Tell us about your latest discovery.", person_example="It was a breakthrough in quantum physics.")
start_formatted = start_template.format(start_question="Welcome! What inspired you to pursue science?")
# 组合最终的提示
final_prompt = combine_prompts(intro_formatted, example_formatted, start_formatted)
print("\n--- 组合提示词模板示例 ---")
print(final_prompt)
# 实际在LangChain中,更推荐使用RunnableSequence来构建复杂的Prompt组合
# from langchain_core.runnables import RunnableSequence
# combined_prompt = RunnableSequence(introduction_template, example_template, start_template)
# 这种方式更符合LangChain 0.2.x 的设计理念
Indexes 主要用于处理和检索外部数据,通常与向量数据库结合使用。以下是一个使用 LangChain 加载文档、分割文本并存储到向量数据库(这里使用内存中的 ChromaDB 作为示例)的简化流程。
import os
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
# 设置您的OpenAI API Key
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY"
# 1. 创建一个示例文档
example_document_path = "./example_document.txt"
with open(example_document_path, "w", encoding="utf-8") as f:
f.write("LangChain 是一个用于开发由语言模型驱动的应用程序的框架。它使得应用程序能够:具有上下文感知能力:将语言模型连接到上下文来源(提示指令,少量的示例,需要回应的内容),并实现自主性:允许语言模型与其环境进行交互。LangChain 的核心组件包括 Models, Prompts, Indexes, Memory, Chains, Agents。")
f.write("\n\nIndexes 在 LangChain 中扮演着连接语言模型与外部数据的关键角色。它允许 LLM 访问和理解其训练数据之外的信息,从而增强其回答特定问题或执行特定任务的能力。")
# 2. 文档加载器 (Document Loaders)
print("\n--- Indexes 示例: 文档加载 ---")
loader = TextLoader(example_document_path)
documents = loader.load()
print(f"加载的文档数量: {len(documents)}")
print(f"第一个文档内容预览: {documents[0].page_content[:100]}...")
# 3. 文本分割器 (Text Splitters)
print("\n--- Indexes 示例: 文本分割 ---")
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0)
splitted_docs = text_splitter.split_documents(documents)
print(f"分割后的文档块数量: {len(splitted_docs)}")
for i, doc in enumerate(splitted_docs):
print(f"块 {i+1}: {doc.page_content}")
# 4. 向量存储 (Vector Stores) 和 嵌入模型 (Embeddings)
print("\n--- Indexes 示例: 向量存储和嵌入 ---")
embeddings = OpenAIEmbeddings(openai_api_key="YOUR_API_KEY")
# 使用 Chroma 作为内存中的向量存储
# 注意:实际应用中,您会使用持久化的向量数据库
vectorstore = Chroma.from_documents(documents=splitted_docs, embedding=embeddings)
# 5. 检索器 (Retrievers)
print("\n--- Indexes 示例: 检索器 ---")
query = "LangChain 的核心组件有哪些?"
retriever = vectorstore.as_retriever()
retrieved_docs = retriever.invoke(query)
print(f"查询: \"{query}\"")
print(f"检索到的相关文档块数量: {len(retrieved_docs)}")
for i, doc in enumerate(retrieved_docs):
print(f"检索到的块 {i+1}: {doc.page_content}")
# 清理示例文档
os.remove(example_document_path)
Memory 用于在对话中维护上下文。以下是一个使用 ConversationBufferMemory
的简单示例。
from langchain_core.messages import HumanMessage, AIMessage
from langchain.memory import ConversationBufferMemory
print("\n--- Memory 示例 ---")
# 初始化记忆模块
memory = ConversationBufferMemory()
# 添加对话消息
memory.chat_memory.add_user_message("你好,我是Alice。")
memory.chat_memory.add_ai_message("你好Alice,有什么可以帮助你的吗?")
memory.chat_memory.add_user_message("我叫什么名字?")
# 获取对话历史
conversation_history = memory.load_memory_variables({})
print("当前对话历史:")
for message in conversation_history["history"]:
if isinstance(message, HumanMessage):
print(f"Human: {message.content}")
elif isinstance(message, AIMessage):
print(f"AI: {message.content}")
# 结合LLM使用记忆
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
# 设置您的OpenAI API Key
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY"
llm = ChatOpenAI(openai_api_key="YOUR_API_KEY", temperature=0.7)
# 创建一个对话链,并传入记忆模块
conversation = ConversationChain(
llm=llm,
memory=memory, # 使用上面定义的memory
verbose=True # 打印详细的执行过程
)
# 进行对话
print("\n--- 结合LLM的Memory示例 ---")
response = conversation.invoke("我叫什么名字?")
print(f"LLM Response: {response['response']}")
# 再次获取对话历史,可以看到新的消息已被添加
print("\n更新后的对话历史:")
updated_history = memory.load_memory_variables({})
for message in updated_history["history"]:
if isinstance(message, HumanMessage):
print(f"Human: {message.content}")
elif isinstance(message, AIMessage):
print(f"AI: {message.content}")
Chains 用于将多个组件组合起来,以实现特定任务。以下是一个使用 LLMChain
和 SimpleSequentialChain
的示例。
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain.chains import LLMChain, SimpleSequentialChain
# 设置您的OpenAI API Key
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY"
llm = ChatOpenAI(openai_api_key="YOUR_API_KEY", temperature=0.7)
print("\n--- Chains 示例: LLMChain ---")
# 1. LLMChain 示例:翻译链
# 定义提示模板
translation_prompt = PromptTemplate(
input_variables=["text", "source_language", "target_language"],
template="Translate the following text from {source_language} to {target_language}:\n\"{text}\"
")
# 创建LLMChain
translation_chain = LLMChain(llm=llm, prompt=translation_prompt)
# 调用链
text_to_translate = "Hello, how are you?"
source_lang = "English"
target_lang = "French"
result_translation = translation_chain.invoke({
"text": text_to_translate,
"source_language": source_lang,
"target_language": target_lang
})
print(f"原始文本: {text_to_translate}")
print(f"翻译结果: {result_translation['text']}")
print("\n--- Chains 示例: SimpleSequentialChain ---")
# 2. SimpleSequentialChain 示例:创意写作链
# 第一个链:生成一个主题
theme_prompt = PromptTemplate(
input_variables=["topic"],
template="Generate a creative and interesting theme for a short story about {topic}."
)
theme_chain = LLMChain(llm=llm, prompt=theme_prompt)
# 第二个链:根据主题写一个故事开头
story_start_prompt = PromptTemplate(
input_variables=["theme"],
template="Write the opening paragraph of a short story based on the following theme: {theme}"
)
story_start_chain = LLMChain(llm=llm, prompt=story_start_prompt)
# 组合成顺序链
creative_writing_chain = SimpleSequentialChain(chains=[theme_chain, story_start_chain], verbose=True)
# 调用顺序链
story_topic = "a magical forest"
result_story = creative_writing_chain.invoke(story_topic)
print(f"\n故事主题: {story_topic}")
print(f"故事开头:\n{result_story['output']}")
Agents 赋予了语言模型决策和行动的能力,使其能够自主地选择并执行工具来完成任务。以下是一个使用 initialize_agent
创建一个简单 Agent 的示例,该 Agent 可以使用搜索工具。
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_react_agent
from langchain_core.tools import Tool
from langchain_community.utilities import WikipediaAPIWrapper
from langchain_core.prompts import ChatPromptTemplate
# 设置您的OpenAI API Key
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY"
llm = ChatOpenAI(openai_api_key="YOUR_API_KEY", temperature=0)
print("\n--- Agents 示例 ---")
# 1. 定义工具
# 这里使用Wikipedia作为示例工具
wikipedia = WikipediaAPIWrapper()
wikipedia_tool = Tool(
name="Wikipedia",
func=wikipedia.run,
description="useful for when you need to answer questions about general knowledge."
)
tools = [wikipedia_tool]
# 2. 定义Agent的Prompt
# LangChain 0.2.x 推荐使用 create_react_agent 来创建Agent
# 需要一个Prompt,其中包含agent_scratchpad用于Agent的思考过程
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"), # 代理的思考过程
])
# 3. 创建Agent
agent = create_react_agent(llm, tools, prompt)
# 4. 创建AgentExecutor
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 5. 调用Agent
question = "What is the capital of France?"
print(f"\nAgent 提问: {question}")
response = agent_executor.invoke({"input": question})
print(f"Agent 回答: {response['output']}")
question_complex = "Who is the current president of the United States and what is their main policy on climate change?"
print(f"\nAgent 提问: {question_complex}")
response_complex = agent_executor.invoke({"input": question_complex})
print(f"Agent 回答: {response_complex['output']}")
LangChain 作为一个强大的 LLM 应用开发框架,通过其模块化的设计和丰富的功能组件,极大地简化了基于大型语言模型的应用程序的开发过程。它将 LLM、向量数据库、提示词、外部知识和工具等元素有机地整合在一起,使得开发者能够构建出具有上下文感知能力、自主性和高度交互性的智能应用。
从 Models 到 Prompts,再到 Indexes、Memory、Chains 和 Agents,LangChain 的每一个核心组件都扮演着不可或缺的角色,共同构成了构建复杂 LLM 应用的基石。通过深入理解这些组件的功能和相互关系,开发者可以更高效地设计、实现和部署各种创新性的 LLM 应用,从而在人工智能时代释放 LLM 的巨大潜力。
随着 LangChain 社区的不断发展和完善,以及底层 LLM 技术的持续进步,我们有理由相信,LangChain 将在未来的 LLM 应用开发中发挥越来越重要的作用,推动人工智能技术在各个领域的广泛应用。
以下是一个综合案例,展示如何使用LangChain的多个核心组件构建一个完整的智能文档问答系统。这个系统集成了文档加载、向量存储、检索、记忆和对话等功能。
import os
import tempfile
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
class DocumentQASystem:
def __init__(self, openai_api_key: str):
"""初始化文档问答系统"""
self.api_key = openai_api_key
# 初始化模型
self.llm = ChatOpenAI(
openai_api_key=self.api_key,
model="gpt-3.5-turbo",
temperature=0.7
)
self.embeddings = OpenAIEmbeddings(openai_api_key=self.api_key)
# 初始化记忆
self.memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="answer"
)
# 向量存储
self.vectorstore = None
self.qa_chain = None
def load_documents(self, text_content: str):
"""加载和处理文档"""
# 创建临时文件
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt', encoding='utf-8') as f:
f.write(text_content)
temp_file_path = f.name
try:
# 文档加载
loader = TextLoader(temp_file_path, encoding='utf-8')
documents = loader.load()
# 文本分割
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
length_function=len,
)
splits = text_splitter.split_documents(documents)
# 创建向量存储
self.vectorstore = Chroma.from_documents(
documents=splits,
embedding=self.embeddings,
persist_directory="./chroma_db"
)
print(f"成功加载文档,分割为 {len(splits)} 个块")
finally:
# 清理临时文件
os.unlink(temp_file_path)
def setup_qa_chain(self):
"""设置问答链"""
if not self.vectorstore:
raise ValueError("请先加载文档")
# 创建检索器
retriever = self.vectorstore.as_retriever(
search_type="similarity",
search_kwargs={"k": 3}
)
# 自定义提示词模板
system_template = """你是一个专业的文档分析助手。请基于提供的上下文信息回答用户的问题。
上下文信息:
{context}
请遵循以下原则:
1. 仅基于提供的上下文信息回答问题
2. 如果上下文中没有相关信息,请明确说明
3. 回答要准确、简洁、有用
4. 可以引用具体的文档片段"""
prompt = ChatPromptTemplate.from_messages([
("system", system_template),
MessagesPlaceholder(variable_name="chat_history"),
("human", "{question}")
])
# 创建对话检索链
self.qa_chain = ConversationalRetrievalChain.from_llm(
llm=self.llm,
retriever=retriever,
memory=self.memory,
return_source_documents=True,
verbose=True,
combine_docs_chain_kwargs={"prompt": prompt}
)
def ask_question(self, question: str):
"""提问并获取答案"""
if not self.qa_chain:
raise ValueError("请先设置问答链")
response = self.qa_chain.invoke({"question": question})
return {
"answer": response["answer"],
"source_documents": response.get("source_documents", []),
"chat_history": self.memory.chat_memory.messages
}
def get_conversation_history(self):
"""获取对话历史"""
return self.memory.chat_memory.messages
# 使用示例
def main():
# 设置API Key
api_key = "YOUR_OPENAI_API_KEY"
# 创建问答系统
qa_system = DocumentQASystem(api_key)
# 示例文档内容
document_content = """
LangChain是一个强大的框架,专门用于开发由语言模型驱动的应用程序。
它的核心优势在于:
1. 模块化设计:LangChain将复杂的LLM应用分解为可重用的组件
2. 丰富的集成:支持多种LLM提供商和第三方工具
3. 灵活的链式组合:可以将多个组件链接成复杂的工作流
4. 内置的记忆管理:支持对话历史的维护和管理
5. 强大的代理系统:允许LLM自主选择和使用工具
LangChain的主要组件包括:
- Models:与各种语言模型的统一接口
- Prompts:提示词模板和管理系统
- Indexes:文档加载、分割和检索系统
- Memory:对话历史管理
- Chains:组件链接和工作流管理
- Agents:智能代理和工具使用
在实际应用中,LangChain被广泛用于构建聊天机器人、问答系统、
文档分析工具、代码助手等各种AI应用。
"""
try:
# 加载文档
print("正在加载文档...")
qa_system.load_documents(document_content)
# 设置问答链
print("正在设置问答系统...")
qa_system.setup_qa_chain()
# 进行问答
questions = [
"LangChain的主要优势是什么?",
"LangChain有哪些核心组件?",
"除了刚才提到的组件,还有其他重要特性吗?"
]
for question in questions:
print(f"\n问题:{question}")
response = qa_system.ask_question(question)
print(f"回答:{response['answer']}")
# 显示引用的文档片段
if response['source_documents']:
print("\n引用来源:")
for i, doc in enumerate(response['source_documents']):
print(f"片段 {i+1}: {doc.page_content[:200]}...")
print("-" * 80)
# 显示对话历史
print("\n=== 对话历史 ===")
history = qa_system.get_conversation_history()
for i, message in enumerate(history):
role = "用户" if message.type == "human" else "助手"
print(f"{role}: {message.content}")
except Exception as e:
print(f"错误:{e}")
if __name__ == "__main__":
main()
这个综合案例展示了以下LangChain组件的集成使用:
这个基础框架可以扩展为:
设计原则:
安全考虑:
缓存优化:
并发处理:
成本控制:
性能监控:
调试技巧:
LangChain 作为一个强大的 LLM 应用开发框架,通过其模块化的设计和丰富的功能组件,极大地简化了基于大型语言模型的应用程序的开发过程。它将 LLM、向量数据库、提示词、外部知识和工具等元素有机地整合在一起,使得开发者能够构建出具有上下文感知能力、自主性和高度交互性的智能应用。
核心价值体现:
模型能力提升:
框架演进方向:
生态系统发展:
垂直领域应用:
企业级应用:
入门学习路径:
进阶发展方向:
持续学习建议:
技术挑战:
发展机遇:
从 Models 到 Prompts,再到 Indexes、Memory、Chains 和 Agents,LangChain 的每一个核心组件都扮演着不可或缺的角色,共同构成了构建复杂 LLM 应用的基石。通过深入理解这些组件的功能和相互关系,开发者可以更高效地设计、实现和部署各种创新性的 LLM 应用,从而在人工智能时代释放 LLM 的巨大潜力。
随着 LangChain 社区的不断发展和完善,以及底层 LLM 技术的持续进步,我们有理由相信,LangChain 将在未来的 LLM 应用开发中发挥越来越重要的作用,推动人工智能技术在各个领域的广泛应用,为人类社会的发展做出更大的贡献。
对于希望在AI领域发展的开发者和研究者来说,掌握LangChain不仅是技术能力的提升,更是参与未来AI应用生态建设的重要基础。