使用LangChain實現自動寫作

banq發表於2024-03-25

使用LangChain製作文件檢索器和生成器的教程

LangChain 是 Python 和 JavaScript 中最常用的 RAG 庫之一。檢索增強生成是一種用更多文件增強大型語言模型的技術,而無需經歷針對特定任務進行微調的麻煩。

當我嘗試使用大模型來幫助我寫作時,我提出了這篇文章的概念,我發現簡單的提示通常無法生成可靠的輸出 - 因此 RAG 應用程式是最佳選擇。

提取文件
LangChain 有一個名為“文件”的專有物件,允許使用者載入文字以與其包一起使用。這些文件可以使用文字拆分器輕鬆拆分,並可以新增到鏈、輸出解析器和 LLM 中。

我將使用我所有的中等部落格文章進行培訓,我已經將它們下載為 html 檔案並將它們放置在專案目錄中。

from os import listdir 
from os.path import isfile, join 

mypath = 'project_directory'
 onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))] 

過濾html格式的檔案
onlyfiles = [x for x in onlyfiles if  'htm'  in x]

下一步是使用 langChain 將這些解析為可在 RAG 管道中使用的文件。

# 有很多 HTMLLoader 可供選擇 from 
langchain_community.document_loaders import UnstructuredHTMLLoader #

資料字典將包含文件
data = {} 

i = 0 
for file in onlyfiles: 
    loader = UnstructuralHTMLLoader(file) 

    data[i] = loader.load( ) 

    i+= 1

這些檔案的大小超過了許多 LLM 的消化能力。ChatGPT 3.5 的令牌標記視窗只有 4096 個,僅一篇文章就有大約 2000 個標記。為了擴大上下文視窗,我必須建立一個管道,讓 LLM 可以從管道中檢索這些文件。將文件分割成塊也是一個不錯的策略,因為這將有助於 LLM 生成這些內容,我還將刪除每個文件中的一些不必要文字。

匯入特定的文字分割器,在本例中我們將使用 TokenTextSplitter 
from langchain.text_splitter import TokenTextSplitter 


text_splitter = TokenTextSplitter(chunk_size= 1000 , chunk_overlap= 25 ) 
包含所有分割後文件的字典
 texts = {} 
for i in  range ( len (data)): 
texts字典的鍵是每個檔案的標題
    texts[data[i][ 0 ].metadata[ 'source' ]] = text_splitter.split_documents(data [我])

文件已被提取,下一步是建立嵌入。我將使用 ChromaDB(本地)和 OpenAI 嵌入,但也可以使用其他向量儲存和嵌入模型。

建立嵌入
簡單來說,嵌入是一個接受字串輸入並輸出數字向量的函式。嵌入函式本身就是一個廣泛的主題,超出了本文的範圍。

如果您有興趣瞭解有關嵌入的更多資訊,請訪問OpenAI 嵌入文件。

from langchain_community.vectorstores import Chroma 
from langchain_openai.embeddings import OpenAIEmbeddings 

for i in  range ( len (texts)): 
    vectordb = Chroma.from_documents( 
獲取文件列表
      texts[texts_keys[i]], 
Embedding 函式,我們是using OpenAI default
       embedding=OpenAIEmbeddings(api_key= 'your_open_ai_key' ), 
指定您想要這些內容的目錄
      persist_directory= './LLM_train_embedding/Doc'
     ) 
將它們推入目錄
    vectordb.persist()

檢索retriever 
對於檢索器的最簡單實現,我使用了 ChromaDB 中的內建方法,它允許您搜尋文件。有一些可用的搜尋演算法,您可以從此處瞭解。

用於基於向量儲存的檢索的內建 ChromaDb LangChain 方法
需要兩個引數,即要使用的演算法和搜尋 kwargs,其中指定
每個演算法的引數。 k 告訴要返回的文件數量等


定義檢索器檢索Defines the retriever
retriever = vectordb.as_retriever(search_type='mmr', search_kwargs ={'k':1})

獲取檢索器的文件Gets the document for the retriever
retriever.get_relevant_documents('What is a Sankey?')

檢索是一個很大的主題,我鼓勵您更多地瞭解它。出於本文的目的,我還將使用父文件檢索器。

父文件檢索:將大文件分解為較小塊的檢索方法,並允許檢索器“瞭解”有關文件特定部分的更多資訊。根據 LangChain 的實現,父文件檢索需要向量儲存和文件儲存。

from langchain.retrievers import ParentDocumentRetriever 
from langchain.storage import InMemoryStore 

告訴如何分割子程序
child_splitter = TokenTextSplitter(chunk_size= 250 , chunk_overlap= 10 ) 
告訴如何分割父程序
parent_splitter = TokenTextSplitter(chunk_size= 1000 , chunk_overlap= 50 ) 

vectorstore = Chroma( 
    collection_name= <font>"full_documents" , embedding_function=OpenAIEmbeddings(api_key= 'your_api_key' ) 

在記憶體中建立文件儲存
 store = InMemoryStore()
此檢索器採用向量儲存和文件儲存
Retriever = ParentDocumentRetriever( 
    vectorstore=vectorstore, 
    docstore=store, 
    child_splitter=child_splitter, 
   Parent_splitter = Parent_splitter 


# 新增子文件並拆分它們。
for i in  range ( len (data)): 
    retrieve.add_documents(data[i]) 

搜尋文件
 retrieve.get_relevant_documents( 'What is a Sankey?' )

生成
現在,我將指示法律碩士使用檢索文件進行生成。這將為 LLM 提供有關我寫作風格的更多背景資訊。

我們將使用 RetrievalQA 鏈

from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

# # 這是我使用的提示

# 它以 {context} 的形式接收檔案,並由使用者提供 {topic} 。
template = """Mimic the writing style in the context:
{context} and produce a blog on the topic

Topic: {topic}


"""

prompt = ChatPromptTemplate.from_template(template)

model = ChatOpenAI(api_key =api_key)

# 使用 LangCHain LCEL 提供提示並生成輸出
chain = (
    {
        "context":itemgetter("topic") | retriever,
        "topic": itemgetter("topic"),

    }
    | prompt
    | model
    | StrOutputParser()
)
running the Chain
chain.invoke({"topic": "Pakistan "})

結論
這就是如何建立一個 LLM 機器人,模仿並嘗試再現你自己的寫作。我將對此進行實驗,並嘗試獲得一些評估,看看 LLM 模仿我的寫作有多 "好"。
 

相關文章