LangChain integration for Firebolt vector store
Project description
LangChain Firebolt Vector Store
A LangChain vector store integration for Firebolt, enabling efficient similarity search and document management using Firebolt's vector search capabilities.
Table of Contents
- Installation
- Prerequisites
- Quick Start
- Configuration
- Usage Examples
- API Reference
- Environment Variables
- Best Practices
Installation
pip install langchain-firebolt
Prerequisites
1. Firebolt Account Setup
You need:
- A Firebolt account (Sign up for a free trial)
- An engine running in your account
- A database created in your account
- Client credentials (client ID and secret, see how to create a service account)
2. Create LOCATION Object for LLM API (Optional)
Note: This step is only required when using server-side embedding calculation (use_sql_embeddings=True, which is the default). If you're using client-side embeddings (use_sql_embeddings=False), you can skip this step.
The Firebolt vector store can use Firebolt's AI_EMBED_TEXT SQL function to generate embeddings server-side. When using this feature, you need to create a LOCATION object in Firebolt that points to your LLM service (e.g., Amazon Bedrock).
Example: Creating a LOCATION for Amazon Bedrock
CREATE LOCATION llm_api WITH
SOURCE = AMAZON_BEDROCK
CREDENTIALS =
(
AWS_ACCESS_KEY_ID='your_access_key'
AWS_SECRET_ACCESS_KEY='your_secret_key'
);
For more details, see the Firebolt documentation.
3. Create Table and Vector Index
The table and vector index will be automatically created when you instantiate the Firebolt vector store if they don't already exist. However, you can also create them manually beforehand using the SQL commands below.
Automatic Creation:
- If the table doesn't exist, it will be created automatically with the required structure
- If the table exists but the index doesn't exist, the index will be created automatically
- The index name will be auto-generated as
{table_name}_indexif not specified in your configuration
Manual Creation (Optional):
Create a table with the following structure:
CREATE TABLE IF NOT EXISTS documents (
id TEXT,
document TEXT,
embedding ARRAY(DOUBLE PRECISION NOT NULL) NOT NULL,
-- Add your metadata columns here
file_name TEXT,
page_number INTEGER,
source TEXT
) PRIMARY INDEX id;
Create a vector search index:
CREATE INDEX documents_index
ON documents
USING HNSW(embedding vector_cosine_ops) WITH (dimension = 256);
Optional index parameters:
When using automatic index creation, you can customize HNSW index parameters via FireboltSettings:
settings = FireboltSettings(
# ... required parameters ...
index_m=16, # Number of bi-directional links per element
index_ef_construction=100, # Size of dynamic candidate list during construction
index_quantization="i8", # Quantization type: bf16, f16, f32, f64, i8
)
These will be included in the WITH clause when the index is created:
CREATE INDEX documents_index
ON documents
USING HNSW(embedding vector_cosine_ops) WITH (dimension = 256, m = 16, ef_construction = 100, quantization = 'i8');
Supported metrics:
vector_cosine_ops(default) - Cosine similarityvector_ip_ops- Inner productvector_l2sq_ops- L2 squared distance
Quick Start
from langchain_firebolt import Firebolt, FireboltSettings
from langchain_core.documents import Document
# Configure Firebolt settings
settings = FireboltSettings(
id="your_client_id",
secret="your_client_secret",
engine_name="your_engine",
database="my_database",
account_name="your_account",
table="documents",
index="documents_index", # Optional: auto-detected if not provided
llm_location="llm_api", # Required for server-side embeddings (use_sql_embeddings=True)
embedding_model="amazon.titan-embed-text-v2:0", # Required for server-side embeddings
embedding_dimension=256,
metric="vector_cosine_ops", # Optional: defaults to vector_cosine_ops
)
# Create vector store instance
vector_store = Firebolt(config=settings)
# Add documents
documents = [
Document(page_content="The quick brown fox jumps over the lazy dog", metadata={"file_name": "doc1.txt"}),
Document(page_content="Python is a programming language", metadata={"file_name": "doc2.txt"}),
]
vector_store.add_documents(documents)
# Search
results = vector_store.similarity_search("programming", k=2)
for doc in results:
print(f"Content: {doc.page_content}")
print(f"Metadata: {doc.metadata}")
Configuration
FireboltSettings
The FireboltSettings class configures the connection and behavior of the vector store.
Required Parameters
id(str): Firebolt client IDsecret(str): Firebolt client secretengine_name(str): Name of the Firebolt enginedatabase(str): Name of the databaseaccount_name(str): Firebolt account nametable(str): Name of the table containing vectorsembedding_model(str): Embedding model identifier (e.g., "amazon.titan-embed-text-v2:0")
Optional Parameters
index(str, optional): Vector index name. If not provided, will be auto-detected from the database.index_m(int, optional): HNSW index parameter. Number of bi-directional links created per element during index construction. Higher values improve recall but increase memory usage.index_ef_construction(int, optional): HNSW index parameter. Size of the dynamic candidate list for constructing the graph. Higher values improve index quality but slow down construction.index_quantization(str, optional): Quantization type for the index. Allowed values:"bf16","f16","f32","f64","i8".llm_location(str, optional): Name of the LOCATION object in Firebolt. Required whenuse_sql_embeddings=True.embedding_dimension(int): Dimension of embeddings. Defaults to 256.batch_size(int): Batch size for MERGE operations. Defaults to 32.metric(str): Similarity metric. Options:"vector_cosine_ops"(default),"vector_ip_ops","vector_l2sq_ops".api_endpoint(str, optional): Custom API endpoint. Defaults to Firebolt's cloud API.column_map(dict): Mapping of LangChain semantics to table columns. Defaults to:{ "id": "id", "document": "document", "embedding": "embedding", "metadata": [] # List of metadata column names }
Firebolt Constructor
Firebolt(
config: Optional[FireboltSettings] = None,
embeddings: Optional[Embeddings] = None,
use_sql_embeddings: bool = True,
**kwargs
)
Parameters:
config(FireboltSettings, optional): Configuration object. If None, will use environment variables.embeddings(Embeddings, optional): Embeddings model. Required ifuse_sql_embeddings=False.use_sql_embeddings(bool): Whether to use SQL-based embeddings (AI_EMBED_TEXT). Defaults toTrue.
Usage Examples
Adding Documents
Using add_documents()
from langchain_core.documents import Document
documents = [
Document(
page_content="Machine learning is a subset of artificial intelligence",
metadata={"file_name": "ml_intro.pdf", "page_number": 1}
),
Document(
page_content="Deep learning uses neural networks",
metadata={"file_name": "dl_basics.pdf", "page_number": 1}
),
]
vector_store.add_documents(documents)
Using add_texts()
texts = ["First document", "Second document"]
metadatas = [{"source": "doc1"}, {"source": "doc2"}]
ids = ["id1", "id2"]
vector_store.add_texts(texts=texts, metadatas=metadatas, ids=ids)
Using Precomputed Embeddings
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
vector_store = Firebolt(
config=settings,
embeddings=embeddings,
use_sql_embeddings=False # Use client-side embeddings
)
# Add documents with precomputed embeddings
vector_store.add_documents(documents)
Batch Processing
# Process documents in batches
vector_store.add_documents(documents, batch_size=64)
Searching Documents
Basic Similarity Search
results = vector_store.similarity_search("machine learning", k=5)
for doc in results:
print(f"Content: {doc.page_content}")
print(f"Metadata: {doc.metadata}")
Search with Scores
results = vector_store.similarity_search_with_score("neural networks", k=3)
for doc, score in results:
print(f"Score: {score:.4f}")
print(f"Content: {doc.page_content}")
Note: Score interpretation depends on the metric:
- For
vector_cosine_opsandvector_l2sq_ops: Lower scores indicate higher similarity - For
vector_ip_ops: Uses1 - VECTOR_INNER_PRODUCT, so lower scores indicate higher similarity
Search with Filters
# Filter by metadata
results = vector_store.similarity_search(
query="machine learning",
k=5,
filter={"file_name": "ml_intro.pdf", "page_number": 1}
)
# Filter with multiple values (IN clause)
results = vector_store.similarity_search(
query="neural networks",
k=5,
filter={"file_name": ["doc1.pdf", "doc2.pdf"]}
)
# Filter for NULL values
results = vector_store.similarity_search(
query="test",
k=5,
filter={"source": None}
)
Index vs Brute Force Search
The use_index parameter controls whether to use the vector search index (fast approximate search) or brute force table scan (exact search):
use_index=True(default): Uses thevector_searchTVF for fast approximate nearest neighbor searchuse_index=False: Scans the entire table, calculates distances, and sorts results (exact search)
# Use vector search index (default behavior)
results = vector_store.similarity_search(
query="machine learning",
k=5
)
# Use brute force table scan (exact search)
results = vector_store.similarity_search(
query="machine learning",
k=5,
use_index=False
)
# Brute force with filter
results = vector_store.similarity_search(
query="machine learning",
k=5,
filter={"file_name": "doc.pdf"},
use_index=False
)
The use_index parameter is available on all similarity search methods:
similarity_search()similarity_search_with_score()similarity_search_by_vector()similarity_search_with_score_by_vector()
Metadata Filter K Multiplier
When using index-based search (use_index=True) with metadata filters, the vector search index returns approximate nearest neighbors before the filter is applied. This can result in fewer results than requested if many candidates are filtered out.
The metadata_filter_k_multiplier parameter (default: 10) addresses this by requesting more results from the index:
# Request 5 results, but fetch 50 candidates from the index to ensure enough after filtering
results = vector_store.similarity_search(
query="machine learning",
k=5,
filter={"category": "technical"},
metadata_filter_k_multiplier=10 # default, fetches k*10 from index
)
# Increase multiplier for very selective filters
results = vector_store.similarity_search(
query="machine learning",
k=5,
filter={"category": "rare_category"},
metadata_filter_k_multiplier=50 # fetches k*50 from index
)
# Disable multiplier (only useful when you know most results will match)
results = vector_store.similarity_search(
query="machine learning",
k=5,
filter={"category": "common_category"},
metadata_filter_k_multiplier=1 # fetches exactly k from index
)
Note: The multiplier only affects index-based searches with filters. Brute force searches (use_index=False) always scan the entire table, so filtering doesn't reduce the result count.
HNSW Search Parameters
You can fine-tune HNSW index search behavior with optional parameters:
ef_search(int): Controls the size of the dynamic candidate list during search. Higher values improve recall but slow down search.load_strategy(str): Controls how the index is loaded. Values:"in_memory"(faster, more memory) or"disk"(slower, less memory).
# Higher ef_search for better recall
results = vector_store.similarity_search(
query="machine learning",
k=5,
ef_search=64
)
# Use disk-based loading for large indexes
results = vector_store.similarity_search(
query="machine learning",
k=5,
load_strategy="disk"
)
# Combine parameters
results = vector_store.similarity_search(
query="machine learning",
k=5,
ef_search=128,
load_strategy="in_memory"
)
Search by Vector
# Get embedding first
query_embedding = vector_store._get_embedding("machine learning")
# Search using the vector
results = vector_store.similarity_search_by_vector(query_embedding, k=5)
Retrieving Documents by ID
# Get documents by their IDs
ids = ["id1", "id2", "id3"]
documents = vector_store.get_by_ids(ids)
for doc in documents:
print(f"ID: {doc.metadata['id']}")
print(f"Content: {doc.page_content}")
Deleting Documents
Delete by IDs
vector_store.delete(ids=["id1", "id2"])
Delete by Filter
# Delete all documents from a specific file
vector_store.delete(filter={"file_name": "old_document.pdf"})
Delete All Documents
# WARNING: This deletes all documents in the table
vector_store.delete(delete_all=True)
Dropping Table and Index
# WARNING: This permanently deletes the table and index
# Requires explicit confirmation
vector_store.drop(drop_table=True)
Using as Retriever
from langchain_firebolt import FireboltRetriever
# Create a retriever
retriever = vector_store.as_retriever(search_kwargs={"k": 5, "filter": {"source": "docs"}})
# Use in a chain
from langchain.chains import RetrievalQA
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever
)
result = qa_chain.invoke({"query": "What is machine learning?"})
Class Methods
from_documents()
vector_store = Firebolt.from_documents(
documents=documents,
config=settings,
use_sql_embeddings=True
)
from_texts()
vector_store = Firebolt.from_texts(
texts=["Text 1", "Text 2"],
metadatas=[{"source": "1"}, {"source": "2"}],
config=settings
)
Async Operations
# Async similarity search
results = await vector_store.asimilarity_search("query", k=5)
# Async get by IDs
docs = await vector_store.aget_by_ids(["id1", "id2"])
Context Manager
# Automatically closes connections when done
with Firebolt(config=settings) as vector_store:
results = vector_store.similarity_search("query", k=5)
# Connections are automatically closed
API Reference
Main Methods
add_documents(documents, ids=None, batch_size=None, **kwargs)
Add documents to the vector store.
add_texts(texts, metadatas=None, ids=None, batch_size=None, **kwargs)
Add texts to the vector store.
similarity_search(query, k=4, filter=None, use_index=True, metadata_filter_k_multiplier=10, ef_search=None, load_strategy=None, **kwargs)
Search for similar documents by query text. The use_index parameter controls whether to use the vector search index (True, default) or brute force table scan (False). The metadata_filter_k_multiplier increases the number of candidates fetched from the index when filtering (default: 10). Optional ef_search controls HNSW search quality/speed tradeoff. Optional load_strategy controls index loading ("in_memory" or "disk").
similarity_search_with_score(query, k=4, filter=None, use_index=True, metadata_filter_k_multiplier=10, ef_search=None, load_strategy=None, **kwargs)
Search for similar documents with similarity scores. The use_index parameter controls index vs brute force search (defaults to True). The metadata_filter_k_multiplier increases the number of candidates fetched from the index when filtering (default: 10). Optional ef_search and load_strategy control search behavior.
similarity_search_by_vector(embedding, k=4, filter=None, use_index=True, metadata_filter_k_multiplier=10, ef_search=None, load_strategy=None, **kwargs)
Search for similar documents using a vector embedding. The use_index parameter controls index vs brute force search (defaults to True). The metadata_filter_k_multiplier increases the number of candidates fetched from the index when filtering (default: 10). Optional ef_search and load_strategy control search behavior.
similarity_search_with_score_by_vector(embedding, k=4, filter=None, use_index=True, metadata_filter_k_multiplier=10, ef_search=None, load_strategy=None, **kwargs)
Search for similar documents by vector with similarity scores. The use_index parameter controls index vs brute force search (defaults to True). The metadata_filter_k_multiplier increases the number of candidates fetched from the index when filtering (default: 10). Optional ef_search and load_strategy control search behavior.
get_by_ids(ids)
Retrieve documents by their IDs.
delete(ids=None, filter=None, delete_all=False)
Delete documents from the vector store.
drop(drop_table=False)
Drop the table and index (destructive operation).
as_retriever(**kwargs)
Create a retriever from the vector store.
close()
Close database connections.
Environment Variables
You can configure the vector store using environment variables instead of passing FireboltSettings:
# Required
FIREBOLT_CLIENT_ID=your_client_id
FIREBOLT_CLIENT_SECRET=your_client_secret
FIREBOLT_ENGINE=your_engine
FIREBOLT_DB=your_database
FIREBOLT_ACCOUNT=your_account
FIREBOLT_TABLENAME=documents
# Optional
FIREBOLT_INDEX=documents_index
FIREBOLT_LLM_LOCATION=llm_api
FIREBOLT_BATCH_SIZE=32
FIREBOLT_API_ENDPOINT=https://api.firebolt.io
Then create the vector store without explicit config:
vector_store = Firebolt() # Uses environment variables
Best Practices
1. Connection Management
The vector store uses two connections:
- Read connection: For search operations (autocommit enabled)
- Write connection: For write operations (autocommit disabled, uses transactions)
Always close connections when done:
vector_store = Firebolt(config=settings)
try:
# Use vector store
results = vector_store.similarity_search("query")
finally:
vector_store.close()
Or use the context manager:
with Firebolt(config=settings) as vector_store:
results = vector_store.similarity_search("query")
2. Batch Operations
For large datasets, use batch operations:
# Process in batches
vector_store.add_documents(documents, batch_size=64)
3. Metadata Design
Design your metadata columns carefully:
# Good: Specific, filterable columns
column_map = {
"id": "id",
"document": "document",
"embedding": "embedding",
"metadata": ["file_name", "page_number", "source", "author", "date"]
}
4. Index Selection
Choose the right metric for your use case:
- Cosine similarity (
vector_cosine_ops): Best for normalized embeddings, most common - Inner product (
vector_ip_ops): Good for unnormalized embeddings - L2 squared distance (
vector_l2sq_ops): Good for distance-based applications
5. SQL Embeddings vs Client-Side Embeddings
SQL Embeddings (Recommended, default):
- Embeddings computed in Firebolt using
AI_EMBED_TEXT - No need to manage embeddings client-side
- Consistent with search-time embeddings
- Requires LOCATION object setup (see Prerequisites section)
- Set
use_sql_embeddings=True(default) and providellm_locationparameter
Client-Side Embeddings:
- Embeddings computed using a LangChain embeddings model (e.g., OpenAI, HuggingFace)
- More control over embedding model
- Useful for testing or when LOCATION object is not available
- LOCATION object not required
- Set
use_sql_embeddings=Falseand provideembeddingsparameter
6. Error Handling
try:
vector_store.add_documents(documents)
except Exception as e:
print(f"Error adding documents: {e}")
# Connection will be rolled back automatically
7. Performance Optimization
- Use appropriate
batch_sizefor your workload - Create indexes on metadata columns used for filtering
- Use connection pooling for high-throughput applications
- Consider using external batch tools for initial data loading
Troubleshooting
Common Issues
1. "No vector search index found"
- Ensure you've created a vector search index on your table
- Or explicitly provide the
indexparameter inFireboltSettings
2. "llm_location must be provided"
- Create a LOCATION object in Firebolt
- Provide the
llm_locationparameter matching the LOCATION name
3. "Authorization failed"
- Verify your client ID and secret are correct
- Check that your credentials have access to the engine and database
Additional Resources
License
This project is licensed under the Apache License, Version 2.0. See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file langchain_firebolt-0.1.2.tar.gz.
File metadata
- Download URL: langchain_firebolt-0.1.2.tar.gz
- Upload date:
- Size: 39.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c09b283361c1a5c5ab50e3b9b81ad80387c4c07d3295f0f7bb7f4a62120ed149
|
|
| MD5 |
e89980ed296a6f5086e41082976c9c25
|
|
| BLAKE2b-256 |
a2b80fc315187ce820a9c7f3253517ef034194971af6d624111ccec8df25b190
|
File details
Details for the file langchain_firebolt-0.1.2-py3-none-any.whl.
File metadata
- Download URL: langchain_firebolt-0.1.2-py3-none-any.whl
- Upload date:
- Size: 33.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2610888f5c7110b85e570fe120ccc43fec3a974c0676b98677231693e2bfa35
|
|
| MD5 |
d926b1cd1ead739b509ff517eedf7938
|
|
| BLAKE2b-256 |
a48902d985d0930601e255cf6e651e2a63c0ba943717561b62997fcdc891adec
|