如何執行使用者個別檢索
本指南示範如何設定檢索鏈的執行階段屬性。一個範例應用程式是根據使用者限制 檢索器 可用的文件。
在建立 檢索應用程式 時,您通常必須以多個使用者為目標來建構它。這表示您可能不僅儲存一個使用者的資料,而是許多不同使用者的資料,而且他們不應該能夠看到彼此的資料。這表示您需要能夠配置您的檢索鏈,使其僅檢索特定資訊。這通常涉及兩個步驟。
步驟 1:確保您使用的檢索器支援多個使用者
目前,LangChain 中沒有針對此功能的統一標誌或篩選器。相反地,每個向量儲存庫和檢索器可能都有自己的方法,並且可能有不同的名稱(命名空間、多租戶等)。對於向量儲存庫,這通常以關鍵字引數的形式公開,該引數在 similarity_search
期間傳遞。透過閱讀文件或原始碼,找出您使用的檢索器是否支援多個使用者,如果支援,請了解如何使用它。
注意:為不支援(或未記錄)多個使用者的檢索器新增文件和/或支援是為 LangChain 做出貢獻的絕佳方式
步驟 2:將該參數新增為鏈的可配置欄位
這將讓您輕鬆調用鏈並在執行階段配置任何相關標誌。有關配置的更多資訊,請參閱 此文件。
現在,在執行階段,您可以使用可配置欄位調用此鏈。
程式碼範例
讓我們來看一個具體的程式碼範例。我們將在本範例中使用 Pinecone。
若要配置 Pinecone,請設定以下環境變數
PINECONE_API_KEY
:您的 Pinecone API 金鑰
from langchain_openai import OpenAIEmbeddings
from langchain_pinecone import PineconeVectorStore
embeddings = OpenAIEmbeddings()
vectorstore = PineconeVectorStore(index_name="test-example", embedding=embeddings)
vectorstore.add_texts(["I worked at Kensho"], namespace="harrison")
vectorstore.add_texts(["I worked at Facebook"], namespace="ankush")
['f907aab7-77c7-4347-acc2-6859f8142f92']
pinecone kwarg 的 namespace
可用於分隔文件
# This will only get documents for Ankush
vectorstore.as_retriever(search_kwargs={"namespace": "ankush"}).invoke(
"where did i work?"
)
[Document(id='f907aab7-77c7-4347-acc2-6859f8142f92', metadata={}, page_content='I worked at Facebook')]
# This will only get documents for Harrison
vectorstore.as_retriever(search_kwargs={"namespace": "harrison"}).invoke(
"where did i work?"
)
[Document(id='16061fc5-c6fc-4f45-a3b3-23469d7996af', metadata={}, page_content='I worked at Kensho')]
我們現在可以建立鏈,我們將使用它來執行問答。
讓我們首先選擇一個 LLM。
pip install -qU "langchain[openai]"
import getpass
import os
if not os.environ.get("OPENAI_API_KEY"):
os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter API key for OpenAI: ")
from langchain.chat_models import init_chat_model
llm = init_chat_model("gpt-4o-mini", model_provider="openai")
這將遵循 RAG 教學 中的基本實作,但我們將允許檢索步驟可配置。
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import ConfigurableField
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
retriever = vectorstore.as_retriever()
在這裡,我們將檢索器標記為具有可配置欄位。所有向量儲存庫檢索器都具有 search_kwargs
作為欄位。這只是一個字典,其中包含向量儲存庫特定的欄位。
這將讓我們在調用鏈時傳入 search_kwargs
的值。
configurable_retriever = retriever.configurable_fields(
search_kwargs=ConfigurableField(
id="search_kwargs",
name="Search Kwargs",
description="The search kwargs to use",
)
)
我們現在可以使用我們的可配置檢索器建立鏈。
from langchain_core.documents import Document
from langchain_core.runnables import RunnableConfig
from langgraph.graph import START, StateGraph
from typing_extensions import List, TypedDict
class State(TypedDict):
question: str
context: List[Document]
answer: str
def retrieve(state: State, config: RunnableConfig):
retrieved_docs = configurable_retriever.invoke(state["question"], config)
return {"context": retrieved_docs}
def generate(state: State):
docs_content = "\n\n".join(doc.page_content for doc in state["context"])
messages = prompt.invoke({"question": state["question"], "context": docs_content})
response = llm.invoke(messages)
return {"answer": response.content}
graph_builder = StateGraph(State).add_sequence([retrieve, generate])
graph_builder.add_edge(START, "retrieve")
graph = graph_builder.compile()
from IPython.display import Image, display
display(Image(graph.get_graph().draw_mermaid_png()))
我們現在可以使用可配置選項調用鏈。search_kwargs
是可配置欄位的 ID。該值是要用於 Pinecone 的搜尋 kwargs。
result = graph.invoke(
{"question": "Where did the user work?"},
config={"configurable": {"search_kwargs": {"namespace": "harrison"}}},
)
result
{'question': 'Where did the user work?',
'context': [Document(id='16061fc5-c6fc-4f45-a3b3-23469d7996af', metadata={}, page_content='I worked at Kensho')],
'answer': 'The user worked at Kensho.'}
result = graph.invoke(
{"question": "Where did the user work?"},
config={"configurable": {"search_kwargs": {"namespace": "ankush"}}},
)
result
{'question': 'Where did the user work?',
'context': [Document(id='f907aab7-77c7-4347-acc2-6859f8142f92', metadata={}, page_content='I worked at Facebook')],
'answer': 'The user worked at Facebook.'}
有關操作特定向量儲存庫的詳細資訊,請參閱 整合頁面。