Skip to main content

Open-source, database-agnostic query agent that translates natural language into vector database operations

Project description

OpenQueryAgent

Open-source, database-agnostic query agent for vector databases.

Translate natural language into precise vector database operations across multiple backends โ€” with a single unified API.

Python 3.11+ License: Apache 2.0 Type Checked: mypy Code Style: ruff Tests: 407 passing


โœจ Features

  • ๐Ÿ”Œ 8 Vector Database Adapters โ€” Qdrant, Milvus, pgvector, Weaviate, Pinecone, Chroma, Elasticsearch, AWS S3 Vectors
  • ๐Ÿง  LLM-Powered Query Planning โ€” Decomposes complex queries into optimized sub-queries with automatic fallback
  • ๐Ÿ” Universal Filter DSL โ€” Write filters once, compile to any backend's native format
  • ๐Ÿ“ก Streaming Responses โ€” Token-by-token answer generation with citation extraction
  • ๐Ÿ”„ Multi-DB Federation โ€” Query across multiple databases in a single request
  • ๐Ÿ—๏ธ Pluggable Pipeline โ€” Swap any component: planner, reranker, synthesizer, LLM, embedding model
  • ๐Ÿ’ฌ Conversation Memory โ€” Multi-turn dialogue with automatic token budget management
  • ๐Ÿ”’ Security Hardened โ€” Input validation, SQL injection prevention, credential redaction, prompt injection protection
  • โœ… Fully Typed โ€” Strict mypy with py.typed marker for downstream consumers

๐Ÿš€ Quick Start

Installation

# Core + Qdrant adapter + OpenAI LLM & embeddings
pip install openqueryagent[qdrant,openai]

# Or with Milvus
pip install openqueryagent[milvus,openai]

# Or with pgvector
pip install openqueryagent[pgvector,openai]

# Or with Elasticsearch
pip install openqueryagent[elasticsearch,openai]

# Everything
pip install openqueryagent[all]

Basic Usage

import asyncio
from openqueryagent.core.agent import QueryAgent
from openqueryagent.adapters.qdrant import QdrantAdapter
from openqueryagent.llm.openai import OpenAIProvider
from openqueryagent.embeddings.openai import OpenAIEmbedding

async def main():
    # Create components
    adapter = QdrantAdapter(url="localhost", port=6333)
    await adapter.connect()

    llm = OpenAIProvider(model="gpt-4o-mini")
    embedding = OpenAIEmbedding(model="text-embedding-3-small")

    # Create agent
    agent = QueryAgent(
        adapters={"qdrant": adapter},
        llm=llm,
        embedding=embedding,
    )
    await agent.initialize()

    # Ask a question โ€” gets synthesized answer with citations
    response = await agent.ask("What are the best products under $50?")
    print(response.answer)
    for citation in response.citations:
        print(f"  [{citation.document_id}]: {citation.text_snippet}")

    # Search โ€” returns ranked documents without synthesis
    results = await agent.search("machine learning papers", limit=5)
    for doc in results.documents:
        print(f"  {doc.document.id}: {doc.score:.3f}")

asyncio.run(main())

Without LLM (Zero-Cost Search)

from openqueryagent.core.agent import QueryAgent
from openqueryagent.adapters.qdrant import QdrantAdapter
from openqueryagent.core.planner import SimpleQueryPlanner

agent = QueryAgent(
    adapters={"qdrant": adapter},
    planner=SimpleQueryPlanner(default_collection="products"),
)
# Uses SimpleQueryPlanner โ€” no LLM calls, just vector search
results = await agent.search("wireless headphones")

๐Ÿ—๏ธ Architecture

User Query
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                  QueryAgent                           โ”‚
โ”‚                                                       โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”            โ”‚
โ”‚  โ”‚  Schema   โ”‚โ”€โ”€โ–ถโ”‚ Query  โ”‚โ”€โ”€โ–ถโ”‚  Router  โ”‚            โ”‚
โ”‚  โ”‚ Inspector โ”‚   โ”‚Planner โ”‚   โ”‚          โ”‚            โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜            โ”‚
โ”‚                                    โ”‚                  โ”‚
โ”‚                               โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”            โ”‚
โ”‚                               โ”‚ Executor โ”‚ (parallel)  โ”‚
โ”‚                               โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜            โ”‚
โ”‚                                    โ”‚                  โ”‚
โ”‚                               โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”            โ”‚
โ”‚                               โ”‚ Reranker โ”‚ (RRF)      โ”‚
โ”‚                               โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜            โ”‚
โ”‚                                    โ”‚                  โ”‚
โ”‚                               โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚
โ”‚                               โ”‚Synthesizerโ”‚ (LLM)     โ”‚
โ”‚                               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
AskResponse { answer, citations, query_plan }

Pipeline

Stage Component Purpose
Plan LLMQueryPlanner / SimpleQueryPlanner / RuleBasedPlanner Decompose query into sub-queries with intent detection
Route QueryRouter Resolve collections, compile filters to native format
Execute QueryExecutor Parallel execution with timeouts and dependency ordering
Rerank RRFReranker / NoopReranker Reciprocal Rank Fusion for multi-source results
Synthesize LLMSynthesizer Generate answer with [N] citation extraction

๐Ÿ”Œ Supported Backends

Vector Databases

Backend Extra Search Types Aggregation
Qdrant openqueryagent[qdrant] Vector, Keyword, Hybrid (prefetch) Client-side scroll
Milvus openqueryagent[milvus] Vector, Keyword, Hybrid Client-side query
pgvector openqueryagent[pgvector] Vector (โŸบ), Keyword (tsquery), Hybrid (CTE RRF) Native SQL
Weaviate openqueryagent[weaviate] Vector, Keyword (BM25), Hybrid Client-side
Pinecone openqueryagent[pinecone] Vector, Keyword, Hybrid Client-side
Chroma openqueryagent[chroma] Vector, Keyword Client-side
Elasticsearch openqueryagent[elasticsearch] Vector (kNN), Keyword (BM25), Hybrid Native agg framework
AWS S3 Vectors openqueryagent[s3vectors] Vector Client-side

LLM Providers

Provider Extra Features
OpenAI openqueryagent[openai] GPT-4o, JSON mode, streaming, Azure support
Anthropic openqueryagent[anthropic] Claude, JSON extraction, streaming
Ollama Built-in Local models (Llama 3, Mistral, Mixtral), streaming
AWS Bedrock openqueryagent[bedrock] Claude, Titan, Llama via Bedrock

Embedding Providers

Provider Models
OpenAI text-embedding-3-small, text-embedding-3-large, text-embedding-ada-002
Cohere embed-english-v3.0, embed-multilingual-v3.0
HuggingFace Any sentence-transformers model
AWS Bedrock Titan Embed, Cohere Embed via Bedrock

๐Ÿ” Universal Filter DSL

Write filters once, compile to any backend:

from openqueryagent.core.filters import F

# Build a filter
f = (F.price < 50) & (F.category == "electronics") & ~(F.status == "discontinued")

# The adapter's FilterCompiler translates to native format automatically
results = await agent.search("wireless headphones", filters=f)

Supported Operators

Category Operators
Comparison ==, !=, <, <=, >, >=
Collection in_, not_in, between
Text contains, not_contains, starts_with, ends_with, regex
Geo geo_radius
Existence exists
Boolean & (AND), `

๐Ÿ’ฌ Conversation Memory

Multi-turn dialogue with automatic context management:

response1 = await agent.ask("What products do you have in electronics?")
# Agent remembers context
response2 = await agent.ask("Which of those are under $30?")
# Uses previous context for follow-up

# Access memory directly
agent.memory.get_messages()
agent.memory.clear()

๐Ÿ› ๏ธ Development

Setup

git clone https://github.com/thirukguru/openqueryagent.git
cd openqueryagent
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev,qdrant,milvus,pgvector,openai,anthropic]"

Quality Checks

# Linting
ruff check openqueryagent/ tests/

# Type checking (strict)
mypy openqueryagent/

# Tests (337 passing)
pytest tests/ -v

Project Structure

openqueryagent/
โ”œโ”€โ”€ core/
โ”‚   โ”œโ”€โ”€ agent.py            # QueryAgent โ€” main orchestrator
โ”‚   โ”œโ”€โ”€ planner.py          # LLM + Simple query planners
โ”‚   โ”œโ”€โ”€ rule_planner.py     # Rule-based query planner
โ”‚   โ”œโ”€โ”€ router.py           # Collection resolution + filter compilation
โ”‚   โ”œโ”€โ”€ executor.py         # Parallel execution with timeouts + circuit breakers
โ”‚   โ”œโ”€โ”€ reranker.py         # NoopReranker + RRFReranker
โ”‚   โ”œโ”€โ”€ synthesizer.py      # LLM answer generation with citations
โ”‚   โ”œโ”€โ”€ memory.py           # Token-budgeted conversation history
โ”‚   โ”œโ”€โ”€ schema.py           # Schema inspector + caching
โ”‚   โ”œโ”€โ”€ filters.py          # Universal filter DSL (F proxy)
โ”‚   โ”œโ”€โ”€ types.py            # Pydantic v2 models + enums
โ”‚   โ”œโ”€โ”€ config.py           # Agent/executor configuration
โ”‚   โ”œโ”€โ”€ exceptions.py       # Error hierarchy
โ”‚   โ”œโ”€โ”€ circuit_breaker.py  # Per-adapter circuit breaker (closed โ†’ open โ†’ half-open)
โ”‚   โ””โ”€โ”€ plugins.py          # Entry-point based plugin discovery
โ”œโ”€โ”€ adapters/
โ”‚   โ”œโ”€โ”€ base.py             # VectorStoreAdapter protocol
โ”‚   โ”œโ”€โ”€ qdrant.py           # Qdrant adapter
โ”‚   โ”œโ”€โ”€ milvus.py           # Milvus adapter
โ”‚   โ”œโ”€โ”€ pgvector.py         # pgvector adapter
โ”‚   โ”œโ”€โ”€ weaviate.py         # Weaviate adapter
โ”‚   โ”œโ”€โ”€ pinecone.py         # Pinecone adapter
โ”‚   โ”œโ”€โ”€ chroma.py           # Chroma adapter
โ”‚   โ”œโ”€โ”€ elasticsearch.py    # Elasticsearch adapter
โ”‚   โ”œโ”€โ”€ s3vectors.py        # AWS S3 Vectors adapter
โ”‚   โ””โ”€โ”€ *_filters.py        # Per-adapter filter compilers
โ”œโ”€โ”€ llm/
โ”‚   โ”œโ”€โ”€ base.py             # LLMProvider protocol
โ”‚   โ”œโ”€โ”€ openai.py           # OpenAI provider
โ”‚   โ”œโ”€โ”€ anthropic.py        # Anthropic provider
โ”‚   โ”œโ”€โ”€ ollama.py           # Ollama provider (local)
โ”‚   โ””โ”€โ”€ bedrock.py          # AWS Bedrock provider
โ”œโ”€โ”€ embeddings/
โ”‚   โ”œโ”€โ”€ base.py             # EmbeddingProvider protocol
โ”‚   โ”œโ”€โ”€ openai.py           # OpenAI embeddings
โ”‚   โ”œโ”€โ”€ cohere.py           # Cohere embeddings
โ”‚   โ”œโ”€โ”€ huggingface.py      # HuggingFace embeddings
โ”‚   โ””โ”€โ”€ bedrock.py          # AWS Bedrock embeddings
โ”œโ”€โ”€ server/
โ”‚   โ”œโ”€โ”€ api.py              # FastAPI REST server + /v1/metrics endpoint
โ”‚   โ”œโ”€โ”€ mcp_server.py       # MCP stdio server for LLM tool-use
โ”‚   โ”œโ”€โ”€ middleware.py       # Auth, rate limiting, request ID, correlation IDs
โ”‚   โ”œโ”€โ”€ models.py           # Request/response Pydantic models
โ”‚   โ”œโ”€โ”€ config.py           # Server configuration
โ”‚   โ”œโ”€โ”€ dependencies.py     # FastAPI dependency injection
โ”‚   โ””โ”€โ”€ websocket.py        # WebSocket streaming handler
โ”œโ”€โ”€ observability/
โ”‚   โ”œโ”€โ”€ tracing.py          # OpenTelemetry span instrumentation
โ”‚   โ””โ”€โ”€ metrics.py          # Prometheus counters, histograms, gauges
โ””โ”€โ”€ py.typed                # PEP 561 marker

๐Ÿ“‹ Roadmap

Phase 3 โ€” Server Layer (Remaining)

####Sprint 9: gRPC Server

  • .proto definitions for all service methods (Ask, Search, Aggregate)
  • Generate Python stubs with grpcio-tools
  • Implement gRPC server in server/grpc/
  • Server-streaming RPC for AskStream

TypeScript & Go SDKs

  • TypeScript SDK (sdks/typescript/)
    • OpenQueryAgent client class with ask(), search(), aggregate()
    • askStream() with WebSocket/SSE
    • Filter builder, full TypeScript types
    • Published to npm
  • Go SDK (sdks/go/)
    • gRPC client with Ask(), Search(), Aggregate()
    • AskStream() with gRPC streaming
    • Published as Go module

Phase 5 โ€” Enterprise

Multi-Tenancy

  • Namespace isolation per tenant
  • Per-tenant configuration and rate limits
  • Tenant-scoped API keys

RBAC & Audit

  • Role-based collection access control
  • API key scoping (read-only, admin, per-collection)
  • Audit logging and usage analytics

๐Ÿ“„ License

Apache 2.0 โ€” see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openqueryagent-1.0.1.tar.gz (100.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openqueryagent-1.0.1-py3-none-any.whl (111.0 kB view details)

Uploaded Python 3

File details

Details for the file openqueryagent-1.0.1.tar.gz.

File metadata

  • Download URL: openqueryagent-1.0.1.tar.gz
  • Upload date:
  • Size: 100.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for openqueryagent-1.0.1.tar.gz
Algorithm Hash digest
SHA256 42c44981218c47ddb3b4d3abdbe62a386428cdf1e9b5d09080eab3a5c106b620
MD5 6f6ef8a84eee68ad0d5146e69c75ec51
BLAKE2b-256 6c4f473f94c9bf40870728c5c5af72fdaed19a46cc5562470969a2c6d16b31a2

See more details on using hashes here.

File details

Details for the file openqueryagent-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: openqueryagent-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 111.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for openqueryagent-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0cadc43175546b9e9bf99968365d2c97d11543e3f872aea35a9b41ef2614c078
MD5 1897566ad7f98ec5014aa7e9b3044685
BLAKE2b-256 99f71d10654af6c8ecc1e0c1eed242d564ac0744e27e21fb9113f4c94150c4c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page