大家好,Neo4j 通過集成原生的向量搜索功能,增強了其對檢索增強生成(RAG)應用的支持,這標志著一個重要的里程碑。這項新功能通過向量索引搜索處理非結構化文本,增強了 Neo4j 在存儲和分析結構化數據方面的現有優勢,進一步鞏固了其在存儲和分析結構化數據方面的領先地位。
本文將詳細介紹如何利用 Neo4j Desktop(本地版)和 Neo4j Aura(云服務版)來存儲向量索引,并構建一個基于純文本數據的 RAG 應用。
1.云服務部署
要使用基于云的 Neo4j Aura,需要按照以下步驟操作:
首先,點擊鏈接創建一個實例(https://neo4j.com)。在設置過程中,系統會提示輸入默認的用戶名(neo4j)和實例的密碼。請務必記下這個密碼,因為設置后將無法再次查看。
創建賬戶后,會看到這樣的界面:
實例啟動并運行后,接下來的任務是生成嵌入向量并將其存儲。這里采用OpenAI的嵌入技術,這需要一個OPENAI_API_KEY。
為了將這些嵌入向量上傳到Neo4j Aura實例,需要準備好以下環境變量:NEO4J_URI(Neo4j實例的URI)、NEO4J_USERNAME(用戶名)和NEO4J_PASSWORD(密碼)。
使用LangChain的WikipediaLoader功能,直接從Wikipedia網頁中導入文章內容。
然后,將文章拆分成多個段落,并去除所有元數據,因為我們不需要存儲這些信息。
import?os
from?langchain.vectorstores?import?Neo4jVector
from?langchain.embeddings.openai?import?OpenAIEmbeddings
from?langchain.document_loaders?import?WikipediaLoader
from?langchain.text_splitter?import?CharacterTextSplitter
from?langchain_core.prompts?import?ChatPromptTemplate
from?langchain_core.output_parsers?import?StrOutputParser
from?langchain_core.prompts?import?ChatPromptTemplate
from?langchain_core.runnables?import?RunnablePassthrough#?OPENAI?API?密鑰
os.environ["OPENAI_API_KEY"]?=?"sk-G7F8rdGxxXOWegj5nxxx3BlbkFJj7AuFUP5yyyAKKxSVTGQw"
#?neo4j?憑證
NEO4J_URI="neo4j+s://9cb33544.databases.neo4j.io"
NEO4J_USERNAME="neo4j"
NEO4J_PASSWORD="rexxxJJOzDt4kjaaKgM_VyWUdT9GE4hNBXXGMNubg"#?加載數據和分塊
#?讀取?Wikipedia?文章
raw_documents?=?WikipediaLoader(query="Leonhard?Euler").load()
#?定義分塊策略
text_splitter?=?CharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000,?chunk_overlap=20
)
#?分塊文檔
documents?=?text_splitter.split_documents(raw_documents)#?從元數據中移除摘要
for?d?in?documents:del?d.metadata['summary']
以下代碼片段可將嵌入向量導入 Neo4j 實例:
#?實例化?Neo4j?向量
neo4j_vector?=?Neo4jVector.from_documents(documents,OpenAIEmbeddings(),url=NEO4J_URI,username=NEO4J_USERNAME,password=NEO4J_PASSWORD
)
要在 Neo4j Aura 中訪問和檢查嵌入向量,需點擊界面上的打開圖標,會在瀏覽器中新開一個標簽頁。在這個新標簽頁中,可以查看到塊和向量索引的詳細信息。我們共有56個塊,在系統中被識別為節點。此外,還可以在這個標簽頁中查看每個塊對應的嵌入向量及其具體細節。
向量檢索
這段代碼片段通過使用 Neo4jVector 對象并進行相似性搜索,幫助檢索與查詢“Euler 在哪里長大?”相關的前 4 個相關塊。這段代碼默認采用余弦相似性方法來識別和排序向量之間的相似度。
query?=?"Where?did?Euler?grow?up?"
results?=?neo4j_vector.similarity_search(query=query,?k=4)
print(results)#?檢索到的四個文檔
#?[Document(page_content='==?Early?life?==\nLeonhard?Euler?was?born?on?15?April?1707,?in?Basel?to?Paul?III?Euler,?a?pastor?of?the?Reformed?Church,?and?Marguerite?(née?Brucker),?whose?ancestors?include?a?number?of?well-known?scholars?in?the?classics.?He?was?the?oldest?of?four?children,?having?two?younger?sisters,?Anna?Maria',?metadata={'title':?'Leonhard?Euler',?'source':?'https://en.wikipedia.org/wiki/Leonhard_Euler'}),?...]
創建鏈
我們構建了一個名為final_chain
的處理鏈,旨在高效地處理問題并生成答案。這個鏈的工作原理是:首先,它接收并傳遞上下文信息給Neo4jVector retriever
,以便從Neo4j數據庫中檢索相關的向量。隨后,鏈會利用一個OpenAI模型(版本為gpt-4-1106-preview
)處理接收到的提示。最終,通過一個解析器對模型的輸出進行處理,以提煉出精確的答案。final_chain
的設計實現了在特定上下文中對問題的智能處理和答案生成,提高了整個操作的自動化和效率。
prompt?=?ChatPromptTemplate.from_template("""Answer?the?question?based?only?on?the?context?provided.Context:?{context}Question:?{question}"""
)#?創建一個?lambda?函數將上下文傳遞給?Neo4jVector?retriever
context_to_retriever?=?lambda?x:?x["question"]#?創建鏈,將上下文賦值給?Neo4jVector?retriever
final_chain?=?(RunnablePassthrough.assign(context=context_to_retriever,?target=lambda?x:?neo4j_vector)|?prompt|?ChatOpenAI(model="gpt-4-1106-preview")|?StrOutputParser()
)result?=?final_chain.invoke({'question':?query})#?最終結果
print(result)
# Euler 在瑞士巴塞爾長大。
2.本地部署
如果想在本地的Neo4j Desktop中存儲嵌入向量,可以直接在本地環境中運行該應用。操作起來非常簡單,只需對憑證信息進行更新,其余的步驟則無需更改。
具體來說,需要分別為數據庫和數據庫管理系統設置用戶名和密碼。完成這些設置后,就可以在本地的Neo4j Desktop上順利地執行應用程序了。
NEO4J_URI="bolt://localhost:7687"
NEO4J_USERNAME="neo4j"
NEO4J_PASSWORD="newpassword"
其余部分與上述相同。
3.總結
綜上所述,Neo4j 通過整合其內置的向量搜索功能,顯著提升了對檢索增強生成(RAG)應用的支持能力。這不僅加強了其在傳統結構化數據分析方面的優勢,還使其能夠更有效地處理非結構化文本數據。本文詳細介紹了如何利用Neo4j Aura和Neo4j Desktop來存儲向量索引,并在LangChain框架的輔助下,構建出高效的RAG應用。