Using Qdrant and LanceDB with Agent Knowledge Bases: Implementation Guide for Agno Agents

You can integrate Qdrant and LanceDB with Agno agents by wrapping them in a knowledge-base abstraction that handles document chunking, OpenAI embedding generation, and vector similarity search.

The Arindam200/awesome-ai-apps repository demonstrates production-ready patterns for connecting large language model agents to vector databases like Qdrant and LanceDB. Both implementations follow a consistent four-stage pipeline—document ingestion, embedding generation, vector storage, and retrieval—that enables agents to query domain-specific knowledge efficiently.

How Vector Databases Power Agent Knowledge Bases

The repository implements a modular architecture where vector stores plug into agents through a standardized interface. The workflow consists of four distinct layers:

  • Knowledge-base abstractionUrlKnowledge or custom PDF loaders hold raw documents and reference a specific vector DB implementation.
  • Embedding generation – OpenAI's text-embedding-3-large or text-embedding-3-small models produce dense vectors for each document chunk.
  • Vector store creation – The database is instantiated (Qdrant via its client constructor, LanceDB via the LanceDb wrapper) and a collection or table is prepared.
  • Upsert and retrieval – Chunks and embeddings are upserted into the store. At query time, the agent requests the most similar vectors, which are fed back to the LLM as contextual knowledge.

Implementing Qdrant for Cloud-Native Vector Storage

The Qdrant implementation in rag_apps/agentic_rag_with_web_search/qdrant_tool.py demonstrates a complete cloud-native RAG pipeline using the qdrant_client library.

Configuration and Client Setup

The implementation reads connection parameters from environment variables and initializes the client. Lines 12–22 load QDRANT_URL, QDRANT_API_KEY, and the collection name from a .env file. Lines 16–20 instantiate the QdrantClient using these credentials:

from qdrant_client import QdrantClient

client = QdrantClient(url=os.getenv("QDRANT_URL"), api_key=os.getenv("QDRANT_API_KEY"))

Document Processing and Embedding Generation

The tool extracts text from PDFs using pdfplumber (lines 24–32) and generates embeddings via OpenAI's API. Lines 34–44 invoke the text-embedding-3-large model to create 3072-dimensional vectors for each text chunk:

response = openai.embeddings.create(
    input=chunks,
    model="text-embedding-3-large"
)

Collection Management and Vector Upsertion

Before storing data, the script ensures the collection exists with the correct parameters. Lines 53–59 delete existing collections if present, then recreate them with VectorParams(size=3072, distance=Distance.COSINE) to match the embedding dimensions. Lines 62–70 convert chunks into PointStruct objects and upsert them via qdrant.upsert:

from qdrant_client.models import PointStruct, VectorParams, Distance

client.recreate_collection(
    collection_name="pdf_knowledge",
    vectors_config=VectorParams(size=3072, distance=Distance.COSINE)
)

points = [PointStruct(id=i, vector=embedding, payload={"text": chunk}) 
          for i, (chunk, embedding) in enumerate(zip(chunks, embeddings))]
client.upsert(collection_name="pdf_knowledge", points=points)

Tool Integration for Agents

Lines 72–84 wrap the Qdrant client in a QdrantVectorSearchTool (from crewai_tools), exposing a search() method that agents can invoke as a function tool. This allows agents to execute semantic searches against the PDF knowledge base during reasoning.

Implementing LanceDB for Embedded Local Storage

The LanceDB implementation in rag_apps/agentic_rag/main.py provides a lightweight, file-based alternative ideal for local development and single-node deployments.

Setting Up the LanceDB Knowledge Base

Line 13 imports LanceDb and SearchType from agno.vectordb.lancedb. Lines 41–48 instantiate UrlKnowledge, configuring it with a LanceDb vector store pointing to a local URI (tmp/lancedb) and a specific table name:

from agno.knowledge.url import UrlKnowledge
from agno.vectordb.lancedb import LanceDb, SearchType

knowledge_base = UrlKnowledge(
    urls=["https://modelcontextprotocol.io/docs/learn/architecture.md"],
    vector_db=LanceDb(
        table_name="mcp-docs-knowledge-base",
        uri="tmp/lancedb",
        search_type=SearchType.vector
    )
)

Embedding and Search Configuration

Line 47 configures the embedding model through OpenAIEmbedder(id="text-embedding-3-small"), generating 1536-dimensional vectors. Line 46 explicitly sets SearchType.vector to enable pure vector similarity lookup using cosine distance by default.

Agent Integration

Lines 60–66 demonstrate how to wire the knowledge base into an Agno Agent. By passing search_knowledge=True, the agent automatically queries the LanceDB collection when it needs contextual information:

from agno.agent import Agent
from agno.models.openai import OpenAIChat

agent = Agent(
    model=OpenAIChat(id="gpt-5-2025-08-07"),
    knowledge=knowledge_base,
    search_knowledge=True,
    markdown=True
)

Because LanceDB operates entirely on local disk, this configuration eliminates network latency and works offline after initial data ingestion.

Architectural Comparison: Qdrant vs. LanceDB

Understanding the operational characteristics of each database helps determine the right choice for your agent architecture.

Deployment Model – Qdrant requires a remote service (cloud-hosted or self-hosted) accessed via URL and API key, while LanceDB operates as an embedded, file-based database under tmp/lancedb requiring no external network calls.

Vector Dimensions – The Qdrant implementation uses 3072-dimensional embeddings from text-embedding-3-large, whereas the LanceDB configuration uses 1536-dimensional vectors from text-embedding-3-small, reducing storage footprint by half.

Distance Metrics – Both implementations use cosine similarity for vector comparison. Qdrant explicitly configures Distance.COSINE in the collection params, while LanceDB defaults to cosine when using SearchType.vector.

Scalability Characteristics – Qdrant handles millions of vectors with native sharding and clustering support for horizontal scaling. LanceDB optimizes for single-node workloads, efficiently managing several million vectors on local disk but without distributed clustering capabilities.

API Surface – Qdrant exposes low-level operations through qdrant_client, requiring manual management of PointStruct objects and collection schemas. LanceDB abstracts these details through the agno.vectordb.lancedb.LanceDb wrapper, which handles schema inference and query building automatically.

Practical Code Examples

The following snippets demonstrate how to use both vector stores in production scenarios.

Loading PDFs into Qdrant

This example processes a PDF document and makes it searchable through a tool interface:

from rag_apps.agentic_rag_with_web_search.qdrant_tool import load_pdf_to_qdrant, get_qdrant_tool

pdf_path = "research_paper.pdf"
load_pdf_to_qdrant(pdf_path)  # Extracts text, embeds with 3072-dim model, upserts to Qdrant

search_tool = get_qdrant_tool()
results = search_tool.search("What methodology was used?", limit=3)

for result in results:
    print(f"Score: {result.score}\nContent: {result.payload['text']}\n")

Building a URL-Based LanceDB Knowledge Base

For web-based knowledge sources, use the UrlKnowledge helper with LanceDB:

from rag_apps.agentic_rag.main import load_knowledge_base
from agno.agent import Agent
from agno.models.openai import OpenAIChat

urls = ["https://docs.python.org/3/tutorial/", "https://docs.python.org/3/library/"]
kb = load_knowledge_base(urls)  # Crawls URLs, chunks content, stores in tmp/lancedb

agent = Agent(
    model=OpenAIChat(id="gpt-5-2025-08-07"),
    knowledge=kb,
    search_knowledge=True,
    instructions=["Answer based on the provided documentation"],
)

response = agent.run("How do I handle exceptions in Python?", stream=False)
print(response.content)

Switching Between Vector Stores at Runtime

You can abstract the store selection to allow runtime configuration without changing agent logic:

def create_knowledge_backend(use_qdrant: bool, source_path: str = None, urls: list = None):
    if use_qdrant:
        from rag_apps.agentic_rag_with_web_search.qdrant_tool import get_qdrant_tool
        # Assumes PDF already loaded via load_pdf_to_qdrant

        return get_qdrant_tool()
    else:
        from rag_apps.agentic_rag.main import load_knowledge_base
        return load_knowledge_base(urls or [])

# Usage

knowledge = create_knowledge_backend(
    use_qdrant=False, 
    urls=["https://example.com/docs"]
)

agent = Agent(
    model=OpenAIChat(id="gpt-5-2025-08-07"),
    knowledge=knowledge,
    search_knowledge=True
)

Summary

  • Qdrant in rag_apps/agentic_rag_with_web_search/qdrant_tool.py provides cloud-native vector storage with explicit collection management, 3072-dimensional embeddings, and tool-based agent integration.
  • LanceDB in rag_apps/agentic_rag/main.py offers embedded local storage with zero network overhead, using 1536-dimensional embeddings and automatic schema handling via Agno's wrapper.
  • Both implementations follow the same four-stage pattern: document loading, embedding generation, vector storage, and similarity retrieval.
  • The choice between stores depends on operational constraints: Qdrant for distributed, high-scale deployments; LanceDB for low-latency, single-node agent applications.
  • Switching between backends requires only changing the knowledge base initialization, as both expose compatible interfaces to the Agno Agent class.

Frequently Asked Questions

What is the primary difference between Qdrant and LanceDB when building agent knowledge bases?

Qdrant operates as a remote service requiring network connectivity, API keys, and explicit collection schema management, making it suitable for multi-agent systems or high-availability production environments. LanceDB functions as an embedded file-based database that stores vectors locally on disk, eliminating network latency and external dependencies ideal for development or edge deployments.

Which embedding model dimensions does the repository use for each vector store?

The Qdrant implementation in rag_apps/agentic_rag_with_web_search/qdrant_tool.py uses OpenAI's text-embedding-3-large model to generate 3072-dimensional vectors with cosine distance metrics. The LanceDB implementation in rag_apps/agentic_rag/main.py uses text-embedding-3-small producing 1536-dimensional vectors, reducing storage requirements while maintaining retrieval accuracy for smaller knowledge bases.

How does the Agno framework handle vector search tool integration?

Agno agents accept a knowledge parameter that implements a standard search interface. When search_knowledge=True is set during agent initialization (as seen in lines 60–66 of rag_apps/agentic_rag/main.py), the agent automatically queries the underlying vector store during reasoning steps. For Qdrant, this requires wrapping the client in a QdrantVectorSearchTool that exposes a callable search method, while LanceDB integration works natively through the UrlKnowledge abstraction.

Can LanceDB handle production-scale workloads compared to Qdrant?

LanceDB efficiently manages several million vectors on a single node with fast local disk I/O, sufficient for many production RAG applications. However, Qdrant offers superior horizontal scalability through built-in sharding and clustering, making it the better choice for multi-tenant systems or knowledge bases exceeding tens of millions of vectors requiring distributed query processing.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →