為什么都放棄了LangChain?
或許從誕生那天起,LangChain 就注定是一個(gè)口碑兩極分化的產(chǎn)品。
看好 LangChain 的人欣賞它豐富的工具和組建和易于集成等特點(diǎn),不看好 LangChain 的人,認(rèn)為它注定失敗 —— 在這個(gè)技術(shù)變化如此之快的年代,用 LangChain 來(lái)構(gòu)建一切根本行不通。
夸張點(diǎn)的還有:
「在我的咨詢工作中,我花了 70% 的精力來(lái)說(shuō)服人們不要使用 langchain 或 llamaindex。這解決了他們 90% 的問(wèn)題?!?/span>
最近,一篇 LangChain 吐槽文再次成為熱議焦點(diǎn):
作者 Fabian Both 是 AI 測(cè)試工具 Octomind 的深度學(xué)習(xí)工程師。Octomind 團(tuán)隊(duì)會(huì)使用具有多個(gè) LLM 的 AI Agent 來(lái)自動(dòng)創(chuàng)建和修復(fù) Playwright 中的端到端測(cè)試。
這是一個(gè)持續(xù)一年多的故事,從選擇 LangChain 開始,隨后進(jìn)入到了與 LangChain 頑強(qiáng)斗爭(zhēng)的階段。在 2024 年,他們終于決定告別 LangChain。
讓我們看看他們經(jīng)歷了什么:
「LangChain 曾是最佳選擇」
我們?cè)谏a(chǎn)中使用 LangChain 超過(guò) 12 個(gè)月,從 2023 年初開始使用,然后在 2024 年將其移除。
在 2023 年,LangChain 似乎是我們的最佳選擇。它擁有一系列令人印象深刻的組件和工具,而且人氣飆升。LangChain 承諾「讓開發(fā)人員一個(gè)下午就能從一個(gè)想法變成可運(yùn)行的代碼」,但隨著我們的需求變得越來(lái)越復(fù)雜,問(wèn)題也開始浮出水面。
LangChain 變成了阻力的根源,而不是生產(chǎn)力的根源。
隨著 LangChain 的不靈活性開始顯現(xiàn),我們開始深入研究 LangChain 的內(nèi)部結(jié)構(gòu),以改進(jìn)系統(tǒng)的底層行為。但是,由于 LangChain 故意將許多細(xì)節(jié)做得很抽象,我們無(wú)法輕松編寫所需的底層代碼。
眾所周知,人工智能和 LLM 是瞬息萬(wàn)變的領(lǐng)域,每周都會(huì)有新的概念和想法出現(xiàn)。而 LangChain 這樣圍繞多種新興技術(shù)創(chuàng)建的抽象概念,其框架設(shè)計(jì)很難經(jīng)得起時(shí)間考驗(yàn)。
LangChain 為什么如此抽象
起初,當(dāng)我們的簡(jiǎn)單需求與 LangChain 的使用假設(shè)相吻合時(shí),LangChain 還能幫上忙。但它的高級(jí)抽象很快就讓我們的代碼變得更加難以理解,維護(hù)過(guò)程也令人沮喪。當(dāng)團(tuán)隊(duì)用在理解和調(diào)試 LangChain 的時(shí)間和用在構(gòu)建功能上的時(shí)間一樣時(shí),這可不是一個(gè)好兆頭。
LangChain 的抽象方法所存在的問(wèn)題,可以通過(guò)「將一個(gè)英語(yǔ)單詞翻譯成意大利語(yǔ)」這一微不足道的示例來(lái)說(shuō)明。
下面是一個(gè)僅使用 OpenAI 軟件包的 Python 示例:
這是一段簡(jiǎn)單易懂的代碼,只包含一個(gè)類和一個(gè)函數(shù)調(diào)用。其余部分都是標(biāo)準(zhǔn)的 Python 代碼。
將其與 LangChain 的版本進(jìn)行對(duì)比:
代碼大致相同,但相似之處僅此而已。
我們現(xiàn)在有三個(gè)類和四個(gè)函數(shù)調(diào)用。但令人擔(dān)憂的是,LangChain 引入了三個(gè)新的抽象概念:
- Prompt 模板: 為 LLM 提供 Prompt;
- 輸出解析器: 處理來(lái)自 LLM 的輸出;
- 鏈: LangChain 的「LCEL 語(yǔ)法」覆蓋 Python 的 | 操作符。
LangChain 所做的只是增加了代碼的復(fù)雜性,卻沒(méi)有帶來(lái)任何明顯的好處。
這種代碼對(duì)于早期原型來(lái)說(shuō)可能沒(méi)什么問(wèn)題。但對(duì)于生產(chǎn)使用,每個(gè)組件都必須得到合理的理解,這樣在實(shí)際使用條件下才不至于意外崩潰。你必須遵守給定的數(shù)據(jù)結(jié)構(gòu),并圍繞這些抽象設(shè)計(jì)應(yīng)用程序。
讓我們看看 Python 中的另一個(gè)抽象比較,這次是從 API 中獲取 JSON。
使用內(nèi)置的 http 包:
使用 requests 包:
高下顯而易見(jiàn)。這就是好的抽象的感覺(jué)。
當(dāng)然,這些都是微不足道的例子。但我想說(shuō)的是,好的抽象可以簡(jiǎn)化代碼,減少理解代碼所需的認(rèn)知負(fù)荷。
LangChain 試圖通過(guò)隱藏細(xì)節(jié),用更少的代碼完成更多的工作,讓你的生活變得更輕松。但是,如果這是以犧牲簡(jiǎn)單性和靈活性為代價(jià)的,那么抽象就失去了價(jià)值。
LangChain 還習(xí)慣于在其他抽象之上使用抽象,因此你往往不得不從嵌套抽象的角度來(lái)思考如何正確使用 API。這不可避免地會(huì)導(dǎo)致理解龐大的堆棧跟蹤和調(diào)試你沒(méi)有編寫的內(nèi)部框架代碼,而不是實(shí)現(xiàn)新功能。
LangChain 對(duì)開發(fā)團(tuán)隊(duì)的影響
一般來(lái)說(shuō),應(yīng)用程序大量使用 AI Agent 來(lái)執(zhí)行不同類型的任務(wù),如發(fā)現(xiàn)測(cè)試用例、生成 Playwright 測(cè)試和自動(dòng)修復(fù)。
當(dāng)我們想從單一 Sequential Agent 的架構(gòu)轉(zhuǎn)向更復(fù)雜的架構(gòu)時(shí),LangChain 成為了限制因素。例如,生成 Sub-Agent 并讓它們與原始 Agent 互動(dòng)。或者多個(gè)專業(yè) Agent 相互交互。
在另一個(gè)例子中,我們需要根據(jù)業(yè)務(wù)邏輯和 LLM 的輸出,動(dòng)態(tài)改變 Agent 可以訪問(wèn)的工具的可用性。但是 LangChain 并沒(méi)有提供從外部觀察 Agent 狀態(tài)的方法,這導(dǎo)致我們不得不縮小實(shí)現(xiàn)范圍,以適應(yīng) LangChain Agent 的有限功能。
一旦我們刪除了它,我們就不再需要將我們的需求轉(zhuǎn)化為適合 LangChain 的解決方案。我們只需編寫代碼即可。
那么,如果不使用 LangChain,你應(yīng)該使用什么框架呢?也許你根本不需要框架。
我們真的需要構(gòu)建人工智能應(yīng)用程序的框架嗎?
LangChain 在早期為我們提供了 LLM 功能,讓我們可以專注于構(gòu)建應(yīng)用程序。但事后看來(lái),如果沒(méi)有框架,我們的長(zhǎng)期發(fā)展會(huì)更好。
LangChain 一長(zhǎng)串的組件給人的印象是,構(gòu)建一個(gè)由 LLM 驅(qū)動(dòng)的應(yīng)用程序非常復(fù)雜。但大多數(shù)應(yīng)用程序所需的核心組件通常如下:
- 用于 LLM 通信的客戶端
- 用于函數(shù)調(diào)用的函數(shù) / 工具
- 用于 RAG 的向量數(shù)據(jù)庫(kù)
- 用于跟蹤、評(píng)估等的可觀察性平臺(tái)。
Agent 領(lǐng)域正在快速發(fā)展,帶來(lái)了令人興奮的可能性和有趣的用例,但我們建議 —— 在 Agent 的使用模式得到鞏固之前,暫時(shí)保持簡(jiǎn)單。人工智能領(lǐng)域的許多開發(fā)工作都是由實(shí)驗(yàn)和原型設(shè)計(jì)驅(qū)動(dòng)的。
以上是 Fabian Both 一年多來(lái)的切身體會(huì),但 LangChain 并非全然沒(méi)有可取之處。
另一位開發(fā)者 Tim Valishev 表示,他會(huì)再堅(jiān)持使用 LangChain 一段時(shí)間:
我真的很喜歡 Langsmith:
- 開箱即用的可視化日志
- Prompt playground,可以立即從日志中修復(fù) Prompt,并查看它在相同輸入下的表現(xiàn)
- 可直接從日志輕松構(gòu)建測(cè)試數(shù)據(jù)集,并可選擇一鍵運(yùn)行 Prompt 中的簡(jiǎn)單測(cè)試集(或在代碼中進(jìn)行端到端測(cè)試)
- 測(cè)試分?jǐn)?shù)歷史
- Prompt 版本控制
而且它對(duì)整個(gè)鏈的流式傳輸提供了很好的支持,手動(dòng)實(shí)現(xiàn)這一點(diǎn)需要一些時(shí)間。
何況,只依靠 API 也是不行的,每家大模型廠商的 API 都不同,并不能「無(wú)縫切換」。
你怎么看?