LangChain 初學者入門指南
自從 ChatGPT 發佈以來,大語言模型(LLM)變得非常受歡迎。雖然我可能沒有足夠的資金和計算資源從頭訓練一個 LLM,但我仍然可以利用預訓練的 LLM 來構建一些很酷的東西,比如:
-
基於你的數據與外界進行交互的個人助手
-
針對你特定需求定製的聊天機器人
-
對你的文件或代碼進行分析或摘要
由於它們奇怪的 API 和提示工程,LLM 正在改變我們構建 AI 驅動產品的方式。因此,新的開發者工具在 “LLMOps” 這一概念下不斷湧現。
LangChain 就是這樣一個新工具。
#01
什麼是 LangChain?
LangChain 是一個框架,旨在幫助你更輕鬆地構建基於 LLM 的應用程序,它提供以下功能:
-
通用接口:LangChain 提供了一個通用接口,用於訪問多種不同的基礎模型。
-
提示管理:LangChain 提供了一個框架,幫助你管理提示信息。
-
長期記憶接口:LangChain 提供了與長期記憶、外部數據、其他 LLM 以及其他代理(用於處理 LLM 無法處理的任務,如計算或搜索)的集中接口。
LangChain 是由 Harrison Chase 創建的開源項目,託管在 GitHub 倉庫中。
GitHub:https://github.com/hwchase17/langchain
由於 LangChain 具有許多不同的功能,一開始可能會對其作用感到困惑。因此,本文將介紹 LangChain 的六個主要模塊,以幫助你更好地瞭解其功能。
#02
先決條件
要按照本教程進行操作,你需要安裝 langchain Python 包,並準備好所有相關的 API 密鑰。
安裝 LangChain
在安裝 langchain 包之前,請確保你的 Python 版本爲不低於 3.8.1 且低於 4.0。
要安裝 langchain Python 包,你可以使用 pip install 命令。
pip install langchain
在本教程中,我們將使用版本號爲 0.0.147 的 LangChain。由於 GitHub 存儲庫經常更新,因此請確保你使用的是最新版本。
設置完成後,導入 langchain Python 包。
import langchain
API 密鑰
在使用 LLM 構建應用程序時,你需要獲取一些服務的 API 密鑰,而且其中一些 API 可能會有相關的費用。
首先,您你要獲取一個 LLM 提供者的 API 密鑰。目前,我們正在經歷 “AI 的 Linux 時刻”,開發者必須在性能和成本之間做出選擇,要麼使用專有的商業 LLM 模型,要麼選擇開源的基礎模型。
LLM 提供者:專有和開源的基礎模型
專有模型是由擁有龐大專家團隊和高額 AI 預算的公司擁有的閉源基礎模型。它們通常比開源模型更大,因此性能更好,但也會伴隨昂貴的 API 費用。專有模型的提供商包括 OpenAI、co:here、AI21 Labs 和 Anthropic。
大多數 LangChain 教程通常使用 OpenAI,但請注意,OpenAI API(用於實驗目的並不昂貴,但)並非免費。要獲取 OpenAI API 密鑰,你需要擁有 OpenAI 賬戶,然後在 API 密鑰下選擇 “Create new secret key”。
import os
os.environ["OPENAI_API_KEY"] = ... # insert your API_TOKEN here
開源模型通常比專有模型小,功能也較爲有限,但它們比專有模型更優惠。一些開源模型的示例包括:
-
BigScience 的 BLOOM
-
Meta AI 的 LLaMA
-
Google 的 Flan-T5
-
Eleuther AI 的 GPT-J
許多開源模型都被整理並託管在 Hugging Face 上,作爲一個社區中心。要獲得 Hugging Face API 密鑰,你需要擁有 Hugging Face 賬戶,並在 “Access Tokens” 下創建一個 “New token”。
import os
os.environ["HUGGINGFACEHUB_API_TOKEN"] = ... # insert your API_TOKEN here
在 Hugging Face 上使用開源的 LLM 是免費的,但會有一些限制,例如只能使用較小、性能較低的 LLM。
讓我們坦誠一點:當然,你可以在這裏嘗試使用開源基礎模型。我嘗試在本教程中僅使用 Hugging Face 上提供的免費開源模型(如 google/flan-t5-xl 和 sentence-transformers/all-MiniLM-L6-v2)。大多數示例都可以工作,但有些示例可能需要一些額外的工作才能使其正常工作。最終,我還是決定註冊一個付費賬戶,使用 OpenAI,因爲大多數 LangChain 的示例似乎都針對 OpenAI 的 API 進行了優化。總體而言,爲了完成本教程的幾個實驗,我花費了約 1 美元。
如果你想使用特定的向量數據庫,如 Pinecone、Weaviate 或 Milvus,你需要註冊並獲取 API 密鑰,並查看它們的定價信息。在本教程中,我們使用的是不需要註冊即可使用的 Faiss。
根據你希望 LLM 與其交互的工具,如 OpenWeatherMap 或 SerpAPI,你可能需要註冊並獲取 API 密鑰,並查看它們的定價信息。在本教程中,我們僅使用不需要 API 密鑰的工具。
#03
LangChain 可以做什麼?
該包提供了通用接口,可訪問許多基礎模型,並支持提示管理,同時作爲其他組件(如提示模板、其他 LLM、外部數據和其他工具)的中央接口。
截至撰寫本文時(版本 0.0.147),LangChain 涵蓋了六個模塊。
以下各節中的代碼示例是從 LangChain 文檔中複製並修改的。
Model:選擇不同的 LLM 和嵌入模型
目前,出現了許多不同的 LLM。LangChain 提供了對多種模型的集成,併爲它們提供了簡化的接口。
LangChain 將不同類型的模型區分爲三類,它們在輸入和輸出方面存在差異:
LLM 接受字符串作爲輸入(提示),並輸出字符串(完成文本)。
# Proprietary LLM from e.g. OpenAI
# pip install openai
from langchain.llms import OpenAI
llm = OpenAI(model_)
# Alternatively, open-source LLM hosted on Hugging Face
# pip install huggingface_hub
from langchain import HuggingFaceHub
llm = HuggingFaceHub(repo_id = "google/flan-t5-xl")
# The LLM takes a prompt as an input and outputs a completion
prompt = "Alice has a parrot. What animal is Alice's pet?"
completion = llm(prompt)
LLM 模型
Chat 模型與 LLM 相似。它們接受一個聊天消息的列表作爲輸入,並返回一個聊天消息。
文本嵌入模型接受文本輸入,並返回一個浮點數列表(嵌入),這些浮點數是輸入文本的數值表示。嵌入有助於從文本中提取信息。這些信息隨後可以在後續使用,例如用於計算文本之間的相似性(例如電影摘要)。
# Proprietary text embedding model from e.g. OpenAI
# pip install tiktoken
from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
# Alternatively, open-source text embedding model hosted on Hugging Face
# pip install sentence_transformers
from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name = "sentence-transformers/all-MiniLM-L6-v2")
# The embeddings model takes a text as an input and outputs a list of floats
text = "Alice has a parrot. What animal is Alice's pet?"
text_embedding = embeddings.embed_query(text)
文本嵌入模型
Prompt:管理 LLM 的輸入
LLM 的 API 使用起來有些奇怪。雖然以自然語言輸入提示給 LLM 可能會覺得直觀,但要獲得所需的輸出卻需要對提示進行相當多的調整。這個過程被稱爲提示工程。
一旦你有了一個好的提示,你可能希望將其作爲其他用途的模板。因此,LangChain 爲你提供了所謂的 PromptTemplates,幫助你從多個組件構建提示。
from langchain import PromptTemplate
template = "What is a good name for a company that makes {product}?"
prompt = PromptTemplate(
input_variables=["product"],
template=template,
)
prompt.format(product="colorful socks")
上述提示可以看作是零樣本問題設置,即你希望 LLM 在訓練時使用了足夠相關的數據,以提供令人滿意的回答。
另一個改進 LLM 輸出的技巧是在提示中添加一些示例,使其成爲小樣本問題設置。
from langchain import PromptTemplate, FewShotPromptTemplate
examples = [
{"word": "happy", "antonym": "sad"},
{"word": "tall", "antonym": "short"},
]
example_template = """
Word: {word}
Antonym: {antonym}\n
"""
example_prompt = PromptTemplate(
input_variables=["word", "antonym"],
template=example_template,
)
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="Give the antonym of every input",
suffix="Word: {input}\nAntonym:",
input_variables=["input"],
example_separator="\n",
)
few_shot_prompt.format(input="big")
以上代碼將生成一個提示模板,並根據提供的示例和輸入組合成以下提示:
Give the antonym of every input
Word: happy
Antonym: sad
Word: tall
Antonym: short
Word: big
Antonym:
Chain:將 LLM 與其他組件結合
在 LangChain 中,Chaining 簡單地描述了將 LLM 與其他組件結合以創建應用程序的過程。一些例子包括:
-
將 LLM 與提示模板結合。
-
通過將第一個 LLM 的輸出作爲第二個 LLM 的輸入,按順序組合多個 LLM。
-
將 LLM 與外部數據結合,例如用於問答系統。
-
將 LLM 與長期記憶結合,例如用於聊天曆史記錄。
在上一節中,我們創建了一個提示模板。當我們希望將其與 LLM 一起使用時,可以使用 LLMChain 按照以下方式進行組合:
from langchain.chains import LLMChain
chain = LLMChain(llm = llm,
prompt = prompt)
# Run the chain only specifying the input variable.
chain.run("colorful socks")
如果我們希望將第一個 LLM 的輸出作爲第二個 LLM 的輸入,我們可以使用 SimpleSequentialChain(簡單順序鏈):
from langchain.chains import LLMChain, SimpleSequentialChain
# Define the first chain as in the previous code example
# ...
# Create a second chain with a prompt template and an LLM
second_prompt = PromptTemplate(
input_variables=["company_name"],
template="Write a catchphrase 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("colorful socks")
使用 LangChain 中的 PromptTemplates 和 LLM 輸出 SimpleSequentialChain
Indexe:訪問外部數據
LLM 的一個限制是它們缺乏上下文信息(例如,無法訪問某些特定文檔或電子郵件)。爲了克服這一限制,你可以讓 LLM 訪問特定的外部數據。
爲此,首先需要使用文檔加載器加載外部數據。LangChain 提供了各種加載器,適用於不同類型的文檔,包括 PDF 文件、電子郵件、網頁和 YouTube 視頻等。
讓我們從 YouTube 視頻中加載一些外部數據。如果你希望加載大型文本文檔並使用文本拆分器進行分割,可以參考官方文檔:
https://python.langchain.com/en/latest/modules/indexes/text_splitters.html
# pip install youtube-transcript-api
# pip install pytube
from langchain.document_loaders import YoutubeLoader
loader = YoutubeLoader.from_youtube_url("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
documents = loader.load()
現在你已經準備好將外部數據作爲文檔進行索引,可以使用文本嵌入模型在向量數據庫中進行索引。流行的向量數據庫包括 Pinecone、Weaviate 和 Milvus。在本文中,我們使用 Faiss,因爲它不需要 API 密鑰。
# 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'])
等一下 —— 你剛剛被 “Rickroll” 了嗎?沒錯,你被騙了。
Memory:記住先前的對話
對於聊天機器人等應用程序來說,能夠記住之前的對話是至關重要的。但是在默認情況下,語言模型缺乏長期記憶能力,除非你輸入聊天曆史。
使用和不使用會話記憶的聊天
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?")
這將導致上述圖片中右側的對話形式。如果沒有 ConversationChain 來保持對話記憶,對話將會像上圖左側那樣。
Agent:訪問其他工具
儘管 LLM 非常強大,但它們也有一些限制:它們缺乏上下文信息(例如,無法訪問訓練數據中未包含的特定知識),它們可能會很快過時(例如,GPT-4 是在 2021 年 9 月之前的數據上進行訓練的),並且在處理數學問題時表現不佳。
LLM 數學不好
因爲 LLM 在無法獨立完成的任務上可能會產生虛構的答案,所以我們需要給它們提供訪問輔助工具的權限,例如搜索引擎(如 Google 搜索)、計算器(如 Python REPL 或 Wolfram Alpha)和查詢工具(如 Wikipedia)。
另外,我們需要代理來根據 LLM 的輸出決定使用哪些工具來完成任務。
需要注意的是,一些 LLM,比如 google/flan-t5-xl,並不適用於下面的示例,因爲它們不遵循 “對話 - 反應 - 描述” 模板。因此,對我而言,這是設置付費賬戶並切換到 OpenAI API 的一個重要因素。
以下是一個示例:代理首先通過 Wikipedia 查找巴拉克・奧巴馬的出生日期,然後再用計算器計算他在 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?")
LLM 代理的輸出
#04
總結
就在幾個月前,我們(至少大部分人)都對 ChatGPT 的能力感到喫驚。而現在,類似 LangChain 這樣的新型開發工具使我們能夠在幾個小時內在自己的筆記本電腦上構建同樣讓人喫驚的原型 —— 這真是激動人心的時刻!
LangChain 是一個開源的 Python 庫,任何懂編程的人都能夠構建基於 LLM 的應用程序。該庫提供了通用接口來連接多個基礎模型,支持提示管理,並通過代理作爲中央接口連接其他組件,如提示模板、其他 LLM、外部數據和其他工具。截止撰寫本文時,該庫提供了許多未在本文中提及的功能。鑑於當前的快速發展速度,本篇文章可能一個月後就會過時。
在撰寫本文時,我注意到該庫和文檔都以 OpenAI 的 API 爲中心。儘管許多示例可以使用開源基礎模型 google/flan-t5-xl,但我在中途切換到了 OpenAI API。儘管 OpenAI API 並非免費,但在本文中嘗試使用它的成本只有約 1 美元。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/F4QokLPrimFS1LRjXDbwQQ