一、 开场:一个让我意外的问题
大家好,我是老金。
上周在技术群里,有人问了这样一个问题:
“LangChain太重了,我只是想简单用一下LLM,有没有轻量级的替代方案?”
我第一反应是:“直接调API不就行了?”
但仔细一想,这问题没那么简单。
LangChain确实强大,但它也确实”重”:
- 安装包大小:50MB+
- 依赖数量:100+
- 抽象层次多,调试困难
- 版本迭代快,Breaking Changes多
对于小项目、快速原型、简单场景,LangChain可能是”杀鸡用牛刀”。
今天这篇文章,我想聊聊:LangChain的替代方案有哪些?什么场景该用什么方案?
二、 先明确你的需求
在讨论替代方案之前,先问自己几个问题:
- 你的项目复杂度如何?
- 简单:调API、简单Prompt
- 中等:需要RAG、工具调用
- 复杂:Multi-Agent、复杂工作流
- 你的技术背景如何?
- 小白:希望开箱即用
- 中级:能看懂源码、做定制
- 高级:喜欢自己造轮子
- 你对性能有什么要求?
- 不敏感:开发效率优先
- 敏感:需要精细控制每个环节
不同的答案,对应不同的方案选择。
三、 替代方案大盘点
3.1 方案一:直接调用API(最轻量)
适用场景:简单的对话、文本生成任务。
代码示例:
import openai
直接调用OpenAI API
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": "你是一个技术专家"},
{"role": "user", "content": "什么是RAG?"}
]
)
print(response.choices[0].message.content)
优点:
- 零依赖(只需要openai库)
- 完全透明,调试方便
- 性能最优
缺点:
- 需要自己管理对话历史
- 没有内置的工具调用、RAG等功能
- 模型切换需要改代码
3.2 方案二:LiteLLM(统一接口)
适用场景:需要支持多种LLM(OpenAI、Claude、国产模型等)。
为什么推荐LiteLLM?
- 统一API格式,一套代码支持20+种LLM
- 内置重试、降级、负载均衡
- 支持流式输出、异步调用
- 轻量级,核心代码只有几千行
代码示例:
from litellm import completion
调用OpenAI
response = completion(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}]
)
调用Claude(同样的接口)
response = completion(
model="claude-3-opus-20240229",
messages=[{"role": "user", "content": "Hello"}]
)
调用国产模型
response = completion(
model="deepseek/deepseek-chat",
messages=[{"role": "user", "content": "Hello"}]
)
3.3 方案三:LlamaIndex(RAG场景)
适用场景:以文档问答、知识库为核心的RAG应用。
为什么LlamaIndex比LangChain更适合RAG?
- 专注RAG场景,设计更聚焦
- 内置丰富的文档加载器
- 索引策略更多样
- 评估工具更完善
代码示例:
from llama_index import VectorStoreIndex, SimpleDirectoryReader
加载文档
documents = SimpleDirectoryReader("./docs").load_data()
创建索引
index = VectorStoreIndex.from_documents(documents)
创建查询引擎
query_engine = index.as_query_engine()
提问
response = query_engine.query("什么是RAG?")
print(response)
3.4 方案四:Haystack(企业级RAG)
适用场景:企业级搜索、问答系统。
为什么推荐Haystack?
- 生产就绪,久经考验
- 支持Pipeline模式,灵活组合
- 丰富的预训练模型
- 有完善的评估和监控工具
代码示例:
from haystack import Pipeline
from haystack.nodes import EmbeddingRetriever, PromptNode
创建Pipeline
pipe = Pipeline()
添加检索节点
retriever = EmbeddingRetriever(
document_store=document_store,
embedding_model="BAAI/bge-large-zh"
)
pipe.add_node(retriever, name="Retriever", inputs=["Query"])
添加生成节点
prompt_node = PromptNode(
model_name_or_path="gpt-4",
default_prompt_template="基于以下内容回答问题:n{documents}n问题:{query}"
)
pipe.add_node(prompt_node, name="Generator", inputs=["Retriever"])
运行
result = pipe.run(query="什么是RAG?")
3.5 方案五:DSPy(程序化Prompt)
适用场景:需要精细控制Prompt、追求最优效果的场景。
DSPy的独特之处:
- 不写Prompt,写”签名”(Signature)
- 自动优化Prompt(类似编译器)
- 支持断言和约束
- Stanford出品,学术背景强
代码示例:
import dspy定义签名
class RAGSignature(dspy.Signature): """基于上下文回答问题""" context = dspy.InputField(desc="相关上下文") question = dspy.InputField() answer = dspy.OutputField(desc="简洁的回答")
定义模块
class RAGModule(dspy.Module): def init(self): super().init() self.generate = dspy.ChainOfThought(RAGSignature)
def forward(self, context, question): return self.generate(context=context, question=question)使用
rag = RAGModule()
result = rag(context="...", question="什么是RAG?")
3.6 方案六:自己封装(最灵活)
适用场景:有特殊需求、对框架不满意。
我自己的封装示例:
class SimpleLLM: """简单的LLM封装,支持多模型切换"""def __init__(self, default_model="gpt-4"): self.models = { "gpt-4": self._call_openai, "claude": self._call_anthropic, "deepseek": self._call_deepseek, } self.default_model = default_model def call(self, prompt, model=None, **kwargs): model = model or self.default_model return self.models[model](prompt, **kwargs) def _call_openai(self, prompt, **kwargs): # ... pass def _call_anthropic(self, prompt, **kwargs): # ... pass def _call_deepseek(self, prompt, **kwargs): # ... pass使用
llm = SimpleLLM()
response = llm.call("什么是RAG?", model="gpt-4")
四、 选择决策树
你的需求是什么? │ ├─ 简单对话、文本生成 │ └─ 推荐:直接调API 或 LiteLLM │ ├─ 文档问答、知识库 │ ├─ 快速原型 │ │ └─ 推荐:LlamaIndex │ │ │ └─ 生产级系统 │ └─ 推荐:Haystack │ ├─ 多工具协作、Agent │ ├─ 简单Agent │ │ └─ 推荐:自己封装 │ │ │ └─ 复杂Multi-Agent │ └─ 推荐:LangGraph 或 LangChain │ ├─ 追求最优Prompt效果 │ └─ 推荐:DSPy │ └─ 需要统一多种LLM └─ 推荐:LiteLLM五、 我的个人选择
说说我自己的实践:
5.1 小项目(<1000行代码)
选择:直接调API + LiteLLM
理由:
- 不需要复杂抽象
- 开发速度最快
- 调试最直观
5.2 RAG项目
选择:LlamaIndex
理由:
- RAG场景优化最好
- 文档加载器丰富
- 社区活跃
5.3 复杂Agent项目
选择:LangGraph(LangChain团队出品,但更轻量)
理由:
- 基于图的工作流设计
- 状态管理清晰
- 调试可视化好
六、 性能对比
我做了一个简单的性能测试:
| 方案 | 启动时间 | 内存占用 | 首次响应延迟 |
|---|---|---|---|
| 直接调API | <1ms | <10MB | ~500ms |
| LiteLLM | ~50ms | ~20MB | ~550ms |
| LlamaIndex | ~200ms | ~50MB | ~700ms |
| LangChain | ~500ms | ~100MB | ~800ms |
结论:对于简单场景,直接调API或LiteLLM的性能优势明显。
七、 写在最后
框架是工具,不是信仰。
不要因为LangChain火,就觉得非用它不可。
也不要因为LangChain重,就完全排斥它。
关键是要根据自己的实际需求,选择最合适的工具。
最后分享几点建议:
- 从简单开始:先用最简单的方案,遇到瓶颈再升级
- 理解底层原理:不管用什么框架,都要理解它底层做了什么
- 关注维护成本:框架越重,升级维护成本越高
- 保持技术开放:新技术不断出现,不要绑定单一框架
如果你也在选择LLM开发框架,欢迎在评论区分享你的经验和选择。
我是技术老金,我们下期见!
📌 往期精彩回顾
- OpenClaw二次开发完全指南:从源码构建到自定义Skill开发
- OpenClaw实战案例:5个真实场景教你打造私人AI助理
- 我写3小时代码不如人家10分钟?OpenClaw Skills让我卧槽了