langchain-vectorpanda makes Vector Panda a first-class LangChain
VectorStore:
your documents live in a Vector Panda collection, and every LangChain
retriever, chain, or agent that speaks the standard interface works
unchanged. The package passes LangChain's official
VectorStoreIntegrationTests conformance suite — sync and async — on every
release.
Install
pip install langchain-vectorpanda langchain-huggingface
langchain-vectorpanda brings the store and the veep client;
langchain-huggingface supplies the embedding model used below (any
LangChain Embeddings implementation works — OpenAI, Cohere, your own).
Create a store and load documents
from_texts creates the collection if it doesn't exist, embeds your texts
client-side, and upserts them in one call. Your raw text never reaches
Vector Panda unembedded — embedding always happens on your side.
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_vectorpanda import VectorPandaStore
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
store = VectorPandaStore.from_texts(
texts=[
"Giant pandas spend up to 14 hours a day eating bamboo.",
"The Eiffel Tower opened in 1889 for the Paris World Fair.",
"Rust guarantees memory safety without a garbage collector.",
"Sourdough bread rises from wild yeast in a fermented starter.",
],
metadatas=[
{"topic": "animals", "year": 2021},
{"topic": "travel", "year": 2019},
{"topic": "tech", "year": 2024},
{"topic": "food", "year": 2022},
],
embedding=embeddings,
collection_name="langchain-tutorial",
ids=["panda", "eiffel", "rust", "sourdough"],
)
A brand-new collection reports status empty, then briefly
awaiting_artifacts while your first rows are indexed. Wait for ready
before the first search:
import time
while store.client.collections.status("langchain-tutorial") != "ready":
time.sleep(2)
Search
for doc in store.similarity_search("what do pandas eat?", k=2):
print(doc.id, "|", doc.page_content)
panda | Giant pandas spend up to 14 hours a day eating bamboo.
sourdough | Sourdough bread rises from wild yeast in a fermented starter.
Why sourdough? k=2 always returns the two nearest neighbors, however far
the second one is — and of the remaining documents, the bread sentence is
the only other one about food. Use similarity_search_with_score to see
the gap numerically, or a metadata filter (next section) when only certain
documents should be eligible at all.
Filter by metadata
Any metadata you stored is filterable with Mongo-style operators
($eq, $gt, $in, $and, …) — the full dialect is in
Filter syntax in depth. Filtering happens
in the database during the search, not in your app afterward.
for doc in store.similarity_search("interesting facts", k=4, filter={"year": {"$gte": 2022}}):
print(doc.id, "|", doc.metadata)
sourdough | {'id': 'sourdough', 'topic': 'food', 'year': 2022}
rust | {'id': 'rust', 'topic': 'tech', 'year': 2024}
Two things to read off that output: $gte means 2022 or later, so the
2024 document qualifies (use {"year": 2022} for exact equality). And
although we asked for k=4, only two documents came back — a filter
narrows the eligible set and never pads the result, so you get every
match up to k, ranked by similarity.
Fetch documents by ID
get_by_ids returns exactly the documents you name — and IDs that don't
exist are simply skipped, never an error:
for doc in store.get_by_ids(["rust", "no-such-id"]):
print(doc.id, "|", doc.page_content)
rust | Rust guarantees memory safety without a garbage collector.
Use it as a retriever
as_retriever() plugs the store into any chain or agent that consumes a
LangChain retriever — this is the line that turns Vector Panda into the
retrieval half of a RAG app:
retriever = store.as_retriever(search_kwargs={"k": 1})
print(retriever.invoke("systems programming languages")[0].id)
rust
For diversity-aware retrieval, store.as_retriever(search_type="mmr")
re-ranks with Maximal Marginal Relevance; similarity_search_with_score
returns cosine scores alongside each document.
Clean up
store.client.collections.delete("langchain-tutorial")
Where to go next
- Filter syntax in depth — every operator, with runnable examples on a 5,000-document corpus.
- Hot, warm, paused: a tier mental model —
pick a storage tier by access pattern;
from_texts(tier="warm")sets it at creation. - The package itself: PyPI · GitHub.
