Skip to main content

langchain-ydb


License PyPI version Functional tests Lint checks

LangChain's YDB integration (langchain-ydb) provides vector capabilities for working with YDB.

Getting Started

Setting Up YDB

Launch a YDB Docker container with:

docker run -d -p 2136:2136 --name ydb-langchain -e YDB_USE_IN_MEMORY_PDISKS=true -h localhost ydbplatform/local-ydb:trunk

Installing the Package

Install langchain-ydb package with:

pip install -U langchain-ydb

VectorStore works along with an embedding model, here using langchain-openai as example.

pip install langchain-openai
export OPENAI_API_KEY=...

Work with YDB Vector Store

Creating a Vector Store

from langchain_openai import OpenAIEmbeddings
from langchain_ydb.vectorstores import YDB, YDBSearchStrategy, YDBSettings


settings = YDBSettings(
    host="localhost",
    port=2136,
    database="/local",
    table="ydb_example",
    strategy=YDBSearchStrategy.COSINE_SIMILARITY,
)

vector_store = YDB(
    OpenAIEmbeddings(),
    config=settings,
)

Async vector store (AsyncYDB)

For native asyncio I/O (ydb.aio via ydb-dbapi), use AsyncYDB instead of YDB:

from langchain_ydb.vectorstores import AsyncYDB, YDBSettings

store = await AsyncYDB.afrom_texts(
    ["hello", "world"],
    embeddings,
    config=YDBSettings(table="my_async_table"),
)
docs = await store.asimilarity_search("hello", k=1)
await store.aclose()

Sync methods on AsyncYDB are not supported; use a* APIs.

Configuration

Pass a YDBSettings instance to YDB or AsyncYDB. The fields below control connections, table creation, and search. Defaults apply when a field is omitted.

Connection and table

Field Default Purpose
host "localhost" YDB host.
port 2136 gRPC port.
credentials None Authentication; see Credentials below.
secure False Use grpcs instead of grpc.
database "/local" Database containing the table.
table "ydb_langchain_store" Table to create or open.
column_map id, document, embedding, metadata Maps these four roles to table columns. Supply all four names for a custom schema.
drop_existing_table False Drop and recreate the table when the store opens. Leave False to reuse existing data.

For a table with custom column names:

settings = YDBSettings(
    table="my_documents",
    column_map={
        "id": "doc_id",
        "document": "body",
        "embedding": "body_vector",
        "metadata": "attributes",
    },
)

Vector search and index

Field Default Purpose
strategy YDBSearchStrategy.COSINE_SIMILARITY Vector scoring function and index metric. Match the metric of an existing index.
index_enabled False Use a vector index for similarity search and rebuild it after writes. On a new table, the index is first created after adding documents. Hybrid search creates missing indexes when the store opens.
index_name "ydb_vector_index" Vector index name; set it to the existing name when reusing an index.
index_config_levels 2 K-means tree depth when a vector index is created or rebuilt.
index_config_clusters 128 Number of clusters when a vector index is created or rebuilt.
index_tree_search_top_size 1 ydb.KMeansTreeSearchTopSize for indexed vector queries, including the vector branch of hybrid search. Higher values search more tree candidates.
vector_dimension None Embedding dimension for index creation or rebuild. If omitted when needed, it is inferred from embed_query("index") or aembed_query("index").
vector_pass_as_bytes True Pass document and query vectors as binary String values. With False, pass List<Float> and convert in YQL.

Index creation settings affect a new or rebuilt vector index. Opening a table with a ready index does not change that index. Adding documents rebuilds the vector index when index_enabled or hybrid_search_enabled is set.

Hybrid index setup

Field Default Purpose
hybrid_search_enabled False Enable hybrid search and create any missing fulltext and vector indexes when opening a new or existing table. Implies indexed vector search even if index_enabled=False.
fulltext_index_name "ydb_fulltext_index" Fulltext relevance index name. Set it to an existing index name to reuse that index.
hybrid_index_ready_timeout 3600.0 seconds Maximum wait for both indexes to become ready after creation. If a build stays incomplete, opening the store raises TimeoutError with the current index states. Increase it for large existing tables.

How to use Credentials

To use YDB credentials pass a credentials value into YDBSettings.

There are several ways to use credentials:

Static Credentials:

settings = YDBSettings(credentials={"username": "name", "password": "pass"})

vector_store = YDB(embeddings, config=settings)

Access Token Credentials:

settings = YDBSettings(credentials={"token": "zxc123"})

vector_store = YDB(embeddings, config=settings)

Service Account Credentials:

settings = YDBSettings(credentials={
    "service_account_json": {
        "id": "...",
        "service_account_id": "...",
        "created_at": "...",
        "key_algorithm": "...",
        "public_key": "...",
        "private_key": "..."
    }
})

vector_store = YDB(embeddings, config=settings)

Credentials Object From YDB SDK:

Additionally, you can use any credentials that comes with ydb package. Example:

import ydb.iam

settings = YDBSettings(credentials=ydb.iam.MetadataUrlCredentials())

vector_store = YDB(embeddings, config=settings)

Add items to vector store

Once you have created your vector store, you can interact with it by adding and deleting different items.

Prepare documents to work with:

from uuid import uuid4

from langchain_core.documents import Document

document_1 = Document(
    page_content="I had chocalate chip pancakes and scrambled eggs for breakfast this morning.",
    metadata={"source": "tweet"},
)

document_2 = Document(
    page_content="The weather forecast for tomorrow is cloudy and overcast, with a high of 62 degrees.",
    metadata={"source": "news"},
)

document_3 = Document(
    page_content="Building an exciting new project with LangChain - come check it out!",
    metadata={"source": "tweet"},
)

document_4 = Document(
    page_content="Robbers broke into the city bank and stole $1 million in cash.",
    metadata={"source": "news"},
)

document_5 = Document(
    page_content="Wow! That was an amazing movie. I can't wait to see it again.",
    metadata={"source": "tweet"},
)

document_6 = Document(
    page_content="Is the new iPhone worth the price? Read this review to find out.",
    metadata={"source": "website"},
)

document_7 = Document(
    page_content="The top 10 soccer players in the world right now.",
    metadata={"source": "website"},
)

document_8 = Document(
    page_content="LangGraph is the best framework for building stateful, agentic applications!",
    metadata={"source": "tweet"},
)

document_9 = Document(
    page_content="The stock market is down 500 points today due to fears of a recession.",
    metadata={"source": "news"},
)

document_10 = Document(
    page_content="I have a bad feeling I am going to get deleted :(",
    metadata={"source": "tweet"},
)

documents = [
    document_1,
    document_2,
    document_3,
    document_4,
    document_5,
    document_6,
    document_7,
    document_8,
    document_9,
    document_10,
]
uuids = [str(uuid4()) for _ in range(len(documents))]

You can add items to your vector store by using the add_documents function.

vector_store.add_documents(documents=documents, ids=uuids)

Delete items from vector store

You can delete items from your vector store by ID using the delete function.

vector_store.delete(ids=[uuids[-1]])

Query vector store

Once your vector store has been created and relevant documents have been added, you will likely want to query it during the execution of your chain or agent.

Query directly

Similarity search:

A simple similarity search can be performed as follows:

results = vector_store.similarity_search(
    "LangChain provides abstractions to make working with LLMs easy", k=2
)
for res in results:
    print(f"* {res.page_content} [{res.metadata}]")

Similarity search with score

You can also perform a search with a score:

results = vector_store.similarity_search_with_score("Will it be hot tomorrow?", k=3)
for res, score in results:
    print(f"* [SIM={score:.3f}] {res.page_content} [{res.metadata}]")

Filtering

You can search with filters as described below:

This works with the default linear scan. Indexed vector search (including a store with hybrid_search_enabled=True) rejects metadata filters.

results = vector_store.similarity_search_with_score(
    "What did I eat for breakfast?",
    k=4,
    filter={"source": "tweet"},
)
for res, _ in results:
    print(f"* {res.page_content} [{res.metadata}]")

Query by turning into retriever

You can also transform the vector store into a retriever for easier usage in your chains.

Here's how to transform your vector store into a retriever and then invoke the retriever with a simple query and filter.

retriever = vector_store.as_retriever(
    search_kwargs={"k": 2},
)
results = retriever.invoke(
    "Stealing from the bank is a crime", filter={"source": "news"}
)
for res in results:
    print(f"* {res.page_content} [{res.metadata}]")

On a YDB server that supports HybridRank, hybrid search combines fulltext relevance over the document column with vector similarity over the embedding column. Both indexes belong to the same table. Set hybrid_search_enabled=True to create missing indexes and wait until they are ready. Existing documents are indexed in place without recomputing their embeddings.

New table

from langchain_openai import OpenAIEmbeddings
from langchain_ydb.vectorstores import YDB, YDBSettings

settings = YDBSettings(
    table="my_documents",
    hybrid_search_enabled=True,
    vector_dimension=1536,  # set this to your model's embedding size
)
store = YDB(OpenAIEmbeddings(), config=settings)
store.add_texts(["A document about databases"])

documents = store.hybrid_search("database", k=4)
retriever = store.as_hybrid_retriever(k=4)
documents = retriever.invoke("database")

Existing table

Open the same table with hybrid_search_enabled=True and leave drop_existing_table=False (the default). Set index_name and fulltext_index_name to the names of any indexes you want to reuse. Missing indexes are built over the existing rows; ready indexes with those names are reused. When reusing an index, opening the store also embeds one probe query and runs a small hybrid search to check that YDB accepts the index types and vector metric.

settings = YDBSettings(
    table="my_documents",
    hybrid_search_enabled=True,
    index_name="existing_vector_index",
    fulltext_index_name="document_relevance_index",
    vector_dimension=1536,
)
store = YDB(OpenAIEmbeddings(), config=settings)
documents = store.hybrid_search("database", k=4)

The automatically created fulltext index is GLOBAL USING fulltext_relevance on column_map["document"] with WITH (tokenizer=standard, use_filter_lowercase=true). These tokenizer and normalization options are fixed in the integration. For different options, create a fulltext_relevance index directly on the document column and pass its name as fulltext_index_name. The store checks the indexed column and readiness of an existing index and runs a small hybrid query to validate its type and vector metric. It does not inspect tokenizer settings. The fulltext index follows subsequent writes automatically; the vector index is rebuilt after documents are added.

Query options

hybrid_search and ahybrid_search use the same input text for fulltext matching and query embedding. Their query-time options are:

Argument Default Purpose
k 4 Number of returned documents; must be a positive integer.
mode "rrf" Fusion by reciprocal rank ("rrf") or normalized weighted scores ("linear").
weights (1.0, 1.0) Non-negative weights in (fulltext, vector) order.
candidate_limits None Positive candidate counts in (fulltext, vector) order. By default, YDB uses k * 10 candidates per branch.

For example, this gives the vector branch twice the weight:

store.hybrid_search(
    "database", k=5, weights=(1.0, 2.0), candidate_limits=(50, 100)
)
retriever = store.as_hybrid_retriever(k=5, weights=(1.0, 2.0))

For asynchronous I/O, use await AsyncYDB.create(embeddings, config=settings), await store.ahybrid_search(...), and await store.as_hybrid_retriever(k=4).ainvoke(...). Close the store with await store.aclose().

The ordinary similarity_search and as_retriever() remain vector-only. Use as_hybrid_retriever() for hybrid retrieval. This integration does not forward metadata filter in hybrid queries and raises ValueError if one is supplied. The API returns documents in fused order without a numeric fused score.

The basic example notebook compares vector and hybrid results on an existing table. The local RAG wiki hybrid notebook shows both retrievers in a complete RAG workflow.

Release files for langchain-ydb 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for langchain-ydb 0.1.0
File Size Uploaded
langchain_ydb-0.1.0.tar.gz 24.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for langchain-ydb 0.1.0
File Interpreter ABI Platform
langchain_ydb-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 46.4 kB

Release files / langchain_ydb-0.1.0.tar.gz

Download URL langchain_ydb-0.1.0.tar.gz
Size 24.7 kB
Tags Source
SHA-256 checksum
How to use checksums
cf4a64ce955355746995e2449c1d5bc5e21a860eff97153c10596c559333ab49
BLAKE2b-256 checksum
How to use checksums
2099bc24fe6c22d835a6bb03dd34bb64aca84eaba2d91d7c3a1a5784994a7869
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / langchain_ydb-0.1.0-py3-none-any.whl

Download URL langchain_ydb-0.1.0-py3-none-any.whl
Size 21.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
51266bc1dd1df717bb5ed0869607e62c736d9f83d9be55f713524fdf51b7280f
BLAKE2b-256 checksum
How to use checksums
70b27ecaa6637c2e3821a397da0e32a46a9fe5f7ecff1b04239f70a9370c6506
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

0.0.17

2 release files

0.0.16

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page