Agent Discovery
Discover available agent capabilities and schemas at runtime for dynamic orchestration
Agent Discovery
Discover available agent capabilities and schemas at runtime for dynamic orchestration
Discover available agents, reasoners, and skills at runtime with their input/output schemas. Perfect for building AI orchestrators that select tools dynamically, generate LLM tool catalogs, or implement intelligent routing based on available capabilities.
Quick Start
Discover all available capabilities:
curl http://localhost:8080/api/v1/discovery/capabilitiesResponse:
{
"discovered_at": "2025-11-23T10:30:00Z",
"total_agents": 5,
"total_reasoners": 23,
"total_skills": 45,
"capabilities": [
{
"agent_id": "research-agent",
"base_url": "http://research-agent:8080",
"version": "2.3.1",
"health_status": "active",
"reasoners": [
{
"id": "deep_research",
"description": "Performs comprehensive research using multiple sources",
"tags": ["research", "ml", "synthesis"],
"invocation_target": "research-agent.deep_research"
}
],
"skills": [
{
"id": "web_search",
"description": "Search the web using multiple engines",
"tags": ["web", "search"],
"invocation_target": "research-agent.skill:web_search"
}
]
}
]
}Endpoint
Wildcard Pattern Matching
Use wildcards to filter capabilities flexibly:
*abc*- Contains "abc" anywhereabc*- Starts with "abc"*abc- Ends with "abc"abc- Exact match (no wildcards)
Examples:
# Find all research-related reasoners
curl 'http://localhost:8080/api/v1/discovery/capabilities?reasoner=*research*'
# Find reasoners starting with "deep_"
curl 'http://localhost:8080/api/v1/discovery/capabilities?reasoner=deep_*'
# Find ML-related capabilities
curl 'http://localhost:8080/api/v1/discovery/capabilities?tags=ml*'
# Find web skills
curl 'http://localhost:8080/api/v1/discovery/capabilities?skill=web_*'Response Formats
JSON Format (Default)
Standard JSON response with full capability details:
curl 'http://localhost:8080/api/v1/discovery/capabilities?format=json'XML Format
XML format optimized for LLM context injection:
curl 'http://localhost:8080/api/v1/discovery/capabilities?format=xml'<?xml version="1.0" encoding="UTF-8"?>
<discovery discovered_at="2025-11-23T10:30:00Z">
<summary total_agents="5" total_reasoners="23" total_skills="45"/>
<capabilities>
<agent id="research-agent" base_url="http://research-agent:8080">
<reasoners>
<reasoner id="deep_research" target="research-agent.deep_research">
<description>Comprehensive research</description>
<tags>
<tag>research</tag>
<tag>ml</tag>
</tags>
</reasoner>
</reasoners>
</agent>
</capabilities>
</discovery>Compact Format
Minimal response for bandwidth-constrained scenarios:
curl 'http://localhost:8080/api/v1/discovery/capabilities?format=compact'{
"discovered_at": "2025-11-23T10:30:00Z",
"reasoners": [
{
"id": "deep_research",
"agent_id": "research-agent",
"target": "research-agent.deep_research",
"tags": ["research", "ml"]
}
],
"skills": [
{
"id": "web_search",
"agent_id": "research-agent",
"target": "research-agent.skill:web_search",
"tags": ["web", "search"]
}
]
}Examples
# Discover all capabilities with schemascurl 'http://localhost:8080/api/v1/discovery/capabilities?include_input_schema=true&include_output_schema=true'# Find research capabilities with ML tagscurl 'http://localhost:8080/api/v1/discovery/capabilities?reasoner=*research*&tags=ml,nlp'# Get compact format for specific agentcurl 'http://localhost:8080/api/v1/discovery/capabilities?agent=research-agent&format=compact'# XML format for LLM contextcurl 'http://localhost:8080/api/v1/discovery/capabilities?format=xml&include_descriptions=true'Schema Discovery
Include input and output schemas to validate requests at runtime:
curl 'http://localhost:8080/api/v1/discovery/capabilities?agent=research-agent&include_input_schema=true&include_output_schema=true'Response with schemas:
{
"capabilities": [
{
"agent_id": "research-agent",
"reasoners": [
{
"id": "deep_research",
"description": "Comprehensive research using multiple sources",
"tags": ["research", "ml"],
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Research query or topic"
},
"depth": {
"type": "integer",
"minimum": 1,
"maximum": 5,
"default": 3,
"description": "Research depth level"
}
},
"required": ["query"]
},
"output_schema": {
"type": "object",
"properties": {
"findings": {
"type": "array",
"items": {"type": "object"}
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
}
},
"invocation_target": "research-agent.deep_research"
}
]
}
]
}Use Cases
AI Orchestrator Pattern
Build AI systems that select tools at runtime:
// Step 1: Discover available tools
const tools = await fetch(
'http://localhost:8080/api/v1/discovery/capabilities?include_input_schema=true'
).then(r => r.json());
// Step 2: Let AI select appropriate tool
const selectedTool = await aiModel.selectTool(userQuery, tools);
// Step 3: Execute selected tool
const result = await fetch(
`http://localhost:8080/api/v1/execute/${selectedTool.invocation_target}`,
{
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({input: userInput})
}
).then(r => r.json());Dynamic Tool Registry for LLMs
Generate LLM function definitions from discovered capabilities:
import requests
# Discover all capabilities with schemas
capabilities = requests.get(
'http://localhost:8080/api/v1/discovery/capabilities',
params={
'include_input_schema': 'true',
'include_descriptions': 'true'
}
).json()
# Convert to OpenAI function definitions
openai_tools = []
for agent_cap in capabilities['capabilities']:
for reasoner in agent_cap['reasoners']:
openai_tools.append({
'type': 'function',
'function': {
'name': reasoner['id'],
'description': reasoner['description'],
'parameters': reasoner['input_schema']
}
})
# Use with OpenAI
response = openai.chat.completions.create(
model='gpt-4',
messages=[{'role': 'user', 'content': user_query}],
tools=openai_tools
)Health-Based Routing
Route to healthy agents only:
curl 'http://localhost:8080/api/v1/discovery/capabilities?health_status=active&tags=search'Response Fields
| Field | Type | Description |
|---|---|---|
discovered_at | string | Discovery timestamp (ISO 8601) |
total_agents | number | Total number of agents discovered |
total_reasoners | number | Total number of reasoners across all agents |
total_skills | number | Total number of skills across all agents |
pagination | object | Pagination metadata (limit, offset, has_more) |
capabilities | array | Array of agent capability objects |
Agent Capability Object
| Field | Type | Description |
|---|---|---|
agent_id | string | Unique agent identifier |
base_url | string | Agent's HTTP endpoint |
version | string | Agent version |
health_status | string | Health status: active, inactive, degraded, unknown |
deployment_type | string | Deployment type: long_running, serverless |
last_heartbeat | string | Last heartbeat timestamp |
reasoners | array | Array of reasoner capability objects |
skills | array | Array of skill capability objects |
Reasoner/Skill Capability Object
| Field | Type | Description |
|---|---|---|
id | string | Reasoner/skill identifier |
description | string | Human-readable description (if include_descriptions=true) |
tags | array | Array of tag strings |
input_schema | object | JSON Schema for input (if include_input_schema=true) |
output_schema | object | JSON Schema for output (if include_output_schema=true) |
examples | array | Usage examples (if include_examples=true) |
invocation_target | string | Target string for execution (format: agent_id.function_name) |
Best Practices
Cache Discovery Results
Discovery results change infrequently—cache them:
let capabilitiesCache = null;
let cacheTime = null;
const CACHE_TTL = 30000; // 30 seconds
async function getCapabilities() {
const now = Date.now();
if (capabilitiesCache && (now - cacheTime) < CACHE_TTL) {
return capabilitiesCache;
}
const response = await fetch(
'http://localhost:8080/api/v1/discovery/capabilities'
);
capabilitiesCache = await response.json();
cacheTime = now;
return capabilitiesCache;
}Use Compact Format for Bandwidth
Use compact format when you only need targets and tags:
curl 'http://localhost:8080/api/v1/discovery/capabilities?format=compact'Filter Aggressively
Request only what you need and combine filters in a single request:
# Bad: Retrieve everything
curl 'http://localhost:8080/api/v1/discovery/capabilities'
# Bad: Multiple separate requests
curl 'http://localhost:8080/api/v1/discovery/capabilities?tags=research'
curl 'http://localhost:8080/api/v1/discovery/capabilities?health_status=active'
# Good: Combine filters in one request (efficient server-side evaluation)
curl 'http://localhost:8080/api/v1/discovery/capabilities?tags=research&health_status=active&include_input_schema=true'Use XML for LLM System Prompts
XML format is easier for LLMs to parse in system prompts:
xml_capabilities = requests.get(
'http://localhost:8080/api/v1/discovery/capabilities',
params={'format': 'xml', 'include_descriptions': 'true'}
).text
system_prompt = f"""
You have access to these capabilities:
{xml_capabilities}
Select and use the appropriate capability for the user's request.
"""Performance Considerations
Caching:
- Discovery results are cached for 30 seconds on the server
- Cache hit rate typically >95%
- Response time: <50ms (p50), <100ms (p95)
Filtering:
- All filtering happens in-memory after cache lookup
- Wildcard matching adds ~5-10ms overhead
- Schema inclusion adds ~10-20ms per agent
Best Performance:
- Use specific filters to reduce response size
- Omit schemas if not needed (
include_input_schema=false) - Use compact format for minimal payloads
- Cache results on client side (30-60 seconds)
Observability
The Discovery API automatically exposes Prometheus metrics for monitoring:
# Request metrics
agentfield_discovery_requests_total{format="json|xml|compact",status="success|error"}
agentfield_discovery_request_duration_seconds{format="json|xml|compact"}
# Cache metrics
agentfield_discovery_cache_hits_total
agentfield_discovery_cache_misses_total
# Usage metrics
agentfield_discovery_filter_usage_total{filter_type="reasoner|skill|tag|agent"}Scrape these metrics at /metrics on the control plane to track discovery usage, cache efficiency, and performance.
Debug Logging: Enable debug-level logs to see cache hit/miss information and filter execution details for slow queries.
Troubleshooting
Related
- Agent Execution - Execute discovered capabilities
- Python SDK app.discover() - Discover from Python code
- Cross-Agent Communication - Build AI orchestrators
- Multi-Agent Orchestration - Workflow patterns