266 lines
9.7 KiB
Plaintext
266 lines
9.7 KiB
Plaintext
---
|
||
id: weaviate
|
||
title: Weaviate
|
||
sidebar_label: Weaviate
|
||
---
|
||
|
||
## Quick Summary
|
||
|
||
**Weaviate** is a cloud-native, open-source vector database that uses state-of-the-art ML models to embed data. It is fast, flexible, and designed for production-readiness, capable of performing 10-NN nearest neighbor searches on millions of objects in milliseconds.
|
||
|
||
:::tip
|
||
To learn more about leveraging Weaviate as your retrieval engine, [visit this page](https://weaviate.io/).
|
||
:::
|
||
|
||
<div
|
||
style={{
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
flexDirection: "column",
|
||
}}
|
||
>
|
||
<ImageDisplayer src="https://weaviate.io/assets/images/rag-base-00430efd1764c948a95b4d1bbd1e19a9.png" />
|
||
<div
|
||
style={{
|
||
fontSize: "13px",
|
||
marginTop: "10px",
|
||
marginBottom: "30px",
|
||
}}
|
||
>
|
||
RAG pipeline with Weaviate retrieval engine (source: Weaviate)
|
||
</div>
|
||
</div>
|
||
|
||
Youn can easily evaluate your **Weaviate** retriever with DeepEval to find the best hyperparameters for your Weaviate engine. This parameters include `with_limit` (top-K) and `vectorizer` (embedding model), among many others.
|
||
|
||
:::info
|
||
You can quickly get started with Weaviate by running the following command in your CLI:
|
||
|
||
```
|
||
pip install weaviate-client
|
||
```
|
||
|
||
:::
|
||
|
||
## Setup Weaviate
|
||
|
||
To start using Weaviate, establish a connection to your local or cloud-hosted instance by initializing a Weaviate client and configuring authentication with your API key.
|
||
|
||
```python
|
||
import weaviate
|
||
import os
|
||
|
||
client = weaviate.Client(
|
||
url="http://localhost:8080", # Change this if using Weaviate Cloud
|
||
auth_client_secret=weaviate.AuthApiKey(os.getenv("WEAVIATE_API_KEY")) # Set your API key
|
||
)
|
||
```
|
||
|
||
To enable efficient similarity search, define a **Weaviate schema** that stores documents with a `text` property for raw content and an associated vector for embeddings. Since Weaviate supports both internal and external vectorization, this schema is configured to use an external embedding model.
|
||
|
||
```python
|
||
...
|
||
|
||
# Define the schema
|
||
class_name = "Document"
|
||
if not client.schema.exists(class_name):
|
||
schema = {
|
||
"classes": [
|
||
{
|
||
"class": class_name,
|
||
"vectorizer": "none", # Using an external embedding model
|
||
"properties": [
|
||
{"name": "text", "dataType": ["text"]}, # Stores chunk text
|
||
]
|
||
}
|
||
]
|
||
}
|
||
client.schema.create(schema)
|
||
```
|
||
|
||
Before adding documents to Weaviate, convert text into vector representations using an embedding model. We'll be using `all-MiniLM-L6-v2` from `sentence_transformers`.
|
||
|
||
:::tip
|
||
Using an external embedding model ensures flexibility in choosing the most suitable representation for your data, which can be important if your Weaviate engine is struggling to score well on metrics like `Contextual Precision`.
|
||
:::
|
||
|
||
```python
|
||
...
|
||
|
||
# Load an embedding model
|
||
from sentence_transformers import SentenceTransformer
|
||
model = SentenceTransformer("all-MiniLM-L6-v2")
|
||
|
||
# Example document chunks
|
||
document_chunks = [
|
||
"Weaviate is a cloud-native vector database for scalable AI search.",
|
||
"Weaviate enables fast semantic search across millions of vectors.",
|
||
"It integrates with external embedding models for custom vectorization.",
|
||
...
|
||
]
|
||
# Store chunks with embeddings
|
||
with client.batch as batch:
|
||
for i, chunk in enumerate(document_chunks):
|
||
embedding = model.encode(chunk).tolist() # Convert text to vector
|
||
batch.add_data_object(
|
||
{"text": chunk}, class_name=class_name, vector=embedding
|
||
)
|
||
```
|
||
|
||
## Evaluating Weaviate Retrieval
|
||
|
||
Once the Weaviate retriever is set up, we can begin evaluating its effectiveness in returning relevant contexts. This involves:
|
||
|
||
- **Constructing a Test Case**: to do so, define an `input` query that represents a typical search scenario and prepare the expected output. Then generate the `actual_output` for the given input and extract the retrieved context during generation.
|
||
- **Evaluating the Test Case**: simply run deepeval's `evaluate` function on your populated test case and selection of retriever metrics.
|
||
|
||
### Preparing your Test Case
|
||
|
||
The first step in generating the `actual_output` from your RAG pipeline is retrieving the relevant `retrieval_context` from your Qdrant collection based on the input query. Below is a function that encodes the query, searches for the top 3 most relevant vectors in Qdrant, and extracts the corresponding text from the retrieved results.
|
||
|
||
```python
|
||
...
|
||
|
||
def search(query):
|
||
query_embedding = model.encode(query).tolist()
|
||
|
||
result = client.query.get("Document", ["text"]) \
|
||
.with_near_vector({"vector": query_embedding}) \
|
||
.with_limit(3) \
|
||
.do()
|
||
|
||
return [hit["text"] for hit in result["data"]["Get"]["Document"]] if result["data"]["Get"]["Document"] else None
|
||
|
||
query = "How does Weaviate work?"
|
||
retrieval_context = search(query)
|
||
```
|
||
|
||
Next, incorporate the retrieved context into your LLM's prompt template to generate a response.
|
||
|
||
```python
|
||
prompt = """
|
||
Answer the user question based on the supporting context.
|
||
|
||
User Question:
|
||
{input}
|
||
|
||
Supporting Context:
|
||
{retrieval_context}
|
||
"""
|
||
|
||
actual_output = generate(prompt) # Replace with your LLM function
|
||
print(actual_output)
|
||
```
|
||
|
||
With both the `actual_output` and `retrieval_context` generated, we now have all the necessary parameters to construct our test case:
|
||
|
||
```python
|
||
from deepeval.test_case import LLMTestCase
|
||
|
||
test_case = LLMTestCase(
|
||
input=input,
|
||
actual_output=actual_output,
|
||
retrieval_context=retrieval_context,
|
||
expected_output="Weaviate is a powerful vector database for AI applications, optimized for efficient semantic retrieval.",
|
||
)
|
||
```
|
||
|
||
Before proceeding with the evaluation, let's examine the generated `actual_output`.
|
||
|
||
```
|
||
Weaviate is a cloud-native vector database that enables fast semantic search using vector embeddings and hybrid retrieval.
|
||
```
|
||
|
||
### Running Evaluations
|
||
|
||
To evaluate an `LLMTestCase`, define the relevant retrieval metrics and pass them into the `evaluate` function along with the test case.
|
||
|
||
```python
|
||
from deepeval.metrics import (
|
||
ContextualRecallMetric,
|
||
ContextualPrecisionMetric,
|
||
ContextualRelevancyMetric,
|
||
)
|
||
from deepeval import evaluate
|
||
|
||
...
|
||
|
||
contextual_recall = ContextualRecallMetric(),
|
||
contextual_precision = ContextualPrecisionMetric()
|
||
contextual_relevancy = ContextualRelevancyMetric()
|
||
|
||
evaluate(
|
||
[test_case],
|
||
metrics=[contextual_recall, contextual_precision, contextual_relevancy]
|
||
)
|
||
```
|
||
|
||
## Improving Weaviate Retrieval
|
||
|
||
Once you've evaluated your Weaviate retriever, it's time to analyze the results and fine-tune your retrieval pipeline. Below are example evaluation results from more test cases.
|
||
|
||
| Query | Contextual Precision | Contextual Recall | Contextual Relevancy |
|
||
| ------------------------------------------- | -------------------- | ----------------- | -------------------- |
|
||
| "How does Weaviate store vector data?" | 0.62 | 0.95 | 0.50 |
|
||
| "Explain Weaviate's indexing method." | 0.55 | 0.89 | 0.47 |
|
||
| "What makes Weaviate efficient for search?" | 0.68 | 0.91 | 0.53 |
|
||
|
||
- **Contextual Precision is suboptimal** → Some retrieved contexts might be too generic or off-topic.
|
||
- **Contextual Recall is strong** → Weaviate is retrieving enough relevant documents.
|
||
- **Contextual Relevancy is inconsistent** → The quality of retrieved documents varies across queries.
|
||
|
||
:::info
|
||
Each metric is impacted by specific retrieval hyperparameters. To understand how these affect your results, refer to [this RAG evaluation guide](/guides/guides-rag-evaluation).
|
||
:::
|
||
|
||
### Improving Retrieval Quality
|
||
|
||
To enhance retrieval performance, experiment with the following Weaviate hyperparameters:
|
||
|
||
1. **Tuning `with_limit` (Top-K retrieval)**
|
||
|
||
- If precision is low, reduce `with_limit` to retrieve fewer but more accurate results.
|
||
- If recall is too high with irrelevant results, adjust `with_limit` to balance quantity and quality.
|
||
|
||
2. **Optimizing `vectorizer` (embedding model)**
|
||
|
||
- Test alternative embedding models for better domain-specific retrieval:
|
||
- `BAAI/bge-small-en` for ranking improvements.
|
||
- `nomic-ai/nomic-embed-text-v1` for retrieving longer-form documents.
|
||
- `msmarco-distilbert-base-v4` for passage retrieval.
|
||
|
||
3. **Implementing Hybrid Retrieval (Vector + BM25)**
|
||
|
||
- If Weaviate’s pure vector search isn’t retrieving precise matches, combining vector search with BM25 keyword retrieval can help.
|
||
|
||
4. **Applying Advanced Filtering (`nearText`, `where` constraints)**
|
||
- Leverage metadata-based filtering to refine search results and remove less relevant chunks.
|
||
|
||
### Experimenting With Different Configurations
|
||
|
||
To systematically test variations in retrieval settings, run multiple test cases and compare contextual metric scores.
|
||
|
||
```python
|
||
# Example of running multiple test cases with different retrieval settings
|
||
for vectorizer in ["all-MiniLM-L6-v2", "bge-small-en", "nomic-embed-text-v1"]:
|
||
retrieval_context = search(query, vectorizer)
|
||
|
||
test_case = LLMTestCase(
|
||
input=query,
|
||
actual_output=llm.generate(query, retrieval_context),
|
||
retrieval_context=retrieval_context,
|
||
expected_output="Weaviate is an optimized vector database for AI applications.",
|
||
)
|
||
|
||
evaluate([test_case], metrics=[contextual_recall, contextual_precision, contextual_relevancy])
|
||
```
|
||
|
||
### Tracking Improvements
|
||
|
||
After tuning your Weaviate retriever, monitor improvements in **Contextual Precision**, **Contextual Recall**, and **Contextual Relevancy** to determine the best hyperparameter combination.
|
||
|
||
:::tip
|
||
For structured tracking of retrieval performance and hyperparameter comparisons, [Confident AI](https://www.confident-ai.com/) provides real-time evaluation analysis.
|
||
:::
|