PGVector
使用 `postgres` 作為後端並利用 `pgvector` 擴展,LangChain 向量資料庫抽象化的一個實現。
程式碼位於一個名為 langchain_postgres 的整合套件中。
狀態
此程式碼已從 `langchain_community` 移植到一個專用的套件 `langchain-postgres`。已進行以下變更
- langchain_postgres 僅適用於 psycopg3。請將您的連線字串從 `postgresql+psycopg2://...` 更新為 `postgresql+psycopg://langchain:langchain@...` (是的,驅動程式名稱是 `psycopg` 而不是 `psycopg3`,但它會使用 `psycopg3`。
- 嵌入儲存和集合的架構已變更,以使 add_documents 能夠正確地使用使用者指定的 ID。
- 現在必須傳遞一個明確的連線物件。
目前**沒有機制**支援架構變更時的簡易資料遷移。因此,向量資料庫中的任何架構變更都將需要使用者重新建立表格並重新新增文檔。如果這是一個考量,請使用不同的向量資料庫。否則,此實作應該適用於您的用例。
設定
首先下載合作夥伴套件
pip install -qU langchain_postgres
您可以執行以下命令來啟動一個具有 `pgvector` 擴展的 postgres 容器
%docker run --name pgvector-container -e POSTGRES_USER=langchain -e POSTGRES_PASSWORD=langchain -e POSTGRES_DB=langchain -p 6024:5432 -d pgvector/pgvector:pg16
憑證
執行此筆記本無需憑證,只需確保您已下載 `langchain_postgres` 套件並正確啟動 postgres 容器即可。
如果您想要獲得一流的模型調用自動追蹤功能,您也可以取消註解下方內容來設定您的 LangSmith API 金鑰
# os.environ["LANGSMITH_API_KEY"] = getpass.getpass("Enter your LangSmith API key: ")
# os.environ["LANGSMITH_TRACING"] = "true"
實例化
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_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
from langchain_postgres import PGVector
# See docker command above to launch a postgres instance with pgvector enabled.
connection = "postgresql+psycopg://langchain:langchain@localhost:6024/langchain" # Uses psycopg3!
collection_name = "my_docs"
vector_store = PGVector(
embeddings=embeddings,
collection_name=collection_name,
connection=connection,
use_jsonb=True,
)
管理向量資料庫
將項目新增到向量資料庫
請注意,通過 ID 新增文檔將覆蓋任何與該 ID 匹配的現有文檔。
from langchain_core.documents import Document
docs = [
Document(
page_content="there are cats in the pond",
metadata={"id": 1, "location": "pond", "topic": "animals"},
),
Document(
page_content="ducks are also found in the pond",
metadata={"id": 2, "location": "pond", "topic": "animals"},
),
Document(
page_content="fresh apples are available at the market",
metadata={"id": 3, "location": "market", "topic": "food"},
),
Document(
page_content="the market also sells fresh oranges",
metadata={"id": 4, "location": "market", "topic": "food"},
),
Document(
page_content="the new art exhibit is fascinating",
metadata={"id": 5, "location": "museum", "topic": "art"},
),
Document(
page_content="a sculpture exhibit is also at the museum",
metadata={"id": 6, "location": "museum", "topic": "art"},
),
Document(
page_content="a new coffee shop opened on Main Street",
metadata={"id": 7, "location": "Main Street", "topic": "food"},
),
Document(
page_content="the book club meets at the library",
metadata={"id": 8, "location": "library", "topic": "reading"},
),
Document(
page_content="the library hosts a weekly story time for kids",
metadata={"id": 9, "location": "library", "topic": "reading"},
),
Document(
page_content="a cooking class for beginners is offered at the community center",
metadata={"id": 10, "location": "community center", "topic": "classes"},
),
]
vector_store.add_documents(docs, ids=[doc.metadata["id"] for doc in docs])
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
從向量資料庫刪除項目
vector_store.delete(ids=["3"])
查詢向量資料庫
一旦您的向量資料庫被建立並且相關文檔已被新增,您很可能希望在您的鏈或代理程式運行期間查詢它。
篩選支援
向量資料庫支援一組篩選器,可以針對文檔的元數據欄位應用。
運算符 | 含義/類別 |
---|---|
$eq | 相等 (==) |
$ne | 不相等 (!=) |
$lt | 小於 (<) |
$lte | 小於或等於 (<=) |
$gt | 大於 (>) |
$gte | 大於或等於 (>=) |
$in | 特殊情況 (in) |
$nin | 特殊情況 (not in) |
$between | 特殊情況 (between) |
$like | 文本 (like) |
$ilike | 文本 (不區分大小寫的 like) |
$and | 邏輯 (and) |
$or | 邏輯 (or) |
直接查詢
執行簡單的相似性搜尋可以如下操作
results = vector_store.similarity_search(
"kitty", k=10, filter={"id": {"$in": [1, 5, 2, 9]}}
)
for doc in results:
print(f"* {doc.page_content} [{doc.metadata}]")
* there are cats in the pond [{'id': 1, 'topic': 'animals', 'location': 'pond'}]
* the library hosts a weekly story time for kids [{'id': 9, 'topic': 'reading', 'location': 'library'}]
* ducks are also found in the pond [{'id': 2, 'topic': 'animals', 'location': 'pond'}]
* the new art exhibit is fascinating [{'id': 5, 'topic': 'art', 'location': 'museum'}]
如果您提供一個具有多個欄位但沒有運算符的字典,則頂層將被解釋為邏輯 AND 篩選器
vector_store.similarity_search(
"ducks",
k=10,
filter={"id": {"$in": [1, 5, 2, 9]}, "location": {"$in": ["pond", "market"]}},
)
[Document(metadata={'id': 1, 'topic': 'animals', 'location': 'pond'}, page_content='there are cats in the pond'),
Document(metadata={'id': 2, 'topic': 'animals', 'location': 'pond'}, page_content='ducks are also found in the pond')]
vector_store.similarity_search(
"ducks",
k=10,
filter={
"$and": [
{"id": {"$in": [1, 5, 2, 9]}},
{"location": {"$in": ["pond", "market"]}},
]
},
)
[Document(metadata={'id': 1, 'topic': 'animals', 'location': 'pond'}, page_content='there are cats in the pond'),
Document(metadata={'id': 2, 'topic': 'animals', 'location': 'pond'}, page_content='ducks are also found in the pond')]
如果您想執行相似性搜尋並接收相應的分數,您可以運行
results = vector_store.similarity_search_with_score(query="cats", k=1)
for doc, score in results:
print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")
* [SIM=0.763449] there are cats in the pond [{'id': 1, 'topic': 'animals', 'location': 'pond'}]
有關您可以在 PGVector 向量資料庫上執行的不同搜尋的完整列表,請參閱 API 參考文檔。
通過轉換為檢索器來查詢
您也可以將向量資料庫轉換為檢索器,以便在您的鏈中更輕鬆地使用。
retriever = vector_store.as_retriever(search_type="mmr", search_kwargs={"k": 1})
retriever.invoke("kitty")
[Document(metadata={'id': 1, 'topic': 'animals', 'location': 'pond'}, page_content='there are cats in the pond')]
用於檢索增強生成的使用
有關如何使用此向量資料庫進行檢索增強生成 (RAG) 的指南,請參閱以下章節
API 參考文檔
有關所有 __ModuleName__VectorStore 功能和配置的詳細文檔,請前往 API 參考文檔: https://langchain-python.dev.org.tw/api_reference/postgres/vectorstores/langchain_postgres.vectorstores.PGVector.html