> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agno.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search & Retrieval

> Search a knowledge base directly or give an agent a knowledge-search tool.

Search a knowledge base directly or give an agent a tool that searches it.

```python theme={null}
from agno.knowledge.knowledge import Knowledge
from agno.vectordb.pgvector import PgVector, SearchType

db_url = "postgresql+psycopg://ai:ai@localhost:5532/ai"

knowledge = Knowledge(
    vector_db=PgVector(
        table_name="embeddings",
        db_url=db_url,
        search_type=SearchType.hybrid,
    ),
    max_results=5,
)

results = knowledge.search("What is the return policy?")
```

## How Search Works

`Knowledge.search()` passes the query, result limit, and filters to the configured vector database. The database returns `Document` objects in its ranked order.

Install the PgVector example dependencies and run PostgreSQL with pgvector enabled:

```bash theme={null}
uv pip install -U agno openai pgvector psycopg sqlalchemy
```

## Search Types

| Search Type          | Signal                                         | Test With                                        |
| -------------------- | ---------------------------------------------- | ------------------------------------------------ |
| `SearchType.vector`  | Distance between query and document embeddings | Conceptual queries and varied phrasing           |
| `SearchType.keyword` | Database-specific lexical ranking              | Product names, IDs, and error codes              |
| `SearchType.hybrid`  | Vector and lexical signals                     | Queries that contain concepts and specific terms |

Search algorithms differ by vector database. Evaluate each supported search type with representative queries and expected documents.

## Direct and Agentic Retrieval

Pass `knowledge` to an agent to register the `search_knowledge_base` tool. `search_knowledge=True` is the default.

<Tabs>
  <Tab title="Direct Search">
    ```python theme={null}
    results = knowledge.search(
        "What is the return policy?",
        max_results=5,
    )
    ```
  </Tab>

  <Tab title="Agentic RAG">
    ```python theme={null}
    from agno.agent import Agent

    agent = Agent(
        knowledge=knowledge,
        search_knowledge=True,
    )

    agent.print_response("What is the return policy?")
    ```
  </Tab>
</Tabs>

The model controls when and how often it calls `search_knowledge_base`. Set `add_knowledge_to_context=True` to retrieve knowledge for each string input and add the results to the model context.

## Filtering Results

Filter searches by metadata:

```python theme={null}
from agno.agent import Agent

knowledge.insert(
    path="policies/",
    metadata={"department": "hr", "type": "policy", "year": 2024},
)

results = knowledge.search(
    query="vacation policy",
    filters={"department": "hr", "type": "policy"},
)

agent = Agent(knowledge=knowledge)
agent.print_response(
    "What is the vacation policy?",
    knowledge_filters={"department": "hr"},
)
```

For `OR`, `NOT`, and comparison operators, see [Filtering](/knowledge/concepts/filters/overview).

## Custom Retrieval Logic

Set `knowledge_retriever` to replace the default `Knowledge.retrieve()` path:

```python theme={null}
from typing import Optional

from agno.agent import Agent

def my_retriever(
    query: str,
    num_documents: Optional[int] = None,
    filters=None,
    **kwargs,
):
    expanded_query = query.replace("vacation", "paid time off PTO")
    docs = knowledge.search(
        expanded_query,
        max_results=num_documents,
        filters=filters,
    )
    return [doc.to_dict() for doc in docs]

agent = Agent(knowledge_retriever=my_retriever)
```

See [Custom Retriever](/knowledge/concepts/search-and-retrieval/custom-retriever) for accepted parameters and examples.

## Retrieval Decisions

| Decision          | What to Evaluate                                                    |
| ----------------- | ------------------------------------------------------------------- |
| Chunking strategy | Whether each chunk contains enough context for the target questions |
| Embedder          | Whether relevant queries and documents rank near each other         |
| Search type       | Whether vector, lexical, or combined signals match the query set    |
| Metadata          | Whether available fields support the required filters               |
| Reranker          | Whether reranking changes the top results in useful ways            |

## Test Retrieval

Compare results with a set of queries and expected documents:

```python theme={null}
test_queries = [
    "What is the vacation policy?",
    "How do I submit expenses?",
    "Remote work guidelines",
]

for query in test_queries:
    results = knowledge.search(query)
    print(f"{query} -> {results[0].content[:100]}..." if results else "No results")
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Hybrid Search" icon="magnifying-glass" href="/knowledge/concepts/search-and-retrieval/hybrid-search">
    Configure vector and lexical retrieval signals
  </Card>

  <Card title="Filtering" icon="filter" href="/knowledge/concepts/filters/overview">
    Apply metadata filters to knowledge searches
  </Card>

  <Card title="Vector DB" icon="database" href="/knowledge/concepts/vector-db">
    Compare storage and search integrations
  </Card>

  <Card title="Performance Tips" icon="gauge" href="/knowledge/concepts/performance-tips">
    Tune ingestion and retrieval settings
  </Card>
</CardGroup>
