Use filter expressions (EQ, AND, OR, NOT) for complex logical filtering of knowledge base searches.
When basic dictionary filters aren’t enough, filter expressions give you powerful logical control over knowledge searches. Use them to combine multiple conditions with AND/OR logic, exclude content with NOT, or perform comparisons like “greater than” and “less than”.For basic filtering with dictionary format, see Search & Retrieval.
from agno.filters import GT, LT# Find recent documentsGT("year", 2020)# Find documents with high priority scoresGT("priority_score", 8.0)# Find documents within a date rangeLT("year", 2025)
from agno.filters import AND, EQ# Find sales documents from North America in 2024AND( EQ("data_type", "sales"), EQ("region", "north_america"), EQ("year", 2024))
from agno.filters import AND, OR, NOT, EQ, IN, GT# Find recent sales data from specific regions, but exclude draftscomplex_filter = AND( EQ("data_type", "sales"), IN("region", ["north_america", "europe"]), GT("year", 2022), NOT(EQ("status", "draft")))# Search for either customer feedback or survey data from the last two yearsfeedback_filter = AND( OR( EQ("data_type", "feedback"), EQ("data_type", "survey") ), GT("year", 2022))agent.print_response( "What do our customers think about our new features?", knowledge_filters=[feedback_filter] # ← List wrapper required)
from agno.filters import AND, EQ, GTasync def progressive_search(agent, query, base_filters=None): """Try broad search first, then narrow if too many results.""" # First attempt: broad search broad_results = await agent.aget_relevant_docs_from_knowledge( query=query, filters=base_filters, # Already a list num_documents=10 ) if len(broad_results) > 8: # Too many results, add more specific filters specific_filter = AND( base_filters[0] if base_filters else EQ("status", "active"), GT("relevance_score", 0.8) ) return await agent.aget_relevant_docs_from_knowledge( query=query, filters=[specific_filter], # ← Wrapped in list num_documents=5 ) return broad_results
Advanced filter expressions (using FilterExpr like EQ(), AND(), etc.) is currently only supported in PGVector.
What happens with unsupported FilterExpr:When using FilterExpr with unsupported vector databases:
You’ll see: WARNING: Filter Expressions are not yet supported in [DatabaseName]. No filters will be applied.
Search proceeds without filters (unfiltered results)
No errors thrown, but filtering is ignored
Workaround: Use dictionary format instead:
Copy
Ask AI
# Works with all vector databasesknowledge_filters=[{"department": "hr", "year": 2024}]# Only works with PgVector currentlyknowledge_filters=[AND(EQ("department", "hr"), EQ("year", 2024))]
Advanced filter expressions (FilterExpr) are not compatible with agentic filtering, where agents dynamically construct filters based on conversation context.For agentic filtering, use dictionary format:
Copy
Ask AI
# Works with agentic filtering (agent decides filters dynamically)knowledge_filters = [{"department": "hr", "document_type": "policy"}]# Does not work with agentic filtering (static, predefined logic)knowledge_filters = [AND(EQ("department", "hr"), EQ("document_type", "policy"))]
When to use each approach:
Approach
Use Case
Example
Dictionary format
Agent dynamically chooses filters based on conversation
User mentions “HR policies” → agent adds {"department": "hr"}
Filter expressions
You need complex, predetermined logic with full control
Always exclude drafts AND filter by multiple regions with OR logic
All the filter expressions shown in this guide can also be used through the Agent OS API. FilterExpressions serialize to JSON and are automatically reconstructed server-side, enabling the same powerful filtering capabilities over REST endpoints.
Copy
Ask AI
import requestsimport jsonfrom agno.filters import EQ, GT, AND# Create filter expressionfilter_expr = AND(EQ("status", "published"), GT("views", 1000))# Serialize to JSONfilter_json = json.dumps(filter_expr.to_dict())# Send through APIresponse = requests.post( "http://localhost:7777/agents/my-agent/runs", data={ "message": "Find popular published articles", "stream": "false", "knowledge_filters": filter_json, })
FilterExpressions use a dictionary format with an "op" key (e.g., {"op": "EQ", "key": "status", "value": "published"}) which tells the API to deserialize them as FilterExpr objects. Regular dict filters without the "op" key continue to work for backward compatibility.
For detailed examples, API-specific patterns, and troubleshooting, see the API Filtering Guide.