两大AI应用框架的实战对比与架构设计
当我们从"玩AI"进入到"用AI做产品"阶段时,需要一个成熟的框架来支撑应用的构建。LangChain和LlamaIndex是目前最主流的两个AI应用框架。
两个框架我都深度使用过,各自在不同的场景下做了几个项目。这篇文章从实战角度,对比两个框架的差异,并分享如何用它们搭建企业级AI应用。
框架 | 一句话 |
|---|---|
LangChain | 如果你想编排复杂的AI工作流,选LangChain |
LlamaIndex | 如果你的核心场景是知识库问答/RAG,选LlamaIndex |
# LangChain的数据加载
from langchain_community.document_loaders import PyPDFLoader, TextLoader
loader = PyPDFLoader("document.pdf")
docs = loader.load()
# LlamaIndex的数据加载
from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader("./data").load_data()维度 | LangChain | LlamaIndex |
|---|---|---|
文档解析 | 多种Loader、扩展性强 | 自带Readers、更易用 |
文本切分 | RecursiveCharacterTextSplitter等 | 多种Splitter、支持语义切分 |
元数据提取 | 需自行实现 | 内置MetadataExtractor |
数据连接 | 通用 | 更专注、更深入 |
LlamaIndex在数据连接方面更深入一步,内置了对多种数据源的深度支持。
# LangChain RAG
from langchain_chroma import Chroma
from langchain.chains import RetrievalQA
vector_store = Chroma.from_documents(docs, embeddings)
chain = RetrievalQA.from_chain_type(llm, retriever=vector_store.as_retriever())
# LlamaIndex RAG
from llama_index.core import VectorStoreIndex
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()维度 | LangChain | LlamaIndex |
|---|---|---|
向量存储 | 多种VectorStore支持 | 多种VectorStore支持 |
检索策略 | 基础检索 | 高级检索(混合/递归/分层) |
检索引擎 | Retriever | QueryEngine(功能更丰富) |
高级特性 | 需自行组合 | 内置多种高级RAG策略 |
LlamaIndex在RAG检索方面明显更强,内置了多种高级RAG策略。
# LangChain Agent
from langchain.agents import create_tool_calling_agent
tools = [search_tool, calculator_tool, database_tool]
agent = create_tool_calling_agent(llm, tools, prompt)
# LlamaIndex Agent
from llama_index.core.agent import ReActAgent
agent = ReActAgent.from_tools(tools, llm=llm, verbose=True)维度 | LangChain | LlamaIndex |
|---|---|---|
Agent类型 | 丰富(ReAct/OpenAI/Planning) | 基础(ReAct为主) |
工具定义 | 灵活、标准化 | 简单直接 |
多Agent | 支持(AgentExecutor) | 基础支持 |
Agent生态 | 更丰富 | 相对弱 |
LangChain在Agent和工具调用方面更强大,生态更丰富。
为一个科技公司搭建内部技术知识库问答系统,需要:
最终选用LlamaIndex为主框架 + 补充LangChain工具能力的混合方案:
# 使用LlamaIndex处理核心RAG逻辑
from llama_index.core import (
VectorStoreIndex,
SimpleDirectoryReader,
StorageContext,
)
from llama_index.core.postprocessor import SentenceTransformerRerank
from llama_index.vector_stores.milvus import MilvusVectorStore
# 知识库构建
documents = SimpleDirectoryReader("./knowledge_base").load_data()
index = VectorStoreIndex.from_documents(
documents,
vector_store=MilvusVectorStore(uri="./milvus.db"),
)
# 查询引擎(带重排序)
query_engine = index.as_query_engine(
similarity_top_k=10,
node_postprocessors=[
SentenceTransformerRerank(top_k=3, model="BAAI/bge-reranker-v2-m3")
],
)
# 使用LangChain补充Agent能力
from langchain.agents import tool
@tool
def query_knowledge_base(question: str) -> str:
"""查询内部技术知识库"""
response = query_engine.query(question)
return str(response)
# 结合Agent实现更复杂的查询用户输入
│
▼
┌──────────────────┐
│ LlamaIndex │
│ ┌──────────────┐│
│ │ 查询重写 ││
│ │ 混合检索 ││ ←── 核心RAG能力
│ │ 重排序 ││
│ │ 引用生成 ││
│ └──────────────┘│
└────────┬─────────┘
│
▼
┌──────────────────┐
│ LangChain │
│ ┌──────────────┐│
│ │ 多轮对话管理 ││ ←── 补充能力
│ │ 工具调度 ││
│ │ 输出格式化 ││
│ └──────────────┘│
└────────┬─────────┘
│
▼
用户看到回答┌────────────────────────────────────────┐
│ 应用层(FastAPI) │
│ REST API / WebSocket / Admin Panel │
├────────────────────────────────────────┤
│ 编排层(LangChain) │
│ Agent编排 / 多轮对话 / Tool调度 │
├────────────────────────────────────────┤
│ 知识层(LlamaIndex) │
│ 索引构建 / 检索 / 重排序 / 引用 │
├────────────────────────────────────────┤
│ 基础设施层 │
│ 向量库(Milvus) / 文档存储(MinIO) / LLM│
└────────────────────────────────────────┘# 缓存策略
from functools import lru_cache
class QueryCache:
def __init__(self, ttl=3600):
self.cache = {}
self.ttl = ttl
async def get_or_query(self, question, query_func):
cache_key = hashlib.md5(question.encode()).hexdigest()
if cache_key in self.cache:
entry = self.cache[cache_key]
if time.time() - entry['time'] < self.ttl:
return entry['result']
result = await query_func(question)
self.cache[cache_key] = {'result': result, 'time': time.time()}
return result# LangChain的Callback实现监控
from langchain.callbacks.base import BaseCallbackHandler
class MonitoringCallback(BaseCallbackHandler):
def on_llm_start(self, serialized, prompts, **kwargs):
logger.info(f"LLM请求开始: {prompts[:100]}...")
def on_llm_end(self, response, **kwargs):
logger.info(f"LLM请求完成: {len(response.generations[0][0].text)} tokens")
def on_chain_error(self, error, **kwargs):
logger.error(f"链执行错误: {error}")
metrics.increment('chain_errors')FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# 预加载模型和索引
RUN python -c "from llama_index.core import VectorStoreIndex; \
VectorStoreIndex.load_from_disk('./index')"
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]优化手段 | 效果 | 实现方式 |
|---|---|---|
索引预加载 | 启动延迟降低80% | Docker构建时预构建索引 |
查询缓存 | 相同问题响应<10ms | Redis缓存高频查询 |
异步处理 | 并发能力提升5倍 | FastAPI异步端点 |
批处理 | 吞吐量提升3倍 | LLM请求合并批处理 |
场景 | 推荐框架 | 理由 |
|---|---|---|
知识库问答系统 | LlamaIndex | 数据连接和检索能力更强 |
智能客服Agent | LangChain | Agent和工具调用生态好 |
复杂工作流编排 | LangChain | Chain和Agent组合灵活 |
文档分析提取 | LlamaIndex | 文档解析和处理能力深入 |
综合AI应用 | 两者结合 | 各取所长,效果最好 |
LangChain和LlamaIndex不是竞争关系,而是互补关系。我的经验是:
对未来保持开放——这两个框架都在快速迭代,同时关注新的竞争者(如Semantic Kernel、Haystack等)。
你在用哪个AI开发框架?有什么心得体会?欢迎评论区分享!