LangChain vs 自己撸框架:选择与组合策略
在工程讨论里,经常会出现这样的问题:要不要用 LangChain?要用到什么程度?要不要自己写一套更轻的 orchestrator?
这一篇不站队,只想从几个维度拆开这件事:LangChain 带来的收益有哪些、潜在代价有哪些,以及在不同规模和阶段的项目里,如何做一个相对务实的选择与组合。
1. 看清楚「多大一把锤子」在手里
先承认一个事实:LangChain 作为一个通用框架,必然是「大而全」的:
- 支持多种模型厂商、多种向量库、多种存储与工具;
- 提供 RAG、工具调用、Agent、多步链路、观测等一整套抽象。
这意味着:
- 在需要这些能力时,可以直接拿现成的组件来拼;
- 在只需要非常简单功能时,引入整个框架可能显得有点「杀鸡用牛刀」。
在做选择前,比较重要的一点是先评估清楚:
- 当前项目到底需要多少「跨组件组合」能力;
- 对未来扩展和演进的预期有多强。
2. LangChain 带来的几个主要收益
从前几篇拆出来的内容,可以归纳出几个主要收益点:
- 抽象出一组通用模块
- Model、PromptTemplate、OutputParser、VectorStore、Retriever、Tool、Agent、Runnable 等;
- 让这些东西成为可以组合与替换的「积木」。
- 提升可观测性与可调试性
- 在链路中的每一步前后挂钩子,记录 prompt、输出、检索命中、时延、错误等;
- 为后续评估、重放、A/B 提供基础设施。
- 降低「换底层」的成本
- 换模型供应商、换向量库、换存储后端,通常只需要动「适配层」和构造部分;
- 上层业务链路可以保持稳定。
- 提供一套「共识化的架构语言」
- 团队内部交流时,可以直接说「这里是一个 RAG Retriever」「这里有一个 Tool + Agent」「这里是一条 Runnable 链」,避免每个项目各讲各话。
这些收益,在项目进入「需要持续演进和多次迭代」阶段时会更明显。
3. 可能带来的代价与约束
引入 LangChain 也并非没有成本,常见的代价包括:
- 学习与心智负担
- 团队成员需要理解框架的核心抽象;
- 对已有架构有一定「侵入性」,需要调整原有代码层次。
- 调试路径变长
- 出现错误时,需要区分是业务逻辑问题、模型问题,还是框架使用方式问题;
- 对不熟悉框架的同学,排查成本会更高。
- 版本演进带来的不确定性
- 框架自身在快速演进时,可能会有 API 调整或推荐写法变化;
- 项目需要在「跟进新版本」和「锁定稳定版本」之间做平衡。
在做决策前,需要把这些潜在成本和预期收益一起放在桌面上评估。
4. 适合优先用 LangChain 的场景
有一些类型的项目,框架带来的收益往往会压过成本:
- 多数据源 + 多种检索方式的 RAG 系统
- 需要同时对接文件、Wiki、数据库、多种向量库;
- 需要在不同场景下调整 Retriever 组合与权重。
- 需要复杂工具调用和 Agent 能力
- 有多类业务工具(API、DB、脚本)需要暴露给模型;
- 决策路径复杂、需要多步规划与回溯。
- 中长期演进的「平台型」项目
- 不是一次性脚本,而是一个长期演进的应用/平台;
- 预计会频繁尝试不同 prompt、不同链路、不同评估指标。
在这些场景中,LangChain 带来的「组合能力 + 观测能力 + 生态支持」往往能明显缩短迭代时间。
5. 适合先自己撸一层轻量封装的场景
同样也有不少项目,其实不需要一上来就引入完整框架:
- 单模型、单数据源、单场景的小工具
- 比如一个只对接某个内部 API 的问答 Bot;
- 或者一个本地脚本,帮忙批量生成某类文案。
- 已存在成熟架构,只是加一点「模型能力」
- 原有系统已经有清晰的数据层、服务层、控制层;
- 只是在某个步骤调用一次模型做补全/分类/打分。
在这些情况下,更推荐:
- 先为模型调用写一个简单的适配层和少量工具函数;
- 明确输入输出、日志打点与错误处理;
- 把复杂度控制在当前需求范围内。
如果后续需求增长,再逐步考虑引入 LangChain 的某些模块,而不是一口气把整个框架搬进来。
6. 一种折中的「组合策略」
在实践中,一个较为稳妥的路线是:
- 业务层只依赖「自定义服务接口」,不直接依赖 LangChain 具体模块
- 比如定义一个
QuestionAnsweringService、CodeReviewService、SearchService; - 内部实现可以用 LangChain 组合出 RAG/Agent 链,也可以是自写 pipeline。
- 比如定义一个
- LangChain 作为「实现细节」存在于某个子模块中
- 这样一来,即便未来决定用其他框架(如 LlamaIndex、Semantic Kernel)或自研方案替代,只需替换实现层;
- 上层业务无需感知底层 orchestrator 的变化。
这种组合策略可以:
- 既享受 LangChain 的组合与观测能力;
+- 又避免让整个项目「紧耦合」在某一个框架之上。
7. 小结:不是二选一,而是找到合适的分层
可以用几句话结束这一篇:
- 「用 LangChain」和「自己撸一层」并不是互斥关系,关键在于如何分层:
- 业务逻辑层关注的是「要完成什么任务」;
- 模型调用层可以选择用 LangChain 或自研 orchestrator 实现;
- 底层模型/向量库/数据源层则由适配模块统一封装。
- 在需求简单、迭代压力不大时,轻量封装往往更直接;
- 在需求复杂、需要频繁实验和多种组合时,引入 LangChain 这类框架则更能发挥优势。
真正值得投入精力的,是弄清楚当前项目在哪里、未来可能走向哪里,然后在合适的层次里引入合适程度的抽象,而不是简单地在「要不要用 LangChain」上做二元选择。