Python与智能体:如何使用LangChain和LlamaIndex构建LLM应用
大家好,今天我们来聊聊如何使用Python,结合LangChain和LlamaIndex这两个强大的框架,构建基于大型语言模型(LLM)的智能体应用。LLM的应用场景非常广泛,例如智能客服、文档问答、数据分析等等。LangChain和LlamaIndex的出现,极大地简化了构建这些应用的过程。
1. LLM应用面临的挑战
直接使用LLM API,虽然可以完成很多任务,但构建复杂的应用往往会面临以下挑战:
- 上下文管理: LLM有上下文长度限制,如何处理超出限制的长文档?
- 知识整合: 如何将外部知识库(如数据库、文档)整合到LLM中?
- 任务编排: 如何将复杂任务分解成多个步骤,并让LLM协同完成?
- 可观测性: 如何追踪LLM的推理过程,方便调试和改进?
LangChain和LlamaIndex正是为了解决这些问题而诞生的。
2. LangChain:构建LLM应用的工具箱
LangChain是一个用于开发由语言模型驱动的应用程序的框架。它提供了一系列的组件,可以帮助我们轻松地构建复杂的LLM应用。
- 模型 (Models): 提供与各种LLM的接口,如OpenAI、Hugging Face等。
- 提示词 (Prompts): 管理和优化输入到LLM的提示词,提高输出质量。
- 链 (Chains): 将多个组件组合在一起,形成一个完整的pipeline。
- 索引 (Indexes): 针对大量文档建立索引,提高检索效率。
- 记忆 (Memory): 在对话中保存历史信息,实现上下文感知。
- 代理 (Agents): 让LLM根据输入自主选择工具,完成复杂任务。
- 回调 (Callbacks): 提供对LLM执行过程的监控和干预机制。
2.1 安装LangChain
pip install langchain
pip install openai # 如果使用OpenAI模型
2.2 使用LLM模型
首先,我们需要配置LLM API的密钥。以OpenAI为例:
import os
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY" # 替换为你的API密钥
from langchain.llms import OpenAI
llm = OpenAI(model_name="text-davinci-003", temperature=0.7) # 初始化OpenAI模型
output = llm("What is the capital of France?")
print(output)
这里,OpenAI
类封装了OpenAI的模型,model_name
指定模型名称,temperature
控制生成文本的随机性。
2.3 提示词模板
使用提示词模板可以更有效地控制LLM的输出。
from langchain.prompts import PromptTemplate
prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
print(chain.run("colorful socks"))
PromptTemplate
允许我们定义带有占位符的模板,然后通过run
方法传入参数。LLMChain
则将LLM和提示词模板组合在一起,形成一个简单的链。
2.4 链 (Chains)
LangChain的核心概念之一就是链。链可以将多个组件连接起来,形成一个工作流。例如,我们可以创建一个链,先用LLM生成文本摘要,再用另一个LLM对摘要进行翻译。
from langchain.chains import SimpleSequentialChain
# 步骤1:生成摘要
prompt1 = PromptTemplate(
input_variables=["topic"],
template="Write a concise summary of the following text: {topic}",
)
chain1 = LLMChain(llm=llm, prompt=prompt1)
# 步骤2:翻译成法语
prompt2 = PromptTemplate(
input_variables=["summary"],
template="Translate the following summary to french: {summary}",
)
chain2 = LLMChain(llm=llm, prompt=prompt2)
# 组合成一个Sequential Chain
overall_chain = SimpleSequentialChain(chains=[chain1, chain2], verbose=True) # verbose=True 可以显示中间步骤
output = overall_chain.run("The quick brown fox jumps over the lazy dog.")
print(output)
SimpleSequentialChain
按顺序执行链中的每个步骤,并将上一步的输出作为下一步的输入。
2.5 记忆 (Memory)
为了让LLM记住对话历史,可以使用ConversationBufferMemory
。
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
conversation = ConversationChain(
llm=llm, memory=memory, verbose=True
) # verbose=True 可以显示memory内容
print(conversation.predict(input="Hi, my name is John."))
print(conversation.predict(input="What is my name?"))
ConversationBufferMemory
会将所有对话内容存储在内存中,并在每次调用LLM时传递给它。
2.6 代理 (Agents)
代理是LangChain中最强大的组件之一。它可以让LLM自主选择工具,完成复杂任务。例如,我们可以让LLM使用搜索引擎查找信息,然后根据信息回答问题。
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
# 加载工具
tools = load_tools(["serpapi", "llm-math"], llm=llm) # 需要安装 serpapi: pip install serpapi
# 初始化Agent
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 运行Agent
print(agent.run("What is the capital of France? What is 2 + 2?"))
这里,load_tools
加载了serpapi
(搜索引擎)和llm-math
(数学计算)两个工具。initialize_agent
创建了一个代理,AgentType.ZERO_SHOT_REACT_DESCRIPTION
指定了代理的类型,verbose=True
可以显示代理的推理过程。
3. LlamaIndex:LLM的知识引擎
LlamaIndex是一个用于连接LLM和外部数据的框架。它可以帮助我们构建基于LLM的知识库问答应用。
- 数据连接器 (Data Connectors): 从各种数据源(如文档、网站、数据库)加载数据。
- 索引 (Index): 将数据转换为LLM可以理解的格式,并建立索引。
- 查询引擎 (Query Engine): 根据用户的问题,从索引中检索相关信息,并传递给LLM。
- 聊天引擎 (Chat Engine): 构建交互式对话界面,支持多轮对话。
3.1 安装LlamaIndex
pip install llama-index
3.2 数据加载
首先,我们需要从数据源加载数据。LlamaIndex支持多种数据源,例如文档、网站、数据库等。
from llama_index import SimpleDirectoryReader
documents = SimpleDirectoryReader('./data').load_data() # 从./data目录加载所有文件
SimpleDirectoryReader
可以从指定目录加载所有文件。
3.3 构建索引
加载数据后,我们需要构建索引。LlamaIndex支持多种索引类型,例如VectorStoreIndex
、TreeIndex
、KeywordTableIndex
等。
from llama_index import VectorStoreIndex
index = VectorStoreIndex.from_documents(documents)
VectorStoreIndex
会将文档嵌入到向量空间中,方便后续的相似性搜索。
3.4 查询索引
构建索引后,我们可以使用查询引擎来检索相关信息。
query_engine = index.as_query_engine()
response = query_engine.query("What is the document about?")
print(response)
as_query_engine
方法创建了一个查询引擎,query
方法根据用户的问题从索引中检索相关信息,并传递给LLM生成答案。
3.5 聊天引擎
LlamaIndex还提供了聊天引擎,可以构建交互式对话界面。
from llama_index.llms import OpenAI
from llama_index import (
VectorStoreIndex,
SummaryIndex,
ServiceContext,
StorageContext,
load_index_from_storage
)
from llama_index.chat_engine import CondenseQuestionChatEngine
import os
# 重新加载索引
PERSIST_DIR = "./storage"
# 检查是否存在持久化文件
if not os.path.exists(PERSIST_DIR):
# 如果不存在,则创建索引并保存
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents)
index.storage_context.persist(persist_dir=PERSIST_DIR)
else:
# 如果存在,则从磁盘加载索引
storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR)
index = load_index_from_storage(storage_context)
# 创建聊天引擎
chat_engine = index.as_chat_engine(chat_mode="condense_question", verbose=True)
# 开始聊天
while True:
query = input("You: ")
if query.lower() == "exit":
break
response = chat_engine.chat(query)
print(f"Bot: {response.response}")
as_chat_engine
方法创建了一个聊天引擎,chat
方法根据用户的问题从索引中检索相关信息,并传递给LLM生成答案。chat_mode="condense_question"
表示使用上下文压缩模式,可以记住之前的对话内容。
4. LangChain与LlamaIndex的结合
LangChain和LlamaIndex可以很好地结合在一起,构建更强大的LLM应用。例如,我们可以使用LangChain的代理来调用LlamaIndex的查询引擎,实现更复杂的知识库问答任务。
from langchain.agents import Tool
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from llama_index.tools import LlamaIndexQueryTool
# 创建LlamaIndex查询工具
query_engine = index.as_query_engine()
query_tool = LlamaIndexQueryTool(query_engine=query_engine)
# 创建LangChain工具列表
tools = [
Tool(
name = "LlamaIndexQueryTool",
func=query_tool.query,
description="Useful for answering questions about the document."
)
]
# 初始化LangChain Agent
agent = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# 运行Agent
print(agent.run("What are the key concepts discussed in the document?"))
这里,我们将LlamaIndex的查询引擎封装成一个LangChain工具,然后让LangChain的代理来调用这个工具。
5. 实例:构建一个基于本地知识库的问答系统
下面我们来构建一个基于本地知识库的问答系统。假设我们有一些关于公司产品的文档,我们希望用户可以通过问答系统来了解产品信息。
步骤1:准备数据
首先,我们需要准备一些关于公司产品的文档,例如产品介绍、用户手册、常见问题解答等。将这些文档放在一个目录中,例如./data
。
步骤2:加载数据
from llama_index import SimpleDirectoryReader
documents = SimpleDirectoryReader('./data').load_data()
步骤3:构建索引
from llama_index import VectorStoreIndex
index = VectorStoreIndex.from_documents(documents)
步骤4:创建聊天引擎
from llama_index.llms import OpenAI
from llama_index.chat_engine import CondenseQuestionChatEngine
import os
from llama_index import (
VectorStoreIndex,
SummaryIndex,
ServiceContext,
StorageContext,
load_index_from_storage
)
PERSIST_DIR = "./storage"
# 检查是否存在持久化文件
if not os.path.exists(PERSIST_DIR):
# 如果不存在,则创建索引并保存
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents)
index.storage_context.persist(persist_dir=PERSIST_DIR)
else:
# 如果存在,则从磁盘加载索引
storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR)
index = load_index_from_storage(storage_context)
chat_engine = index.as_chat_engine(chat_mode="condense_question", verbose=True)
步骤5:运行问答系统
while True:
query = input("You: ")
if query.lower() == "exit":
break
response = chat_engine.chat(query)
print(f"Bot: {response.response}")
6. 高级技巧
- RAG (Retrieval-Augmented Generation): 这是一种将检索和生成结合起来的技术。先从外部知识库中检索相关信息,然后将信息传递给LLM生成答案。LlamaIndex擅长检索,LangChain擅长生成,两者结合可以构建更强大的RAG应用。
- 向量数据库: 可以使用向量数据库(如Chroma、Pinecone)来存储文档的向量表示,提高检索效率。
- 评估指标: 可以使用评估指标(如准确率、召回率)来评估LLM应用的性能,并进行优化。
- 提示词工程: 优化提示词可以显著提高LLM的输出质量。可以使用LangChain的提示词模板来管理和优化提示词。
- 微调 (Fine-tuning): 如果有大量特定领域的数据,可以对LLM进行微调,提高其在特定领域的性能。
表格:LangChain和LlamaIndex的比较
特性 | LangChain | LlamaIndex |
---|---|---|
核心功能 | 构建LLM应用的工作流 | 连接LLM和外部数据 |
主要组件 | 模型、提示词、链、索引、记忆、代理、回调 | 数据连接器、索引、查询引擎、聊天引擎 |
应用场景 | 智能客服、任务自动化、对话式AI | 知识库问答、文档理解、数据分析 |
优势 | 灵活性高、可定制性强、支持多种LLM | 易于上手、专注于数据连接和索引、提供聊天引擎 |
适用人群 | 开发者、研究人员 | 数据科学家、企业用户 |
总结:回顾和展望
今天我们学习了如何使用Python,结合LangChain和LlamaIndex这两个框架,构建基于LLM的智能体应用。LangChain提供了一系列的组件,可以帮助我们轻松地构建复杂的LLM应用,而LlamaIndex则专注于连接LLM和外部数据。两者结合可以构建更强大的RAG应用。希望今天的分享能帮助大家更好地理解和应用LLM技术。
未来的LLM应用将更加智能化、个性化和自动化。我们可以期待更多创新性的应用出现,例如:
- 自主学习的智能体: 能够从环境中学习,不断提高自身能力。
- 多模态智能体: 能够处理图像、语音、文本等多种类型的数据。
- 可解释的智能体: 能够解释自己的推理过程,方便用户理解和信任。
LLM技术的发展将为我们带来无限的可能性。