當前位置: 華文世界 > 科技

LangChain結合LLM做私有化文件搜尋

2024-09-06科技

我們知道LLM(大語言模型)的底模是基於已經過期的公開數據訓練出來的,對於新的知識或者私有化的數據LLM一般無法作答,此時LLM會出現「幻覺」。針對「幻覺」問題,一般的解決方案是采用RAG做檢索增強。

但是我們不可能把所有數據都丟給LLM去學習,比如某個公司積累的某個行業的大量內部知識。此時就需要一個私有化的文件搜尋工具了。

本文聊聊如何使用LangChain結合LLM快速做一個私有化的文件搜尋工具。之前介紹過,LangChain幾乎是LLM套用開發的第一選擇,它的野心也比較大,它致力於將自己打造成LLM套用開發的最大社群。自然,它有這方面的成熟解決方案。

文末,還會向朋友們推薦一款非常好用的AI機器人和LLM API超市,價格實惠又穩定,還可以領一波福利。

1. RAG檢索流程

使用 LangChain 實作私有化文件搜尋的主要流程,如下圖所示:

文件載入 → 文件分割 → 文件嵌入 → 向量化儲存 → 文件檢索 → 生成回答

2. 程式碼實踐細節

2.1. 文件載入

首先,我們需要載入文件數據。文件可以是各種格式,比如文字檔案、PDF、Word 等。使用 LangChain,可以輕松地載入這些文件。下面以PDF為例:

from langchain_community.document_loaders import PyPDFLoaderloader = PyPDFLoader("./GV2.pdf")docs = loader.load()

2.2. 文件分割

載入的文件通常會比較大,為了更高效地處理和檢索,我們需要將文件分割成更小的段落或句子。LangChain 提供了便捷的文本分割工具,可以按句子、塊長度等方式分割文件。

from langchain.text_splitter import RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter( chunk_size=50, chunk_overlap=20, separators=["\n", "。", "!", "?", ",", "、", ""], add_start_index=True,)texts = text_splitter.split_documents(docs)

分割後的文件內容可以進一步用於生成向量。

2.3. 文件嵌入 Embeddings

文件分割後,我們需要將每一段文本轉換成向量,這個過程稱為文件嵌入。文件嵌入是將文本轉換成高維向量,這是相似性搜尋的關鍵。這裏我們選擇OpenAI的嵌入模型來生成文件的嵌入向量。

from langchain_openai import OpenAIEmbeddingsembeddings_model = OpenAIEmbeddings( openai_api_key="sk-xxxxxxxxxxx", openai_api_base="https://api.302.ai/v1",)txts = [txt.page_content for txt in texts]embeddings = embeddings_model.embed_documents(txts)

2.4. 文件向量化儲存

接下來,我們需要將生成的向量化的文件,存入向量資料庫中。向量資料庫主要用來做相似性搜尋,可以高效地儲存和檢索高維向量。LangChain 支持與多種向量資料庫的整合,比如 Pinecone、FAISS、Chroma 等。

本文以FAISS為例,首先需要安裝FAISS,直接使用pip install faiss-cpu安裝。

from langchain_community.vectorstores import FAISSdb = FAISS.from_documents(texts, embeddings_model)FAISS.save_local(db, "faiss_db2")

2.5. 文件檢索

當使用者提出問題時,我們需要在向量資料庫中檢索最相關的文件。檢索過程是計算使用者問題的向量表示,然後在向量資料庫中尋找與之最相似的文件。最後將找到的文件內容,拼接成一個大的上下文。

向量資料庫的檢索支持多種模式,本文先用最簡單的,後續再出文章繼續介紹別的模式。

from langchain.retrievers.multi_query import MultiQueryRetrieverretriever = db.as_retriever()# retriever = db.as_retriever(search_type="similarity_score_threshold",search_kwargs={"score_threshold":.1,"k":5})# retriever = db.as_retriever(search_type="mmr")# retriever = MultiQueryRetriever.from_llm(# retriever = db.as_retriever(),# llm = model,# )context = retriever.get_relevant_documents(query="張學立是誰?")_content = ""for i in context: _content += i.page_content

2.6. 將檢索內容丟給LLM作答

最後,我們需要將檢索到的文件內容丟入到 prompt 中,讓LLM生成回答。LangChain 可以PromptTemplate樣版的方式,將檢索到的上下文動態嵌入到 prompt 中,然後丟給LLM,這樣可以生成準確的回答。

from langchain.prompts import ChatPromptTemplatefrom langchain_core.output_parsers import StrOutputParserquestion = "張學立是誰?"template = [ ( "system", "你是一個處理文件的助手,你會根據下面提供<context>標簽裏的上下文內容來繼續回答問題.\n 上下文內容\n <context>\n{context} \n</context>\n", ), ("human", "你好!"), ("ai", "你好"), ("human", "{question}"),]prompt = ChatPromptTemplate.from_messages(template)messages = prompt.format_messages(context=_content, question=question)response = model.invoke(messages)output_parser = StrOutputParser()output_parser.invoke(response)

2.7. 完整程式碼

最後,將以上所有程式碼串起來,整合到一起,如下:

from langchain_openai import ChatOpenAIfrom langchain_community.document_loaders import PyPDFLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain_openai import OpenAIEmbeddingsfrom langchain_community.vectorstores import FAISSfrom langchain.retrievers.multi_query import MultiQueryRetrieverfrom langchain.prompts import ChatPromptTemplatefrom langchain_core.output_parsers import StrOutputParsermodel = ChatOpenAI( model_name="gpt-3.5-turbo", openai_api_key="sk-xxxxxxx", openai_api_base="https://api.302.ai/v1",)loader = PyPDFLoader("./GV2.pdf")docs = loader.load()text_splitter = RecursiveCharacterTextSplitter( chunk_size=50, chunk_overlap=20, separators=["\n", "。", "!", "?", ",", "、", ""], add_start_index=True,)texts = text_splitter.split_documents(docs)embeddings_model = OpenAIEmbeddings( openai_api_key="sk-xxxxxxx", openai_api_base="https://api.302.ai/v1",)txts = [txt.page_content for txt in texts]embeddings = embeddings_model.embed_documents(txts)db = FAISS.from_documents(texts, embeddings_model)FAISS.save_local(db, "faiss_db2")retriever = db.as_retriever()template = [ ( "system", "你是一個處理文件的助手,你會根據下面提供<context>標簽裏的上下文內容來繼續回答問題.\n 上下文內容\n <context>\n{context} \n</context>\n", ), ("human", "你好!"), ("ai", "你好"), ("human", "{question}"),]prompt = ChatPromptTemplate.from_messages(template)question = "張學立是誰?"context = retriever.get_relevant_documents(query=question)_content = ""for i in context: _content += i.page_contentmessages = prompt.format_messages(context=_content, question=question)response = model.invoke(messages)output_parser = StrOutputParser()output_parser.invoke(response)

2.8. 總結、推薦

透過 LangChain可以輕松實作私有化文件搜尋,充分利用LLM的能力來處理和檢索文件資訊。按照文中的步驟,你也可以輕松實作。

好的問答系統離不開優秀的LLM,根據我的個人經驗,OpenAI的大模型能力排名是Top1的。但是使用OpenAI不方便,不但需要梯子而且還不穩定。

一款好的LLM擺在面前,卻用不了,著實頭疼。有沒有方便穩定的方式呢?當然有啦,下面我來推薦一款AI自助平台,不但有問答機器人、文生圖機器人、文生視訊機器人,還有常見的LLM API,穩定又還便宜。

3. 推薦一款好用的AI平台 - 302.AI

3.1. 什麽是302.AI

302.AI是一個匯集全球頂級AI的自助平台,匯集全球各類頂尖AI大模型,提供多種AI機器人,各種AI工具的使用和AI API接入。

這個平台太適合開發者了,一站式配齊了 支持各種模型的工具 AI API ,再也不用這個網站用一下,那個網站用一下了。

自由配置機器人、自由配置各種模型,每一款都很能打。

3.2. 302.AI的優勢

我為什麽願意使用302.AI呢?主要還是優點比較多:

  • 功能全面:平台提供了各種機器人,其中包括不限於文書處理,圖片處理,聲音處理。 這一點就可以輕松應付我們平時的工作了,無需到處找AI工具網站。總之,平台提供的機器人,工具和API多種使用方法,可以滿足從小白到開發者多種角色的需求。
  • 精選優質大模型:平台幫使用者測試市面上眾多的AI模型,挑出最好用的模型接入到平台,簡化使用者的挑選成本。而且再大模型的API呼叫處,還很貼心的整合了Apifox,線上偵錯,自動生成多種語言的程式碼。
  • 價格透明價格便宜:價格透明,token計算清晰,我對比過多個代理的價格,302.AI絕對是最便宜的,沒有之一。
  • 按需付費,零門檻:302.AI另外一個特點是,不像大部份的AI工具網站按月收費或者按年收費,302.AI是按需付費,用多少付多少,價格便宜又透明,計費清晰,更無須擔心跑路。這兩年我見過的倒閉的AI工具站太多了。
  • 管理者和使用者分離:使用者無需關心復雜的AI設定,讓懂AI的管理者來配置,配置完畢後分享給使用者,簡化使用流程。小白也可簡易使用。更無需使用梯子,方便又穩定。
  • 穩定性好:從我最近的使用感受來看,整體還是比較穩定的。不像有些API,時不時的給我冒一個配額不足的情況。
  • 下面上幾個截圖,功能較多,我就不一一解說了,歡迎朋友們自行嘗試。

    總之,302.AI是一個可以滿足從工具到API的聚合AI網站,也是一個可以滿足從小白到開發者的需求的AI網站,同時,又兼顧了穩定性和價效比。更多功能,歡迎朋友們自行嘗試解鎖。

    3.3. 粉絲福利

    我這邊建立了AI全能工具箱分享給大家體驗,每天都會有 5美元額度,先到先用。

    AI全能工具箱連結:https://aitoolbox1-all.tools302.com?pwd=0658 分享碼0658,註冊完填寫個問卷會得到1美元的試用額度。

    對於開發者朋友,可以私信我獲取免費token,薅一波羊毛。

    =====>>>>>> 關於我 <<<<<<=====

    本篇完結!歡迎點贊 關註 收藏!!!

    原文連結:LangChain結合LLM做私有化文件搜尋