精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

多用戶數(shù)據(jù)檢索:LangChain技術(shù)指南與案例分析

原創(chuàng) 精選
人工智能
文章探討了如何確保不同用戶數(shù)據(jù)的隔離,并提供靈活的配置選項以適應(yīng)各種檢索需求。

作者 | 崔皓

審校 | 重樓

摘要

文章探討了如何確保不同用戶數(shù)據(jù)的隔離,并提供靈活的配置選項以適應(yīng)各種檢索需求。

文章首先介紹了多用戶數(shù)據(jù)檢索的背景和挑戰(zhàn),包括數(shù)據(jù)權(quán)限管理、檢索系統(tǒng)靈活性和用戶體驗問題。接著進行了技術(shù)分析,特別強調(diào)了使用Pinecone作為向量數(shù)據(jù)庫來處理高維向量數(shù)據(jù)的優(yōu)勢。文中詳細討論了數(shù)據(jù)存儲和檢索的關(guān)鍵步驟,如多用戶支持的檢索器確認、鏈條配置字段的添加和運用可配置字段來調(diào)用鏈條。最后,通過實際代碼演示了如何在LangChain中實現(xiàn)多用戶檢索,包括環(huán)境設(shè)置、文本嵌入、配置索引器與Chain的構(gòu)建,以及通過特定命名空間對文檔庫進行隔離的測試結(jié)果。

背景

多用戶環(huán)境下的數(shù)據(jù)檢索,要求系統(tǒng)能夠區(qū)分并管理不同用戶的數(shù)據(jù)。這不僅涉及到數(shù)據(jù)安全性和隱私保護,還要求檢索系統(tǒng)能夠靈活應(yīng)對不同用戶的數(shù)據(jù)檢索需求。假設(shè)有一家大型企業(yè),擁有龐大的知識庫系統(tǒng),該系統(tǒng)存儲了從市場分析到技術(shù)文檔的各類信息。企業(yè)內(nèi)部有多個部門,如研發(fā)、市場、人力資源等,每個部門對知識庫的數(shù)據(jù)訪問需求不同。為了保證信息安全,企業(yè)需要實現(xiàn)數(shù)據(jù)的權(quán)限控制,確保每個部門只能訪問對應(yīng)的相關(guān)數(shù)據(jù)。

在這個業(yè)務(wù)場景中,最大的挑戰(zhàn)是如何在保證數(shù)據(jù)安全的同時,還能滿足不同用戶的數(shù)據(jù)檢索需求。具體問題包括:

數(shù)據(jù)權(quán)限管理:如何確保每個用戶只能訪問授權(quán)的數(shù)據(jù)?

檢索系統(tǒng)的靈活性:如何設(shè)計一個既能保護數(shù)據(jù)安全,又能靈活響應(yīng)不同用戶檢索需求的系統(tǒng)?

用戶體驗:如何在不泄露其他部門數(shù)據(jù)的前提下,提供快速準確的檢索結(jié)果?

技術(shù)分析

LangChain是大模型應(yīng)用框架特別擅長處理檢索任務(wù),即從大量數(shù)據(jù)中找到與給定查詢最相關(guān)的信息。在這篇文章中,我們將重點介紹如何在LangChain框架中實現(xiàn)多用戶檢索。那么為了實現(xiàn)多用戶檢索不同數(shù)據(jù),就需要解決數(shù)據(jù)存儲和數(shù)據(jù)檢索兩個問題。

數(shù)據(jù)存儲方面

在AI應(yīng)用中,如推薦系統(tǒng)或語義搜索,需要處理和檢索大量的高維向量數(shù)據(jù)。因此處理大規(guī)模向量數(shù)據(jù)會面臨如下問題

  • 實時數(shù)據(jù)更新和查詢延遲問題:AI應(yīng)用需要快速反映數(shù)據(jù)的最新變更(如實時更新用戶偏好)。許多系統(tǒng)難以在保證準確性的同時實現(xiàn)低延遲的數(shù)據(jù)更新和查詢。
  • 復雜的基礎(chǔ)設(shè)施管理和成本:構(gòu)建和維護用于存儲和檢索向量數(shù)據(jù)的基礎(chǔ)設(shè)施通常復雜且成本高昂,尤其是在云環(huán)境下。
  • 高維數(shù)據(jù)的存儲和索引優(yōu)化問題:存儲密集或稀疏的向量嵌入,需要優(yōu)化的存儲結(jié)構(gòu)和索引策略,以保持高效檢索和存儲性能。
  • 多語言和多平臺接入難題:AI應(yīng)用開發(fā)者可能需要在不同的編程環(huán)境(如PythonNode.js)中處理向量數(shù)據(jù),需要一個跨平臺、易于使用的API。

為了解決上述問題,本例我們選用Pinecone。Pinecone是一個為AI應(yīng)用設(shè)計的云原生向量數(shù)據(jù)庫,提供簡易API和自管理的基礎(chǔ)設(shè)施。它專門處理高維向量數(shù)據(jù),能夠以低延遲處理數(shù)十億向量的檢索請求。向量嵌入作為其核心,代表語義信息,賦予AI應(yīng)用長期記憶功能,使其能在執(zhí)行復雜任務(wù)時利用以往經(jīng)驗。

與傳統(tǒng)標量數(shù)據(jù)庫相比,Pinecone提供了針對向量數(shù)據(jù)的優(yōu)化存儲和查詢,解決了處理復雜向量數(shù)據(jù)的難題。它的索引包含獨特ID和密集向量嵌入的浮點數(shù)數(shù)組,也支持稀疏向量嵌入和元數(shù)據(jù)鍵值對,用于混合搜索和過濾查詢。Pinecone保證高性能、實時性,每個pod副本每秒可處理200個查詢,反映最新數(shù)據(jù)更新。用戶可通過HTTP、Python或Node.js進行增刪改查操作,靈活處理向量數(shù)據(jù)。

數(shù)據(jù)檢索方面

為了實現(xiàn)多用戶檢索需要執(zhí)行如下關(guān)鍵步驟:

1. 多用戶支持的檢索器確認:檢查使用的檢索器是否支持多用戶功能。目前LangChain沒有統(tǒng)一的標識或過濾器來實現(xiàn)這一點,每個向量存儲和檢索器可能有自己的實現(xiàn)方式(如命名空間、多租戶等)。通常,這通過在`similarity_search`時傳遞的關(guān)鍵字參數(shù)來暴露。因此,需要通過閱讀文檔或源代碼來確定所用檢索器是否支持多用戶功能,以及如何使用它。

2. 為鏈條添加配置字段:在運行時調(diào)用鏈條并配置任何相關(guān)標志。查閱相關(guān)文檔了解更多關(guān)于配置的信息。需要說明的是, “鏈條”(Chains)是LangChain的一個關(guān)鍵概念,它們是一系列處理步驟的集合,用于執(zhí)行特定的任務(wù)。為了支持多用戶檢索,用戶需要在鏈條中添加配置字段。這些字段允許在運行時動態(tài)調(diào)整鏈條的行為,以適應(yīng)不同用戶的需求。

3. 使用可配置字段調(diào)用鏈條:運行時,通過前面設(shè)置的可配置字段,可以實現(xiàn)對鏈條的個性化調(diào)用。這意味著用戶可以根據(jù)不同的情境或用戶需求,調(diào)整鏈條的行為。這一步是實現(xiàn)多用戶檢索的關(guān)鍵,它確保了檢索結(jié)果能夠根據(jù)不同用戶的獨特需求進行優(yōu)化和調(diào)整。

上面三點需要索引支持多用戶查詢,用戶查詢數(shù)據(jù)的參數(shù)可以通過配置字段的方式傳遞給Chains,同時Chains 可以接受配置字段并且執(zhí)行,完成數(shù)據(jù)檢索的操作。

根據(jù)前面對Pinecone向量存儲的描述,我們通過查閱LangChain 官方文檔了解

既然數(shù)據(jù)存儲和數(shù)據(jù)檢索的問題都得到了解決,下面就開始代碼實踐的環(huán)節(jié)。包langchain_community.vectorstores.pinecone.Pinecone 下面包含了as_retriever方法,該方法創(chuàng)建并返回一個VectorStoreRetriever對象,該對象從VectorStore初始化。這個檢索器提供了多種搜索類型,使得用戶可以根據(jù)不同需求進行定制化的向量數(shù)據(jù)檢索。

該方法的關(guān)鍵參數(shù)如下

search_type(可選字符串)
定義:指定檢索器執(zhí)行的搜索類型。
選項:
"similarity":標準的相似度搜索,默認選項。
"mmr":最大邊緣相關(guān)性(Maximum Marginal Relevance),用于生成多樣化的搜索結(jié)果。
"similarity_score_threshold":設(shè)置相似度分數(shù)閾值,僅返回超過此閾值的文檔。
search_kwargs(可選字典)
功能:提供給搜索函數(shù)的關(guān)鍵字參數(shù)。
包含內(nèi)容:
k:返回的文檔數(shù)量,默認為4。
score_threshold:用于similarity_score_threshold的最小相關(guān)性閾值。
fetch_k:傳遞給MMR算法的文檔數(shù)量,默認為20。
lambda_mult:MMR結(jié)果的多樣性程度,從1(最小多樣性)到0(最大多樣性),默認為0.5。
filter:基于文檔元數(shù)據(jù)的過濾條件。
返回值
類型:VectorStoreRetriever
功能:一個檢索類,用于在VectorStore上執(zhí)行數(shù)據(jù)檢索操作。

代碼實踐

技術(shù)分析之后就需要分幾個步驟進行代碼實踐,具體步驟如下:

Pinecone信息獲取

首先需要注冊Pinecone的賬號,然后獲取對應(yīng)API Keys在調(diào)用Pinecone服務(wù)的時候會用到它。注冊Pinecone的過程比較簡單,填寫基本信息就可以完成,這里不再贅述。如下圖所示,在用戶控制臺的“API Keys” 菜單中選擇key對應(yīng)的“復制”圖標,從而復制“API Keys”留作備用。

接著“Indexes”頁面去創(chuàng)建index,如下圖所示,選擇“Setup by model”。

在彈出的對話框中,我們選擇OpenAI 的embedding 作為index 的配置項。

最終,如下圖所示,點擊“Create indexes” 按鈕創(chuàng)建index。

創(chuàng)建index 完成之后,可以通過下圖看到對應(yīng)的信息,其中“rag-per-user”是index的名字,gcp-starter作為環(huán)境的名字。這兩個信息在初始化Pinecone的時候是需要的。

環(huán)境安裝與參數(shù)配置

需要將代碼需要的組件包安裝好,通過如下命令實現(xiàn)安裝

!pip install openai langchain pinecone-client pypdf tiktoken -q -U

Openai這是OpenAI提供的官方Python庫,用于與OpenAI的API(如GPT和DALL-E等)進行交互。

Langchain這個庫可能是用于處理語言相關(guān)任務(wù)的。它可能包含了一些用于自然語言處理、機器翻譯或其他語言技術(shù)的工具和模型。

pinecone-clientPinecone是一個向量數(shù)據(jù)庫,用于構(gòu)建和部署大規(guī)模相似性搜索應(yīng)用。pinecone-client 是其客戶端庫,用于與Pinecone服務(wù)進行交互。

Pypdf:這是一個Python庫,用于處理PDF文件。它可能允許用戶讀取、寫入、分割、合并和轉(zhuǎn)換PDF文檔。

Tiktoken:用來對文本進行分詞。

接著再對一些參數(shù)進行賦值如下:

import os
import getpass
os.environ["PINECONE_API_KEY"] = getpass.getpass("輸入Pinecone key")
os.environ["OPENAI_API_KEY"] = getpass.getpass("輸入OpenAI Key")
PINECONE_API_KEY=os.environ.get("PINECONE_API_KEY")
PINECONE_ENVIRONMENT="gcp-starter"
PINECONE_INDEX="rag-per-user"

(1) 導入模塊

import os: 導入 Python 的 os 模塊,它提供了許多與操作系統(tǒng)交互的功能,包括管理環(huán)境變量。

import getpass導入 getpass 模塊,它用于安全地獲取用戶輸入,而不在屏幕上顯示輸入(如密碼或密鑰)。

(2) 獲取并設(shè)置環(huán)境變量

os.environ["PINECONE_API_KEY"] = getpass.getpass("輸入Pinecone key"): 這行代碼首先顯示提示“輸入Pinecone key”,然后等待用戶輸入 Pinecone 的 API 密鑰。輸入的內(nèi)容不會在屏幕上顯示。輸入完成后,該密鑰被設(shè)置為環(huán)境變量 PINECONE_API_KEY。

os.environ["OPENAI_API_KEY"] = getpass.getpass("輸入OpenAI Key"): 同樣,這行代碼用于獲取并設(shè)置 OpenAI 的 API 密鑰作為環(huán)境變量 OPENAI_API_KEY。

(3) 讀取環(huán)境變量

PINECONE_API_KEY = os.environ.get("PINECONE_API_KEY")從環(huán)境變量中讀取 PINECONE_API_KEY 的值,并將其賦給變量 PINECONE_API_KEY。如果該環(huán)境變量不存在,它將返回 None。

(4) 設(shè)置其他Pinecone相關(guān)的變量

PINECONE_ENVIRONMENT="gcp-starter"設(shè)置了一個字符串變量 PINECONE_ENVIRONMENT,其值為 "gcp-starter"。這通常用于指定 Pinecone 服務(wù)的運行環(huán)境。

PINECONE_INDEX="rag-per-user": 設(shè)置 PINECONE_INDEX 變量為 "rag-per-user",這個值通常用于指定在 Pinecone 中使用的特定索引。

整體上,這段代碼的目的是安全地獲取和存儲與 Pinecone 和 OpenAI 服務(wù)相關(guān)的敏感信息(如 API 密鑰),同時還設(shè)定了一些與 Pinecone 服務(wù)相關(guān)的配置變量。這樣做可以在代碼的其他部分安全地使用這些密鑰和配置,而不必硬編碼在代碼中,從而增強了安全性和靈活性。

文本嵌入

接下來,使用 Pinecone 作為向量存儲(Vector Store)和 OpenAI 作為嵌入生成器,用于搭建一個語言處理系統(tǒng)。

import pinecone
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain_community.chat_models import ChatOpenAI
from langchain.vectorstores import Pinecone

pinecone.init(api_key=PINECONE_API_KEY, environment=PINECONE_ENVIRONMENT)
index = pinecone.Index(PINECONE_INDEX)
embeddings = OpenAIEmbeddings()
vectorstore = Pinecone(index, embeddings, "text")
vectorstore.add_texts(["我的工作職責是為用戶提供產(chǎn)品方面的介紹。"], namespace="product-service")
vectorstore.add_texts(["我的工作職責是為用戶提供技術(shù)方面的支持。"], namespace="tech-service")
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import (
    ConfigurableField,
    RunnableBinding,
    RunnableLambda,
    RunnablePassthrough,
)
template = """基于如下信息回答問題:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI()
retriever = vectorstore.as_retriever()

代碼解釋如下:

(1) 導入所需模塊和類

import pinecone: 導入 pinecone 模塊,用于與 Pinecone 服務(wù)交互。

from langchain.embeddings.openai import OpenAIEmbeddings: 從 langchain 庫中導入 OpenAIEmbeddings 類,用于生成文本嵌入(embeddings)。

from langchain_community.chat_models import ChatOpenAI: 導入 ChatOpenAI,這可能是用于處理聊天或問答類型任務(wù)的模型。

from langchain.vectorstores import Pinecone: 導入 Pinecone 類,用于在 Pinecone 服務(wù)上操作向量存儲。

(2) 初始化 Pinecone 服務(wù)并創(chuàng)建索引

pinecone.init(api_key=PINECONE_API_KEY, envirnotallow=PINECONE_ENVIRONMENT): 使用提供的 API 密鑰和環(huán)境變量初始化 Pinecone 服務(wù)。

index = pinecone.Index(PINECONE_INDEX): 創(chuàng)建或訪問一個名為 PINECONE_INDEX 的 Pinecone 索引。

(3) 設(shè)置嵌入生成器和向量存儲

embeddings = OpenAIEmbeddings(): 實例化 OpenAIEmbeddings 以生成文本嵌入。

vectorstore = Pinecone(index, embeddings, "text"): 創(chuàng)建一個 Pinecone 實例,用于存儲和檢索文本嵌入。這里使用了之前創(chuàng)建的 index 和 embeddings。

(4) 向量存儲中添加文本

vectorstore.add_texts(["我的工作職責是為用戶提供產(chǎn)品方面的介紹。"], namespace="product-service"): 將一段文本添加到向量存儲中,用于表示“產(chǎn)品服務(wù)”相關(guān)的信息。

vectorstore.add_texts(["我的工作職責是為用戶提供技術(shù)方面的支持。"], namespace="tech-service"): 將另一段文本添加到向量存儲中,用于表示“技術(shù)服務(wù)”相關(guān)的信息。

(5) 設(shè)置輸出解析器、提示模板和模型

導入了多個 langchain_core 中的類和函數(shù),這些可能用于處理和解析語言模型的輸出。

template = "..." 和 prompt = ChatPromptTemplate.from_template(template): 定義一個聊天提示模板,用于指導語言模型如何回答問題。

model = ChatOpenAI(): 實例化一個 ChatOpenAI 模型,可能用于處理聊天或問答任務(wù)。

retriever = vectorstore.as_retriever(): 將 vectorstore 轉(zhuǎn)換為一個檢索器(Retriever),用于從存儲的嵌入中檢索相關(guān)信息。

這段代碼設(shè)置了一個基于 Pinecone 和 OpenAI 的語言處理系統(tǒng),它能夠存儲和檢索文本信息,并且使用特定的模型和模板處理聊天或問答類型的任務(wù)。

配置索引器與Chain

緊跟著,需要建立一個處理鏈(chain),使用配置的檢索器(configurable_retriever),提示模板(Prompt),模型(Model),和輸出解析器(StrOutputParser)。這個Chain 就是用來執(zhí)行按照namespace 進行索引的。代碼如下:

(1) 配置檢索器

configurable_retriever = retriever.configurable_fields(...): 這行代碼創(chuàng)建了一個可配置的檢索器 configurable_retriever。它通過 ConfigurableField 定義一個可配置的字段 search_kwargs,該字段用于定義檢索器的搜索參數(shù)(例如,如何從向量存儲中檢索數(shù)據(jù))。

(2) 構(gòu)建處理鏈

處理鏈由幾個部分組成,通過 | 符號連接,表示數(shù)據(jù)將按順序通過這些組件。

{"context": configurable_retriever, "question": RunnablePassthrough()}: 這是鏈的第一部分,包含兩個輸入:context 和 question。context 通過 configurable_retriever 獲取,而 question 直接通過 RunnablePassthrough 傳遞,后者意味著問題(question)不進行任何處理就傳遞到鏈的下一個部分。

  • prompt: 然后,輸入數(shù)據(jù)傳遞到 prompt。這個ChatPromptTemplate 對象負責根據(jù)上下文和問題格式化提示,準備好交給語言模型處理。
  • model: 接下來,格式化好的提示傳遞給 model,這里的 model 是 ChatOpenAI 實例,它會根據(jù)提供的提示生成回答。
  • StrOutputParser(): 最后,模型的輸出傳遞給StrOutputParser,這個解析器將模型的輸出轉(zhuǎn)換成字符串形式。

整體來看,這個處理鏈的作用是:根據(jù)檢索到的上下文和未處理的問題生成一個格式化的提示,然后使用 ChatOpenAI 模型來生成回答,并將這個回答轉(zhuǎn)換為字符串。這種方式非常適合于問答系統(tǒng),其中上下文信息是根據(jù)需要動態(tài)檢索的,而問題直接傳遞給模型以生成答案。

測試結(jié)果

創(chuàng)建好Chain之后,我們來嘗試對其提出問題,由于我們之前定義了不同namespace對應(yīng)的工作職責。這里我們就直接詢問工作職責的問題,首先測試product-service 這個namespace,看看它返回什么答案。

chain.invoke(
    "你的工作職責是什么?",
    config={"configurable": {"search_kwargs": {"namespace": "product-service"}}},
)

結(jié)果如下

我的工作職責是為用戶提供產(chǎn)品方面的介紹。

結(jié)果和我們預(yù)期一致,product-service 這個namespace 確實是用來處理產(chǎn)品方面的問題的。

接著再測試tech-service 這個namespace的回答。

chain.invoke(
    "你的工作職責是什么?",
    config={"configurable": {"search_kwargs": {"namespace": "tech-service"}}},
)

結(jié)果如下

我的工作職責是為用戶提供技術(shù)方面的支持。

看來返回結(jié)果也是正確的。

文檔庫隔離

上面通過在不同的namespace 中加入不同的text文本信息,讓不同用戶通過訪問不同的namespace 來做到“知識”內(nèi)容的隔離。但是,真實的應(yīng)用場景是針對不同的namespace上傳不同的文檔,當我們提問的時候需要制定namespace,來確定由哪個文檔來回應(yīng)消息。

于是,我們針對product-service 和tech-service 兩個不同的namespace 上傳兩個不同的文檔,分別是product-service.pdf 和 tech-service.pdf。兩個文檔的內(nèi)容如下:

product-service.pdf 是一個產(chǎn)品服務(wù)知識庫,采用問答形式。它提供了關(guān)于客戶服務(wù)的具體指導,特別是關(guān)于退貨政策的細節(jié)。

產(chǎn)品服務(wù)知識庫(問答形式) 
問:如果客戶詢問關(guān)于退貨政策的具體細節(jié),我們應(yīng)該如何回答? 
答:?先,禮貌地感謝客戶對產(chǎn)品的購買。然后, 詳細解釋我們的退貨政策:客戶可以在購買后的30 天內(nèi)?條件退貨,產(chǎn)品必須保持原始狀態(tài)且包裝完整。提醒客戶保留收據(jù),因為這是退貨的必要憑證。 最后,告知客戶退貨流程,并提供相關(guān)表格和聯(lián)系信息。

tech-service.pdf 是一個技術(shù)服務(wù)知識庫,同樣采用問答形式。它主要提供了關(guān)于技術(shù)問題解決方案的指導,特別是針對智能鎖失靈的問題。

技術(shù)服務(wù)知識庫(問答形式) 
問:客戶如何解決智能鎖頻繁失靈的問題? 
答:?先,指導客戶檢查智能鎖的電源和電池狀態(tài),確認電量是否充?。如果電量正常,請引導客戶重置智能鎖,具體?法是?按重置鍵 5 秒鐘。如果問題仍然存在,請建議客戶檢查智能鎖的軟件版本是否最新,并引導進?系統(tǒng)更新。若以上步驟?法解決問題,建議客戶聯(lián)系技術(shù)?持以獲取進?步的幫助。

有了文檔之后,我們就需要將其上傳并且嵌入到向量庫Pinecone中, 代碼如下:

from langchain.document_loaders import PyPDFLoader
from google.colab import drive
drive.mount('/content/drive')
file_path = '/content/drive/My Drive/files/product-service.pdf'
loader = PyPDFLoader(file_path)
documents = loader.load_and_split()
vectorstore.add_documents(documents, namespace="product-service")
file_path = '/content/drive/My Drive/files/tech-service.pdf'
loader = PyPDFLoader(file_path)
documents = loader.load_and_split()
vectorstore.add_documents(documents, namespace="tech-service")

由于我使用的是colab 環(huán)境,所以這段代碼是關(guān)于如何在 Google Colab 環(huán)境中加載 PDF 文件并將它們的內(nèi)容添加到一個向量存儲(vector store)中。下面是對代碼的詳細解釋:

(1) **導入所需模塊和類**

  • `from langchain.document_loaders import PyPDFLoader`: 導入 `PyPDFLoader` 類,這個類用于加載 PDF 文件并將其內(nèi)容轉(zhuǎn)換為可處理的文檔格式。
  •  `from google.colab import drive`: 導入用于在 Google Colab 環(huán)境中掛載 Google Drive 的模塊。

(2) **掛載 Google Drive**

  • `drive.mount('/content/drive')`: 這行代碼將 Google Drive 掛載到 Colab 的文件系統(tǒng)中。這使得在 Colab 中可以直接訪問存儲在 Google Drive 中的文件。

(3) **加載并處理第一個 PDF 文件**

  •  `file_path = '/content/drive/My Drive/files/product-service.pdf'`: 設(shè)置第一個 PDF 文件的路徑。
  •  `loader = PyPDFLoader(file_path)`: 創(chuàng)建 `PyPDFLoader` 實例并傳入文件路徑,準備加載文件。
  • `documents = loader.load_and_split()`: 使用 `load_and_split` 方法加載 PDF 文件并將其內(nèi)容分割成單獨的文檔。這些文檔通常是 PDF 的每一頁或者每個段落。

(4) **將文檔添加到向量存儲**

  •  `vectorstore.add_documents(documents, namespace="product-service")`: 將從 PDF 文件中加載的文檔添加到向量存儲中,指定命名空間為 "product-service"。

(5) **重復以上步驟加載第二個 PDF 文件**

  • 設(shè)置第二個 PDF 文件 `tech-service.pdf` 的路徑。
  • 再次創(chuàng)建 `PyPDFLoader` 實例,加載第二個文件。
  • 將從第二個文件中加載的文檔添加到向量存儲中,這次指定命名空間為 "tech-service"。

整體來看,這段代碼的目的是將兩個 PDF 文件(分別關(guān)于產(chǎn)品服務(wù)和技術(shù)服務(wù)的知識庫)的內(nèi)容加載到一個向量存儲系統(tǒng)中,可能用于后續(xù)的搜索或檢索任務(wù)。通過將文件內(nèi)容分割成單獨的文檔,并使用命名空間區(qū)分不同的文件內(nèi)容,代碼有效地組織了信息,便于后續(xù)處理。

既然PDF文檔已經(jīng)嵌入了,接下來就是重頭戲了。我們義了一個名為ask_question 的函數(shù),它使用一系列處理步驟(即一個處理鏈)來根據(jù)給定的問題和命名空間從一個向量存儲中檢索并回答問題。代碼如下:

from langchain.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

def ask_question(question, namespace):
  retriever = vectorstore.as_retriever()
  template = """基于如下的上下文內(nèi)容進行回答[CONTEXT][/CONTEXT]:
  [CONTEXT]{context}[/CONTEXT]
  如果你不知道答案,你就回答:我不知道。
  Question: {question}
  """
  prompt = ChatPromptTemplate.from_template(template)
  model = ChatOpenAI()
   configurable_retriever = retriever.configurable_fields(
      search_kwargs=ConfigurableField(
          id="search_kwargs",
          name="Search Kwargs",
          description="The search kwargs to use",
      )
  )
  chain = (
      {"context": configurable_retriever, "question": RunnablePassthrough()}
      | prompt
      | model
      | StrOutputParser()
  )
  response = chain.invoke(
      question,
      config={"configurable": {"search_kwargs": {"namespace": namespace}}},
  )
  print(response)

代碼解釋如下:

(1) 導入所需模塊和類

導入 ChatPromptTemplate,StrOutputParser,RunnablePassthrough 等類,這些類用于處理和解析語言模型的輸出。

(2) 定義 ask_question 函數(shù)

def ask_question(question, namespace): 定義一個函數(shù),接受兩個參數(shù):question(要問的問題)和 namespace(用于指定搜索的命名空間,可能代表不同類型的知識庫)。

(3) 設(shè)置檢索器和提示模板

retriever = vectorstore.as_retriever(): 獲取向量存儲的檢索器。

template = """...""": 定義一個聊天提示模板,該模板指定如何格式化問題和上下文。需要特別注意的是,這里設(shè)計的prompt template 為“如果你不知道答案,你就回答:我不知道。”這是在告訴大模型,如果不能從知識庫中獲取答案,就如實回答“不知道”,不要試圖去編造答案。

prompt = ChatPromptTemplate.from_template(template): 使用上述模板創(chuàng)建一個 ChatPromptTemplate 實例。

(4) 配置檢索器

configurable_retriever = retriever.configurable_fields(...): 創(chuàng)建一個可配置的檢索器,它允許調(diào)整搜索參數(shù)(如命名空間)。

(5) 構(gòu)建處理鏈

chain = (...): 創(chuàng)建一個處理鏈,它包括以下部分:

將 configurable_retriever 和 RunnablePassthrough 作為輸入,前者用于獲取上下文,后者直接傳遞問題。

使用 prompt 來格式化輸入。

model(這里是 ChatOpenAI 實例)用于生成回答。

StrOutputParser 將模型的輸出轉(zhuǎn)換為字符串。

(6) 調(diào)用處理鏈并打印響應(yīng)

response = chain.invoke(...): 使用 invoke 方法調(diào)用處理鏈,并傳入問題和配置(包括指定的命名空間)。

print(response): 打印出生成的響應(yīng)。

函數(shù)利用一個配置好的處理鏈來自動回答問題。它從指定命名空間的向量存儲中檢索相關(guān)上下文,然后使用這些上下文和提供的問題生成一個合適的回答。這對于基于特定知識庫自動回答用戶問題的場景非常有用。

最后,我們來看運行結(jié)果。

執(zhí)行如下語句

ask_question("退貨政策", "product-service")

傳入提出的問題,以及對應(yīng)的namespace由于之前PDF文件中就對退貨政策進行了描述,現(xiàn)在就通過product-service 這個namespace 搜索與之相關(guān)的內(nèi)容。得到如下結(jié)果:

答:客戶可以在購買后的30天內(nèi)無條件退貨,產(chǎn)品必須保持原始狀態(tài)且包裝完整。請?zhí)嵝芽蛻舯A羰論?jù),因為這是退貨的必要憑證。退貨流程和相關(guān)表格以及聯(lián)系信息可以提供給客戶。

從結(jié)果上看與PDF文檔中的內(nèi)容保持一致。

接著,我們再提問“智能鎖失靈”的問題,這里我們不向“tech-service”提問,而向“product-service”提問。顯然,product-service的namespace 存放的文檔是關(guān)于產(chǎn)品服務(wù)相關(guān)的,并不知道“智能鎖失靈”這樣的技術(shù)支持問題。所以,先執(zhí)行代碼再看結(jié)果,代碼如下:

我不知道。

很顯然結(jié)果是“我不知道”,通過上面prompt template 的定義,我們讓大模型在沒有搜索到文檔內(nèi)容的時候,不要編造任何信息,而是如實回答:“我不知道”。這也證明了在product-service的namespace中不存在與技術(shù)支持相關(guān)的信息。

最后,我們通過如下代碼詢問 tech-service,

ask_question("智能鎖失靈", "tech-service")

看結(jié)果如下

回答:首先,指導客戶檢查智能鎖的電源和電池狀態(tài),確認電量是否充足。如果電量正常,請引導客戶重置智能鎖,具體方法是長按重置鍵5秒鐘。如果問題仍然存在,請建議客戶檢查智能鎖的軟件版本是否最新,并引導進行系統(tǒng)更新。若以上步驟無法解決問題,建議客戶聯(lián)系技術(shù)支持以獲取進一步的幫助。

從結(jié)果上看,與我們的設(shè)想相同,和技術(shù)支持相關(guān)的問題從tech-service 的namespace中獲取。

總結(jié)

文章提供了一種有效的方法可以在LangChain框架下實現(xiàn)多用戶數(shù)據(jù)檢索,確保了數(shù)據(jù)安全性和隱私保護的同時,也保證了檢索系統(tǒng)的靈活性和用戶體驗。通過使用Pinecone作為向量數(shù)據(jù)庫,它克服了傳統(tǒng)標量數(shù)據(jù)庫在處理高維向量數(shù)據(jù)時遇到的難題。文章詳細介紹了多用戶檢索的實現(xiàn)步驟,從檢索器的配置到鏈條的構(gòu)建,再到實際的代碼演示,全面覆蓋了從理論到實踐的各個方面。通過提供具體的示例和代碼,文檔使讀者能夠更容易地理解和應(yīng)用這些概念到實際的多用戶檢索任務(wù)中。

作者介紹

崔皓,51CTO社區(qū)編輯,資深架構(gòu)師,擁有18年的軟件開發(fā)和架構(gòu)經(jīng)驗,10年分布式架構(gòu)經(jīng)驗。

責任編輯:華軒 來源: 51CTO
相關(guān)推薦

2021-08-16 09:36:06

數(shù)據(jù)泄露T-Mobile信息安全

2015-01-05 09:56:41

UDPLinux TCP

2021-01-20 23:40:27

數(shù)據(jù)泄露OpenWRT攻擊

2011-03-25 15:21:43

2021-05-25 13:54:01

數(shù)字化

2016-01-22 12:20:11

PHP數(shù)據(jù)爬取分析

2009-11-25 11:28:00

并發(fā)用戶數(shù)

2021-01-06 10:01:09

數(shù)據(jù)泄露漏洞信息安全

2022-12-01 12:14:09

2023-10-23 19:18:05

2021-05-11 11:05:58

蘋果iOS隱私

2015-10-19 18:18:44

2012-06-13 13:52:48

LinuxVNC

2012-05-24 10:08:51

ibmdw

2016-03-16 10:56:12

數(shù)據(jù)營銷數(shù)據(jù)分析LinkedIn

2015-10-30 17:58:43

用戶數(shù)據(jù)收集信息安全WhatsApp

2019-08-14 16:08:43

大數(shù)據(jù)安全互聯(lián)網(wǎng)

2023-09-08 09:53:41

API開發(fā)

2021-04-02 11:09:35

MobiKwik 移動支付數(shù)據(jù)泄露

2015-10-29 13:22:09

php數(shù)據(jù)分析爬蟲
點贊
收藏

51CTO技術(shù)棧公眾號

国产综合视频在线| 自拍偷拍亚洲天堂| 啪啪免费视频一区| www.亚洲免费av| 国产成人精品优优av| 欧美性生给视频| 国产伦精品一区二区三区四区 | 毛片在线看片| 成人手机电影网| 国产精品日韩欧美| 国产真人真事毛片| 成人中文在线| 亚洲精品www| aaa一级黄色片| 黄色成人免费网| 一区二区三区免费看视频| 欧美人与物videos另类| 亚洲第一成年人网站| 三级一区在线视频先锋| 久久久久久久久久久亚洲| 中文字幕人妻一区二区三区在线视频 | 亚洲综合一区在线| 一区二区三区在线视频看| 五月婷婷在线观看视频| 国产91精品在线观看| 国产视频观看一区| jizz国产在线观看| 99伊人成综合| 色综合五月天导航| 极品色av影院| jiujiure精品视频播放| 亚洲国产精品va| 香蕉视频1024| 欧美国产亚洲精品| 欧美日韩一级黄| 欧美精品aaaa| 都市激情亚洲综合| 精品久久久中文| 我的公把我弄高潮了视频| 少妇av在线| 亚洲男人的天堂在线观看| 亚洲精品中字| 午夜在线播放| 国产精品乱码一区二三区小蝌蚪| 欧美一区二区福利| 免费黄色片在线观看| 91美女片黄在线观看| 国产自产精品| 亚州男人的天堂| 久久综合狠狠综合久久激情| 精品日本一区二区三区在线观看| 丰满肥臀噗嗤啊x99av| 成人综合婷婷国产精品久久蜜臀| 亚洲综合视频1区| 国产成人久久精品77777综合| 激情久久五月天| 91丨九色丨国产在线| 国产伦精品一区二区三区视频痴汉| 另类欧美日韩国产在线| 国产精品普通话| 91禁在线观看| 狠狠色丁香久久婷婷综合_中| 91精品国产自产在线| 在线免费观看一区二区| 美女尤物国产一区| 亚洲free性xxxx护士hd| 性生交大片免费看女人按摩| 国产成人一区在线| 国产一级特黄a大片99| 亚洲色欧美另类| 国产三区在线成人av| 亚洲精品成人久久久998| 麻豆传媒视频在线观看免费| 亚洲精品国产一区二区精华液 | 久久亚洲成人av| 中文在线一区| 国产精品成人久久久久| 6—12呦国产精品| 国产不卡在线播放| 欧美成人综合一区| 国产在线一区二区视频| 亚瑟在线精品视频| 浓精h攵女乱爱av| 欧洲一区在线| 亚洲欧美在线磁力| 一区二区三区四区五区| 亚洲日本成人| 国产精品网站视频| 国产香蕉在线观看| 中文字幕欧美国产| 国产毛片久久久久久国产毛片 | 成人亲热视频网站| 日韩中文字幕综合| 国产精品免费视频观看| 精品少妇人欧美激情在线观看| 日韩国产激情| 欧美成人一区二区三区片免费| 亚洲av成人无码一二三在线观看| 精品欧美激情在线观看| 久久久久久九九九| 亚洲视频一区在线播放| www.亚洲在线| 久久国产精品免费观看| 成人福利视频| 欧美不卡123| 永久av免费网站| 久久av一区| 国产91免费视频| 日韩精品毛片| 色婷婷久久久亚洲一区二区三区| 国产xxxxhd| 久久99影视| 久久久久亚洲精品国产| 在线免费观看av片| 国产亚洲欧洲997久久综合 | 变态调教一区二区三区| 欧美剧情片在线观看| 一级黄色片大全| 99热这里只有精品8| 成人免费在线看片| а天堂中文在线官网| 欧美午夜片在线观看| 无码人妻精品一区二区三区温州| 欧美午夜电影在线观看| 成人在线中文字幕| √天堂资源地址在线官网| 色哟哟一区二区在线观看| 蜜臀av粉嫩av懂色av| 中文字幕日韩一区二区不卡| 国产精品永久免费| 岛国在线大片| 91福利区一区二区三区| 一级性生活大片| 国产亚洲一级| 免费观看国产成人| 欧美电影免费观看| 国产视频亚洲视频| 精品人妻无码一区二区性色| 成人高清伦理免费影院在线观看| 免费人成自慰网站| 1313精品午夜理伦电影| 色综合久久88色综合天天看泰| 国产精品九九九九| 亚洲精品美腿丝袜| 日韩女优在线视频| 亚洲精品激情| 久久99久久精品国产| 台湾佬中文娱乐网欧美电影| 日韩成人性视频| 亚洲天堂视频网站| 久久久精品免费免费| 538在线视频观看| 欧美韩日高清| 91亚洲精品在线| 香蕉久久aⅴ一区二区三区| 日韩欧美综合一区| 久久免费黄色网址| 99久久国产综合精品麻豆| 一二三四视频社区在线| 羞羞色国产精品网站| 国产成人一区二区三区| wwwww在线观看免费视频| 欧美日韩一区二区三区高清| 欧美成人777| 国产白丝精品91爽爽久久| 日本精品久久久久久久久久| 天天久久夜夜| 国产精品视频yy9099| 麻豆tv免费在线观看| 亚洲成人精品av| 黄色一级视频免费看| 综合久久一区二区三区| 日韩黄色一区二区| 久久久www| 日本一级淫片演员| 久久97精品| 国产精品偷伦视频免费观看国产| 伊人影院在线视频| 亚洲精品天天看| 国产又粗又猛又爽又黄视频 | 大奶在线精品| 国产精品久久久久久av福利| a视频在线播放| 亚洲女人被黑人巨大进入al| 中文字幕永久在线观看| 亚洲一区欧美一区| avhd101老司机| 成人性视频网站| 五月婷婷激情久久| 在线成人国产| 伊人久久av导航| 欧美黄色录像| 91精品啪在线观看麻豆免费| 麻豆成全视频免费观看在线看| 色妞一区二区三区| 天天综合在线视频| 在线不卡的av| 亚洲 欧美 中文字幕| 亚洲精品免费一二三区| 成都免费高清电影| 成人性生交大片免费| 伊人国产在线视频| 免费在线日韩av| 欧美大片免费播放| 日本电影一区二区| 精品久久久久久一区二区里番| 色狠狠一区二区三区| 欧美中文字幕在线播放| 手机电影在线观看| 日韩在线观看免费av| 免费在线一级视频| 亚洲第一区中文99精品| 国产偷拍一区二区| 欧美天天综合网| 久久久久亚洲av成人毛片韩| 亚洲激情五月婷婷| 三级黄色录像视频| 国产精品每日更新在线播放网址| 久久久国产精品无码| 国产伦精品一区二区三区视频青涩| 少妇性l交大片| 国产亚洲成人一区| heyzo亚洲| 激情综合久久| 久艹在线免费观看| 欧美精品色网| 粉嫩av一区二区三区天美传媒 | 污网站在线免费| 日韩va亚洲va欧美va久久| 精品国产免费av| 91久久午夜| 欧美乱大交xxxxx潮喷l头像| 中文字幕一区二区三区欧美日韩 | 国产视频一区二区不卡| 日韩精品中文字幕一区二区 | 日韩av资源网| 国产亚洲精品自在久久| 老司机aⅴ在线精品导航| 99理论电影网| 超碰一区二区三区| 国产美女99p| 久久狠狠久久| 久久久久久精| 亚洲综合福利| 日韩中文一区| 日韩欧美1区| 香蕉精品视频在线| 91成人网在线观看| 国产91porn| 亚洲国产日本| 久久网站免费视频| 久久一日本道色综合久久| 免费激情视频在线观看| 日韩黄色小视频| gai在线观看免费高清| 久久国产福利国产秒拍| 天天av天天操| 成人免费高清在线| 国产偷人妻精品一区| 国产日产欧美一区二区三区| 91视频免费看片| 亚洲欧美一区二区三区极速播放 | 日韩国产一区二| 中文字幕 日韩 欧美| 国产成人综合自拍| 国产精品无码专区| 久久精品免费在线观看| chinese全程对白| 亚洲一区二区三区小说| 99超碰在线观看| 欧美精品视频www在线观看 | a级精品国产片在线观看| 国产熟妇久久777777| 一色屋精品亚洲香蕉网站| 国产亚洲成人精品| 色综合久久88色综合天天免费| 又骚又黄的视频| 精品国产乱码久久久久久影片| 男人天堂资源在线| 久久夜色精品国产| 在线女人免费视频| 91香蕉电影院| 亚洲人亚洲人色久| 91免费版看片| 久久天堂精品| 中文字幕一二三| 久久在线观看免费| 欧美三级日本三级| 在线视频国内自拍亚洲视频| 国产乱淫av免费| 亚洲欧洲免费视频| 欧美人与禽性xxxxx杂性| 国产98色在线| www国产精品| 亚洲一区三区| 久久精品毛片| 国产伦理在线观看| 国产精品女主播在线观看| www.av视频在线观看| 欧美日韩精品免费| 亚洲欧美日韩综合在线| 久久91亚洲人成电影网站| 亚洲综合av一区二区三区| 国产精品一区二| 91成人影院| 精品亚洲一区二区三区四区| 99国产精品国产精品毛片| 波多野结衣不卡视频| 欧美午夜视频网站| 久久精品蜜桃| 欧美一级在线播放| 国产欧美自拍一区| japanese在线播放| 美腿丝袜亚洲综合| 欧美黄色激情视频| 天天综合网天天综合色| av高清一区二区| 日韩中文字幕视频在线观看| 激情都市亚洲| 美国av一区二区三区| 欧美视频不卡| 久久久久亚洲av无码麻豆| 国产精品久久久久影院色老大| 中文字幕在线播| 亚洲美女av黄| 色在线免费观看| 精品一区二区日本| 99亚洲一区二区| yy1111111| 偷窥少妇高潮呻吟av久久免费| 亚洲国产精品欧美久久| 九九热精品视频国产| 国产一区二区三区免费在线| 亚洲一区二区三区精品视频| 日本不卡一区二区三区高清视频| www.av欧美| 欧美性做爰猛烈叫床潮| 国产精品一二三区视频| 国产成人av网址| 亚洲婷婷影院| 欧美日韩在线免费播放| 欧美国产一区在线| 亚洲天堂狠狠干| 深夜精品寂寞黄网站在线观看| 国产精品高潮久久| 亚洲一区二区三区在线观看视频| 蜜臀av一级做a爰片久久| 91精品国自产在线| 欧美成人久久| 日本精品中文字幕| 日韩av网站在线免费观看| 中国丰满人妻videoshd| 91在线国产福利| 中文人妻av久久人妻18| 国产一区二区三区高清在线观看| 久久久人成影片一区二区三区在哪下载 | 色男人天堂av| 亚洲一区在线电影| 天天干天天爽天天操| 欧美在线亚洲在线| 精品日韩在线| 亚洲一区二区在线视频观看| 亚洲视频一二区| 好吊视频一二三区| 欧美亚洲成人免费| 日本久久一二三四| 涩多多在线观看| 亚洲电影激情视频网站| 欧美日本韩国一区二区| 国产欧美日韩丝袜精品一区| 欧美激情1区| 亚洲调教欧美在线| 亚洲国产精品精华液ab| 亚洲视频在线免费播放| 久久91精品国产91久久久| 亚洲图区在线| 在线视频一二区| 午夜精品福利视频网站| av在线首页| 国产精品10p综合二区| 久久精品二区三区| 黑人狂躁日本娇小| 亚洲国产毛片完整版| 国产成人精品一区二区三区视频| 欧美xxxx吸乳| 国产色婷婷亚洲99精品小说| 99精品免费观看| 欧美专区在线视频| 91精品国产成人观看| 欧美激情a∨在线视频播放| 欧美a在线看| 久久久久高清| 国产一区在线观看麻豆| 欧美激情黑白配| 久久精品国产免费观看| 神马日本精品| 天天爽夜夜爽视频| 在线精品视频一区二区三四| 男女视频在线| 一区二区三区不卡在线|