Introduction
As AI agent systems evolve, the need for modular, scalable, and manageable agent orchestration becomes paramount. In my latest contribution to the Strands Agents SDK (currently under review), I introduce the AgentRegistry
—a feature designed to bring order, flexibility, and power to agent management, mirroring the successful ToolRegistry
pattern.
This blog post is a comprehensive, developer-focused deep dive into the what, why, how, and when of AgentRegistry
. We’ll cover its motivation, design, features, comparisons, and practical usage, with full code examples and implementation details.
PR is currently under review. Stay tuned for updates and documentation examples!
⭐️ My implementation here
Feature Request Issue Created in Official repo
PR Status
Why Do We Need an Agent Registry?
The Problem
- Single-agent workflows are simple—but as soon as you want multiple agents (collaborative, specialized, or per-session), things get messy.
- Manual agent management (lists, dicts, passing references) is error-prone and hard to scale.
- Session-based or multi-user applications (e.g., chatbots, workflow engines) need to keep track of which agents are active, and where.
- Tool specialization and security: Sometimes, you want certain agents to have access to only a subset of tools.
The Solution
A central registry for agents, just like for tools, solves these problems by providing:
- Centralized lookup and management of all agents in your application.
- Session or event loop scoping, so you can group agents per user, conversation, or workflow.
- Specialization and isolation by mapping subsets of tools to specific agents.
- Clean, optional integration—no breaking changes for simple, single-agent use cases.
What is AgentRegistry?
AgentRegistry
is a lightweight, optional utility class that:
- Registers and discovers agents by name (or auto-generated name).
- Optionally groups agents by session or event loop.
- Allows mapping a subset of tools to each agent.
- Integrates cleanly with agent state and event loop patterns.
- Is fully backward compatible and opt-in.
It is inspired by the ToolRegistry
pattern, but for agents.
Feature-by-Feature Breakdown
1. Centralized Registration and Discovery
What:
All agents are registered in a single place. You can easily add, find, or remove agents by name.
Why:
- Simplifies orchestration in multi-agent systems.
- Avoids passing agent references everywhere.
- Makes debugging and monitoring easier.
How:
from strands.agent.agent_registry import AgentRegistry
agent_registry = AgentRegistry()
agent_registry.register_agent(my_agent, name="assistant")
agent = agent_registry.get_agent("assistant")
Comparison:
- Without registry: You manage agents in your own dict/list.
- With registry: The SDK manages it for you, with a clean API.
2. Optional Session-Scoped Management
What:
Group agents by session or event loop. This is perfect for multi-user or multi-conversation systems.
Why:
- Supports scenarios where you have multiple users or conversations, each with their own set of agents.
- Makes it easy to clean up agents when a session ends.
- Prevents cross-session data leakage or confusion.
How:
agent_registry.register_agent(my_agent, name="assistant", session_id="session123")
session_agents = agent_registry.list_agents(session_id="session123")
Comparison:
- Without registry: You must manually track which agents belong to which session.
- With registry: The registry handles session grouping and lookup.
3. Tool Subset Mapping for Specialization
What:
Assign a unique set of tools to each agent, supporting specialization and security.
Why:
- Enables agent specialization (e.g., one agent can only use math tools, another can only use web search).
- Improves security and isolation (agents can’t access tools they shouldn’t).
- Makes it easy to reason about and test agent capabilities.
How:
from strands_tools import calculator, web_search
agent_registry.register_agent(
my_agent,
name="math_agent",
tool_subset=[calculator]
)
agent_registry.register_agent(
another_agent,
name="search_agent",
tool_subset=[web_search]
)
Comparison:
- Without registry: You must ensure each agent is constructed with the right tools and keep track yourself.
- With registry: The registry can enforce and manage tool subsets per agent.
4. Clean, Lightweight, and Optional Integration
What:
- No forced changes to the default single-agent workflow.
- No extra overhead if you don’t need advanced features.
- Separation of concerns: agent state and event loop logic remain untouched.
Why:
- Maintains the separation of concerns: agent logic, state, and event loop are not coupled to the registry.
- Keeps the codebase clean and maintainable.
- Advanced features are available, but only if you opt in.
How:
If you use a single agent:
agent = Agent(...)
# No registry needed!
If you want advanced management:
agent_registry = AgentRegistry()
agent_registry.register_agent(agent, ...)
Comparison:
- Without registry: No change to your workflow.
- With registry: You get advanced management when you need it.
5. Backward Compatible and Developer Friendly
What:
- If you don’t use the registry, everything works as before.
- Advanced users can opt-in for powerful orchestration and management.
Why:
- Ensures backward compatibility.
- Keeps the learning curve low for new users.
- Power users can leverage the registry for complex workflows without affecting others.
How:
Default usage (no registry):
agent = Agent(tools=[...])
result = agent("Hello!")
Advanced usage (with registry):
agent_registry = AgentRegistry()
agent_registry.register_agent(Agent(tools=[...]), name="assistant", session_id="user1")
Intrinsic Details: Naming, Auto-Generation, and Retrieval
How Are Agent Names Handled?
- By default, agents in Strands Agents SDK do not have a name.
- When registering with the registry, you can provide a name, or let the registry auto-generate one.
- The registry uses:
agent_name = name or getattr(agent, 'name', None) or f"agent_{uuid4().hex[:8]}"
- If you provide a name, it uses that.
- If the agent has a
name
attribute, it uses that. - Otherwise, it generates a unique name like
"agent_1a2b3c4d"
.
Best Practice:
- Provide a name when registering for clarity.
- If you don’t, capture the return value of
register_agent()
to refer to the agent later.
Example:
auto_name = agent_registry.register_agent(agent)
retrieved_agent = agent_registry.get_agent(auto_name)
Full Example: Multi-Agent, Session-Scoped Workflow
Here’s a full-featured example that demonstrates all the core functionalities of AgentRegistry in a multi-agent orchestration scenario:
This example demonstrates:
- Registering agents with and without tool subsets (showing both patterns).
- Listing all registered agents at any time.
- Accessing the tool registry for each agent, showing which tools are available (either via subset or the agent’s own list).
- Wrapping agents as tools for orchestration, so the orchestrator can delegate tasks.
- Unregistering a specific agent and verifying the change.
- Clearing the registry and confirming all agents are removed.
from strands import Agent, tool
from strands_tools import calculator, web_search
from strands.agent.agent_registry import AgentRegistry
# 1. Define system prompts for each specialized agent
RESEARCH_PROMPT = "You are a research assistant. Provide factual, well-sourced answers."
MATH_PROMPT = "You are a math expert. Solve math problems accurately."
SEARCH_PROMPT = "You are a web search specialist. Find up-to-date information online."
# 2. Create specialized agents
research_agent = Agent(system_prompt=RESEARCH_PROMPT, tools=[web_search])
math_agent = Agent(system_prompt=MATH_PROMPT, tools=[calculator])
search_agent = Agent(system_prompt=SEARCH_PROMPT, tools=[web_search, calculator]) # Multi-tool agent
# 3. Register agents in the AgentRegistry, with and without tool subsets
agent_registry = AgentRegistry()
agent_registry.register_agent(research_agent, name="research_agent", tool_subset=[web_search])
agent_registry.register_agent(math_agent, name="math_agent", tool_subset=[calculator])
agent_registry.register_agent(search_agent, name="search_agent") # No subset, uses all provided tools
# 4. List all registered agents
print("Registered agents:", agent_registry.list_agents())
# 5. Access the tool registry for a specific agent
for agent_name in agent_registry.list_agents():
tool_registry = agent_registry.get_tool_registry_for_agent(agent_name)
if tool_registry:
print(f"Tools for {agent_name}: {tool_registry.tool_names}")
else:
print(f"{agent_name} uses its own tool list (no registry subset)")
# 6. Wrap agents as tools for orchestration
@tool
def research_tool(query: str) -> str:
"""Delegate research queries to the research agent."""
agent = agent_registry.get_agent("research_agent")
return str(agent(query))
@tool
def math_tool(query: str) -> str:
"""Delegate math queries to the math agent."""
agent = agent_registry.get_agent("math_agent")
return str(agent(query))
@tool
def search_tool(query: str) -> str:
"""Delegate search queries to the search agent."""
agent = agent_registry.get_agent("search_agent")
return str(agent(query))
# 7. Orchestrator agent with access to agent-tools
ORCHESTRATOR_PROMPT = """
You are an orchestrator. Route queries to the correct specialized agent:
- Use research_tool for research questions
- Use math_tool for math problems
- Use search_tool for web searches
- Answer directly if no tool is needed
"""
orchestrator = Agent(
system_prompt=ORCHESTRATOR_PROMPT,
tools=[research_tool, math_tool, search_tool]
)
# 8. Example usage
print("\n=== Orchestrator handles a research query ===")
print(orchestrator("What are the latest advancements in quantum computing?"))
print("\n=== Orchestrator handles a math query ===")
print(orchestrator("What is the square root of 2025?"))
print("\n=== Orchestrator handles a web search query ===")
print(orchestrator("Find the current weather in Tokyo."))
# 9. Unregister a particular agent
agent_registry.unregister_agent("math_agent")
print("\nAfter unregistering math_agent, registered agents:", agent_registry.list_agents())
# 10. Clear the registry
agent_registry.clear()
print("After clearing, registered agents:", agent_registry.list_agents())
When Should You Use AgentRegistry?
Single-agent, simple scripts:
You don’t need it! Just useAgent
as before.Multi-agent, multi-session, or advanced orchestration:
AgentRegistry is your friend. It keeps your code clean, modular, and scalable.
Developer Insights
- Extensible: You can add metadata, hooks, or analytics to the registry in the future.
- Safe: No agent state is stored in the registry—each agent manages its own state.
- Flexible: You can use the registry for global, per-session, or even per-task agent management.
- Auto-naming: If you don’t provide a name, the registry generates a unique one and returns it, so you can always refer to your agent.
Comparison Table
Feature | Without AgentRegistry | With AgentRegistry |
---|---|---|
Agent lookup | Manual dict/list | Centralized, by name/session |
Session grouping | Manual, error-prone | Built-in, easy |
Tool specialization | Manual, per-agent | Enforced, per-agent via registry |
Naming/uniqueness | Up to you | Auto-generated or user-provided |
Backward compatibility | N/A | 100% preserved |
Overhead for simple use | None | None (if not used) |
Extensibility | Manual | Registry pattern, easy to extend |
Conclusion
The new AgentRegistry
brings the Strands Agents SDK one step closer to being a truly modular, production-ready platform for building sophisticated AI agent systems. It’s developer-friendly, backward compatible, and powerful—and it’s available as an opt-in utility for those who need it.
Try it out, give feedback, and help shape the future of agent orchestration in Strands-agents!
Top comments (0)