<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > 我為什么放棄了 LangChain?(1)

我為什么放棄了 LangChain?(1)

發(fā)布人:機器之心 時(shí)間:2023-07-24 來(lái)源:工程師 發(fā)布文章
「LangChain 的流行已經(jīng)扭曲了圍繞其本身的人工智能創(chuàng )業(yè)生態(tài)系統,這就是為什么我不得不坦誠自己對它的疑慮?!?/span>

如果你關(guān)注了過(guò)去幾個(gè)月中人工智能的爆炸式發(fā)展,那你大概率聽(tīng)說(shuō)過(guò) LangChain。

圖片

簡(jiǎn)單來(lái)說(shuō),LangChain 是一個(gè) Python 和 JavaScript 庫,由 Harrison Chase 開(kāi)發(fā),用于連接 OpenAI 的 GPT API(后續已擴展到更多模型)以生成人工智能文本。
更具體地說(shuō),它是論文《ReAct: Synergizing Reasoning and Acting in Language Models》的實(shí)現:該論文展示了一種提示技術(shù),允許模型「推理」(通過(guò)思維鏈)和「行動(dòng)」(通過(guò)能夠使用預定義工具集中的工具,例如能夠搜索互聯(lián)網(wǎng))。

圖片


論文鏈接:https://arxiv.org/pdf/2210.03629.pdf
事實(shí)證明,這種組合能夠大幅提高輸出文本的質(zhì)量,并使大型語(yǔ)言模型具備正確解決問(wèn)題的能力。
2023 年 3 月,ChatGPT 的 API 因升級降價(jià)大受歡迎,LangChain 的使用也隨之爆炸式增長(cháng)。
這之后,LangChain 在沒(méi)有任何收入也沒(méi)有任何明顯的創(chuàng )收計劃的情況下,獲得了 1000 萬(wàn)美元的種子輪融資和 2000-2500 萬(wàn)美元的 A 輪融資,估值達到 2 億美元左右。
圖片ReAct 論文中的 ReAct 流示例。

由 LangChain 推廣的 ReAct 工作流在 InstructGPT/text-davinci-003 中特別有效,但成本很高,而且對于小型項目來(lái)說(shuō)并不容易使用。
Max Woolf 是一位 BuzzFeed 的數據科學(xué)家。他也使用過(guò) LangChain,這次經(jīng)歷總體來(lái)說(shuō)不太好。
讓我們看看他經(jīng)歷了什么。
「是只有我不會(huì )用嗎?」
在 BuzzFeed 工作時(shí),我有一個(gè)任務(wù)是為 Tasty 品牌創(chuàng )建一個(gè)基于 ChatGPT 的聊天機器人(后來(lái)在 Tasty iOS 應用中發(fā)布為 Botatouille),可以與用戶(hù)聊天并提供相關(guān)食譜。
具體來(lái)說(shuō),源菜譜將被轉換為嵌入式菜譜并保存在一個(gè)向量存儲中:例如如果用戶(hù)詢(xún)問(wèn)「健康食品」,查詢(xún)會(huì )被轉換為嵌入式菜譜,然后執行近似最近鄰搜索以找到與嵌入式查詢(xún)相似的菜譜,然后將其作為附加上下文提供給 ChatGPT,再由 ChatGPT 顯示給用戶(hù)。這種方法通常被稱(chēng)為檢索增強生成。

圖片使用檢索增強生成的聊天機器人的架構示例。

「LangChain 是 RAG 最受歡迎的工具,所以我想這是學(xué)習它的最佳時(shí)機。我花了一些時(shí)間閱讀 LangChain 的全面文檔,以便更好地理解如何最好地利用它?!?/span>


經(jīng)過(guò)一周的研究,我一無(wú)所獲。運行 LangChain 的 demo 示例確實(shí)可以工作,但是任何調整它們以適應食譜聊天機器人約束的嘗試都會(huì )失敗。在解決了這些 bug 之后,聊天對話(huà)的整體質(zhì)量很差,而且毫無(wú)趣味。經(jīng)過(guò)緊張的調試之后,我沒(méi)有找到任何解決方案。
總而言之,我遇到了生存危機:當很多其他 ML 工程師都能搞懂 LangChain 時(shí),我卻搞不懂,難道我是一個(gè)毫無(wú)價(jià)值的機器學(xué)習工程師嗎?
我用回了低級別的 ReAct 流程,它立即在對話(huà)質(zhì)量和準確性上超過(guò)了我的 LangChain 實(shí)現。
浪費了一個(gè)月的時(shí)間來(lái)學(xué)習和測試 LangChain,我的這種生存危機在看到 Hacker News 關(guān)于有人用 100 行代碼重現 LangChain 的帖子后得到了緩解,大部分評論都在發(fā)泄對 LangChain 的不滿(mǎn):

圖片


LangChain 的問(wèn)題在于它讓簡(jiǎn)單的事情變得相對復雜,而這種不必要的復雜性造成了一種「部落主義」,損害了整個(gè)新興的人工智能生態(tài)系統。
所以,如果你是一個(gè)只想學(xué)習如何使用 ChatGPT 的新手,絕對不要從 LangChain 開(kāi)始。
LangChain 的「Hello World」

LangChain 的快速入門(mén),從一個(gè)關(guān)于如何通過(guò) Python 與 LLM/ChatGPT 進(jìn)行簡(jiǎn)單交互的迷你教程開(kāi)始。例如,創(chuàng )建一個(gè)可以將英語(yǔ)翻譯成法語(yǔ)的機器人:

from langchain.chat_models import ChatOpenAIfrom langchain.schema import (    AIMessage,    HumanMessage,    SystemMessage)
chat = ChatOpenAI(temperature=0)chat.predict_messages([HumanMessage(content="Translate this sentence from English to French. I love programming.")])# AIMessage(content="J'adore la programmation.", additional_kwargs={}, example=False)
使用 OpenAI ChatGPT 官方 Python 庫的等效代碼:
import openai
messages = [{"role": "user", "content": "Translate this sentence from English to French. I love programming."}]
response = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=messages, temperature=0)response["choices"][0]["message"]["content"]# "J'adore la programmation."
LangChain 使用的代碼量與僅使用官方 openai 庫的代碼量大致相同,估計 LangChain 合并了更多對象類(lèi),但代碼優(yōu)勢并不明顯。 
提示模板的示例揭示了 LangChain 工作原理的核心:
from langchain.prompts.chat import (    ChatPromptTemplate,    SystemMessagePromptTemplate,    HumanMessagePromptTemplate,)
template = "You are a helpful assistant that translates {input_language} to {output_language}."system_message_prompt = SystemMessagePromptTemplate.from_template(template)human_template = "{text}"human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
chat_prompt.format_messages(input_language="English", output_language="French", text="I love programming.")
LangChain 吹噓的提示工程只是 f-strings,一個(gè)存在于每個(gè) Python 安裝中的功能,但是有額外的步驟。為什么我們需要使用這些 PromptTemplates 來(lái)做同樣的事情呢?
我們真正想做的是知道如何創(chuàng )建 Agent,它結合了我們迫切想要的 ReAct 工作流。幸運的是,有一個(gè)演示,它利用了 SerpApi 和另一個(gè)數學(xué)計算工具,展示了 LangChain 如何區分和使用兩種不同的工具:
from langchain.agents import load_toolsfrom langchain.agents import initialize_agentfrom langchain.agents import AgentTypefrom langchain.chat_models import ChatOpenAIfrom langchain.llms import OpenAI
# First, let's load the language model we're going to use to control the agent.chat = ChatOpenAI(temperature=0)
# Next, let's load some tools to use. Note that the `llm-math` tool uses an LLM, so we need to pass that in.llm = OpenAI(temperature=0)tools = load_tools(["serpapi", "llm-math"], llm=llm)
# Finally, let's initialize an agent with the tools, the language model, and the type of agent we want to use.agent = initialize_agent(tools, chat, agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# Now let's test it out!agent.run("Who is Olivia Wilde's boyfriend? What is his current age raised to the 0.23 power?")
各個(gè)工具如何工作?AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION 到底是什么?agent.run () 的結果輸出(僅在 verbose=True 時(shí)出現)更有幫助。


> Entering new AgentExecutor chain...Thought: I need to use a search engine to find Olivia Wilde's boyfriend and a calculator to raise his age to the 0.23 power.Action:{    "action": "Search",    "action_input": "Olivia Wilde boyfriend"}
Observation: Sudeikis and Wilde's relationship ended in November 2020. Wilde was publicly served with court documents regarding child custody while she was presenting Don't Worry Darling at CinemaCon 2022. In January 2021, Wilde began dating singer Harry Styles after meeting during the filming of Don't Worry Darling.Thought:I need to use a search engine to find Harry Styles' current age.Action:{    "action": "Search",    "action_input": "Harry Styles age"}
Observation: 29 yearsThought:Now I need to calculate 29 raised to the 0.23 power.Action:{    "action": "Calculator",    "action_input": "29^0.23"}
Observation: Answer: 2.169459462491557
Thought:I now know the final answer.Final Answer: 2.169459462491557
> Finished chain.'2.169459462491557'
文檔中沒(méi)有明確說(shuō)明,但是在每個(gè)思想 / 行動(dòng) / 觀(guān)察中都使用了自己的 API 調用 OpenAI,所以鏈條比你想象的要慢。另外,為什么每個(gè)動(dòng)作都是一個(gè) dict?答案在后面,而且非常愚蠢。
最后,LangChain 如何存儲到目前為止的對話(huà)?
from langchain.prompts import (    ChatPromptTemplate,    MessagesPlaceholder,    SystemMessagePromptTemplate,    HumanMessagePromptTemplate)from langchain.chains import ConversationChainfrom langchain.chat_models import ChatOpenAIfrom langchain.memory import ConversationBufferMemory
prompt = ChatPromptTemplate.from_messages([    SystemMessagePromptTemplate.from_template(        "The following is a friendly conversation between a human and an AI. The AI is talkative and ""provides lots of specific details from its context. If the AI does not know the answer to a ""question, it truthfully says it does not know."    ),    MessagesPlaceholder(variable_name="history"),    HumanMessagePromptTemplate.from_template("{input}")])
llm = ChatOpenAI(temperature=0)memory = ConversationBufferMemory(return_messages=True)conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm)
conversation.predict(input="Hi there!")# 'Hello! How can I assist you today?'
我不完全確定為什么這些都是必要的。什么是 MessagesPlaceholder?history 在哪里?ConversationBufferMemory 有必要這樣做嗎?將此調整為最小的 openai 實(shí)現:
import openai
messages = [{"role": "system", "content":        "The following is a friendly conversation between a human and an AI. The AI is talkative and ""provides lots of specific details from its context. If the AI does not know the answer to a ""question, it truthfully says it does not know."}]
user_message = "Hi there!"messages.append({"role": "user", "content": user_message})response = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=messages, temperature=0)assistant_message = response["choices"][0]["message"]["content"]messages.append({"role": "assistant", "content": assistant_message})# Hello! How can I assist you today?

這樣代碼行數就少了,而且信息保存的位置和時(shí)間都很清楚,不需要定制對象類(lèi)。你可以說(shuō)我對教程示例吹毛求疵,我也同意每個(gè)開(kāi)源庫都有值得吹毛求疵的地方(包括我自己的)。但是,如果吹毛求疵的地方比庫的實(shí)際好處還多,那么這個(gè)庫就根本不值得使用。
因為,如果快速入門(mén)都已經(jīng)這么復雜,那么實(shí)際使用 LangChain 會(huì )有多痛苦呢?


*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。



關(guān)鍵詞: AI

相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>