本文分享自華為云社區(qū)《LangChain是什么?LangChain的詳細介紹和使用場景》,作者:碼上開花_Lancer 。
一、概念介紹
1.1 Langchain 是什么?
官方定義是:LangChain是一個強大的框架,旨在幫助開發(fā)人員使用語言模型構建端到端的應用程序,它提供了一套工具、組件和接口,可簡化創(chuàng)建由大型語言模型 (LLM) 和聊天模型提供支持的應用程序的過程。LangChain是一個語言模型集成框架,其使用案例與語言模型的使用案例大致重疊,包括文檔分析和摘要、聊天機器人和代碼分析。
簡單來說,LangChain提供了靈活的抽象和AI優(yōu)先的工具,可幫助開發(fā)人員將LLM應用程序從原型轉(zhuǎn)化為生產(chǎn)環(huán)境。 它還提供了一套工具,可幫助開發(fā)人員構建上下文感知、推理應用程序, LangChain的工具包括聊天機器人、文檔分析、摘要、代碼分析、工作流自動化、自定義搜索等。
1.2 如何使用 LangChain?
要使用 LangChain,開發(fā)人員首先要導入必要的組件和工具,例如 LLMs, chat models, agents, chains, 內(nèi)存功能。這些組件組合起來創(chuàng)建一個可以理解、處理和響應用戶輸入的應用程序。
LangChain 為特定用例提供了多種組件,例如個人助理、文檔問答、聊天機器人、查詢表格數(shù)據(jù)、與 API 交互、提取、評估和匯總。
本地詳細搭建過程請前往:??https://bbs.huaweicloud.com/blogs/414657??
二、主要包含組件:
- Model I/O:管理大語言模型(Models),及其輸入(Prompts)和格式化輸出(Output Parsers)
- Data connection:管理主要用于建設私域知識(庫)的向量數(shù)據(jù)存儲(Vector Stores)、內(nèi)容數(shù)據(jù)獲?。―ocument Loaders)和轉(zhuǎn)化(Transformers),以及向量數(shù)據(jù)查詢(Retrievers)
- Memory:用于存儲和獲取 對話歷史記錄 的功能模塊
- Chains:用于串聯(lián) Memory ?? Model I/O ?? Data Connection,以實現(xiàn) 串行化 的連續(xù)對話、推測流程
- Agents:基于 Chains 進一步串聯(lián)工具(Tools),從而將大語言模型的能力和本地、云服務能力結合
- Callbacks:提供了一個回調(diào)系統(tǒng),可連接到 LLM 申請的各個階段,便于進行日志記錄、追蹤等數(shù)據(jù)導流
Langchain核心模塊架構圖:
三、核心模塊
3.1 Model I/O
模型接入 LLM 的交互組件,用于和不同類型模型完成業(yè)務交互,LangChain 將模型分為 LLMS、Chat Model兩種模型方式,分別通過不同template操作完成三種模型的業(yè)務交互。
3.2 LLMs
是指具備語言理解和生成能力的商用大型語言模型,以文本字符串作為輸入,并返回文本字符串作為輸出。LangChain 中設計 LLM 類用于與大語言模型進行接口交互,該類旨在為 LLM 提供商提供標準接口,如 OpenAI、Cohere、Hugging Face。
以 OpenAI LLM 包裝器為例,其使用方法如下:
from LangChain.llms import OpenAI llm = OpenAI(temperature=0, model_name='gpt-3.5-turbo', openai_api_key=OPENAI_API_KEY) llm("Please introduce yourself") llm.get_num_tokens(question)
3.3 Chat
聊天模型是語言模型的一個變體,聊天模型以語言模型為基礎,其內(nèi)部使用語言模型,不再以文本字符串為輸入和輸出,而是將聊天信息列表為輸入和輸出,他們提供更加結構化的 API。通過聊天模型可以傳遞一個或多個消息。LangChain 目前支持四類消息類型:分別是 AIMessage、HumanMessage、SystemMessage 和 ChatMessage 。
- SystemMessage:系統(tǒng)消息是用來設定模型的一種工具,可以用于指定模型具體所處的環(huán)境和背景,如角色扮演等;
- HumanMessage:人類消息就是用戶信息,由人給出的信息,如提問;使用 Chat Model 模型就得把系統(tǒng)消息和人類消息放在一個列表里,然后作為 Chat Model 模型的輸入
- AIMessage:就是 AI 輸出的消息,可以是針對問題的回答
- ChatMessage:Chat 消息可以接受任意角色的參數(shù)
大多數(shù)情況下,我們只需要處理 HumanMessage、AIMessage 和 SystemMessage 消息類型。此外聊天模型支持多個消息作為輸入,如下系統(tǒng)消息和用戶消息的示例
messages = [ SystemMessage(cnotallow="You are a helpful assistant that translates English to French."), HumanMessage(cnotallow="I love programming.") ] chat(messages) AIMessage(cnotallow="J'aime programmer.", additional_kwargs={})
使用generate來生成多組消息
batch_messages = [ [ SystemMessage(cnotallow="You are a helpful assistant that translates English to French."), HumanMessage(cnotallow="I love programming.") ], [ SystemMessage(cnotallow="You are a helpful assistant that translates English to French."), HumanMessage(cnotallow="I love artificial intelligence.") ], ] result = chat.generate(batch_messages)
3.4 Prompts
提示(Prompt)指的是模型的輸入,這個輸入一般很少是硬編碼的,而是從使用特定的模板組件構建而成的,這個模板組件就是 PromptTemplate 提示模板,可以提供提示模板作為輸入,模板指的是我們希望獲得答案的具體格式和藍圖。LangChain 提供了預先設計好的提示模板,可以用于生成不同類型任務的提示。當預設的模板無法滿足要求時,也可以使用自定義的提示模板。
在 LangChain 中,我們可以根據(jù)需要設置提示模板,并將其與主鏈相連接以進行輸出預測。此外,LangChain 還提供了輸出解析器的功能,用于進一步精煉結果。輸出解析器的作用是指導模型輸出的格式化方式,以及將輸出解析為所需的格式。
提供了幾個類和函數(shù),使構建和處理提示變得容易:
3.4.1 PromptTemplate 提示模板
可以生成文本模版,通過變量參數(shù)的形式拼接成完整的語句:?
from langchain.llms import OpenAI from langchain import PromptTemplate import os openai_api_key = os.environ["OPENAI_API_KEY"] # 使用 openAi 模型 llm = OpenAI(model_name="gpt-3.5-turbo", openai_api_key=openai_api_key) # 模版格式 template = "我像吃{value}。我應該怎么做出來?" # 構建模版 prompt = PromptTemplate( input_variables=["value"], template=template, ) # 模版生成內(nèi)容 final_prompt = prompt.format(value='紅燒肉') print("輸入內(nèi)容::", final_prompt) print("LLM輸出:", llm(final_prompt))
輸入內(nèi)容:: 我想吃紅燒肉。我應該怎么做出來? LLM輸出: 做紅燒肉的步驟如下: 1.準備材料:500克豬五花肉、2顆蒜瓣、1塊姜、2勺糖、3勺生抽、1勺老抽、2勺料酒、500毫升水。 2.將五花肉切成2-3厘米見方的塊狀。 3.將切好的五花肉放入冷水中煮沸,焯水去腥,撈出備用。 4.熱鍋冷油,加入姜片和蒜瓣煸炒出香味。 5.將焯水后的五花肉加入鍋中,煎至兩面微黃。 6.加入糖,小火翻炒至糖溶化并上色。 7.加入生抽和老抽,均勻翻炒均勻上色。 8.倒入料酒,翻炒均勻。 9.加入煮肉的水,水量需稍微淹沒五花肉,再放入一個小茶包或者香料包提味,蓋上鍋蓋,大火燒沸。 10.轉(zhuǎn)小火燉煮40-50分鐘,期間要時常翻煮肉塊,保持肉塊上色均勻。 11.最后收汁,汁液收濃后即可關火。 12.盛出紅燒肉,切片裝盤即可享用。
3.4.2 FewShotPromptTemplate 選擇器
將提示的示例內(nèi)容同樣拼接到語句中,讓模型去理解語義含義進而給出結果。
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector from langchain.vectorstores import FAISS from langchain.embeddings import OpenAIEmbeddings from langchain.prompts import FewShotPromptTemplate, PromptTemplate from langchain.llms import OpenAI import os ## prompt 選擇器示例 openai_api_key = os.environ["OPENAI_API_KEY"] llm = OpenAI(model_name="gpt-3.5-turbo", openai_api_key=openai_api_key) example_prompt = PromptTemplate( input_variables=["input", "output"], template="示例輸入:{input}, 示例輸出:{output}", ) # 這是可供選擇的示例列表 examples = [ {"input": "飛行員", "output": "飛機"}, {"input": "駕駛員", "output": "汽車"}, {"input": "廚師", "output": "廚房"}, {"input": "空姐", "output": "飛機"}, ] # 根據(jù)語義選擇與您的輸入相似的示例 example_selector = SemanticSimilarityExampleSelector.from_examples( examples, # 生成用于測量語義相似性的嵌入的嵌入類。 OpenAIEmbeddings(openai_api_key=openai_api_key), # 存儲詞向量 FAISS, # 生成的示例數(shù) k=4 ) # 選擇器示例 prompt similar_prompt = FewShotPromptTemplate( example_selector=example_selector, example_prompt=example_prompt, # 加到提示頂部和底部的提示項 prefix="根據(jù)下面示例,寫出輸出", suffix="輸入:{value},輸出:", # 輸入變量 input_variables=["value"], ) value = "學生" # 模版生成內(nèi)容 final_prompt = similar_prompt.format(value=value) print("輸入內(nèi)容::", final_prompt) print("LLM輸出:", llm(final_prompt))
輸入內(nèi)容:: 根據(jù)下面示例,寫出輸出 示例輸入:廚師, 示例輸出:廚房 示例輸入:駕駛員, 示例輸出:汽車 示例輸入:飛行員, 示例輸出:飛機 示例輸入:空姐, 示例輸出:飛機 輸入:學生,輸出: LLM輸出: 教室
3.4.3 ChatPromptTemplate 聊天提示模版
以聊天消息作為輸入生成完整提示模版。
from langchain.schema import HumanMessage from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate # 我們將使用聊天模型,默認為 gpt-3.5-turbo from langchain.chat_models import ChatOpenAI # 解析輸出并取回結構化數(shù)據(jù) from langchain.output_parsers import StructuredOutputParser, ResponseSchema import os openai_api_key = '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' chat_model = ChatOpenAI(temperature=0, model_name='gpt-3.5-turbo', openai_api_key=openai_api_key) prompt = ChatPromptTemplate( messages=[ HumanMessagePromptTemplate.from_template("根據(jù)用戶內(nèi)容,提取出公司名稱和地域名, 用用戶內(nèi)容: {user_prompt}") ], input_variables=["user_prompt"] ) user_prompt = "水滴公司總部在北京嗎?" fruit_query = prompt.format_prompt(user_prompt=user_prompt) print('輸入內(nèi)容:', fruit_query.messages[0].content) fruit_output = chat_model(fruit_query.to_messages()) print('LLM 輸出:', fruit_output)
輸入內(nèi)容: 根據(jù)用戶內(nèi)容,提取出公司名稱和地域名, 用用戶內(nèi)容: 水滴公司總部在北京嗎? LLM 輸出: cnotallow='公司名稱: 水滴公司\n地域名: 北京' additional_kwargs={} example=False
3.4.4 StructuredOutputParser 輸出解析器
輸出解析器是指對模型生成的結果進行解析和處理的組件。它的主要功能是將模型生成的文本進行解析,提取有用的信息并進行后續(xù)處理。如對模型生成的文本進行解析、提取有用信息、識別實體、分類和過濾結果,以及對生成文本進行后處理,從而使生成結果更易于理解和使用。它在與大型語言模型交互時起到解析和處理結果的作用,增強了模型的應用和可用性。
語言模型輸出文本。但是很多時候,可能想要獲得比文本更結構化的信息。這就是輸出解析器的作用。即輸出解析器是幫助結構化語言模型響應的類,LangChain 中主要提供的類是 PydanticOutputParser。
3.5 Data connection
打通外部數(shù)據(jù)的管道,包含文檔加載,文檔轉(zhuǎn)換,文本嵌入,向量存儲幾個環(huán)節(jié),此模塊包含用于處理文檔的實用工具函數(shù)、不同類型的索引,以及可以在鏈中使用這些索引
可以將外部數(shù)據(jù)和 LLM 進行結合來理解和生成自然語言,其中外部數(shù)據(jù)可以是本地文檔、數(shù)據(jù)庫等資源,將這些數(shù)據(jù)進行分片向量化存儲于向量存儲數(shù)據(jù)庫中,再通過用戶的 Prompt 檢索向量數(shù)據(jù)庫中的相似信息傳遞給大語言模型進行生成和執(zhí)行 Action。
文檔加載器
重點包括了 txt(TextLoader)、csv(CSVLoader),html(UnstructuredHTMLLoader),json(JSONLoader),markdown(UnstructuredMarkdownLoader)以及 pdf(因為 pdf 的格式比較復雜,提供了 PyPDFLoader、MathpixPDFLoader、UnstructuredPDFLoader,PyMuPDF 等多種形式的加載引擎)幾種常用格式的內(nèi)容解析。
3.5.2 Document transformers 文檔轉(zhuǎn)換器
有許多內(nèi)置的文檔轉(zhuǎn)換器,可以輕松地拆分、組合、過濾和以其他方式操作文檔,重點關注按照字符遞歸拆分的方式 RecursiveCharacterTextSplitter 。
3.5.3 Text embedding models 文本嵌入
LangChain 中的 Embeddings 基類公開了兩種方法:一種用于嵌入文檔,另一種用于嵌入查詢。前者采用多個文本作為輸入,而后者采用單個文本。將它們作為兩種單獨方法的原因是,某些嵌入提供程序?qū)ξ臋n(要搜索的)與查詢(搜索查詢本身)有不同的嵌入方法。
文本嵌入模型 text-embedding-model 是將文本進行向量表示,從而可以在向量空間中對文本進行諸如語義搜索之類的操作,即在向量空間中尋找最相似的文本片段。而這些在 LangChain 中是通過 Embedding 類來實現(xiàn)的。
Embedding 類是一個用于與文本嵌入進行交互的類。這個類旨在為提供商(有許多嵌入提供商,如 OpenAI、Cohere、Hugging Face 等)提供一個標準接口
from langchain.schema import HumanMessage from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate # 我們將使用聊天模型,默認為 gpt-3.5-turbo from langchain.chat_models import ChatOpenAI # 解析輸出并取回結構化數(shù)據(jù) from langchain.output_parsers import StructuredOutputParser, ResponseSchema import os openai_api_key = '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' chat_model = ChatOpenAI(temperature=0, model_name='gpt-3.5-turbo', openai_api_key=openai_api_key) prompt = ChatPromptTemplate( messages=[ HumanMessagePromptTemplate.from_template("根據(jù)用戶內(nèi)容,提取出公司名稱和地域名, 用用戶內(nèi)容: {user_prompt}") ], input_variables=["user_prompt"] ) user_prompt = "水滴公司總部在北京嗎?" fruit_query = prompt.format_prompt(user_prompt=user_prompt) print('輸入內(nèi)容:', fruit_query.messages[0].content) fruit_output = chat_model(fruit_query.to_messages()) print('LLM 輸出:', fruit_output)
3.5.4 VectorStores 向量存儲
存儲和搜索非結構化數(shù)據(jù)的最常見方法之一是嵌入它并存儲生成的嵌入向量,然后在查詢時嵌入非結構化查詢并檢索與嵌入查詢“最相似”的嵌入向量。
矢量存儲負責存儲嵌入數(shù)據(jù)并為您執(zhí)行矢量搜索。。處理向量存儲的關鍵部分是創(chuàng)建要放入其中的向量,這通常是通過 embedding 來創(chuàng)建的。這個就是對常用矢量數(shù)據(jù)庫(Chroma、FAISS,Milvus,Pinecone,PGVector 等)封裝接口的說明,大概流程:初始化數(shù)據(jù)庫連接信息——>建立索引——>存儲矢量——>相似性查詢,下面以 Chroma 為例:
# 加載文件 loader = TextLoader(filePath) documents = loader.load() # 切塊數(shù)據(jù) text_splitter = CharacterTextSplitter( chunk_size=chunkSize, chunk_overlap=0, length_functinotallow=len, separator=separator) split_docs = text_splitter.split_documents(documents) # 初始請求向量化數(shù)據(jù) embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY) # 持久化文件地址 persist_directory = '/data/' + collectName # 執(zhí)行向量化 vectorstore = Chroma.from_documents( split_docs, embeddings, persist_directory=persist_directory) # 持久化到本地 vectorstore.persist()
3.5.5 Retrievers 查詢
檢索器是一個接口,它根據(jù)非結構化查詢返回文檔。它比矢量存儲更通用。檢索器不需要能夠存儲文檔,只需返回(或檢索)它。矢量存儲可以用作檢索器的骨干,但也有其他類型的檢索器。
檢索器接口是一種通用接口,使文檔和語言模型易于組合。LangChain 中公開了一個 get_relevant_documents 方法,該方法接受查詢(字符串)并返回文檔列表。
重點關注數(shù)據(jù)壓縮,目的是獲得相關性最高的文本帶入 prompt 上下文,這樣既可以減少 token 消耗,也可以保證 LLM 的輸出質(zhì)量。
from langchain.llms import OpenAI from langchain.retrievers import ContextualCompressionRetriever from langchain.retrievers.document_compressors import LLMChainExtractor from langchain.document_loaders import TextLoader from langchain.vectorstores import FAISS documents = TextLoader('../../../state_of_the_union.txt').load() text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) texts = text_splitter.split_documents(documents) retriever = FAISS.from_documents(texts, OpenAIEmbeddings()).as_retriever() docs = retriever.get_relevant_documents("What did the president say about Ketanji Brown Jackson") # 基礎檢索會返回一個或兩個相關的文檔和一些不相關的文檔,即使是相關的文檔也有很多不相關的信息 pretty_print_docs(docs) llm = OpenAI(temperature=0) compressor = LLMChainExtractor.from_llm(llm) # 迭代處理最初返回的文檔,并從每個文檔中只提取與查詢相關的內(nèi)容 compression_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever=retriever) compressed_docs = compression_retriever.get_relevant_documents("What did the president say about Ketanji Jackson Brown") pretty_print_docs(compressed_docs)
3.5.6 Caching Embeddings 緩存嵌入
嵌入可以被存儲或臨時緩存以避免需要重新計算它們。緩存嵌入可以使用CacheBackedEmbeddings。
3.5.7 Memory
Memory 是在用戶與語言模型的交互過程中始終保持狀態(tài)的概念。體現(xiàn)在用戶與語言模型的交互聊天消息過程,這就涉及為從一系列聊天消息中攝取、捕獲、轉(zhuǎn)換和提取知識。Memory 在 Chains/Agents 調(diào)用之間維持狀態(tài),默認情況下,Chains 和 Agents 是無狀態(tài)的,這意味著它們獨立地處理每個傳入的查詢,但在某些應用程序中,如:聊天機器人,記住以前的交互非常重要,無論是在短期的還是長期的?!癕emory”這個概念就是為了實現(xiàn)這一點。
提供了兩種方式使用記憶存儲 Memory 組件,一種是提供了管理和操作以前的聊天消息的輔助工具來從消息序列中提取信息;另一種是在 Chains 中進行關聯(lián)使用。Memory 可以返回多條信息,如最近的 N 條消息或所有以前消息的摘要等。返回的信息可以是字符串,也可以是消息列表。
LangChain 提供了從聊天記錄、緩沖記憶、Chains 中提取記憶信息的方法類以及接口,如 ChatMessageHistory 類,一個超輕量級的包裝器,提供了一些方便的方法來保存人類消息、AI 消息,然后從中獲取它們;再如 ConversationBufferMemory 類,它是 ChatMessageHistory 的一個包裝器,用于提取變量中的消息等等。
from langchain.memory import ChatMessageHistory from langchain.chat_models import ChatOpenAI import os openai_api_key=os.environ["OPENAI_API_KEY"] chat = ChatOpenAI(temperature=0, openai_api_key=openai_api_key) # 聲明歷史 history = ChatMessageHistory() history.add_user_message("你是一個很好的 AI 機器人,可以幫助用戶在一個簡短的句子中找出去哪里旅行") history.add_user_message("我喜歡海灘,我應該去哪里?") # 添加AI語言 history.add_ai_message("你應該去廣東深圳") # 添加人類語言 history.add_user_message("當我在那里時我還應該做什么?") print('history信息:', history.messages) # 調(diào)用模型 ai_response = chat(history.messages) print('結果', ai_response) # 繼續(xù)添加 AI 語言 history.add_ai_message(ai_response.content) print('history信息:', history.messages) # 繼續(xù)添加人類語言 history.add_user_message("推薦下美食和購物場所") ai_response = chat(history.messages) print('結果', ai_response)
3.5.8 Chains
通常我們使用單獨的 LLM 也可以解決問題,但是對于更加復雜的應用程序需要在 LLM 之間或與其他系統(tǒng)進行鏈接來完成任務,這個通常稱為鏈接 LLM。
鏈允許將模型或系統(tǒng)間的多個組件組合起來,創(chuàng)建一個單一的、一致的應用程序。舉例來說,我們創(chuàng)建一個鏈,該鏈接受用戶的輸入,通過 PromptTemplate 模板對輸入進行格式化并傳遞到 LLM 語言模型。還可以將多個鏈組合起來,或者將鏈與其他系統(tǒng)組件組合起來,來構建更復雜的鏈,實現(xiàn)更強大的功能。LangChain 為鏈提供了標準接口以及常見實現(xiàn),與其他工具進行了大量集成,并為常見應用程序提供了端到端鏈。
基礎順序鏈:
from langchain.llms import OpenAI from langchain.chains import LLMChain from langchain.prompts import PromptTemplate from langchain.chains import SimpleSequentialChain import os openai_api_key = os.environ["OPENAI_API_KEY"] llm = OpenAI(temperature=1, openai_api_key=openai_api_key) # 第一個鏈模版內(nèi)容 template1 = "根據(jù)用戶的輸入的描述推薦一個適合的地區(qū),用戶輸入: {value}" prompt_template1 = PromptTemplate(input_variables=["value"], template=template1) # 構建第一個鏈 chain1 = LLMChain(llm=llm, prompt=prompt_template1) # 第二個鏈模版內(nèi)容 template2 = "根據(jù)用戶的輸入的地區(qū)推薦該地區(qū)的美食,用戶輸入: {value}" prompt_template2 = PromptTemplate(input_variables=["value"], template=template2) # 構建第二個鏈 chain2 = LLMChain(llm=llm, prompt=prompt_template2) # 將鏈組裝起來 overall_chain = SimpleSequentialChain(chains=[chain1, chain2], verbose=True) # 運行鏈 review = overall_chain.run("我想在中國看大海") print('結果:', review) from LangChain.prompts import PromptTemplate from LangChain.llms import OpenAI from LangChain.chains import LLMChain llm = OpenAI(temperature=0.9) prompt = PromptTemplate( input_variables=["product"], template=" Please help me to find a new name for my company that makes {product}?", ) chain = LLMChain(llm=llm, prompt=prompt) print(chain.run("super phone"))
上例中接受用戶輸入通過模板格式化輸入后傳遞到語言模型就可以通過一個簡單的鏈類來實現(xiàn),如在 LangChain 中的 LLMChain 類。它是一個簡單的鏈,可接受一個提示模板,使用用戶輸入對其進行格式化,并從 LLM 返回響應。當然 LLMChain 也可以用于聊天模型。?
3.5.9 Agents
通常用戶的一個問題可能需要應用程序的多個邏輯處理才能完成相關任務,而且往往可能是動態(tài)的,會隨著用戶的輸入不同而需要不同的 Action,或者 LLM 輸出的不同而執(zhí)行不同的 Action。因此應用程序不僅需要預先確定 LLM 以及其他工具調(diào)用鏈,而且可能還需要根據(jù)用戶輸入的不同而產(chǎn)生不同的鏈條。使用代理可以讓 LLM 訪問工具變的更加直接和高效,工具提供了無限的可能性,LLM 可以搜索網(wǎng)絡、進行數(shù)學計算、運行代碼等等相關功能。
中代理使用 LLM 來確定采取哪些行動及順序,查看觀察結果,并重復直到完成任務。LangChain 庫提供了大量預置的工具,也允許修改現(xiàn)有工具 或創(chuàng)建新工具。當代理被正確使用時,它們可以非常強大。在 LangChain 中,通過“代理人”的概念在這些類型鏈條中訪問一系列的工具完成任務。根據(jù)用戶的輸入,代理人可以決定是否調(diào)用其中任何一個工具。如下是一段簡單的示例:
#加載要使用的語言模型來控制代理人 llm = OpenAI(temperature=0); #加載一些需要使用的工具,如serpapi和llm-math,llm-math工具需要使用LLM tools = load_tools(["serpapi", "llm-math"], llm=llm) #使用工具、語言模型和代理人類型初始化一個代理人。 agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True) #控制代理執(zhí)行 agent.run("Who is Vin Diesel's girlfriend? What is her current age raised to the 0.5 power?")
3.5.10 Callbacks
LangChain 提供了一個回調(diào)系統(tǒng),允許您連接到 LLM 申請的各個階段。這對于日志記錄、監(jiān)控、流傳輸和其他任務非常有用。
可以使用整個 API 中可用的參數(shù)來訂閱這些事件。該參數(shù)是處理程序?qū)ο蟮牧斜恚@些對象預計將實現(xiàn)下面更詳細描述的一個或多個方法。
四、如何在華為云平臺ModelArts 快速使用 LangChain 構建端到端語言模型應用程序
前期準備:
1.登錄華為云官方賬號:
點擊右上角“控制臺”,搜索欄輸入“ModelArts”
點擊“開發(fā)環(huán)境”-“notebook”,“創(chuàng)建”:
進入創(chuàng)建notebook,名稱“notebook-LangChain”,選擇GPU規(guī)格,“GPU: 1*T4(16GB)|CPU: 8核 32GB”,點擊“立即創(chuàng)建”,磁盤規(guī)格選擇“50G”,點擊“創(chuàng)建”
?文章來源地址http://www.zghlxwxcb.cn/news/detail-745967.html
點擊返回“任務中心”,點擊notebook進入
?
1. 安裝LangChain
首先,安裝 LangChain。只需運行以下命令:
!pip install langchain Looking in indexes: http://repo.myhuaweicloud.com/repository/pypi/simple Collecting langchain Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/1f/fd/f2aa39f8e63a6fbacf2e7be820b846c27b1e5830af9c2e2e208801b6c07f/langchain-0.0.27-py3-none-any.whl (124 kB) |████████████████████████████████| 124 kB 49.0 MB/s eta 0:00:01 Collecting sqlalchemy Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/ac/d8/51e617a1eb143a48ab2dceb194afe40b3c42b785723a031cc29a8c04103d/SQLAlchemy-2.0.20-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.9 MB) |████████████████████████████████| 2.9 MB 30.8 MB/s eta 0:00:01 Requirement already satisfied: numpy in /home/ma-user/anaconda3/envs/PyTorch-1.8/lib/python3.7/site-packages (from langchain) (1.19.5) Requirement already satisfied: pyyaml in /home/ma-user/anaconda3/envs/PyTorch-1.8/lib/python3.7/site-packages (from langchain) (5.1) Requirement already satisfied: requests in /home/ma-user/anaconda3/envs/PyTorch-1.8/lib/python3.7/site-packages (from langchain) (2.27.1) Collecting pydantic Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/fd/35/86b1e7571e695587df0ddf2937100436dce0caa277d2f016d4e4f7d3791a/pydantic-2.2.1-py3-none-any.whl (373 kB) |████████████████████████████████| 373 kB 55.0 MB/s eta 0:00:01 Collecting typing-extensions>=4.6.1 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/38/60/300ad6f93adca578bf05d5f6cd1d854b7d140bebe2f9829561aa9977d9f3/typing_extensions-4.6.2-py3-none-any.whl (31 kB) Collecting pydantic-core==2.6.1 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/c0/ca/4cf24afe80f5839a5cad5e35e2a0a11fe41b0f4f6a544109f73337567579/pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.9 MB) |████████████████████████████████| 1.9 MB 38.3 MB/s eta 0:00:01 Collecting annotated-types>=0.4.0 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/d8/f0/a2ee543a96cc624c35a9086f39b1ed2aa403c6d355dfe47a11ee5c64a164/annotated_types-0.5.0-py3-none-any.whl (11 kB) Requirement already satisfied: urllib3<1.27,>=1.21.1 in /home/ma-user/anaconda3/envs/PyTorch-1.8/lib/python3.7/site-packages (from requests->langchain) (1.26.12) Requirement already satisfied: certifi>=2017.4.17 in /home/ma-user/anaconda3/envs/PyTorch-1.8/lib/python3.7/site-packages (from requests->langchain) (2022.9.24) Requirement already satisfied: charset-normalizer~=2.0.0 in /home/ma-user/anaconda3/envs/PyTorch-1.8/lib/python3.7/site-packages (from requests->langchain) (2.0.12) Requirement already satisfied: idna<4,>=2.5 in /home/ma-user/anaconda3/envs/PyTorch-1.8/lib/python3.7/site-packages (from requests->langchain) (3.4) Collecting greenlet!=0.4.17 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/1a/ed/72998fb3609f6c4b0817df32e2b98a88bb8510613d12d495bbab8534ebd0/greenlet-2.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (514 kB) |████████████████████████████████| 514 kB 12.0 MB/s eta 0:00:01
2.環(huán)境設置
在 Jupyter notebook 或 Python 腳本中工作,您可以像這樣設置環(huán)境變量:
import os os .environ[ "OPENAI_API_KEY" ] = "..."
構建語言模型應用程序:LLM
安裝好 LangChain 并設置好環(huán)境后,我們就可以開始構建我們的語言模型應用程序了。LangChain 提供了一堆模塊,您可以使用它們來創(chuàng)建語言模型應用程序。您可以將這些模塊組合起來用于更復雜的應用程序,或者將它們單獨用于更簡單的應用程序。構建語言模型應用程序:Chat Model
除了 LLM,您還可以使用聊天模型。這些是語言模型的變體,它們在底層使用語言模型但具有不同的界面。聊天模型使用聊天消息作為輸入和輸出,而不是“文本輸入、文本輸出”API。聊天模型 API 的使用還比較新,所以大家都還在尋找最佳抽象使用方式。要完成聊天,您需要將一條或多條消息傳遞給聊天模型。LangChain 目前支持 AIMessage、HumanMessage、SystemMessage 和 ChatMessage 類型。您將主要使用 HumanMessage、AIMessage 和 SystemMessage。 下面是使用聊天模型的示例:
from langchain.chat_models import ChatOpenAI from langchain.schema import ( AIMessage, HumanMessage, SystemMessage ) chat = ChatOpenAI(temperature=0)
您可以通過傳遞一條消息來完成:
chat([HumanMessage(content="Translate this sentence from English to French. I love programming.")]) # -> AIMessage(content="J'aime programmer.", additional_kwargs={})
或者傳遞多條消息給 OpenAI 的 gpt-3.5-turbo 和 gpt-4 models:
messages = [ SystemMessage(content="You are a helpful assistant that translates English to Chinese."), HumanMessage(content="Translate this sentence from English to Chinese. I love programming.") ] chat(messages) # -> AIMessage(content="我喜歡編程。(Wǒ xǐhuān biānchéng.)", additional_kwargs={})
您還可以使用 generate 為多組消息生成完成。這將返回一個帶有附加消息參數(shù)的 LLMResult:
batch_messages = [ [ SystemMessage(content="You are a helpful assistant that translates English to Chinese."), HumanMessage(content="Translate this sentence from English to Chinese. I love programming.") ], [ SystemMessage(content="You are a helpful assistant that translates English to Chinese."), HumanMessage(content="Translate this sentence from English to Chinese. I love artificial intelligence.") ], ] result = chat.generate(batch_messages) result # -> LLMResult(generations=[[ChatGeneration(text="我喜歡編程。(Wǒ xǐhuān biānchéng.)", generation_info=None, message=AIMessage(content="我喜歡編程。(Wǒ xǐhuān biānchéng.)", additional_kwargs={}))], [ChatGeneration(text="我喜愛人工智能。(Wǒ xǐ'ài rén gōng zhì néng.)", generation_info=None, message=AIMessage(content="我喜愛人工智能。(Wǒ xǐ'ài rén gōng zhì néng.)", additional_kwargs={}))]], llm_output={'token_usage': {'prompt_tokens': 71, 'completion_tokens': 18, 'total_tokens': 89}})
您還可以從 LLMResult 中提取 tokens 使用等信息:
result.llm_output['token_usage'] # -> {'prompt_tokens': 71, 'completion_tokens': 18, 'total_tokens': 89}
對于聊天模型,您還可以通過使用 MessagePromptTemplate 來使用模板。您可以從一個或多個 MessagePromptTemplates 創(chuàng)建 ChatPromptTemplate。ChatPromptTemplate 的方法format_prompt返回一個 PromptValue,您可以將其轉(zhuǎn)換為字符串或 Message 對象,具體取決于您是否要使用格式化值作為 LLM 或聊天模型的輸入。
以下是一個例子:
from langchain.chat_models import ChatOpenAI from langchain.prompts.chat import ( ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, ) chat = ChatOpenAI(temperature=0) 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]) # get a chat completion from the formatted messages chat(chat_prompt.format_prompt(input_language="English", output_language="Chinese", text="I love programming.").to_messages()) # -> AIMessage(content="我喜歡編程。(Wǒ xǐhuān biānchéng.)", additional_kwargs={})
您也可以將 LLMChain 與 Chat Model 一起使用:
from langchain.chat_models import ChatOpenAI from langchain import LLMChain from langchain.prompts.chat import ( ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, ) chat = ChatOpenAI(temperature=0) 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]) chain = LLMChain(llm=chat, prompt=chat_prompt) chain.run(input_language="English", output_language="Chinese", text="I love programming.") # -> "我喜歡編程。(Wǒ xǐhuān biānchéng.)"
您還可以將代理與聊天模型一起使用。使用 AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION 作為代理類型初始化 Agent
from langchain.agents import load_tools from langchain.agents import initialize_agent from langchain.agents import AgentType from langchain.chat_models import ChatOpenAI from 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?")
在此示例中,代理將以交互的方式執(zhí)行搜索和計算以提供最終答案。
最后,讓我們探索將內(nèi)存與使用聊天模型初始化的鏈和代理一起使用。這與 Memory for LLMs 的主要區(qū)別在于我們可以將以前的消息保留為它們自己唯一的內(nèi)存對象,而不是將它們壓縮成一個字符串。
下面是使用 a 的示例ConversationChain:
from langchain.prompts import ( ChatPromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate, HumanMessagePromptTemplate ) from langchain.chains import ConversationChain from langchain.chat_models import ChatOpenAI from 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?' conversation.predict(input="I'm doing well! Just having a conversation with an AI.") # -> "That sounds like fun! I'm happy to chat with you. Is there anything specific you'd like to talk about?" conversation.predict(input="Tell me about yourself.") # -> "Sure! I am an AI language model created by OpenAI. I was trained on a large dataset of text from the internet, which allows me to understand and generate human-like language. I can answer questions, provide information, and even have conversations like this one. Is there anything else you'd like to know about me?"
在此示例中,我們使用 aConversationChain來維護跨與 AI 的多次交互的對話上下文。
就是這樣!現(xiàn)在您已經(jīng)對如何使用 LangChain 構建端到端的語言模型應用有了深入的了解。通過遵循這些示例,您可以使用 LLM、聊天模型、代理、鏈和內(nèi)存功能開發(fā)強大的語言模型應用程序。
結論
總之,LangChain 是一個強大的框架,它通過提供模塊化和靈活的方法簡化了構建高級語言模型應用程序的過程。通過了解組件、鏈、提示模板、輸出解析器、索引、檢索器、聊天消息歷史記錄和代理等核心概念,您可以創(chuàng)建適合您特定需求的自定義解決方案。LangChain 的適應性和易用性使其成為開發(fā)人員的寶貴工具,使他們能夠釋放語言模型的全部潛力,并在廣泛的用例中創(chuàng)建智能的、上下文感知的應用程序。
參考文獻
- https://python.langchain.com/docs/get_started/introduction.html
- https://blog.csdn.net/crystal_csdn8/article/details/131753160?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169163537516800184147830%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=169163537516800184147830&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-22-131753160-null-null.142^v92^insert_down1&utm_term=langchain&spm=1018.2226.3001.4187
- https://blog.csdn.net/qq_43692950/article/details/131359743?ops_request_misc=&request_id=&biz_id=102&utm_term=langchain&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-131359743.nonecase&spm=1018.2226.3001.4187
- https://www.bilibili.com/video/BV1vX4y127v4/?spm_id_from=333.788&vd_source=288508e12cf774ee9ad65190776756be
- https://www.bilibili.com/video/BV1GL411e7K4/?spm_id_from=333.337.search-card.all.click&vd_source=288508e12cf774ee9ad65190776756be
- https://www.bilibili.com/video/BV11a4y1c7SW/?spm_id_from=333.337.search-card.all.click&vd_source=288508e12cf774ee9ad65190776756be
- https://www.bilibili.com/video/BV1BM4y177Dk/?spm_id_from=333.788.recommend_more_video.-1&vd_source=288508e12cf774ee9ad65190776756be
?
??點擊關注,第一時間了解華為云新鮮技術~??文章來源:http://www.zghlxwxcb.cn/news/detail-745967.html
?
到了這里,關于理論+實踐詳解最熱的LLM應用框架LangChain的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!