arun or a FastAPI handler — knowledge search never blocks the event loop.
Quick Start
1
Agent under arun
An agent that searches knowledge inside
arun() no longer blocks the event loop — concurrent requests stay responsive.2
Orchestrator (library authors)
Call
aretrieve_knowledge / aadd_knowledge directly when you build on the persistence layer.3
Streaming + knowledge
Stream tokens from an agent that also retrieves knowledge — the retrieved context is normalized the same way as the sync path.
How It Works
aretrieve_knowledge and aadd_knowledge inspect the underlying store and pick the right path automatically.
Every real vector backend issues a network round trip on
search. From an async agent, the sync retrieve_knowledge would block the loop for the whole round trip and serialise every other concurrent request. The a* methods align RAG with the existing async conversation hooks (aon_message, aon_agent_start).
Agent RAG lookups are offloaded automatically. Inside
Agent._achat_impl, the built-in knowledge.search(...) call runs via asyncio.to_thread(...), so it is safe under concurrent task execution. Multiple async agents — or an asyncio.gather(...) of tasks — that share one knowledge base run in parallel; no lookup blocks the loop, even when the underlying store is synchronous. See Async Safety.When to Use a* vs Sync
Use the a* variants whenever an event loop is running. In a plain sync script, the existing retrieve_knowledge / add_knowledge methods are the right choice.
Configuration Options
aretrieve_knowledge(query_embedding, collection="default", limit=5, filters=None)
aadd_knowledge(documents, collection="default")
Best Practices
Use a* variants inside arun() or a web handler
Use a* variants inside arun() or a web handler
Any code path that already runs on an event loop —
agent.arun(...), a FastAPI route, a background async task — should call aretrieve_knowledge / aadd_knowledge. The sync methods would block the loop for the full network round trip.Sync stores are still safe
Sync stores are still safe
A sync knowledge store plugged into an async agent is not rejected — it is offloaded to a thread via
asyncio.to_thread(...). You do not need a native async backend to benefit.Concurrency is real — verify it
Concurrency is real — verify it
Two concurrent RAG calls against a store with a 0.3 s round trip finish in ~0.3 s, not 0.6 s. Fire two
aretrieve_knowledge calls with asyncio.gather and confirm they overlap.Async, streaming, and sync now use the same normalization
Async, streaming, and sync now use the same normalization
Since PR #4887,
.chat(), .achat(), .start_stream(), and .astart(..., stream=True) all route knowledge retrieval through _get_knowledge_context(). The SearchResult dataclass, legacy dict, and plain list shapes are handled in one place — no per-path guardrails needed. Switch an agent between sync, async, and streaming freely; knowledge injection behaves identically.Related
Async Conversation Store
Sibling async hooks (
aon_message, aon_agent_start).Persistence Overview
Where knowledge stores are configured.
RAG Module
The full RAG pipeline.
Search Results
The
SearchResult shape and the “check .results” pitfall this fix protects against.Streaming
Stream tokens while injecting knowledge context.

