Qdrant 向量数据库¶
创建 Qdrant 客户端¶
%pip install llama-index-vector-stores-qdrant llama-index-readers-file llama-index-embeddings-fastembed llama-index-llms-openai
import logging
import sys
import os
import qdrant_client
from IPython.display import Markdown, display
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core import StorageContext
from llama_index.vector_stores.qdrant import QdrantVectorStore
from llama_index.embeddings.fastembed import FastEmbedEmbedding
from llama_index.core import Settings
Settings.embed_model = FastEmbedEmbedding(model_name="BAAI/bge-base-en-v1.5")
如果是首次运行,请使用以下命令安装依赖项:
!pip install -U qdrant_client fastembed
设置您的 OpenAI 密钥以验证 LLM 身份
按照以下步骤将 OpenAI API 密钥设置为 OPENAI_API_KEY 环境变量 -
- 使用终端
export OPENAI_API_KEY=your_api_key_here
- 在 Jupyter Notebook 中使用 IPython 魔术命令
%env OPENAI_API_KEY=<YOUR_OPENAI_API_KEY>
- 使用 Python 脚本
import os
os.environ["OPENAI_API_KEY"] = "your_api_key_here"
注意:通常建议将 API 密钥等敏感信息设置为环境变量,而非直接硬编码在脚本中。
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
下载数据
!mkdir -p 'data/paul_graham/'
!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'
加载文档¶
# load documents
documents = SimpleDirectoryReader("./data/paul_graham/").load_data()
构建向量存储索引¶
client = qdrant_client.QdrantClient(
# you can use :memory: mode for fast and light-weight experiments,
# it does not require to have Qdrant deployed anywhere
# but requires qdrant-client >= 1.1.1
# location=":memory:"
# otherwise set Qdrant instance address with:
# url="http://<host>:<port>"
# otherwise set Qdrant instance with host and port:
host="localhost",
port=6333
# set API KEY for Qdrant Cloud
# api_key="<qdrant-api-key>",
)
vector_store = QdrantVectorStore(client=client, collection_name="paul_graham")
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
)
查询索引¶
# set Logging to DEBUG for more detailed outputs
query_engine = index.as_query_engine()
response = query_engine.query("What did the author do growing up?")
display(Markdown(f"<b>{response}</b>"))
The author worked on writing and programming before college.
# set Logging to DEBUG for more detailed outputs
query_engine = index.as_query_engine()
response = query_engine.query(
"What did the author do after his time at Viaweb?"
)
display(Markdown(f"<b>{response}</b>"))
The author arranged to do freelance work for a group that did projects for customers after his time at Viaweb.
异步构建 VectorStoreIndex¶
# To connect to the same event-loop,
# allows async events to run on notebook
import nest_asyncio
nest_asyncio.apply()
aclient = qdrant_client.AsyncQdrantClient(
# you can use :memory: mode for fast and light-weight experiments,
# it does not require to have Qdrant deployed anywhere
# but requires qdrant-client >= 1.1.1
location=":memory:"
# otherwise set Qdrant instance address with:
# uri="http://<host>:<port>"
# set API KEY for Qdrant Cloud
# api_key="<qdrant-api-key>",
)
vector_store = QdrantVectorStore(
collection_name="paul_graham",
client=client,
aclient=aclient,
prefer_grpc=True,
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
use_async=True,
)
异步查询索引¶
query_engine = index.as_query_engine(use_async=True)
response = await query_engine.aquery("What did the author do growing up?")
display(Markdown(f"<b>{response}</b>"))
The author worked on writing short stories and programming, particularly on an IBM 1401 computer in 9th grade using an early version of Fortran. Later, the author transitioned to working on microcomputers, starting with a TRS-80 in about 1980, where they wrote simple games, programs, and a word processor.
# set Logging to DEBUG for more detailed outputs
query_engine = index.as_query_engine(use_async=True)
response = await query_engine.aquery(
"What did the author do after his time at Viaweb?"
)
display(Markdown(f"<b>{response}</b>"))
The author went on to co-found Y Combinator after his time at Viaweb.
混合搜索¶
在创建 Qdrant 索引时,您可以启用混合搜索功能。这里我们利用 Qdrant 的 BM25 能力,快速构建稀疏与稠密索引以实现混合检索。
from qdrant_client import QdrantClient, AsyncQdrantClient
from llama_index.core import VectorStoreIndex
from llama_index.core import StorageContext
from llama_index.vector_stores.qdrant import QdrantVectorStore
client = QdrantClient(host="localhost", port=6333)
aclient = AsyncQdrantClient(host="localhost", port=6333)
vector_store = QdrantVectorStore(
client=client,
aclient=aclient,
collection_name="paul_graham_hybrid",
enable_hybrid=True,
fastembed_sparse_model="Qdrant/bm25",
)
index = VectorStoreIndex.from_documents(
documents,
storage_context=StorageContext.from_defaults(vector_store=vector_store),
)
# retrieve 2 sparse, 2 dense, and filter down to 3 total hybrid results
query_engine = index.as_query_engine(
vector_store_query_mode="hybrid",
sparse_top_k=2,
similarity_top_k=2,
hybrid_top_k=3,
)
response = query_engine.query("What did the author do growing up?")
display(Markdown(f"<b>{response}</b>"))
保存与加载¶
要恢复索引,在大多数情况下,您可以直接通过向量存储对象本身进行恢复。Qdrant 会自动保存索引。
loaded_index = VectorStoreIndex.from_vector_store(
vector_store,
# Embedding model should match the original embedding model
# embed_model=Settings.embed_model
)