偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

LangChain居然不香了?一線程序員現(xiàn)身說法,硬核博文剖析LLM應(yīng)用開發(fā)原則

人工智能 新聞
最近,Hacker News熱榜上出現(xiàn)了一篇「聲討」LangChain的技術(shù)文章,得到了評論區(qū)網(wǎng)友的一致呼應(yīng)。去年還火遍LLM圈的LangChain,為什么口碑逆轉(zhuǎn)了?

 2023年是屬于LLM初創(chuàng)公司的一年,也是屬于LangChain的一年。

這個(gè)發(fā)布于2022年10月的開源框架可以支持開發(fā)者構(gòu)建由LLM驅(qū)動的應(yīng)用程序,目前依舊是社區(qū)中一種不可忽視的開發(fā)范式。

圖片

更具體地說,基于LLM構(gòu)建應(yīng)用程序的過程有點(diǎn)像在搭積木。即使模型本身的能力已經(jīng)很強(qiáng)大了,我們依舊需要其他的組件和工具才能更好發(fā)揮其潛力。

比如聊天模型、提示模板、文本嵌入模型、文本分割器、文檔加載器、檢索器、向量存儲等,這些工具的不同的搭配組合能夠構(gòu)建出各種的應(yīng)用鏈,滿足RAG、Agent、存儲&索引、信息提取等不同的應(yīng)用需求。

圖片

舉個(gè)例子,你想用GPT-4開發(fā)一個(gè)旅行顧問機(jī)器人,為用戶提供行程方面的規(guī)劃和建議。如果只依靠GPT-4在訓(xùn)練時(shí)學(xué)到的知識,沒有實(shí)時(shí)查詢最新的航班、酒店、景區(qū)信息,提供的建議就不可能準(zhǔn)確實(shí)用。

借助LangChain框架,這個(gè)機(jī)器人就能鏈接到各種API和外部數(shù)據(jù)庫,并記住用戶的旅行偏好,甚至能根據(jù)用戶的對話歷史提供個(gè)性化建議。

這樣聽起來,LangChain是一個(gè)非常強(qiáng)大的工具,流行起來也是理所應(yīng)當(dāng)。

然而,最近一個(gè)技術(shù)團(tuán)隊(duì)的博文登上了HN熱榜,描述了他們從「入坑」LangChain到「幡然醒悟」,最終決定拋棄這個(gè)熱門框架的過程。

圖片

「為什么我們不再使用LangChain構(gòu)建AI agents——當(dāng)抽象弊大于利時(shí):在生產(chǎn)中使用LangChain的教訓(xùn)以及我們應(yīng)該做什么」

底下的評論也紛紛附和,表示這個(gè)框架有種「代碼糟糕」的感覺,而且把使用LangChain描述為一條「充滿雷區(qū)的道路」。

圖片

「LangChain的抽象就是死亡的定義?!?/span>

圖片

從大受追捧到「人人喊打」,LangChain到底有什么樣的問題?

問題浮現(xiàn)

這個(gè)技術(shù)團(tuán)隊(duì)在生產(chǎn)中使用LangChain已經(jīng)超過12個(gè)月,開始于2023年初。

當(dāng)時(shí),LangChain似乎是最佳選擇,因?yàn)樗鼡碛幸幌盗辛钊擞∠笊羁痰慕M件和工具,并且承諾開發(fā)者「用一個(gè)下午將想法轉(zhuǎn)變?yōu)榭蓤?zhí)行的代碼」,流行程度飆升。

然而,隨著需求逐漸變得復(fù)雜,LangChain的不靈活性開始顯現(xiàn)出來,開始阻礙生產(chǎn)力、成為摩擦的源頭。

團(tuán)隊(duì)不得不深入研究框架的內(nèi)部結(jié)構(gòu),以改善系統(tǒng)的底層行為。但因?yàn)長angChain有意通過抽象屏蔽細(xì)節(jié),編寫底層代碼的嘗試通常也不可行,或至少是十分復(fù)雜。

究其根源,作者認(rèn)為是LangChain的抽象程度過高。在開發(fā)的初期階段,較為簡單的需求與框架的假設(shè)相一致,因此配合得很好。

但高級抽象很快使之后的代碼變得難以理解、維護(hù),團(tuán)隊(duì)花費(fèi)在理解和調(diào)試LangChain上的時(shí)間越來越多,幾乎趕上了真正構(gòu)建功能所用的時(shí)間。

舉個(gè)具體的例子,上代碼:用OpenAI的包,將英語單詞翻譯為意大利語(沒錯(cuò),就是GPT-4o發(fā)布會demo的功能)

from openai import OpenAI

client = OpenAI(api_key="<your_api_key>")
text = "hello!"
language = "Italian"

messages = [
    {"role": "system", "content": "You are an expert translator"},
    {"role": "user", "content": f"Translate the following from English into {language}"},
    {"role": "user", "content": f"{text}"},
]

response = client.chat.completions.create(model="gpt-4o", messages=messages)
result = response.choices[0].message.content

這段代碼很好理解,包含一個(gè)OpenAI類的實(shí)例client以及一個(gè)函數(shù)調(diào)用,其余都是標(biāo)準(zhǔn)的python代碼。

那如果用LangChain寫呢?

from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate

os.environ["OPENAI_API_KEY"] = "<your_api_key>"
text = "hello!"
language = "Italian"


prompt_template = ChatPromptTemplate.from_messages(
    [("system", "You are an expert translator"),
     ("user", "Translate the following from English into {language}"),
     ("user", "{text}")]
)

parser = StrOutputParser()
chain = prompt_template | model | parser
result = chain.invoke({"language": language, "text": text})

涉及到三個(gè)類、四個(gè)函數(shù)調(diào)用。但最令人擔(dān)憂的是,一個(gè)如此簡單的任務(wù)需要引入三個(gè)抽象概念——

  • 提示模板(prompt template):為LLM提供提示
  • 輸出解析器(output parser):處理LLM的輸出
  • 鏈(chain):LangChain的「LCEL語法」覆蓋了Python的「|」運(yùn)算符

這似乎徒增代碼復(fù)雜性,卻沒有任何額外的好處。

LangChain似乎更適合早期原型,但不適合實(shí)際的生產(chǎn)使用。

對于后者而言,開發(fā)人員必須理解每一個(gè)組件,才能保證代碼不會在真實(shí)的使用場景中意外崩潰,但LangChain限制他們必須遵守給定的數(shù)據(jù)結(jié)構(gòu)和抽象概念,這無疑是額外的負(fù)擔(dān)。

再舉一個(gè)例子,這次是從API獲取JSON。

要使用Python內(nèi)置的http包可以這樣寫:

import http.client
import json

conn = http.client.HTTPSConnection("api.example.com")
conn.request("GET", "/data")
response = conn.getresponse()
data = json.loads(response.read().decode())
conn.close()

用requests包的寫法則更加簡潔:

import requests

response = requests.get("/data")
data = response.json()

這感覺上就是好的抽象。雖然是微不足道的小例子,但足以說明一個(gè)觀點(diǎn)——好的抽象可以簡化代碼,并能讓人快速理解。

LangChain的初衷是好的,它希望隱藏細(xì)節(jié),讓開發(fā)人員用更少的代碼完成更多的功能。但如果代價(jià)是失去開發(fā)的簡潔和靈活,這種抽象就失去了價(jià)值。

此外,LangChain還習(xí)慣于「嵌套抽象」,在一個(gè)抽象概念之上再使用抽象。

這不僅讓學(xué)習(xí)API的過程更加復(fù)雜,開發(fā)人員還不得不面對大量的堆棧跟蹤信息,并調(diào)試那些自己不熟悉的內(nèi)部框架代碼。

以這個(gè)技術(shù)團(tuán)隊(duì)自己的開發(fā)為例,他們的應(yīng)用程序使用大量AI agent執(zhí)行不同類型的任務(wù),比如測試用例發(fā)現(xiàn)、Playwright測試生成和自動修復(fù)。

當(dāng)他們想要從只有單個(gè)順序代理的架構(gòu)轉(zhuǎn)向更復(fù)雜架構(gòu)時(shí),例如,生成sub-agnet并與原始agent交互,或者多個(gè)專業(yè)agent彼此交互,LangChain就成為了限制因素。

另一個(gè)示例中,需要根據(jù)業(yè)務(wù)邏輯和LLM的輸出,動態(tài)更改agent可訪問工具的可用性。但LangChain沒有提供從外部觀察agent狀態(tài)的方法,導(dǎo)致他們不得不縮小實(shí)現(xiàn)范圍,以適應(yīng)LangChain對agent可用功能的限制。

下決心刪除LangChain之后,技術(shù)團(tuán)隊(duì)仿佛得到了真正的「解脫」。不僅工作高效了,內(nèi)耗也少了。


一旦刪除了它,我們就可以不用先將需求轉(zhuǎn)化為適合LangChain的解決方案。我們只寫代碼就可以了。


拋棄LangChain,下一個(gè)框架用什么?

事后,團(tuán)隊(duì)仔細(xì)反思復(fù)盤了這個(gè)問題。他們認(rèn)為,長期來看,不使用框架是更好的選擇。

LangChain提供了一長串組件,讓人感覺LLM驅(qū)動的應(yīng)用程序很復(fù)雜,但其實(shí)并不是。核心組件只有幾樣——

  • 用于LLM通信的客戶端
  • 函數(shù)或調(diào)用函數(shù)的工具
  • 用于RAG的向量數(shù)據(jù)庫
  • 用于追蹤、評估等功能的可觀察平臺

其余的組件,要么是以上核心組件的輔助(比如向量數(shù)據(jù)庫的分塊和嵌入),要么只是完成常規(guī)應(yīng)用程序的任務(wù)(比如使用數(shù)據(jù)持久化和緩存,以管理文件和應(yīng)用程序狀態(tài))。

如果不使用任何框架,毫無疑問會增加前期用于學(xué)習(xí)、調(diào)研的工作量,開發(fā)者需要更長時(shí)間來組建自己的工具箱。

但「磨刀不誤砍柴工」,這些時(shí)間是值得的。在即將進(jìn)入的領(lǐng)域打下基礎(chǔ),這對你本人和應(yīng)用程序的未來都是良好的投資。

而且,很多情況下,使用LLM的流程都是非常簡單直接的。開發(fā)人員主要編寫順序代碼、迭代提示,并提高輸出的質(zhì)量和可預(yù)測性。絕大多數(shù)任務(wù)都可以通過簡潔的代碼和較小的外部包集合來實(shí)現(xiàn)。

即使用到了agent,也不一定需要框架才能實(shí)現(xiàn)。在處理業(yè)務(wù)邏輯時(shí),一般只需要在預(yù)定順序流中進(jìn)行agent之間的通信,處理它們的狀態(tài)和響應(yīng),超出這個(gè)范圍的工作內(nèi)容并不多。

雖然agent領(lǐng)域正在迅速發(fā)展,并帶來許多令人興奮的用例和可能性,但在代理的使用模式逐漸固化的過程中,我們還是應(yīng)該遵循簡潔原則。

構(gòu)建基本塊,「輕裝疾行」

假設(shè)技術(shù)團(tuán)隊(duì)沒有在生產(chǎn)中混入垃圾代碼,那么創(chuàng)新和迭代的速度是衡量成功的最重要指標(biāo),因?yàn)锳I領(lǐng)域的許多發(fā)展都是由實(shí)驗(yàn)和原型設(shè)計(jì)驅(qū)動的。

這意味著,代碼庫需要盡可能精簡且適應(yīng)性強(qiáng),才能最大限度提升開發(fā)人員的學(xué)習(xí)速度,每個(gè)迭代周期才能產(chǎn)生更多價(jià)值。

然而,「框架」的概念與此并不相容,它通常是人為設(shè)計(jì)出一種代碼結(jié)構(gòu),為了匹配根據(jù)既有的使用模式。

但LLM驅(qū)動的應(yīng)用還在發(fā)展階段,沒有固定的使用模式。當(dāng)你不得不將創(chuàng)新的想法「翻譯」為特定于某個(gè)框架的代碼時(shí),就限制了迭代速度。

因此,相比于使用框架,更好的辦法是構(gòu)建基本塊(builing blocks),通過簡潔的底層代碼和精心挑選的外部依賴包,保持架構(gòu)的精簡,從而讓開發(fā)人員專注于真正需要解決的問題。

「構(gòu)建基本塊」意味著簡潔、可被完全理解,且不易變動。最典型的例子就是矢量數(shù)據(jù)庫,它屬于已知類型的模塊化組件,只有基本功能,因此可以輕松被更換或取代。

因此,作者所在團(tuán)隊(duì)目前的策略是,完全不使用任何框架,用盡可能少的抽象進(jìn)行模塊化構(gòu)建,從而讓開發(fā)過程更快、更流暢。

雖然LangChain的槽點(diǎn)如此之多,但作者還是選擇不過分苛責(zé)。某種程度上,這些缺陷都是無法避免的。

在AI和LLM這樣快速變化的領(lǐng)域,每周都會涌現(xiàn)新的概念和想法。因此,想要在如此多新型技術(shù)中間創(chuàng)建LangChain這樣的框架,并設(shè)計(jì)出經(jīng)得起時(shí)間考驗(yàn)的抽象,是非常困難的。

作者非常坦誠地承認(rèn),如果當(dāng)初是自己去構(gòu)建LangChain,也不會做得比現(xiàn)在更好。當(dāng)一個(gè)「事后諸葛」指出錯(cuò)誤總是容易的,這篇博文的目的并不是批評任何LangChain的開發(fā)人員或貢獻(xiàn)者,因?yàn)槊總€(gè)人都在盡力而為。

即使能很好地理解需求,構(gòu)建精心設(shè)計(jì)的抽象也是很困難的。因此在不斷變動的條件下對組件(比如agent)進(jìn)行建模時(shí),更安全的選擇是僅對底層模塊使用抽象。

責(zé)任編輯:張燕妮 來源: 新智元
相關(guān)推薦

2019-01-03 11:26:07

碼農(nóng)大齡程序員工作

2020-03-04 15:56:16

碼農(nóng)程序員開發(fā)

2013-11-06 10:15:01

微軟Windows廣告

2011-05-26 09:01:32

2024-03-07 09:15:57

2010-11-18 17:04:14

2017-12-07 14:38:06

2020-05-11 10:00:04

程序員技術(shù)管理

2010-02-24 14:16:56

Visual Stud

2011-12-19 14:26:46

云計(jì)算

2010-04-01 14:35:58

數(shù)據(jù)中心

2018-08-08 08:51:17

微軟谷歌面試

2018-07-17 14:05:49

2020-09-01 14:21:27

程序員薪水開發(fā)

2021-09-30 11:09:53

亞馬遜云科技ISV

2009-05-27 09:31:41

2014-07-11 10:05:31

程序員開發(fā)原則

2021-06-21 08:19:26

碼農(nóng)工作工程師

2021-06-15 15:00:25

碼農(nóng)編程開發(fā)

2020-08-27 16:43:23

程序員加班工作
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號