Custom Retriever
Implement custom retrieval logic for full control over how agents search knowledge.
Custom retrievers let you implement your own search logic instead of using the default knowledge search. This is useful when you need to:
- Query external APIs or databases directly
- Implement custom ranking or filtering
- Reformulate queries before searching
- Combine multiple data sources
1from kern.agent import Agent23def knowledge_retriever(query: str, num_documents: int = 5, **kwargs) -> list[dict]:4 # Your custom retrieval logic here5 return [{"content": "..."}]67agent = Agent(8 knowledge_retriever=knowledge_retriever,9 search_knowledge=True,10)How It Works
When the agent decides to search for information:
- The agent calls your
knowledge_retrieverfunction with the query - Your function retrieves documents however you want
- Results are returned to the agent as a list of dictionaries
- The agent uses the retrieved content to generate a response
Retriever Function Signature
1from typing import Optional2from kern.agent import Agent34def knowledge_retriever(5 query: str,6 agent: Optional[Agent] = None,7 num_documents: int = 5,8 **kwargs9) -> Optional[list[dict]]:10 """11 Args:12 query: The search query from the agent13 agent: The agent instance (optional, for accessing agent state)14 num_documents: Number of documents to retrieve15 **kwargs: Additional arguments passed from the agent1617 Returns:18 List of documents as dictionaries, or None if search fails19 """20 # Your logic here21 return [{"content": "..."}]Example: Direct Vector Database Query
This example bypasses the Knowledge abstraction and queries Qdrant directly:
1from typing import Optional23from kern.agent import Agent4from kern.knowledge.embedder.openai import OpenAIEmbedder5from qdrant_client import QdrantClient67embedder = OpenAIEmbedder(id="text-embedding-3-small")8qdrant_client = QdrantClient(url="http://localhost:6333")910def knowledge_retriever(11 query: str, num_documents: int = 5, **kwargs12) -> Optional[list[dict]]:13 try:14 # Generate embedding for the query15 query_embedding = embedder.get_embedding(query)1617 # Search Qdrant directly18 results = qdrant_client.query_points(19 collection_name="recipes",20 query=query_embedding,21 limit=num_documents,22 )2324 return results.model_dump().get("points")25 except Exception as e:26 print(f"Search error: {e}")27 return None2829agent = Agent(30 knowledge_retriever=knowledge_retriever,31 search_knowledge=True,32)3334agent.print_response("What ingredients do I need for Massaman Gai?")Example: Query Reformulation
Expand or modify queries before searching:
1from kern.knowledge.knowledge import Knowledge23knowledge = Knowledge(vector_db=vector_db)45def knowledge_retriever(query: str, num_documents: int = 5, **kwargs) -> list[dict]:6 # Expand common terms7 expanded_query = query.replace("vacation", "vacation PTO paid time off")8 expanded_query = expanded_query.replace("WFH", "work from home remote")910 # Search with expanded query11 results = knowledge.search(expanded_query, max_results=num_documents)1213 return [doc.to_dict() for doc in results]Example: Multi-Source Retrieval
Combine results from multiple knowledge bases:
1def knowledge_retriever(query: str, num_documents: int = 5, **kwargs) -> list[dict]:2 # Search multiple sources3 policy_results = policy_knowledge.search(query, max_results=3)4 faq_results = faq_knowledge.search(query, max_results=3)56 # Combine and deduplicate7 all_results = []8 seen_ids = set()910 for doc in policy_results + faq_results:11 if doc.id not in seen_ids:12 all_results.append(doc.to_dict())13 seen_ids.add(doc.id)1415 return all_results[:num_documents]When to Use Custom Retrievers
| Use Case | Why Custom Retriever |
|---|---|
| Direct database access | Skip the Knowledge abstraction for performance |
| Query expansion | Add synonyms or related terms before searching |
| Multi-source search | Combine results from multiple knowledge bases |
| External APIs | Search third-party services (Elasticsearch, Algolia, etc.) |
| Custom ranking | Implement domain-specific relevance scoring |
| Conditional logic | Apply different search strategies based on query type |
For most use cases, the built-in Knowledge search is sufficient. Use custom retrievers when you need full control over the retrieval process.