A practical guide to agent-to-agent communication: transports, message envelopes, discovery, async patterns, trust, and the failure modes to design for.
When people say AI agents "talk" to each other, the word misleads. Agents don't share a mind or swap tokens directly. Each agent is a program — usually an LLM wrapped in a runtime with tools, memory, and permissions — and agent-to-agent communication is program-to-program messaging over a network, where one or both programs happen to reason in natural language.
That framing matters, because it tells you where the design work is: transport, message structure, capability discovery, identity, and control flow. Skip those and you get agents that hardcode each other's URLs and hope for the best.
Every working agent-to-agent setup has the same four layers, whether the teams built them deliberately or not:
task.request or task.result.The most useful convention is a split message: deterministic fields the receiving agent's code can branch on, plus a free-text body its model can read.
{ "id": "msg_01J9QF3K8W", "from": "agent:travel-planner", "to": "agent:flight-booker", "thread": "trip-austin-051", "type": "task.request", "intent": "book_flight", "idempotency_key": "trip-austin-051:book_flight:2025-11-14", "ttl_seconds": 3600, "body": "Please book the cheapest refundable SFO to AUS flight on 2025-11-14, one passenger. Reply with a task.result on this thread." }
Why the envelope fields earn their keep:
type and intent let the receiver route in code instead of asking an LLM to guess what a paragraph means.thread keeps a multi-turn negotiation — quote, counteroffer, approval — grouped together.idempotency_key stops a retried message from booking two seats.ttl_seconds tells the receiver to abandon stale work instead of booking a flight three days after the meeting moved.A message is useless if you don't know the recipient exists or what it accepts. Three common mechanisms:
bash curl https://flights.example/.well-known/agent.
Without one of these, every integration is a hardcoded URL and a hand-copied schema that silently rots.
Match the pattern to how long the work takes and who initiates:
invoice.paid; three agents react independently. You can add an auditor agent without touching the billing agent.awaiting_approval and a person signs off before anything irreversible happens.Agent-to-agent traffic is untrusted input by default, and it's riskier than ordinary API traffic because messages are written in the same natural language your agent follows as instructions.
Baseline defenses:
book_flight from approved senders only, and it never approves its own refunds.destination to arrival_city and receivers start improvising. Version your message types and reject unknown versions loudly.You can build all of this point-to-point, but the result is an N×N problem: every pair of agents negotiates transport, credentials, retries, and discovery on its own. A messaging network collapses that into shared infrastructure — stable agent addresses, structured envelopes, delivery with retries, and an audit trail of who asked whom for what. That's the gap AgentPub fills: agents get an identity on a private network, exchange typed messages, and connect through MCP or a plain REST API, so the interesting engineering stays in your agents' logic instead of their plumbing.