第 8 章

框架赌局

把时钟拨回2022年。README.md。这份文件躺在LangChain仓库的根目录下,在2022年10月的第一个提交里只有寥寥数十行。它定义的抽象简单到可以全文引述:一个Chain类接收输入、调用语言模型、返回输出。示例代码展示了最基础的使用模式——导入Chain、初始化模型、运行、获取结果。不需要理解提示词模板的内部实现,不需要处理不同模型API的响应格式差异,不需要手动管理重试逻辑。所有这些"胶水代码"被封装在一个统一的接口后面。

这不是一个技术突破。它甚至算不上创新。在软件工程史上,封装API调用、提供统一接口的模式已经被重复了无数次。

JDBC封装了不同数据库的SQL方言,Hibernate在JDBC之上又封装了一层对象关系映射,Spring在Hibernate之上又封装了一层依赖注入和事务管理。每一层封装都在解决同一个问题:让开发者用更少的代码做更多的事,同时让底层实现的差异变得透明。

Harrison Chase在旧金山公寓里写下的第一版LangChain,不过是把这个模式应用到了大语言模型这个新领域。他的判断是:当每个AI应用都需要与模型对话时,为这个对话提供标准接口的框架本身就有价值。这个判断在2022年秋天是对的。GPT-3已经发布两年,开发者们开始认真尝试将大模型嵌入实际应用,但每次调用都意味着从头编写提示词拼接逻辑、输出解析逻辑、错误重试逻辑。这些代码散落在各个项目里,彼此重复,没有标准。LangChain在最恰当的时机出现:一个正在快速扩大的开发者群体,一个刚刚被认识到的通用需求,一个还没有任何人占据的生态位。

但真正让LangChain区别于历史上那些SDK封装库的,不是它最初的简洁,而是它在接下来几个月里经历的膨胀。膨胀的动力来自用户。2022年冬天,第一批LangChain用户在GitHub上提交issue,描述他们的真实场景:如何让模型记住之前的对话?如何让模型调用外部API?

如何让模型从文档中检索信息?每一个问题都是合理的,每一个场景都是真实的,每一个需求都指向模型能力的一个具体缺口。

Chase和他的团队选择了回应这些需求。他们为记忆添加了Memory模块,为工具调用添加了Tools抽象,为文档检索添加了Retrieval层,为执行追踪添加了Callbacks系统。到2023年春天,LangChain的模块列表已经扩展到了十几个,每个模块下面又有多个子类和变体。文档从最初的几页扩展到了需要滚动好几屏的目录。

这不是一个错误。在框架发展史上,这是一个经典的生存策略。一个框架如果只解决最简单的问题,它会被更轻量的替代品取代——因为那些简单问题用户自己就能解决,不需要框架。一个框架要锁定用户,它必须解决那些用户自己解决起来很麻烦的问题。越是复杂的场景,框架提供的价值越大,用户的迁移成本越高。

Chase在2023年4月完成种子轮融资时,向投资者讲述的正是这个逻辑:LangChain正在成为AI应用开发的标准层,它的生态锁定效应会随着每一次功能增加而增强。

但这个策略有一个隐藏的前提:框架必须建立在相对稳定的底层技术之上。Spring Framework之所以能承受数十个模块的膨胀,是因为Java的反射机制、数据库的SQL标准、HTTP协议的基础规范在二十年里基本保持不变。框架的抽象层有时间慢慢沉淀,用户有足够的时间学习这些抽象,社区有足够的耐心等待框架的成熟。

但LangChain建立在大模型之上,而大模型的能力边界正在以月为单位移动。2022年10月,模型还不能可靠地调用工具。开发者需要手动构造提示词,让模型输出特定格式的文本,然后解析这些文本提取出工具调用指令。LangChain的Tools抽象正是为了解决这个问题:它定义了一套标准化的接口,让开发者可以声明工具、让模型选择工具、解析模型输出的工具调用。

这是模型能力缺口上的一个补丁。2023年3月,模型仍然需要复杂的提示词工程来引导推理。思维链、ReAct、少样本示例——这些技术需要精心设计的提示模板和输出解析器。LangChain的PromptTemplate和Chain抽象正是为这些需求量身定做的。这也是补丁。

2023年6月,OpenAI将发布函数调用功能。这个功能将允许模型直接输出结构化的函数调用,不需要提示词工程,不需要输出解析,不需要框架在中间做任何转换。Tools抽象和Chain编排中的相当一部分,将从“必要的补丁”变成“可选的包装”。当模型自己填平了能力缺口,补丁就变成了冗余。

这就是脚手架悖论在框架层面的完整展开。LangChain的每一层抽象,本质上都是在为模型当前的能力缺口设计解决方案。这些解决方案在当下是价值的来源——用户用LangChain是因为它解决了他们自己解决起来很麻烦的问题。

但也是未来的负债——当模型进化到不再需要这些解决方案时,它们就从资产变成了包袱。更致命的是,框架无法预测模型会在哪个方向上进化、进化多快。它在黑暗中补洞,看不见洞的另一面是否有光透进来。

2023年夏天,这个悖论开始从理论变成现实。一位在AI开发者社区有影响力的工程师在7月发表了一篇博客,详细解释了他为什么放弃LangChain。他的论点不是框架不好,而是框架的抽象层已经超过了它解决的问题。他列举了一组对比:用LangChain实现一个简单的文档问答系统需要引入十几个类、理解数层抽象、阅读大量文档;而用原生模型API实现同样的功能只需要几十行代码,逻辑清晰,调试容易。这篇博客在Hacker News上引发了激烈讨论,支持者与反对者的争论持续了数天。

但讨论本身暴露了一个深层问题:LangChain的价值主张正在从“让简单的事更简单”滑向“让复杂的事成为可能”。前者是基础设施的特质,后者是应用层服务的逻辑。两者的商业模型完全不同。

批评不是最危险的。最危险的是那些沉默的流失。一个开发者在2023年春天用LangChain搭建了原型,在夏天版本迭代时发现框架的API发生了破坏性变化,文档里的示例代码不再工作,GitHub issue里相同的问题已经讨论了上百条却没有明确的解决方案。这个开发者花了一个小时调试框架的抽象层,然后放弃了。他用原生模型API重写了整个应用,代码量从数百行降到了几十行。他不会写博客批评LangChain,不会在社交媒体上宣布自己的迁移,不会在GitHub上提issue说明自己为什么离开。他只是走了。

这些沉默的流失在框架的星标数上看不出来——星标数仍然在增长,因为新用户仍在涌入。但新用户的涌入速度掩盖了老用户的流失速度,直到某个临界点。

2023年9月,一个开发者在LangChain的GitHub仓库提交了一个issue,标题直白到近乎挑衅:“为什么调用一个API需要框架?”这个问题在24小时内获得了数百条回复。

支持者解释了框架在复杂场景中的价值:多步推理的编排、多工具调用的协调、多数据源的整合——这些场景确实需要框架层的抽象。批评者列举了框架的过度抽象带来的困扰:为了调用一个API要理解链、代理、工具、记忆、回调等多层概念,而这些概念中的相当一部分在简单场景中完全不需要。Chase亲自回复,承认框架需要改进,但强调框架的核心价值在于为复杂的语言模型应用提供编排能力。

这个issue最终被关闭了,但它留下了一个无法用代码解决的问题。框架赌局的逻辑在此暴露。

LangChain押注的是,大语言模型应用将长期保持高度的复杂性——需要多步推理、需要外部工具、需要记忆管理、需要数据检索——因此需要一个框架来管理这些复杂性。模型厂押注的是,模型自身的进化将逐步降低这些复杂性——更好的推理能力、更直接的工具调用、更简单的API——因此框架的填补工作最终会变成冗余。这两个赌注在2023年夏天同时存在,各自的胜负将在未来两年内分晓。

但在这一刻,没有任何一方能确定自己是对的。Chase的选择是继续扩张。2023年8月,LangChain发布了LangSmith,一个用于监控和调试LangChain应用的平台。调用链追踪、性能监控、错误诊断——这些功能在微服务架构中已经存在多年,现在被移植到了语言模型调用链上。这个产品在商业上是一个聪明的举动:它把框架的复杂性本身变成了一个新产品的需求来源。一个框架复杂到需要专门的监控平台,这本身就在说明什么。但LangSmith同时也为LangChain提供了一个新的收入来源和生态锁定点:使用LangSmith的团队会更深入地绑定在LangChain生态中,因为他们的监控数据和调试配置都建立在这个平台之上。2023年10月,距离Chase写下第一行LangChain代码整整一年。

这一年里,框架从一条简单的链膨胀成了一个拥有数十个模块的庞大系统,从GitHub上的一个个人项目变成了种子轮融资的创业公司,从解决一个清晰问题变成了覆盖一个模糊领域。它的成功是真实的:在开源工具史中,很少有项目能在如此短的时间内获得如此高的采用率。它的脆弱也是真实的:它的每一层抽象都在等待模型进化的判决。

在框架赛道的光谱上,其他玩家做出了不同的选择。LlamaIndex的前身GPT Index在2022年11月由Jerry Liu创建,它的切入点比LangChain窄得多,也具体得多:专注于数据连接和索引,让语言模型能够高效地检索外部知识库。这个聚焦让它避免了LangChain的过度抽象问题。LlamaIndex的文档只围绕一个核心概念展开:如何将外部数据转化为模型可以检索的格式。它在2023年夏天没有获得LangChain那样广泛的采用,但它在数据检索这个细分领域建立了稳固的口碑。

因为它的场景有明确的地面真值——检索结果可以验证,回答质量可以评估——它在脚手架悖论面前有更强的抵抗力。即使模型能力提升,高效检索外部知识的需求不会消失。微软在2023年2月发布了Semantic Kernel,它的设计哲学与LangChain形成鲜明对比。Semantic Kernel不提供高度抽象的链和代理,而是提供一组轻量级工具让开发者自己编排模型调用。这个选择在短期内损失了“开箱即用”的优势——用Semantic Kernel搭建一个应用需要写更多的代码,需要理解更多的底层逻辑。但长期来看,它更不容易被模型进化所吞并。因为它的抽象层很薄,薄到几乎只是一个对模型API的轻量封装。当模型API进化时,Semantic Kernel只需要更新底层适配,而不需要重构整个抽象体系。

这三个框架——LangChain的全栈抽象、LlamaIndex的领域聚焦、Semantic Kernel的轻量工具——构成了2023年夏天缰绳层框架赛道的光谱。它们各自押注了不同的未来,各自的赌注将在接下来的两年里接受检验。但在这个时间点上,一个更紧迫的问题正在逼近:模型厂即将发布的函数调用功能,将直接吞并框架赛道的一部分价值。LangChain的Tools抽象、Chain编排中的工具调用部分、以及围绕这些功能构建的文档和社区知识,都将面临被替代的风险。

这不是预言。这是已经发生的事。在GitHub上,已经有开发者开始发布“LangChain替代方案”的代码库,用几十行原生模型API代码实现LangChain最常用的功能。这些替代方案不提供框架的完整性,不覆盖所有场景,不支持所有模型。但它们足够轻量,足够透明,足够容易理解。它们在蚕食框架赛道的外围。在旧金山,Chase的办公室墙上贴着最初那个README的打印件。

在模块列表膨胀到需要滚动好几屏的2023年春天,一个细节暴露了LangChain扩张策略的内在紧张。框架的文档同时维护着两个相互矛盾的声明。在“为什么选择LangChain”页面上,它承诺“一行代码调用任何模型”——这是对简单性的承诺。在“快速开始”指南里,新用户需要先理解Chain、PromptTemplate、LLM、OutputParser四个核心抽象,才能跑通第一行代码。这两个声明之间的差距,就是框架在2022年10月到2023年4月之间走过的路。这不是文档团队的疏漏。这是框架膨胀过程中一个无法回避的后果:每一个新增的抽象层都在解决一个真实问题,但也在推高理解框架的门槛。当用户需要理解四个概念才能完成“快速开始”时,“快速”这个词本身已经改变了含义。

这个矛盾在开发者社区中引发了一种独特的焦虑。它不是“这个框架不好用”的简单抱怨,而是一种更微妙的不安:开发者在使用LangChain时,无法判断自己正在学习的知识是长期投资还是临时补丁。一个在2023年3月投入两周时间学习LangChain的Chain编排和Tools抽象的工程师,在2023年6月函数调用发布后,会发现这两周学到的知识中有相当一部分变成了“可以绕过”的复杂性。

这种知识折旧的速度在软件工程史中极为罕见。一个Java工程师在2005年学习的Spring Framework知识,在2015年仍然有效。一个前端工程师在2015年学习的React知识,在2023年仍然有效。但一个在2023年3月学习的LangChain知识,在2023年6月就可能变成过时的抽象。这不是因为LangChain的设计有问题,而是因为LangChain建立在移动的地基上,而地基移动的速度超过了框架稳定化的速度。

Chase的团队并非没有意识到这个问题。他们在2023年春天开始调整文档结构,试图通过分层来缓解认知负担:核心抽象放在最前面,高级功能放在后面,示例代码按场景组织。

但这个调整本身暴露了一个更深的困境。框架的抽象层之间不是松散的并列关系,而是紧密的依赖关系。你要理解Retrieval,必须先理解Chain。你要理解Agent,必须先理解Tools和Memory。你要理解回调,必须先理解整个调用链的生命周期。

这些依赖关系不是框架设计者强加的,而是框架试图解决的场景本身具有的复杂性。一个文档问答系统确实需要同时处理检索、记忆、推理、工具调用。当你试图用框架来管理这些复杂性时,框架的抽象层自然会反映出这些复杂性之间的依赖关系。

问题不在于框架制造了不必要的复杂性,而在于框架的复杂性成为了用户必须承担的认知成本。而模型厂的API进化,正在降低用户面对这些场景时的认知成本——不是因为场景变简单了,而是因为模型自己承担了更多的复杂性。

2023年5月,一个开源项目在GitHub上引起了注意。它的名字叫“LangChain minus LangChain”,一个讽刺性的标题,但它做的事情很严肃:它用大约两百行Python代码实现了LangChain最常用的功能——链式调用、提示词模板、输出解析。它不支持记忆、不支持代理、不支持检索、不支持回调。但它支持了百分之八十的用户在百分之八十的时间里需要的功能。

这个项目的README写得很克制:“这不是LangChain的替代品。这是一个实验,用来测试在不使用框架的情况下,我们能多接近LangChain的体验。”测试结果很清楚:在简单场景中,接近度很高。在复杂场景中,框架的抽象层确实提供了价值,但价值的大小取决于用户是否真的需要那些复杂场景。

这个项目在两天内获得了数百个星标,随后被LangChain社区的一些成员批评为“忽视了框架在复杂场景中的价值”。批评是对的,但批评没有触及问题的核心。问题的核心是:如果百分之八十的用户只需要百分之二十的功能,那么框架为那百分之八十的功能设计的百分之二十的抽象,是否正在成为用户的负担?

这个问题的答案在2023年夏天开始变得清晰。不是通过论证,而是通过行为。在GitHub上,一个可观测的趋势正在出现:越来越多的开发者开始在项目中使用LangChain的“低级”API,而不是“高级”抽象。他们导入LLMChain进行简单的链式调用,但避开Agent和Tools。他们使用PromptTemplate进行提示词构造,但手动管理输出解析。他们用LangChain作为模型调用的轻量封装,而不是作为应用架构的完整框架。这不是框架设计者期望的使用方式,但这是开发者自然选择的结果。他们直觉地判断出哪些抽象层提供了价值,哪些抽象层增加了不必要的复杂度。他们不是在反驳框架的逻辑,而是在用自己的代码投票。

这种投票在GitHub的依赖图上是可见的。2023年6月,LangChain的安装量仍在增长,但其中导入核心模块的比例在上升,而导入高级模块的比例在下降。更多的用户在使用LangChain最基础的功能,更少的用户在尝试最复杂的抽象。这组数据可以有两种解读。乐观的解读是:LangChain的核心价值得到验证,用户正在根据自己的需求选择合适的功能层级。悲观的解读是:框架的复杂抽象正在失去用户,而那些失去的用户正是框架生态锁定的核心目标。两种解读都有道理,但一个事实无可争议:框架赌局的核心押注——用户会因为复杂场景的需要而接受框架的复杂性——正在被用户的实际行为削弱。

Harrison Chase在2023年7月接受了一次技术播客的采访。主持人问了一个问题:“如果一年后,OpenAI的API直接支持了LangChain最核心的功能,框架的价值在哪里?”

这不是一个假设性问题。在2023年6月函数调用已经发布的背景下,这是一个已经部分实现的问题。

Chase的回答主要集中在两个方向。第一,编排能力。即使模型可以直接调用工具,编排多个工具调用、管理调用顺序、处理调用失败、协调多个模型并行工作——这些编排层面的需求不会消失。第二,生态集成。LangChain已经集成了数十个模型提供商、数十个向量数据库、数十个工具API。这种集成广度不是单个模型厂能够提供的,它需要中立的第三方来维护。

这两个方向在逻辑上都是成立的。但它们的成立需要两个前提。前提一:编排需求确实足够复杂,复杂到需要框架来管理。前提二:集成广度本身对用户有足够大的价值,大到用户愿意为这种广度承受框架的复杂性。这两个前提在2023年夏天都还没有被充分验证。

在同一个播客里,Chase承认了一个压力点。LangChain的版本迭代速度在过去一年里非常快,这在早期用户获取阶段是必要的——快速响应需求、快速增加功能、快速建立生态。

但快速迭代也意味着破坏性变化。2023年4月,LangChain发布了0.0.200版本,对Agent模块进行了重构。2023年5月,0.0.220版本改动了Chain的基类。这些改动在技术上是合理的——框架在早期需要调整架构以适应不断增长的功能需求。但每次改动都意味着一些用户的代码需要重写,一些教程需要更新,一些社区知识需要更新。在框架的早期采用者中,这种持续的重写成本正在累积。

一个在2023年1月用LangChain搭建了原型的初创公司,在2023年7月发现自己的代码库中有百分之三十的LangChain调用需要适配新版本。这不是一个巨大的数字,但它在不断增长。

那条简单的链——接收用户输入、构造提示、调用模型、解析输出——在2023年秋天看起来已经像一个遥远的记忆。

框架从那里出发,走过了一条不断加速的扩张之路。每一个新模块、每一个新抽象、每一个新版本,都在试图回答同一个问题:如何让语言模型真正可用。但每一次回答都在创造新的问题:这些抽象层本身是否正在成为可用性的障碍?

框架赌局的终局不取决于框架做得有多好。它取决于模型进化得有多快,以及框架公司能否在模型进化吞并下层抽象之前,建立起上层的编排能力和生态标准。

在这个意义上,LangChain的膨胀不是工程失误,而是创新者窘境下的理性生存策略。它必须向上爬,必须在模型吞并旧价值之前创造出新价值,必须在抽象层被替代之前建立起更深的生态锁定。它爬得越快,存活的机会越大。

但爬得越快,体量也越重,被吞并时摔得也越惨。这个悖论在2023年秋天的LangChain仓库里无声地运转。星标数仍在增长,issue仍在堆积,代码仍在合并。

但在这些可见的指标之下,一个不可见的过程正在加速:模型厂正在把框架的补丁变成自己的功能。那些补丁被写进API文档,被集成进模型调用格式,被吸收进下一次训练的强化学习奖励函数。脚手架正在被吞并,而吞并的速度比任何人预想的都要快。一个具体的问题悬在框架赛道的上空。当函数调用功能发布时,那些在2023年春天加入LangChain生态的开发者,将面临一个选择:继续使用框架的Tools抽象,还是直接使用模型的函数调用。这个选择不是技术问题,而是信任问题——他们信任框架能持续提供比模型API更高的价值吗?如果答案是否定的,他们就会离开。而离开的人,不会发出声音。