隨著OpenAI在2020年發布了開創性的GPT-3,我們見證了LLM的普及度穩步攀升,如今還在逐漸升溫發酵。這些強大的人工智能模型為自然語言處理應用帶來了新的可能性,使開發人員能夠創建更為復雜、類似于人類交互的聊天機器人、問答系統、摘要工具等產品。
LangChain作為一個多功能框架應運而生,旨在幫助開發人員充分發揮LLMs在各種應用中的潛力?;凇版準健辈煌M件的核心概念,LangChain簡化了與GPT-3/4,Bloom、Huggingface等LLM的工作過程,允許開發者無縫地構建基于LLM的高級應用程序。
圖片
1. Langchain 是什么
LangChain是一種創新性的框架,是語言模型驅動的應用程序的開發方式,關于應用框架的概念和使用可以參考《全棧認知:應用框架》和《探索嵌入式應用框架(EAF)》。LangChain 是基于大模型的應用開發框架,是一個開源的Python庫,旨在通過以下方式更輕松地構建基于LLM的應用程序:
- 向多種不同的基礎模型提供通用接口,
- 提供管理Prompt提示的框架,以及
- 提供長期記憶能力、外部數據以及其他代理程序的中央接口,用于處理LLM無法處理的任務(例如計算或搜索)。
通過融合先進原則,LangChain正在重新定義通過傳統API可以實現的極限。此外,LangChain應用程序是主動的,使語言模型能夠輕松地與其環境交互和適應。Langchain由幾個模塊組成。正如其名稱所示,連接不同的模塊在一起是Langchain的主要目的。這里的想法是將每個模塊鏈接在一個鏈中,并最終使用該鏈一次性調用所有模塊。
圖片
2. LangChain 中的核心概念
LangChain簡化了Prompt提示詞的管理,提供提供了優化能力,為所有LLM提供了通用接口,并包括用于處理LLM的常用程序。LangChain為鏈式調用提供了標準接口,使開發人員能夠創建超出單個LLM調用的調用序列。LangChain 還為開發人員提供了創建與外部數據源集成的鏈的能力,此功能使基于特定數據而不是用于訓練語言模型的通用數據生成文本成為可能。而且,LangChain為開發人員提供了一個標準接口,使LLM能夠根據LLM的輸出做出明智的決策,確定采取哪些行動以及何時采取這些行動。記憶能力是LangChain中的一個關鍵概念,因為它涉及在鏈/代理的調用之間保留狀態。LangChain還提供了一個標準的記憶接口、一系列的記憶實現以及使用記憶的鏈/代理的示例。
圖片
2.1. 模型
大型語言模型(LLM)是指由具有眾多參數的神經網絡組成并在大量未標記的文本上進行訓練的模型。有許多技術巨頭和學術組織都有著自己的LLM,例如:OpenAI的GPT-3/4,Google的LaMDA/PaLM,Meta AI的LLaMA,百度的文心,阿里的千問,訊飛的星火,清華的GLM等等。借助Langchain,應用成效與大型語言模型的交互變得更容易。
LangChain輕松地集成和使用不同的語言模型,用于增強應用程序的功能,可連接到大多數第三方LLM可用的API。它具有與公共LLM、聊天和embedding模型的 ~40 個API連接。LangChain還通過asyncio庫為LLM提供異步支持,還為同時調用多個LLMs的情況提供了異步支持。我們可以使用agenerate方法異步調用LLM,還可以編寫自定義的LLM包裝器。每個大模型都有自己的優點、令牌的使用次數和用例。更多的細節,可以到相關大模型的官網去閱讀更多信息。
2.2. Prompt提示
LangChain允許有效地管理、優化和序列化Prompt提示,允許開發者使用模板構建動態提示。它可以根據上下文窗口大小和用作上下文(對話歷史記錄,搜索結果,以前的答案等)的輸入變量適應不同的LLM類型。這有助于從語言模型生成更準確且具有上下文相關性的響應。
Prompt提示是我們向LLM系統提供的輸入,以改進我們的答案,使其更準確或更能夠適應我們的具體用例。很多時候,我們可能希望獲得比純文本更具體結構化的信息。許多基于對比預訓練和零樣本學習的目標檢測和分類算法都將Prompt作為有效的結果輸入。例如,OpenAI的CLIP和META的Grounding DINO都使用Prompt作為預測的輸入。
圖片
在Langchain中,可以根據我們想要的答案設置Prompt模板,然后將其鏈接到主鏈以進行輸出預測,還有一個用于結果精煉的輸出解析器的功能。輸出解析器負責指示模型輸出的格式,并將輸出解析為所需的格式,必要時需要重試。模板是指我們希望回答的特定格式或藍圖。LangChain提供了預先設計的Prompt模板,可以為不同類型的任務生成Prompt。然而,在某些情況下,預設模板可能無法滿足要求,可以使用自定義的提示模板。
2.3. 記憶能力
LangChain為記憶能力提供了標準接口和一系列實現,為LLM提供了訪問對話歷史記錄的權限。它促進了在鏈或代理的調用之間保持狀態的持久性,增強了模型的知識召回能力。
LangChain在默認情況下以無狀態模式運行,這意味著獨立處理每個傳入的查詢。然而,對于某些應用程序,如聊天機器人,無論是短期還是長期,保留前面的交互非常重要。這就是“記憶能力”概念發揮作用的地方。為了跟蹤用戶與語言模型的交互,LangChain的記憶能力涉及將聊天消息序列轉化為ChatMessages,并從中攝取、捕獲、轉換和提取知識。在LangChain中有許多不同的記憶類型,每一種都有其處理消息序列的獨特方式。在使用記憶能力時,一種是獨立的函數,它們從消息序列中提取信息,另一種是如何在鏈中使用這種類型的記憶。LangChain的記憶能力可以返回多個信息,例如最近的N個消息或所有先前消息的摘要,返回的信息可以是一個字符串或一個消息列表。
LangChain提供了兩種形式的記憶能力組件。首先,提供了管理和操作以前聊天消息的輔助工具,這些工具被設計為模塊化和可用的,適應于各種用例。其次,LangChain提供了將這些常用程序集成到鏈中的簡便方法,使它們具有高度的適應性。
2.4. 索引
索引是指以LLM最佳地與它們交互的方式來構造文檔的方法。為了增強語言模型的能力,LangChain有效地將LLM與用戶的文本數據結合使用,包含用于處理文檔、不同類型的索引的實用函數以及使用這些索引在鏈中的示例,提供了索引和搜索數據源的最佳實踐。
LangChain提供了三種文檔加載器:
- 轉換加載器
- 公共數據集或服務加載器
- 專有數據集或服務加載器
轉換加載器將數據從特定格式轉換為文檔格式,例如有用于CSV和SQL的轉換器。大多數情況下,這些加載器從文件中輸入數據,有時也可以從URL中輸入數據。許多這些轉換器的主要驅動程序是Unstructured模塊。該包可以將許多類型的文件(文本、PowerPoint、圖像、HTML、PDF 等)轉換為文本數據。對于在公共領域創建的數據集和數據源,對于這些數據集和服務,我們不需要任何訪問權限可以使用查詢來搜索并下載所需的文檔。對于不屬于公共領域的數據集和服務,專有數據集或服務加載器主要用于轉換特定格式的應用程序或云服務的數據,我們需要訪問令牌和其他參數才能訪問這些數據集和服務。
圖片
一般地,這些文檔會以 embedding 的形式存儲在向量數據庫中,從而建立索引并實現搜索。
2.5. 鏈
鏈是一系列調用,可以是語言模型或其他常用程序。LangChain提供了鏈的標準接口,以及許多與常見應用程序集成好的鏈。
鏈是將一個或多個大型語言模型(LLM)以邏輯方式連接起來得到的結果,提供了將各種組件合并成一個統一應用的方法。例如,可以創建一個鏈,從用戶那里接收輸入,使用Prompt提示模版進行格式化,然后將格式化后的回復發送給LLM中,還可以通過將多個鏈條與其他組件集成來生成更復雜的鏈。LLMChain被認為是查詢LLM對象最廣泛使用的方法之一。它根據提示模板格式化提供的輸入鍵值和需要記憶的鍵值,然后將格式化的字符串發送給LLM,LLM會生成返回的輸出。在調用語言模型之后,可以采取一系列的步驟,并進行一系列對模型的調用。當希望將一個調用的輸出用作另一個調用的輸入時,這種做法的價值更大。在這一系列的鏈中,每個單獨的鏈都有一個輸入和一個輸出,一個步驟的輸出被用作下一個步驟的輸入。
2.6. 代理
代理使語言模型能夠做出決策、采取行動、觀察結果并重復這個過程,直到完成目標。LangChain為代理提供了標準接口、可供選擇的代理以及端到端代理的示例。
某些應用程序可能不僅需要LLM/其他工具調用的預定序列,而且需要依賴于用戶輸入的不確定序列。這類序列包括一個可以訪問一系列工具的“代理”?;谟脩糨斎?,代理可以確定應該調用這些工具中的哪一個,以及該工具的輸入應該是什么。然后使用這個輸入調用該工具,并記錄一個觀察結果。工具、工具輸入和觀察的歷史記錄會傳回代理,代理決定下一步要采取什么步驟。重復此過程,直到代理決定不再需要使用工具,然后直接響應用戶。
3. 使用LangChain 構建應用
我們或許正在經歷著“AI的Linux時刻”,開發人員必須根據性能和成本之間的權衡選擇專有或開源基礎大模型。
圖片
3.1 構建開發環境
首先,創建基于Python 的虛擬環境,虛擬環境是一個隔離的Python環境,允許您安裝特定于特定項目的軟件包和依賴項,而不會干擾系統范圍的Python安裝或其他項目。這種隔離有助于保持一致性并避免不同項目要求之間的潛在沖突。
然后,安裝LangChain,例如: pip install langchain。
最后,選擇一個或多大模型,并安裝相應的軟件包, 以openai 為例,pip install openai。進一步,還要配置訪問權限,例如需要從OpenAI獲取API密鑰。
3.2 大模型的使用
LangChain 提供了一個 LLM 類,專門用于與各種語言模型提供者(如 OpenAI 和 Hugging Face等等)進行交互。該類為所有 LLM 類型提供了標準接口。在使用大模型的基本能力時,可以先導入包,直接調用LLM實例即可根據問題的輸入生成文本。
import os
from langchain.llms import OpenAI
os.environ["OPENAI_API_KEY"] = ""
llm = OpenAI(model_name="text-ada-001", n=2, best_of=2)
result = llm("給我講個笑話")
print(result)
如果希望獲取包括多個響應,可以調用LLM實例的generate()方法,generate()方法需要一個提示列表作為輸入,LLM為列表中的每個提示生成響應。
在使用OpenAI LLM的場景下,llm.generate的返回結果中包含了程序特定信息,尤其是token 的使用狀況,例如completion_tokens,total_tokens,prompt_tokens的統計數據。
3.3 構建鏈式服務
構建一個典型的鏈式服務主要包括如下4個部分:- 將LLM與提示模板結合- 通過將第一個LLM的輸出作為第二個LLM的輸入,將多個LLM按順序結合在一起(請參見本節)- 將LLM與外部數據結合,例如用于問答- 將LLM與長期記憶結合,例如用于聊天歷史記錄
如果已經創建了Prompt 模板,可以通過LangChain 將 Prompt 模板 應用于大模型:
from langchain.chains import LLMChain
chain = LLMChain(llm = llm,
prompt = prompt)
chain.run(my_query)
如果我們想要將第一個LLM的輸出作為第二個LLM的輸入,可以使用SimpleSequentialChain:
from langchain.chains import LLMChain, SimpleSequentialChain
# Define the first chain as in the previous example
# ...
# Create a second chain with a prompt template and an LLM
second_prompt = PromptTemplate(
input_variables=["company_name"],
template="Write a business domain for the following company: {company_name}",
)
chain_two = LLMChain(llm=llm, prompt=second_prompt)
# Combine the first and the second chain
overall_chain = SimpleSequentialChain(chains=[chain, chain_two], verbose=True)
# Run the chain specifying only the input variable for the first chain.
catchphrase = overall_chain.run(my_query)
LLM的一個限制是它們缺乏上下文信息(例如,無法訪問某些特定的文檔或電子郵件),我們可以通過讓LLM訪問特定的外部數據來解決這個問題。LangChain提供了各種加載程序,用于不同類型的文檔。例如,加載我本地某一路徑下的所有PDF文件——
from langchain.document_loaders import DirectoryLoader
loader = DirectoryLoader(
'./Abel/ePapers/llm',# my local directory
glob='**/*.pdf',# only get pdfs
show_progress=True
)
papers_llm = loader.load()
papers_llm
在準備好將外部數據作為“文檔”之后,可以使用文本嵌入模型在向量數據庫中進行索引 。流行的向量數據庫包括Pinecone、Weaviate和Milvus,已經無需API密鑰的Faiss等等。
# pip install faiss-cpu
from langchain.vectorstores import FAISS
# create the vectorestore to use as the index
db = FAISS.from_documents(documents, embeddings)
將文檔以嵌入形式存儲在了向量數據庫中之后,我們可以對此外部數據進行各種操作,例如使用信息檢索器將其用于問答任務:
from langchain.chains import RetrievalQA
retriever = db.as_retriever()
qa = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True)
query = "What am I never going to do?"
result = qa({"query": query})
print(result['result'])
對于像聊天機器人這樣的應用,能夠記住以前的對話信息是至關重要的。但是默認情況下,LLM沒有任何長期記憶,除非用戶手工輸入聊天歷史記錄。LangChain通過提供了幾種處理聊天歷史記錄的方式:
- 保留所有對話,
- 保留最新的 k 條對話,
- 總結對話。例如,我們使用ConversationChain來為這個應用程序提供對話的歷史信息。
from langchain import ConversationChain
conversation = ConversationChain(llm=llm, verbose=True)
conversation.predict(input="Alice has a parrot.")
conversation.predict(input="Bob has two cats.")
conversation.predict(input="How many pets do Alice and Bob have?")
除了歷史信息之外,LLM仍存在一些限制,例如,無法訪問未包含在訓練數據中的特定知識,數據還可能很快過時(例如,GPT-4是在2021年9月之前的數據上進行訓練的),而且它們不擅長數學計算。因此,我們需要使用代理根據LLM的輸出做出決策,決定使用哪些工具來完成任務。例如,通過建立代理,使用Wikipedia查找Barack Obama的出生日期,然后使用計算器計算他在2022年的年齡。
# pip install wikipedia
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
tools = load_tools(["wikipedia", "llm-math"], llm=llm)
agent = initialize_agent(tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True)
agent.run("When was Barack Obama born? How old was he in 2022?")
在使用LangChain的過程中,有一些鏈不需要LLM,主要是Prompt提示的預處理轉換鏈,例如在將其輸入LLM之前刪除額外的空格,另一參考https://python.langchain.com/en/latest/modules/chains/generic/transformation.html。
4. 基于LangChain 的典型用例
圖片
LangChain 作為一款先進的語言模型應用開發框架,它賦能開發者基于底層語言模型打造出各種智能語言應用。常見用例如下:
- 自治的代理:LangChain支持自治代理的開發,如AutoGPT和BabyAGI,它們是長時間運行的代理,執行多個步驟以實現目標。
- 代理模擬:LangChain促進了創建沙盒環境,其中代理可以相互交互或對事件做出反應,提供對其長期記憶能力的洞察。
- 個人助理:LangChain非常適合構建個人助理,它可以執行操作、記住交互并訪問您的數據,提供個性化的幫助。
- 問答:LangChain在回答特定文檔中的問題方面表現出色,利用這些文檔中的信息構建準確和相關的答案。
- 聊天機器人:利用語言模型的文本生成能力,LangChain賦予了創造引人入勝的聊天機器人的能力。
- 查詢表格數據:LangChain提供了使用語言模型查詢存儲在表格格式中的數據(如CSV文件、SQL數據庫或數據框)的指南。
- 代碼理解:LangChain協助使用語言模型查詢和理解來自GitHub等平臺的源代碼。
- 與API交互:LangChain使語言模型能夠與API交互,為它們提供最新信息,并能夠根據實時數據采取行動。
- 提?。篖angChain幫助從非結構化文本中提取結構化信息,簡化數據分析和解釋。
- 摘要:LangChain支持將較長的文檔摘要成簡潔、易于消化的信息塊,使其成為數據增強的強大工具。
- 評估:由于生成模型難以使用傳統指標進行評估,LangChain提供提示和鏈來輔助使用語言模型本身進行評估過程。
5. 小結
LangChain賦予了開發人員將LLM與其他計算和知識來源相結合以構建應用程序的能力。使用LangChain,開發人員可以使用一個抽象LLM應用程序的核心構建塊的框架。探索LangChain的能力并嘗試其各個組件,會發現可能性幾乎無限。LangChain框架提供了一種靈活和模塊化的語言生成方法,允許創建根據用戶特定需要量身定制的定制解決方案。
但是, LangChain有著把簡單問題復雜化的嫌疑,或許還存在著更好的選擇等待我們去發現和探索。因此,保持好奇心并繼續學習,LLM和生成式AI的世界還在快速發展,是機會,也是挑戰。
【參考資料與關聯閱讀】
- LangChain 中文網:https://www.langchain.asia/
- LangChain 文檔:https://python.langchain.com/docs/get_started/introduction
- LangChain 博客:https://blog.langchain.dev/
- https://minimaxir.com/2023/07/langchain-problem/