Elasticsearch Hybrid Search
Combine kNN and keyword search in one Elasticsearch request with SearchType.hybrid.
Code
from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.knowledge.knowledge import Knowledge
from agno.models.openai import OpenAIResponses
from agno.vectordb.elasticsearch import Elasticsearch
from agno.vectordb.search import SearchType
knowledge = Knowledge(
name="Elasticsearch Hybrid Search Recipe Knowledge Base",
description="This is a knowledge base that uses Elasticsearch with hybrid search",
vector_db=Elasticsearch(
index_name="recipe_hybrid",
search_type=SearchType.hybrid,
),
)
knowledge.insert(
name="Thai Recipes",
url="https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf",
metadata={"doc_type": "recipe_book"},
)
agent = Agent(
model=OpenAIResponses(id="gpt-5.6-luna"),
knowledge=knowledge,
search_knowledge=True,
# A db is required for the agent to read its own chat history
db=SqliteDb(db_file="tmp/elasticsearch_hybrid.db"),
read_chat_history=True,
markdown=True,
)
agent.print_response(
"How do I make chicken and galangal in coconut milk soup", stream=True
)
agent.print_response("What was my last question?", stream=True)This example uses the default HybridStrategy.boost, which sums the kNN and keyword scores with weights of 0.7 and 0.3 and works on any license. On a Platinum, Enterprise, or trial cluster, pass hybrid_strategy=HybridStrategy.rrf to use reciprocal rank fusion instead.
Usage
Set up your virtual environment
uv venv --python 3.12
source .venv/bin/activateInstall dependencies
uv pip install -U "elasticsearch[async]" pypdf openai sqlalchemy agnoSet environment variables
export OPENAI_API_KEY=xxxRun Elasticsearch
docker run -d \
--name elasticsearch \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
-e "ES_JAVA_OPTS=-Xms1g -Xmx1g" \
docker.elastic.co/elasticsearch/elasticsearch:9.1.0Run Agent
python elasticsearch_db_hybrid_search.py