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