Was this page helpful?
LangChain and CassIO Compatibility¶
ScyllaDB Vector Search is compatible with LangChain
through the Cassandra connector, which is built on top of
CassIO. This lets you use the popular LangChain
Cassandra vector store — and other AI frameworks that integrate with
Cassandra or Astra DB through CassIO — against a ScyllaDB cluster with little
or no code changes.
This page explains how the compatibility layer works, what it requires, the limitations you should be aware of, and provides a complete Retrieval-Augmented Generation (RAG) example.
How Compatibility Works¶
In Cassandra, the native vector index type is the Storage Attached Index
(SAI). Libraries such as CassIO, LangChain, and LlamaIndex generate
CREATE CUSTOM INDEX statements that reference the SAI class name when they
set up their schema. ScyllaDB’s native vector index type is instead called
vector_index (see Vector Index Type).
To allow CassIO-based libraries to run unmodified, ScyllaDB recognizes the
Cassandra SAI class name in CREATE CUSTOM INDEX statements on vector
columns and transparently creates a native vector_index instead. The
following class names are accepted:
org.apache.cassandra.index.sai.StorageAttachedIndex(exact case required)StorageAttachedIndex(case-insensitive)SAI(case-insensitive)
For example, the following Cassandra SAI statement is accepted by ScyllaDB:
CREATE CUSTOM INDEX ON my_table (embedding)
USING 'org.apache.cassandra.index.sai.StorageAttachedIndex'
WITH OPTIONS = {'similarity_function': 'COSINE'};
ScyllaDB treats it as equivalent to its native syntax:
CREATE CUSTOM INDEX ON my_table (embedding)
USING 'vector_index'
WITH OPTIONS = {'similarity_function': 'COSINE'};
The similarity_function option is supported by both Cassandra SAI and
ScyllaDB, so no translation is needed for it.
The CassIO Metadata-Map Pattern¶
CassIO also creates an SAI index on the entries of a non-frozen map column
(the column it uses to store document metadata). When ScyllaDB encounters an
SAI class name on ENTRIES(map_column), it strips the SAI class and creates
a standard secondary index
instead. For example, CassIO issues this during schema setup:
CREATE CUSTOM INDEX ON my_table (ENTRIES(metadata_s))
USING 'org.apache.cassandra.index.sai.StorageAttachedIndex';
ScyllaDB creates the equivalent of:
CREATE INDEX ON my_table (ENTRIES(metadata_s));
A CQL warning is emitted noting possible behavioral differences from Cassandra
SAI metadata filtering. This rewrite requires the enable_cassio_compatibility
configuration option to be enabled (see Requirements).
Note
This rewrite provides compatibility for index creation only. The resulting
standard secondary index cannot be used to filter the results of an
ANN OF similarity search. To combine similarity search with metadata
constraints, use ScyllaDB’s native
vector search filtering.
See Limitations and Compatibility Gaps for
details.
Requirements¶
To use LangChain and CassIO with ScyllaDB Vector Search, your environment must meet the following requirements:
ScyllaDB 2026.2 or later, with the Vector Search feature enabled on the cluster. The Approximate Nearest Neighbor (ANN) search itself is served by the ScyllaDB Vector Store service, which must be configured for the cluster.
The
enable_cassio_compatibilityconfiguration option must be enabled. LangChain/CassIO automatic schema setup creates an SAI index on the metadata map column, and this option allows ScyllaDB to rewrite that statement into a standard secondary index.
Enabling CassIO Compatibility¶
The enable_cassio_compatibility option must be enabled on every node. It is
live-updatable, so you can enable it at runtime — without a restart — using the
following CQL statement:
UPDATE system.config SET value = 'true' WHERE name = 'enable_cassio_compatibility';
Self-managed deployments can alternatively pass --enable-cassio-compatibility 1
on the command line, or set enable_cassio_compatibility: true in
scylla.yaml.
Note
Changing cluster configuration requires appropriate permissions. If you are using ScyllaDB Cloud and the option is not enabled on your cluster, contact ScyllaDB Support.
Limitations and Compatibility Gaps¶
The compatibility layer is designed to make CassIO-generated schema statements work on ScyllaDB. Keep the following limitations in mind:
DDL-level compatibility. Compatibility applies to the
CREATE CUSTOM INDEXdata-definition statements that CassIO and LangChain issue. The underlying vector index is a native ScyllaDBvector_index, and queries use ScyllaDB’s vector search implementation.SAI is accepted only on vector columns and map entries. SAI class names are recognized on vector columns (rewritten to
vector_index) and on ENTRIES of non-frozen map columns (rewritten to a standard secondary index). Using an SAI class name on any other non-vector column (for example,textorint) results in an error. General SAI indexing is not supported; use a secondary index instead. Multi-column SAI targets are also rejected.The
source_modeloption is accepted but not used. Cassandra client libraries such as CassIO may send asource_modeloption to tag the index with the name of the embedding model that produced the vectors (for example,ada002). Cassandra SAI rejects this as an unrecognized property; ScyllaDB accepts and preserves it inDESCRIBEoutput for compatibility, but does not act on it.Combining metadata filtering with ANN queries requires native filtering. The CassIO metadata-map SAI index is rewritten to a standard secondary index, which provides compatibility for index creation only. It does not make CassIO-style metadata filtering work together with similarity search: an
ANN OFquery combined with a metadata filter served through the rewritten secondary index will usually not work without custom integration. To combine similarity search with metadata constraints, use ScyllaDB’s native vector search filtering instead. The rewritten secondary index can serve metadata filtering only when it is not combined with an ANN query. ScyllaDB emits a CQL warning when it performs this rewrite.Vector index feature limitations apply. Vector indexes do not support all ScyllaDB features. Tracing, TTL, paging, and grouping are not supported on vector indexes regardless of whether the index was created through CassIO or native CQL.
The ANN index is built asynchronously. After the table and index are created, the ScyllaDB Vector Store service builds the ANN index in the background. If the index is created on a table that already contains data, ScyllaDB scans the existing rows to build the HNSW graph. Until the build completes, a similarity search issued right after schema setup can briefly fail or return incomplete results, so applications should wait and retry the first query (see Index build progress monitoring). This initial build is distinct from the incremental write-to-query latency that applies to an already-built index.
Example: LangChain RAG with ScyllaDB¶
The following example uses LangChain’s Cassandra vector store against a
ScyllaDB deployment. It lets LangChain/CassIO create the vector table and
indexes automatically (SetupMode.SYNC), inserts a small set of documents,
waits for the asynchronously built ANN index to become ready, and runs a
similarity search.
The example uses a local FastEmbed
embedding model (BAAI/bge-small-en-v1.5, 384 dimensions), so it does not
require a paid embedding API. The model is downloaded on first use.
Note
This example is adapted from the LangChain RAG example in the ScyllaDB Vector Store repository. See that directory for the complete, runnable project.
Install Dependencies¶
Create and activate a Python virtual environment, then install the required packages:
python3 -m venv .venv
. .venv/bin/activate
pip install \
"cassio>=0.1,<0.2" \
"cassandra-driver>=3.30,<4" \
"fastembed>=0.8,<0.9" \
"langchain-community>=0.4,<0.5" \
"langchain-core>=1.4,<2"
Connect and Build the Vector Store¶
First, connect to ScyllaDB and create the keyspace. Then build a LangChain
Cassandra vector store on top of the session. With SetupMode.SYNC,
LangChain/CassIO creates the table and its vector index up front, so you do not
have to write any CQL DDL yourself.
from cassandra.auth import PlainTextAuthProvider
from cassandra.cluster import Cluster
from langchain_community.embeddings.fastembed import FastEmbedEmbeddings
from langchain_community.utilities.cassandra import SetupMode
from langchain_community.vectorstores import Cassandra
from langchain_core.documents import Document
KEYSPACE = "langchain_demo"
TABLE_NAME = "langchain_rag_demo"
# A small local embedding model. Its 384-dimensional output determines
# the size of the stored vectors. The same model must be used for both
# inserts and queries so the vectors live in the same space.
EMBEDDING_MODEL = "BAAI/bge-small-en-v1.5"
auth = PlainTextAuthProvider(username="scylla", password="YOUR_PASSWORD")
cluster = Cluster(
contact_points=["node-0.your-cluster.cloud.scylladb.com"],
port=9042,
auth_provider=auth,
)
session = cluster.connect()
session.execute(
f"""
CREATE KEYSPACE IF NOT EXISTS {KEYSPACE}
WITH replication = {{'class': 'NetworkTopologyStrategy', 'replication_factor': 1}}
"""
)
session.set_keyspace(KEYSPACE)
# SetupMode.SYNC creates the table and vector index synchronously if they
# do not already exist. This is the step that relies on CassIO
# compatibility being enabled on the cluster.
embeddings = FastEmbedEmbeddings(model_name=EMBEDDING_MODEL)
vector_store = Cassandra(
embedding=embeddings,
session=session,
keyspace=KEYSPACE,
table_name=TABLE_NAME,
setup_mode=SetupMode.SYNC,
)
Note
Automatic schema setup with SetupMode.SYNC only works when you do not
need metadata filtering combined with ANN OF queries. As noted in
Limitations and Compatibility Gaps, the
secondary index that CassIO’s schema setup creates provides index-creation
compatibility only and cannot filter ANN search results. If your application
needs to combine similarity search with metadata constraints, use
SetupMode.OFF instead, create the table and a native ScyllaDB
vector index (with the
required filtering columns) manually to apply ScyllaDB’s native
vector search filtering.
Insert Documents¶
LangChain embeds each document’s content and stores the resulting vector. Passing explicit ids makes inserts idempotent, so re-running the example updates the same rows instead of creating duplicates.
DEMO_DOCUMENTS = (
("vector-store-indexing",
"ScyllaDB Vector Store indexes vector columns stored in ScyllaDB "
"tables and serves approximate nearest-neighbor search for queries."),
("langchain-cassandra-connector",
"LangChain's Cassandra vector store connector uses the Cassandra "
"Query Language protocol and can exercise ScyllaDB through CassIO."),
("ann-search",
"Approximate nearest-neighbor queries compare an embedded question "
"with stored document embeddings and return the closest documents."),
)
documents = [
Document(page_content=text, metadata={"id": doc_id})
for doc_id, text in DEMO_DOCUMENTS
]
ids = [doc_id for doc_id, _ in DEMO_DOCUMENTS]
vector_store.add_documents(documents, ids=ids)
Wait for the Index, Then Search¶
Because the ANN index is built asynchronously, a search issued immediately
after setup can briefly fail while the index is still being constructed. While
the index is not ready, the Vector Store service answers with HTTP status
404 (index not created yet) or 503 (index still being built), and
ScyllaDB surfaces that status in the CQL error message. Probe once with retries,
then run searches directly.
import time
def is_index_still_building(error: Exception) -> bool:
message = str(error)
return "HTTP status 404" in message or "HTTP status 503" in message
def wait_for_index(store: Cassandra, query: str, attempts: int = 30,
delay_seconds: int = 2) -> None:
for _ in range(attempts):
try:
store.similarity_search_with_score(query, k=1)
return
except Exception as error:
if not is_index_still_building(error):
raise
time.sleep(delay_seconds)
raise RuntimeError("Vector Store did not finish building the ANN index in time")
query = "How does ScyllaDB support vector search?"
wait_for_index(vector_store, query)
results = vector_store.similarity_search_with_score(query, k=3)
for document, score in results:
print(f"id={document.metadata.get('id')} score={score:.6f}")
print(document.page_content)
Higher scores indicate closer (more similar) matches. The example prints the retrieved documents and their scores; it does not run text generation, which you would add as the “generation” step of a full RAG pipeline.
See also
Working with Vector Search — vector data type, vector indexes, ANN queries, and driver integration.
Filtering Vector Search Results — combine similarity search with metadata constraints.
Example Applications — RAG applications, semantic caching, and integrations with LLM libraries such as LlamaIndex and LangChain.