10.4 ANP Protocol in Practice
After the MCP protocol solved tool invocation and the A2A protocol solved peer-to-peer agent collaboration, the ANP protocol focuses on solving agent management problems in large-scale, open network environments.
In Sections 10.2 and 10.3, we learned about MCP (tool access) and A2A (agent collaboration). Now, let's learn about the ANP (Agent Network Protocol) protocol, which focuses on building large-scale, open agent networks.
10.4.1 Protocol Goals
When a network contains a large number of agents with different functions (e.g., natural language processing, image recognition, data analysis, etc.), the system faces a series of challenges:
- Service Discovery: When a new task arrives, how to quickly find agents capable of handling that task?
- Intelligent Routing: If multiple agents can handle the same task, how to choose the most suitable one (e.g., based on load, cost, etc.) and dispatch the task to it?
- Dynamic Scaling: How to make newly joined agents discoverable and callable by other members?
The design goal of ANP is to provide a standardized mechanism to solve the above service discovery, routing selection, and network scalability problems.
To achieve its design goals, ANP defines the following core concepts, as shown in Table 10.8:
Table 10.8 ANP Core Concepts

We also borrow from the official Getting Started Guide to introduce ANP's architectural design, as shown in Figure 10.9

Figure 10.9 ANP Overall Process
In this flowchart, the main steps include:
1. Service Discovery and Matching: First, Agent A uses a public discovery service to query based on semantic or functional descriptions to locate Agent B that meets its task requirements. The discovery service establishes an index by pre-crawling standard endpoints (.well-known/agent-descriptions) exposed by each agent, thereby achieving dynamic matching between service demanders and providers.
2. DID-based Identity Verification: At the start of interaction, Agent A uses its private key to sign a request containing its own DID. After Agent B receives it, it parses the DID to obtain the corresponding public key and uses it to verify the authenticity of the signature and the integrity of the request, thereby establishing trusted communication between both parties.
3. Standardized Service Execution: After identity verification passes, Agent B responds to the request, and both parties exchange data or invoke services (such as booking, querying, etc.) according to predefined standard interfaces and data formats. Standardized interaction processes are the foundation for achieving cross-platform and cross-system interoperability.
In summary, the core of this mechanism is using DID to build a decentralized trust foundation and leveraging standardized description protocols to achieve dynamic service discovery. This approach enables agents to form collaborative networks on the internet securely and efficiently without requiring central coordination.
10.4.2 Using ANP Service Discovery
(1) Creating Service Discovery Center
from hello_agents.protocols import ANPDiscovery, register_service
# Create service discovery center
discovery = ANPDiscovery()
# Register Agent services
register_service(
discovery=discovery,
service_id="nlp_agent_1",
service_name="NLP Processing Expert A",
service_type="nlp",
capabilities=["text_analysis", "sentiment_analysis", "ner"],
endpoint="http://localhost:8001",
metadata={"load": 0.3, "price": 0.01, "version": "1.0.0"}
)
register_service(
discovery=discovery,
service_id="nlp_agent_2",
service_name="NLP Processing Expert B",
service_type="nlp",
capabilities=["text_analysis", "translation"],
endpoint="http://localhost:8002",
metadata={"load": 0.7, "price": 0.02, "version": "1.1.0"}
)
print("✅ Service registration completed")(2) Discovering Services
from hello_agents.protocols import discover_service
# Find by type
nlp_services = discover_service(discovery, service_type="nlp")
print(f"Found {len(nlp_services)} NLP services")
# Select service with lowest load
best_service = min(nlp_services, key=lambda s: s.metadata.get("load", 1.0))
print(f"Best service: {best_service.service_name} (load: {best_service.metadata['load']})")(3) Building Agent Network
from hello_agents.protocols import ANPNetwork
# Create network
network = ANPNetwork(network_id="ai_cluster")
# Add nodes
for service in discovery.list_all_services():
network.add_node(service.service_id, service.endpoint)
# Establish connections (based on capability matching)
network.connect_nodes("nlp_agent_1", "nlp_agent_2")
stats = network.get_network_stats()
print(f"✅ Network construction completed, total {stats['total_nodes']} nodes")10.4.3 Practical Case
Let's build a complete distributed task scheduling system:
from hello_agents.protocols import ANPDiscovery, register_service
from hello_agents import SimpleAgent, HelloAgentsLLM
from hello_agents.tools.builtin import ANPTool
import random
from dotenv import load_dotenv
load_dotenv()
llm = HelloAgentsLLM()
# 1. Create service discovery center
discovery = ANPDiscovery()
# 2. Register multiple compute nodes
for i in range(10):
register_service(
discovery=discovery,
service_id=f"compute_node_{i}",
service_name=f"Compute Node {i}",
service_type="compute",
capabilities=["data_processing", "ml_training"],
endpoint=f"http://node{i}:8000",
metadata={
"load": random.uniform(0.1, 0.9),
"cpu_cores": random.choice([4, 8, 16]),
"memory_gb": random.choice([16, 32, 64]),
"gpu": random.choice([True, False])
}
)
print(f"✅ Registered {len(discovery.list_all_services())} compute nodes")
# 3. Create task scheduler Agent
scheduler = SimpleAgent(
name="Task Scheduler",
llm=llm,
system_prompt="""You are an intelligent task scheduler, responsible for:
1. Analyzing task requirements
2. Selecting the most suitable compute node
3. Assigning tasks
When selecting nodes, consider: load, CPU cores, memory, GPU, and other factors."""
)
# Add ANP tool
anp_tool = ANPTool(
name="service_discovery",
description="Service discovery tool, can find and select compute nodes",
discovery=discovery
)
scheduler.add_tool(anp_tool)
# 4. Intelligent task assignment
def assign_task(task_description):
print(f"\nTask: {task_description}")
print("=" * 50)
# Let Agent intelligently select node
response = scheduler.run(f"""
Please select the most suitable compute node for the following task:
{task_description}
Requirements:
1. List all available nodes
2. Analyze characteristics of each node
3. Select the most suitable node
4. Explain selection reasoning
""")
print(response)
print("=" * 50)
# Test different types of tasks
assign_task("Train a large deep learning model, requires GPU support")
assign_task("Process large amounts of text data, requires high memory")
assign_task("Run lightweight data analysis task")This is a load balancing example
from hello_agents.protocols import ANPDiscovery, register_service
import random
# Create service discovery center
discovery = ANPDiscovery()
# Register multiple services of the same type
for i in range(5):
register_service(
discovery=discovery,
service_id=f"api_server_{i}",
service_name=f"API Server {i}",
service_type="api",
capabilities=["rest_api"],
endpoint=f"http://api{i}:8000",
metadata={"load": random.uniform(0.1, 0.9)}
)
# Load balancing function
def get_best_server():
"""Select server with lowest load"""
servers = discovery.discover_services(service_type="api")
if not servers:
return None
best = min(servers, key=lambda s: s.metadata.get("load", 1.0))
return best
# Simulate request allocation
for i in range(10):
server = get_best_server()
print(f"Request {i+1} -> {server.service_name} (load: {server.metadata['load']:.2f})")
# Update load (simulated)
server.metadata["load"] += 0.1