Vectorstore¶
Qdrant-based vector storage for RAG. Embeddings, collections, and ingestion. Used for catalog and example-plan semantic retrieval when RAG is enabled.
flowchart LR
Q["User Query"] --> E["Embed (OpenAI)"]
E --> S["Search Qdrant"]
S --> T["Threshold Filter"]
T --> P["Prune & Rank"]
P --> R["Agent Context"]
style Q fill:#2563eb,color:#fff
style R fill:#059669,color:#fff
Overview¶
Qdrant Store — Client wrapper. Collection management, point upsert, similarity search. Powers catalog_rag and example_plans_rag tools.
Bootstrap — Initialize vectorstore at startup. Create collections, run migrations. Called when RAG is enabled.
Design Decisions¶
Why Qdrant for RAG?
Qdrant is a purpose-built vector database with native filtering, payload storage, and similarity search. For PathFinder’s use case (semantic search over ~2000 WDK searches and ~500 public strategies), Qdrant provides fast approximate nearest-neighbor search without the overhead of managing a general-purpose database extension (like pgvector).
Two-collection design
The vectorstore uses two collections: catalog
(record types + searches) and example_plans (public strategies). Separating
them allows independent ingestion cycles (catalog changes rarely; example plans
grow over time) and different embedding strategies (catalog entries use search
descriptions; plans use strategy summaries).
Incremental ingestion
The startup ingestion job checks existing point IDs before upserting, avoiding re-embedding unchanged data. This makes startup fast (typically < 5 seconds) while keeping the vectorstore up-to-date with catalog changes.
OpenAI embeddings
PathFinder uses text-embedding-3-small (1536
dimensions) for all embeddings. This model provides good quality at low cost
and is compatible with Qdrant’s cosine similarity search.
Qdrant Store¶
Purpose: Qdrant client wrapper. Manages collections (e.g. catalog, example_plans), upserts points with embeddings, runs similarity search. Used for RAG retrieval when the agent explores the catalog or example plans.
Key methods: Collection operations, search, point upsert
- veupath_chatbot.integrations.vectorstore.qdrant_store.stable_json_dumps(value)[source]¶
- Return type:
- veupath_chatbot.integrations.vectorstore.qdrant_store.context_hash(context)[source]¶
Stable hash for (WDK-wire) contextParamValues.
- Parameters:
context (JSONObject) – Context param dict from WDK wire format.
- Returns:
SHA256 hex digest.
- Return type:
- veupath_chatbot.integrations.vectorstore.qdrant_store.point_uuid(key)[source]¶
Deterministic UUID for a human-readable key.
Qdrant point IDs must be either an integer or UUID.
- class veupath_chatbot.integrations.vectorstore.qdrant_store.QdrantStore(url: str, api_key: str | None = None, timeout_seconds: float = 10.0)[source]¶
Bases:
object- connect()[source]¶
Yield the shared persistent AsyncQdrantClient.
The client is created lazily on first use and reused across all subsequent calls. It is NOT closed when the context manager exits; call
close()during application shutdown instead.- Return type:
AsyncIterator[AsyncQdrantClient]
- async close()[source]¶
Close the shared client and release its connection pool.
Safe to call multiple times or when no client has been created.
- async reset_collections(*names)[source]¶
Delete collections if they exist (used before re-ingestion).
- async ensure_collection(*, name, vector_size, distance='Cosine')[source]¶
Create collection if missing; validate vector size if present.
- async upsert(*, collection, points)[source]¶
Upsert points.
Each point dict: {“id”: str|int, “vector”: list[float], “payload”: dict}
- async get(*, collection, point_id)[source]¶
- Return type:
JSONObject | None
- __init__(url, api_key=None, timeout_seconds=10.0)¶
Bootstrap¶
Purpose: Vectorstore initialization at API startup. Creates collections if missing, runs migrations. Called when RAG is enabled and QDRANT_URL is set.
Key function: Startup entry point
Vectorstore startup/bootstrap helpers.
Collections¶
Purpose: Qdrant collection definitions and schema. Defines the embedding dimensions, distance metrics, and payload indices for each collection (catalog, example_plans).
Qdrant collection name constants.
Keep these stable to avoid accidentally writing to multiple collections.
Dependent Vocab Cache¶
Purpose: Cache for dependent vocabulary lookups. Avoids repeated WDK calls for parameter vocabularies that depend on other parameter values.
- async veupath_chatbot.integrations.vectorstore.dependent_vocab_cache.ensure_dependent_vocab_collection(store)[source]¶
Create the dependent vocab cache collection if missing.
This collection is used for keyed lookup (site/rt/search/param/contextHash). We still store vectors to keep Qdrant schema consistent and allow optional similarity later.
- async veupath_chatbot.integrations.vectorstore.dependent_vocab_cache.get_dependent_vocab_authoritative_cached(*, site_id, record_type, search_name, param_name, context_values, store=None)[source]¶
Return authoritative dependent vocab, cached in Qdrant.
Cache key is the WDK-wire encoded context values (json-string encoding for lists/dicts).
On cache miss, calls WDK /refreshed-dependent-params (via existing client) and stores result.
- Return type:
Ingestion¶
Purpose: Ingest data into the vectorstore. WDK catalog ingestion, public strategy ingestion, and shared utilities.
- async veupath_chatbot.integrations.vectorstore.ingest.wdk_catalog.ingest_site(*, site_id, store, qdrant_client, embedder, concurrency, batch_size, skip_existing)[source]¶
- async veupath_chatbot.integrations.vectorstore.ingest.wdk_catalog.ingest_wdk_catalog(*, sites, reset=False, skip_existing=True, batch_size=64)[source]¶
- async veupath_chatbot.integrations.vectorstore.ingest.public_strategies.ingest_site(*, site_id, store, embedder, llm_model, report_path, max_strategies, concurrency, skip_existing)[source]¶
- async veupath_chatbot.integrations.vectorstore.ingest.public_strategies.ingest_public_strategies(*, sites, reset=False, llm_model='gpt-4.1-nano', report_path=PosixPath('ingest_public_strategies_report.jsonl'), max_strategies_per_site=None, concurrency=None, skip_existing=True)[source]¶
- veupath_chatbot.integrations.vectorstore.ingest.public_strategies_helpers.backoff_delay_seconds(attempt)[source]¶
Exponential backoff delay (capped).
Matches the ingest script’s prior behavior: min(8, 2 ** (attempt - 1)).
- veupath_chatbot.integrations.vectorstore.ingest.public_strategies_helpers.truncate(s, *, max_chars)[source]¶
- Return type:
- veupath_chatbot.integrations.vectorstore.ingest.public_strategies_helpers.iter_compact_steps(step_tree)[source]¶
- Return type:
- veupath_chatbot.integrations.vectorstore.ingest.public_strategies_helpers.embedding_text_for_example(*, name, description, compact)[source]¶
- Return type:
- veupath_chatbot.integrations.vectorstore.ingest.public_strategies_helpers.simplify_strategy_details(details)[source]¶
- Return type:
- veupath_chatbot.integrations.vectorstore.ingest.public_strategies_helpers.full_strategy_payload(details)[source]¶
- Return type:
- veupath_chatbot.integrations.vectorstore.ingest.utils.parse_sites(value)[source]¶
Parse a comma-separated list of site IDs or ‘all’ → None (meaning all).