Build your first
agent
Run a scope-bound agent on Ezra locally in under 15 minutes — shared memory, belief tracking, federated data. This guide drives it from Google ADK; the same runtime works with LangGraph, LangChain, or any framework via the SDK and REST API. To run it on a cluster, see Deployment.
Prerequisites
Before starting, ensure you have:
- ✓ Python 3.12 +
uv - ✓ Docker — runs Redis (hot tier) + Qdrant (warm tier) locally
- ✓ A MongoDB Atlas cluster (cold tier; the free tier works) and its connection string
- ✓ A Gemini API key from AI Studio (on GKE, Ezra uses keyless Vertex instead — see Deployment)
curl -fsSL https://ezra128.vercel.app/install.sh | bashInstall Ezra
Ezra isn't on PyPI yet — clone the repo and sync with uv (or run the one-command installer, which does this for you):
git clone https://github.com/xavio2495/Ezra.git cd Ezra uv sync --frozen --group agents # google-adk + connectors
curl -fsSL https://ezra128.vercel.app/install.sh | bashStart the Backends
Ezra's hot (Redis) and warm (Qdrant) tiers run as local containers; the repo ships a docker-compose.yml for both. The cold tier is your MongoDB Atlas cluster (external).
docker compose up -d redis qdrant
Configure Ezra
Create a .env file for local development. In production these values are pulled automatically
from Secret Manager.
# Storage (cold = MongoDB Atlas, hot = Redis, warm = Qdrant) EZRA_MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/?retryWrites=true EZRA_REDIS_URL=redis://localhost:6379 EZRA_QDRANT_URL=http://localhost:6333 # Model (local: AI Studio key; on GKE: keyless Vertex) EZRA_LLM_MODEL=gemini/gemini-3.5-flash EZRA_LLM_API_KEY=your-gemini-key EZRA_EMBEDDING_MODEL=gemini/gemini-embedding-001 # API auth EZRA_API_BEARER_TOKEN=change-me
First ADK Agent
Spawn a scope-bound agent and drive it from a Google ADK agent. Ezra registers as an ADK EzraToolset (recall · query · commit · snapshot · rewind · replay · branch), so the
agent calls Ezra through normal tool use.
import asyncio from ezra_core.runtime import Ezra from ezra_core.adk_service import EzraToolset from google.adk.agents import Agent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.genai import types async def main(): # Shared runtime: Redis (hot) + Qdrant (warm) + MongoDB Atlas (cold) + LLM. ezra = Ezra.from_env() graph = await ezra.create_session_graph(session_graph_id="demo-fleet") # A scope-bound agent handle. svc = await ezra.spawn_agent( graph, agent_id="analyst", permission_scope=["market_data", "reports"], ) # Drive it from Google ADK — Ezra is registered as a toolset. agent = Agent( name="analyst", model="gemini-2.5-flash", instruction="Analyse market data; record findings with commit_belief.", tools=[EzraToolset(svc)], ) sessions = InMemorySessionService() await sessions.create_session(app_name="ezra", user_id="team", session_id="s1") runner = Runner(app_name="ezra", agent=agent, session_service=sessions) msg = types.Content(role="user", parts=[types.Part(text="Summarise Q1 revenue and flag anomalies.")]) async for event in runner.run_async(user_id="team", session_id="s1", new_message=msg): if event.is_final_response(): print(event.content.parts[0].text) await ezra.aclose() asyncio.run(main())
Run & Verify
Run the agent locally:
uv run python agent.py
The same runtime is exposed over HTTP by the REST API (uvicorn ezra_core.api.asgi:app). With it running, check health:
curl http://localhost:8080/ezra/health # Expected: { "status": "ok", "service": true, "branching": true, "router": true }
Inspect the belief state the agent committed:
curl -X POST http://localhost:8080/ezra/belief/snapshot \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $EZRA_API_BEARER_TOKEN" \ -d '{"session_graph_id": "demo-fleet", "permission_scope": ["market_data"]}'