Registry-driven LLM routing: build classifier prompts from agent descriptions, validate decisions, and dispatch.
Project description
agent-registry-router
Registry-driven LLM routing: build classifier prompts, validate decisions, and dispatch to the right agent.
Why
When you have multiple AI agents, something needs to decide which one handles each user message. Most teams hardcode if/else chains or build bespoke classifiers. This library gives you a clean, framework-agnostic way to:
- Build classifier prompts from a registry of agent descriptions
- Validate routing decisions with typed errors or optional graceful fallback
- Dispatch to the selected agent with observability hooks
- Benchmark classifier accuracy across LLMs and embedding models
How It Works
graph LR
A[User Message] --> B{Classifier}
B -->|LLM| C[Build Prompt from Registry]
B -->|FAISS| D[Embed & Similarity Search]
C --> E[RouteDecision]
D --> E
E --> F[Validate Against Registry]
F --> G[Dispatch to Agent]
G --> H[Response]
Install
pip install agent-registry-router
With a framework adapter:
pip install "agent-registry-router[pydanticai]" # PydanticAI
pip install "agent-registry-router[openai-agents]" # OpenAI Agents SDK
pip install "agent-registry-router[google-adk]" # Google ADK
pip install "agent-registry-router[faiss]" # FAISS classifier
Quick Start
from agent_registry_router import (
AgentRegistry,
AgentRegistration,
RouteDecision,
build_classifier_system_prompt,
validate_route_decision,
)
# Register your agents
registry = AgentRegistry()
registry.register(AgentRegistration(name="billing", description="Handles billing and payments."))
registry.register(AgentRegistration(name="technical", description="Handles technical support."))
registry.register(AgentRegistration(name="general", description="Handles general inquiries."))
# Build a classifier prompt from the registry
prompt = build_classifier_system_prompt(registry, default_agent="general")
# Validate a routing decision
decision = RouteDecision(agent="billing", confidence=0.9, reasoning="Payment question.")
validated = validate_route_decision(decision, registry=registry, default_agent="general")
Adapters
Framework-specific dispatchers that handle classify → validate → dispatch. Each is opt-in — the core has no framework dependencies.
| Adapter | Install Extra | Dispatcher Class |
|---|---|---|
| PydanticAI | pydanticai |
PydanticAIDispatcher |
| OpenAI Agents SDK | openai-agents |
OpenAIAgentsDispatcher |
| Google ADK | google-adk |
GoogleADKDispatcher |
All adapters are duck-typed (no runtime imports of the framework). Any object matching the protocol works. All support:
route_and_run()— classify, validate, dispatchroute_and_stream()— same flow, streaming output- Pinned agent bypass (skip classifier, dispatch directly)
on_eventobservability hooks
from agent_registry_router.adapters.pydantic_ai import PydanticAIDispatcher
from agent_registry_router.adapters.openai_agents import OpenAIAgentsDispatcher
from agent_registry_router.adapters.google_adk import GoogleADKDispatcher
FAISS Classifier
An alternative to LLM-based classification: embed agent descriptions, find the nearest match by cosine similarity. Near-zero latency, near-zero cost.
from agent_registry_router import FaissClassifier
classifier = FaissClassifier(
registry=registry,
embed_fn=your_embedding_function, # any callable: list[str] -> list[list[float]]
)
decision = classifier.classify("I was charged twice")
Structured Logging
Built-in JSON logging for routing events. One line to set up.
from agent_registry_router import StructuredLogger
dispatcher = PydanticAIDispatcher(
...,
on_event=StructuredLogger(),
)
# Produces: {"ts": "...", "event": "classifier_run_success", "agent": "billing", "confidence": 0.92}
Eval Suite
Benchmarks the classifier prompts this library generates across LLMs and FAISS. Includes fixtures, a runner, and a report generator.
make install-eval
cp .env.example .env # add your API keys
make eval
See evals/README.md for details. Bring your own fixtures to benchmark your own agent registries.
Error Handling
Fail-fast by default with typed exceptions:
InvalidRouteDecision— classifier picked a non-routable agentInvalidFallback— default agent isn't routable or registry is emptyAgentNotFound— validated agent can't be resolved for dispatchRegistryError— invalid names, descriptions, or empty registry
Graceful Fallback
Opt in to graceful degradation instead of hard failures:
validated = validate_route_decision(
decision,
registry=registry,
default_agent="general",
allow_fallback=True, # swap to default instead of raising on invalid agent
confidence_threshold=0.5, # swap to default when confidence is below threshold
)
if validated.did_fallback:
print(f"Fell back: {validated.fallback_reason}")
Design Principles
- Framework-agnostic core: routing logic has no opinion on your agent framework
- Duck-typed adapters: protocols, not imports — any compatible object works
- Fail-fast validation: typed errors, never silent wrong-agent routing
- Deterministic prompts: registration order preserved, routable-only, size-bounded
- Observable:
on_eventhooks +StructuredLoggerfor production monitoring
Development
make install # install dev dependencies
make lint # ruff + mypy
make test # pytest with 85% coverage gate
make format # auto-format
make eval # run classifier benchmarks (requires API keys)
License
Apache-2.0
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_registry_router-0.4.0.tar.gz.
File metadata
- Download URL: agent_registry_router-0.4.0.tar.gz
- Upload date:
- Size: 21.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e246f35bfc1d7fdcfe36924d46865959bc724055d4f436fc221693044bc91a13
|
|
| MD5 |
104bb70f3bda5a344c5943524bfd95b3
|
|
| BLAKE2b-256 |
1f6d3516345957256ac431476fb94e917697e928e170a7a1bb8c4800bc81a859
|
Provenance
The following attestation bundles were made for agent_registry_router-0.4.0.tar.gz:
Publisher:
publish-pypi.yml on agibson22/agent-registry-router
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_registry_router-0.4.0.tar.gz -
Subject digest:
e246f35bfc1d7fdcfe36924d46865959bc724055d4f436fc221693044bc91a13 - Sigstore transparency entry: 1018507432
- Sigstore integration time:
-
Permalink:
agibson22/agent-registry-router@422b3b30aee5267d8c18a22d359af319cc2fe86d -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/agibson22
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@422b3b30aee5267d8c18a22d359af319cc2fe86d -
Trigger Event:
push
-
Statement type:
File details
Details for the file agent_registry_router-0.4.0-py3-none-any.whl.
File metadata
- Download URL: agent_registry_router-0.4.0-py3-none-any.whl
- Upload date:
- Size: 34.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1bb8eeffddba857eec2874a7309e383d27c4164e394048f52fc041cb79cc4c8b
|
|
| MD5 |
1d6e77cf79c1c49b1131eef9475a891d
|
|
| BLAKE2b-256 |
df0ba16e6d2ead2e43a1de9d53509928e83d80368f7c5862c084b482f0500c08
|
Provenance
The following attestation bundles were made for agent_registry_router-0.4.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on agibson22/agent-registry-router
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_registry_router-0.4.0-py3-none-any.whl -
Subject digest:
1bb8eeffddba857eec2874a7309e383d27c4164e394048f52fc041cb79cc4c8b - Sigstore transparency entry: 1018507595
- Sigstore integration time:
-
Permalink:
agibson22/agent-registry-router@422b3b30aee5267d8c18a22d359af319cc2fe86d -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/agibson22
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@422b3b30aee5267d8c18a22d359af319cc2fe86d -
Trigger Event:
push
-
Statement type: