The A2A Protocol

Last update: 2026-03-18 19:10:43 +0800 +0800
Available translations: 日本語 / 中文(简体) / 中文(繁體)

inventing mcp again.

The Agent2Agent Protocol, abbreviated A2A, is an open protocol for communication between independent AI-agent applications. It lets one agent discover another agent’s capabilities, send it work, continue a multi-turn interaction, track a long-running task, and receive structured results without knowing how the remote agent is implemented.

A2A was initiated by Google and donated to the Linux Foundation. It is framework-, model-, language-, and vendor-neutral. An A2A client built in Java can collaborate with a remote agent built in Python using a different model and agent framework.

The important boundary is:

text
Agent A knows what Agent B offers and how to communicate with it.
Agent A does not need Agent B's prompt, memory, tools, model, or source code.

This article describes the released A2A v1.0 data model. The specification is still evolving, so production implementations should negotiate and validate the protocol version declared by the remote Agent Card.

The Problem A2A Solves #

Suppose a general assistant must arrange a business trip. It may need to collaborate with:

  • a flight agent;
  • a hotel agent;
  • an employer travel-policy agent;
  • a ground-transport agent; and
  • an expense-management agent.

Without a common protocol, every pair needs a custom integration:

text
orchestrator -> flight vendor's private API
orchestrator -> hotel vendor's private API
orchestrator -> policy agent's custom WebSocket
orchestrator -> expense agent's message queue

Each integration invents its own:

  • capability description;
  • request and response schemas;
  • authentication metadata;
  • progress events;
  • cancellation behavior;
  • file handling;
  • conversation identifier;
  • long-running job model; and
  • error representation.

As the number of independently developed agents grows, these point-to-point adapters become expensive to build and govern.

A conventional REST API solves part of this problem when the remote operation is deterministic and completely specified. An agent interaction is often less rigid:

text
Client: Arrange travel within company policy.
Agent: I need the employee ID and preferred departure window.
Client: Employee E-1042, after 18:00.
Agent: The only compliant flight arrives after hotel check-in. May I request
       an exception?
Client: Yes; prepare the exception request but do not purchase anything.

The work is stateful, may require clarification or authorization, can last a long time, and may produce several evolving artifacts. A2A standardizes that interaction envelope while leaving the domain reasoning to each agent.

From an Integration Matrix to One Protocol #

If every agent has a bespoke interface, connecting \(N\) agents can approach \(N \times (N - 1)\) directional integrations. With A2A, each implementation targets a shared protocol:

text
Agent A --\
Agent B ----> A2A data model and operations
Agent C --/

This does not eliminate domain differences. A flight-booking skill and a security-review skill still accept different information. It standardizes how their capabilities are advertised and how work, state, content, and results are exchanged.

What A2A Is Not #

A2A is:

  • a wire protocol and interaction model between agentic applications;
  • suitable across process, framework, team, and organization boundaries; and
  • designed for opaque, potentially long-running agents.

A2A is not:

  • an LLM;
  • an agent framework;
  • an orchestration algorithm;
  • a prompt format;
  • a workflow engine;
  • a model-routing system;
  • an identity provider;
  • a registry API standard;
  • a guarantee that an advertised agent is trustworthy; or
  • a replacement for a well-defined ordinary API.

If the remote capability is simply getExchangeRate(from, to), a normal API or tool protocol may be clearer. A2A is valuable when the remote party is an autonomous collaborator that can reason, negotiate, maintain task state, ask for more information, and return complex deliverables.

A2A and MCP #

A2A and the Model Context Protocol solve different problems:

ProtocolRelationshipTypical Remote Capability
MCPAgent to tool or resourceQuery a database, read a file, call an API
A2AAgent to agentResearch, negotiate, plan, delegate, and deliver a result

An agent can use both:

text
Travel Orchestrator
  |
  | A2A: "Find compliant flight options"
  v
Flight Agent
  |
  | MCP: call inventory and pricing tools
  v
Airline systems

MCP exposes relatively bounded primitives to an agent. A2A exposes an independent agent as an opaque collaborator. Wrapping every agent as one large tool hides useful task lifecycle, clarification, artifacts, and asynchronous behavior; treating every simple tool as an agent adds unnecessary autonomy and complexity.

The Three Protocol Layers #

A2A v1.0 separates three layers:

  1. Canonical data model: Agent Cards, Messages, Tasks, Parts, Artifacts, events, security declarations, and extensions.
  2. Abstract operations: Send a message, stream a message, retrieve/list or cancel tasks, subscribe to task updates, manage push-notification configuration, and retrieve an extended Agent Card.
  3. Bindings: Concrete mappings to JSON-RPC, gRPC, HTTP+JSON, or a governed custom binding.

The canonical Protocol Buffer definition is normative. Bindings serialize the same concepts differently. Clients should use a maintained SDK rather than assuming one JSON-RPC example describes every binding.

The official project maintains SDKs for Python, Go, Java, JavaScript, .NET, and Rust, plus a separate sample repository.

Actors #

An interaction has three conceptual actors:

  • User: A human or automated system whose goal motivates the request.
  • A2A client: The application or client agent that initiates the protocol operation on the user’s behalf.
  • A2A server: The remote agent that publishes an A2A interface and performs the work.

The same application can be both a server and a client. A travel orchestrator serves its user’s request while acting as a client of flight and hotel agents.

text
User
  -> A2A server: Travel Orchestrator
       -> A2A client: Flight Agent
       -> A2A client: Hotel Agent
       -> A2A client: Policy Agent

A2A does not standardize the orchestrator’s planning logic. It may use a fixed workflow, a rules engine, an LLM planner, or human decisions.

Agent Discovery #

An A2A server describes itself with an Agent Card, a JSON document that contains:

  • agent name, description, provider, and version;
  • one or more supported interfaces and A2A protocol versions;
  • supported protocol bindings;
  • default input and output media types;
  • optional streaming, push-notification, and extended-card capabilities;
  • security schemes and requirements;
  • skills, descriptions, tags, examples, and media types; and
  • optional signatures and extensions.

A simplified v1.0 Agent Card is:

json
{
  "name": "Corporate Travel Agent",
  "description": "Plans policy-compliant business travel",
  "version": "3.4.0",
  "provider": {
    "organization": "Example Travel",
    "url": "https://travel.example"
  },
  "supportedInterfaces": [
    {
      "url": "https://agents.example/a2a/travel",
      "protocolBinding": "HTTP+JSON",
      "protocolVersion": "1.0"
    }
  ],
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "extendedAgentCard": true
  },
  "defaultInputModes": [
    "text/plain",
    "application/json"
  ],
  "defaultOutputModes": [
    "text/plain",
    "application/json"
  ],
  "skills": [
    {
      "id": "plan-business-trip",
      "name": "Plan a Business Trip",
      "description": "Finds policy-compliant flight and hotel options",
      "tags": ["travel", "flight", "hotel", "corporate-policy"],
      "examples": [
        "Plan a trip from Singapore to Helsinki for 12-16 October"
      ],
      "inputModes": ["text/plain", "application/json"],
      "outputModes": ["application/json"]
    }
  ]
}

The exact JSON field names are derived from the v1.0 canonical model. Validate cards through an SDK or generated schema rather than accepting arbitrary JSON.

Discovery Strategies #

For domain-based discovery, the standard well-known URL is:

text
https://agent.example/.well-known/agent-card.json

Other practical approaches are:

  • Curated registry: An enterprise catalog or marketplace returns approved Agent Cards based on skill, provider, geography, or trust policy.
  • Direct configuration: A deployment manifest supplies known card URLs for a closed set of agents.
  • Authenticated extended card: A public card advertises basic capability; an authenticated operation returns sensitive skills or interfaces available to that caller.

A2A standardizes the card, not the API of a centralized registry.

Treat discovery as input to policy, not automatic trust. Before invoking an agent, a client may need to check:

  • trusted issuer or registry;
  • card signature;
  • allowed domain and TLS identity;
  • protocol version;
  • required binding;
  • supported media types;
  • approved provider;
  • data residency;
  • security scheme;
  • contractual relationship; and
  • whether the skill is authorized for the current user.

Agent Cards change less often than tasks and should use normal HTTP caching, including Cache-Control, ETag, and conditional requests.

When the Agent Card Is Exchanged #

The Agent Card is control-plane metadata used during discovery, normally before the first A2A operation:

text
Client -> discover or receive Agent Card
Client -> validate trust, version, binding, security, and media types
Client -> select an interface URL from supportedInterfaces
Client -> send A2A operations to that interface

The card is not normally attached to every Message. A client can cache it and refresh it according to normal HTTP caching rules or local policy.

An A2A server must make an Agent Card available, but v1.0 permits several discovery mechanisms: the standard well-known URI, a registry or catalog, and directly configured card URLs or card content. Consequently, /.well-known/agent-card.json is the conventional interoperable location, not the only compliant way to exchange a card.

If the public card advertises extendedAgentCard, an authorized client may later invoke Get Extended Agent Card. That authenticated card can reveal caller-specific skills or interfaces that should not be published during anonymous discovery.

Messages and Parts #

A Message is one communication turn. It has:

  • a caller-generated messageId;
  • a role, ROLE_USER or ROLE_AGENT;
  • one or more Parts;
  • optional contextId and taskId;
  • optional references to previous tasks;
  • optional metadata; and
  • declared extensions.

A Part contains exactly one content representation:

ContentUse
textPlain textual content
dataStructured JSON value
urlReference to external content
rawInline bytes, represented as Base64 in JSON

A Part can also have a MIME mediaType, filename, and metadata:

json
{
  "messageId": "msg-01JZ8P...",
  "role": "ROLE_USER",
  "parts": [
    {
      "text": "Review the attached contract for renewal risk.",
      "mediaType": "text/plain"
    },
    {
      "url": "https://files.example/contracts/42",
      "filename": "contract.pdf",
      "mediaType": "application/pdf",
      "metadata": {
        "sha256": "..."
      }
    },
    {
      "data": {
        "jurisdiction": "Singapore",
        "riskTolerance": "low"
      },
      "mediaType": "application/json"
    }
  ]
}

Prefer a URL for a large file rather than putting Base64 data in every protocol hop. The URL should be short-lived, scoped to the intended agent, integrity checked, and protected against confused-deputy access.

Media negotiation matters. The client declares output media types it accepts, and the Agent Card describes what the agent supports. A machine orchestrator should request structured data rather than parse prose when a skill offers application/json.

Direct Messages and Stateful Tasks #

The Send Message operation can return either:

  • a Message for an immediate, self-contained response; or
  • a Task for stateful or long-running work.

For example, an agent may answer a capability question directly:

text
Client: Can you review contracts governed by Singapore law?
Agent: Yes.

Reviewing a 300-page contract should create a Task that can be tracked, interrupted, canceled, and associated with output artifacts.

The Task Model #

A Task has:

  • a server-generated task ID;
  • a server-generated context ID;
  • current status and timestamp;
  • optional status Message;
  • Message history;
  • zero or more Artifacts; and
  • metadata.

The lifecycle states are:

StateMeaning
TASK_STATE_SUBMITTEDAccepted but not yet actively processed
TASK_STATE_WORKINGProcessing
TASK_STATE_INPUT_REQUIREDMore user or client information is needed
TASK_STATE_AUTH_REQUIREDAdditional out-of-band authentication is needed
TASK_STATE_COMPLETEDSuccessful terminal result
TASK_STATE_FAILEDTerminal processing failure
TASK_STATE_CANCELEDTerminal cancellation
TASK_STATE_REJECTEDAgent declined the work

INPUT_REQUIRED and AUTH_REQUIRED interrupt processing but are not terminal. The client can send another Message associated with the Task to continue it.

Terminal Tasks are immutable. A correction or refinement creates a new Task in the same context and can reference the previous task:

text
context C
  task T1: Generate itinerary       -> completed -> artifact A1
  task T2: Replace morning flight   -> completed -> artifact A2
            references T1

This gives auditability: each Task remains a stable unit of input, state, and output.

Context and Task IDs #

contextId groups related Tasks and Messages. taskId identifies one unit of work:

text
context: "Plan Helsinki trip"
  task: find flights
  task: reserve hotel
  task: request policy exception

Do not confuse a context ID with authentication, authorization, or tenant identity. It is an opaque correlation handle assigned by the server. The server must still verify that the authenticated caller may access every referenced context, task, and artifact.

Artifacts #

An Artifact is a concrete Task output, as opposed to a conversational status Message. Examples include:

  • an itinerary;
  • a security report;
  • generated source code;
  • a PDF contract analysis;
  • an image;
  • a structured list of offers; or
  • a deployment manifest.

An Artifact has an ID unique within its Task, name, description, Parts, metadata, and optional extensions:

json
{
  "artifactId": "offers-v1",
  "name": "flight-offers.json",
  "description": "Policy-compliant flight options",
  "parts": [
    {
      "mediaType": "application/json",
      "data": {
        "currency": "SGD",
        "offers": [
          {
            "offerId": "F-812",
            "price": 1420.30,
            "refundable": true
          }
        ]
      }
    }
  ],
  "metadata": {
    "expiresAt": "2026-07-20T10:15:00Z"
  }
}

An Artifact is not automatically durable or trustworthy. The client must validate its schema, media type, size, integrity, provenance, expiration, and business meaning.

Core Operations #

The binding-neutral v1.0 operations include:

OperationPurpose
Send MessageStart or continue an interaction
Send Streaming MessageStart an interaction and receive incremental events
Get TaskRetrieve current Task state, history, and Artifacts
List TasksList authorized Tasks with filters and pagination
Cancel TaskAsk the agent to cancel ongoing work
Subscribe to TaskReconnect to updates for an active Task
Manage Task Push Notification ConfigCreate, read, list, or delete webhook configuration
Get Extended Agent CardRetrieve caller-specific Agent Card details

Bindings and Endpoint Mapping #

The interface URL and protocolBinding in the Agent Card determine how these abstract operations appear on the wire.

With JSON-RPC, the advertised interface URL is one HTTP endpoint for all operations. A URL such as /a2a is only an implementation choice; the A2A specification does not require that path. The client sends an ordinary HTTP request with a JSON-RPC body, and the method field selects the A2A operation:

http
POST /a2a HTTP/1.1
Host: agents.example
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": "request-17",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "msg-01JZ8P...",
      "role": "ROLE_USER",
      "parts": [{"text": "Hello"}]
    }
  }
}

JSON-RPC is a protocol convention layered over HTTP here, not a replacement for HTTP. HTTP supplies transport, headers, authentication, and status codes; JSON-RPC standardizes the body fields method, params, id, result, and error, plus request correlation, notifications, and protocol error semantics. Other protocols can also use JSON-RPC over transports such as WebSocket or standard input/output, but A2A’s JSON-RPC binding specifically uses HTTP(S), with Server-Sent Events for streaming.

All JSON-RPC A2A methods go to the same advertised URL:

A2A operationJSON-RPC method
Send MessageSendMessage
Send Streaming MessageSendStreamingMessage
Get TaskGetTask
List TasksListTasks
Cancel TaskCancelTask
Subscribe to TaskSubscribeToTask
Create push configurationCreateTaskPushNotificationConfig
Get push configurationGetTaskPushNotificationConfig
List push configurationsListTaskPushNotificationConfigs
Delete push configurationDeleteTaskPushNotificationConfig
Get Extended Agent CardGetExtendedAgentCard

The HTTP+JSON binding instead uses distinct resource-oriented paths relative to its advertised interface base URL:

HTTP endpointA2A operation
POST /message:sendSend Message
POST /message:streamSend Streaming Message using SSE
GET /tasks/{id}Get Task
GET /tasksList Tasks
POST /tasks/{id}:cancelCancel Task
POST /tasks/{id}:subscribeSubscribe to Task using SSE
POST /tasks/{id}/pushNotificationConfigsCreate push configuration
GET /tasks/{id}/pushNotificationConfigs/{configId}Get push configuration
GET /tasks/{id}/pushNotificationConfigsList push configurations
DELETE /tasks/{id}/pushNotificationConfigs/{configId}Delete push configuration
GET /extendedAgentCardGet Extended Agent Card

These paths belong to the HTTP+JSON binding; a JSON-RPC implementation does not expose one HTTP route per operation. The gRPC binding likewise exposes RPC methods rather than these REST paths.

Blocking and Non-Blocking Sends #

The Send Message configuration controls whether the call waits:

  • With returnImmediately false or absent, it waits until the Task reaches a terminal or interrupted state.
  • With returnImmediately true, it returns after Task creation; the client polls, subscribes, or waits for a push notification.

A simplified HTTP+JSON request is:

http
POST /message:send HTTP/1.1
Host: agents.example
Authorization: Bearer eyJ...
Content-Type: application/json

{
  "message": {
    "messageId": "msg-01JZ8P...",
    "role": "ROLE_USER",
    "parts": [
      {
        "text": "Review repository example/payments for critical vulnerabilities",
        "mediaType": "text/plain"
      }
    ]
  },
  "configuration": {
    "acceptedOutputModes": [
      "application/json",
      "text/markdown"
    ],
    "historyLength": 10,
    "returnImmediately": true
  }
}

The immediate response may contain:

json
{
  "task": {
    "id": "task-sec-2048",
    "contextId": "ctx-release-91",
    "status": {
      "state": "TASK_STATE_SUBMITTED",
      "timestamp": "2026-07-20T08:30:00Z"
    }
  }
}

This example targets the v1.0 HTTP+JSON binding. Use an SDK for exact request and response wrappers.

Streaming and Asynchronous Work #

Agent work often lasts longer than a normal request timeout. A2A offers three update patterns.

Polling #

The client sends a non-blocking request and periodically invokes Get Task:

text
Send Message -> Task(submitted)
Get Task     -> Task(working)
Get Task     -> Task(completed, artifacts=[...])

Polling is simple and survives process restarts. Use exponential backoff, jitter, and server hints rather than polling every few milliseconds.

Streaming #

If the Agent Card advertises streaming, Send Streaming Message returns a stream. Depending on the binding, HTTP can use Server-Sent Events and gRPC can use a server stream.

A Task lifecycle stream begins with the Task and then emits:

  • TaskStatusUpdateEvent for state changes or intermediate status Messages;
  • TaskArtifactUpdateEvent for new or incrementally updated Artifacts.
text
Task(submitted)
Status(working: "Scanning dependencies")
Artifact(report, append=true, chunk=1)
Status(working: "Analyzing reachable call paths")
Artifact(report, append=true, chunk=2, lastChunk=true)
Status(completed)

Artifact updates identify whether data appends to the existing Artifact and whether the final chunk has arrived. A client should assemble chunks by task and artifact IDs, enforce size limits, and tolerate reconnects without duplicating content.

If a stream disconnects while the Task is active, Subscribe to Task can resume receiving future updates. Persist the Task ID before processing streamed data so recovery remains possible.

Push Notifications #

For work lasting minutes, hours, or days, a client can register an HTTPS webhook if the agent advertises push-notification support:

text
Client -> Agent: start Task and register callback
Client disconnects
Agent performs work
Agent -> Client webhook: Task completed
Client -> Agent: Get Task

The notification tells the client that state changed; the client normally fetches the authoritative Task afterward.

Webhook support introduces serious risks:

  • SSRF: A malicious caller supplies an internal or cloud-metadata URL.
  • Spoofing: An attacker sends a fake completion event.
  • Replay: A valid old event is processed again.
  • Amplification: The server is induced to flood a third party.
  • Duplicate delivery: Network retries deliver the same event more than once.

The server should allowlist or verify callback ownership and restrict outbound networks. The receiver should authenticate the sender, validate issuer, audience, expiry, task ID, and unique event ID, reject stale events, and process notifications idempotently.

Input and Authentication Interruptions #

Long-running work may need another user decision:

text
Client -> Agent: "Book the best compliant option"
Agent -> Client: Task(INPUT_REQUIRED)
                "Two options have equal policy score. Prefer lower price or
                 refundable fare?"
Client -> Agent: Message(taskId=T1, "Prefer refundable")
Agent -> Client: Task(WORKING)
Agent -> Client: Task(COMPLETED, artifact=booking)

AUTH_REQUIRED indicates that additional authorization is needed during work. For example, the travel agent may discover that it needs the user to authorize an airline account.

The client should perform the OAuth or consent flow out of band and then continue the Task. Do not send a password, refresh token, or reusable secret as ordinary Message text merely because the agent requested authentication.

Detailed Example: Corporate Travel #

Consider a company assistant that coordinates independently operated agents.

Participants #

text
Travel Orchestrator
  -> Policy Agent
  -> Flight Agent
  -> Hotel Agent
  -> Expense Agent

Each remote system publishes an Agent Card. The orchestrator’s approved registry contains the trusted cards and OAuth audience for each provider.

Flow #

  1. The user asks:

    text
    Plan travel from Singapore to Helsinki for 12-16 October.
    I need to arrive before Monday's 09:00 meeting.
    Do not make purchases yet.
  2. The orchestrator sends employee grade, cost center, route, and dates as structured Parts to the Policy Agent.

  3. The Policy Agent returns a completed Task with a policy Artifact:

    json
    {
      "cabin": "economy",
      "maxNightlyHotelRate": 240,
      "currency": "EUR",
      "approvalRequiredAbove": 1800
    }
  4. The orchestrator starts Flight and Hotel Tasks in parallel within its own workflow. It sends only the policy fields each agent needs.

  5. The Flight Agent streams status:

    text
    working: searching direct routes
    working: direct route violates arrival constraint
    working: searching one-stop routes
    completed: artifact flight-offers.json
  6. The Hotel Agent reaches INPUT_REQUIRED because there are two office locations. The orchestrator asks the user and continues that same Task with the selected office.

  7. The orchestrator joins the two structured Artifacts, calculates complete itinerary options, and presents them to the user.

  8. The user selects one option. This creates new booking Tasks in the same orchestration context; it does not mutate the completed search Tasks.

  9. Because the total exceeds the policy threshold, the Expense Agent creates an approval Task and configures a push notification. A manager approves it several hours later.

  10. The orchestrator receives the authenticated notification, retrieves the Task, confirms the approved amount and expiration, and only then continues the booking Tasks.

Why A2A Helps #

The flight and hotel providers retain their own models, tools, pricing systems, and planning logic. The orchestrator sees declared skills, task state, Messages, and Artifacts. A provider can replace its internal framework without changing the collaboration contract.

A2A does not solve transaction atomicity. If the flight succeeds and the hotel fails, the orchestrator still needs compensation logic, reservations with expiry, or a domain-specific transaction workflow.

Detailed Example: Software Delivery #

A release orchestrator coordinates agents owned by different engineering teams:

text
Coding Agent -> Test Agent -> Security Agent -> Deployment Agent

Flow #

  1. The Coding Agent completes Task T1 and emits:

    • a Git commit reference;
    • a patch Artifact;
    • a change-summary Artifact; and
    • the expected test scope.
  2. The orchestrator sends separate Messages to the Test and Security Agents. Each Message references T1, but includes only a short-lived repository credential authorized for that repository and operation.

  3. The Test Agent streams:

    text
    Task submitted
    Compiling module payments
    Running 1,842 unit tests
    Running 37 integration tests
    Artifact: junit-results.xml
    Task completed
  4. The Security Agent returns INPUT_REQUIRED:

    text
    The patch changes authorization behavior. Is the endpoint intended for
    service identities, end users, or both?
  5. The orchestrator obtains the answer from the code owner and continues the same security Task.

  6. The Security Agent completes with structured findings:

    json
    {
      "decision": "block",
      "findings": [
        {
          "severity": "high",
          "file": "AuthorizationService.java",
          "line": 118,
          "summary": "Tenant constraint omitted"
        }
      ]
    }
  7. The orchestrator does not invoke deployment. It creates refinement Task T4 for the Coding Agent, references T1 and the security Task, and requests a fix.

  8. The new patch receives new test and review Tasks. Completed Tasks remain immutable audit records.

  9. Only deterministic release policy, not an LLM’s prose, decides whether all required checks permit deployment.

Why A2A Helps #

Each team can build its agent with a different framework. Results remain typed Artifacts rather than scraped chat. Streaming exposes progress for expensive test suites, and interrupted Tasks support questions without discarding prior work.

The protocol does not make generated code safe. Branch protection, authorization, reproducible builds, signatures, isolated execution, and human approval remain necessary.

Detailed Example: Insurance Claim #

A claim intake agent receives text, images, and documents from a mobile application:

text
Claim Intake Agent
  -> Damage Assessment Agent
  -> Coverage Agent
  -> Fraud Review Agent
  -> Repair Network Agent

Multimodal Exchange #

The intake Message contains:

  • text describing the accident;
  • image Parts referenced by scoped URLs;
  • a PDF police report;
  • structured vehicle and policy data; and
  • hashes for integrity verification.

The Damage Assessment Agent returns:

  • a human-readable summary;
  • a structured list of damaged components;
  • annotated-image Artifacts; and
  • an uncertainty score.

The Coverage Agent sees policy terms but not unnecessary accident images. The Fraud Agent receives redacted evidence appropriate to its role. Data minimization occurs in the orchestrator before each A2A call.

Human in the Loop #

If assessment confidence is low, the Task enters INPUT_REQUIRED:

text
Please provide a photograph of the rear-left wheel at ground level.

The mobile user uploads another image, and the intake agent continues the same Task.

If estimated loss exceeds a threshold, the workflow creates a separate human adjuster Task. A2A tracks collaboration, but deterministic claims policy and a qualified human make the legally consequential decision.

Why A2A Helps #

Parts support text, structured data, and file references in one interaction. Tasks survive intermittent mobile connectivity. Artifacts represent durable deliverables, and remote specialist agents remain opaque.

The implementation must still enforce consent, retention, regional processing, medical-data rules, and strict authorization for every Artifact URL.

Detailed Example: Procurement and Negotiation #

A procurement agent needs quotes for 500 laptops from several supplier agents. This illustrates why an agent is more than a stateless price tool.

Flow #

  1. The client sends required specifications, delivery locations, service terms, and a response deadline to three approved supplier agents.

  2. Each supplier creates a Task and may ask clarifying questions.

  3. Suppliers return quote Artifacts with price, inventory, warranty, expiration, and commercial terms.

  4. The procurement agent requests refinements in new Tasks:

    text
    Keep the same hardware and delivery date. Offer a three-year warranty and
    quote the price difference.
  5. Each refinement references the prior Task and quote Artifact.

  6. The client tracks quote versions because Artifact lineage and acceptance are client responsibilities.

  7. A deterministic policy engine compares mandatory terms. The model may summarize tradeoffs but cannot waive requirements.

  8. A human approves the selected quote.

  9. A separate purchase Task performs the order with an idempotency key and narrow authorization.

Why A2A Helps #

Negotiation is multi-turn and each supplier owns its reasoning and inventory tools. Tasks and Artifacts provide consistent mechanics without forcing all suppliers into one proprietary agent SDK.

A2A does not standardize the quote schema. The buyer and suppliers still need a shared domain schema or an extension for machine-comparable commercial terms.

Security Model #

A2A reuses standard web security rather than placing credentials in protocol Messages.

The Agent Card declares supported security schemes and requirements. The client obtains credentials out of band, then sends them through transport headers:

http
Authorization: Bearer eyJ...

Production A2A interfaces should use HTTPS and verify server identity. Cross-organization deployments commonly use OAuth 2.0/OIDC, workload identity, mTLS, or a combination.

Authentication answers who the caller is. Every operation still requires authorization:

  • May this caller invoke this skill?
  • May it access this task and context?
  • May it reference this artifact?
  • May it request this output modality?
  • May it cancel this work?
  • May the remote agent perform the underlying action for this end user?

Opaque execution protects implementation details, not users. A malicious or compromised agent can still return harmful content, misuse delegated credentials, or claim work succeeded when it did not.

Delegation #

When one agent acts for a user across another agent boundary, preserve:

  • end-user identity where policy requires it;
  • calling workload identity;
  • tenant;
  • audience;
  • authorized scopes;
  • purpose and consent;
  • token expiry; and
  • trace context.

Do not forward a broad bearer token merely because both agents can technically accept it. Exchange it for a short-lived, audience-bound token with only the remote skill’s required scopes.

Untrusted Content #

Every Message, Part, Artifact, Agent Card, and referenced file is untrusted input. Apply:

  • JSON and media-type validation;
  • byte, history, and nesting limits;
  • malware scanning;
  • decompression limits;
  • URL scheme and destination restrictions;
  • content-security policies for rendered output;
  • prompt-injection defenses;
  • output-schema validation; and
  • domain authorization independent of agent text.

Do not render an HTML Artifact directly in a privileged application origin.

Reliability and Workflow Semantics #

A2A supplies task state but is not a distributed transaction coordinator. Clients and servers still need:

  • durable Task storage;
  • idempotent business operations;
  • request deduplication;
  • bounded retries with jitter;
  • deadlines and expiration;
  • cancellation propagation;
  • compensation for partial success;
  • artifact integrity and retention;
  • backpressure;
  • concurrency limits; and
  • recovery after process restart.

A canceled Task does not prove that an external side effect was undone. A flight may already have been ticketed or an email already sent. Model cancellation and business compensation separately.

Network failures create ambiguity:

text
Client sends "purchase"
Server performs purchase
Response is lost
Client does not know whether purchase occurred

Use a domain idempotency key and queryable business reference for consequential actions. messageId identifies a protocol Message but should not be the sole business guarantee unless the implementation explicitly defines and persists that behavior.

Tasks and Artifacts need retention policies. A client cannot assume it can retrieve a completed Task forever unless the service contract says so.

Observability #

Propagate W3C Trace Context headers across A2A calls. Useful span attributes and logs include:

  • remote agent identity and version;
  • protocol and binding version;
  • operation;
  • task and context IDs;
  • skill;
  • state transition;
  • media types;
  • artifact size;
  • retry count;
  • latency; and
  • authenticated client application.

Do not put prompt text, document content, access tokens, or personal data into metric labels. Logs containing Messages or Artifacts need redaction, access control, and retention limits.

Important metrics include:

  • request and error rates by operation;
  • task queue and execution latency;
  • Tasks by state;
  • time spent waiting for input or authentication;
  • stream disconnect and resubscription rates;
  • push-notification delivery failures;
  • cancellation latency;
  • Artifact bytes; and
  • downstream model and tool cost.

Audit consequential actions separately from diagnostic logging.

Extensions #

Extensions add behavior or data without changing the core protocol. An Agent Card declares each extension by a stable URI, description, parameters, and whether clients must understand it.

A client must not call an agent when a required extension is unsupported. Optional extensions should degrade cleanly.

Use an extension when several independent implementations need interoperable semantics, not merely to carry one application’s private metadata. Vendor extensions can recreate the same lock-in A2A is meant to reduce, so keep the core interaction usable where possible and document conformance precisely.

Implementing an A2A Server #

A practical server implementation proceeds as follows:

  1. Define a narrow set of skills and their input/output media types.
  2. Publish a minimal public Agent Card.
  3. Choose one official binding and SDK first.
  4. Authenticate at the HTTP or transport boundary.
  5. Authorize skills, Tasks, contexts, and Artifacts.
  6. Validate Messages and dereference files safely.
  7. Decide when to return a direct Message versus create a Task.
  8. Persist Tasks before acknowledging non-blocking work.
  9. Emit valid state transitions and immutable terminal state.
  10. Store or reference Artifacts with integrity and retention metadata.
  11. Add streaming only when intermediate updates have value.
  12. Add push notifications only with SSRF protection and authenticated delivery.
  13. Propagate tracing and record audit events.
  14. Publish compatibility and retention guarantees.

The agent’s internal implementation can use an LLM, deterministic workflow, human queue, tools, or other A2A agents. Do not expose chain-of-thought or internal credentials as status Messages.

Implementing an A2A Client #

A robust client should:

  1. Discover the Agent Card from a trusted source.
  2. Validate and cache it.
  3. Select a mutually supported protocol version, binding, and media type.
  4. Enforce local trust and data-sharing policy.
  5. Obtain an audience-bound credential.
  6. Generate and persist Message correlation data.
  7. Send the smallest required context.
  8. Persist returned Task and context IDs immediately.
  9. Handle direct Message and Task responses.
  10. Handle every Task state, including rejection and authentication.
  11. Reconnect, poll, or process push notifications idempotently.
  12. Validate Artifacts before use.
  13. Apply deterministic policy before consequential follow-up actions.
  14. Record trace and audit relationships across delegated Tasks.

Do not let an LLM choose arbitrary Agent Card URLs and immediately send them credentials or private data. Discovery and invocation need an allowlist or trust policy.

When to Use A2A #

Use A2A when:

  • independently owned agents must interoperate;
  • the remote system is genuinely agentic rather than a single function;
  • capability discovery is useful;
  • interaction may require clarification or negotiation;
  • work is long-running or resumable;
  • rich or incremental Artifacts are required;
  • internal agent implementation must remain opaque; or
  • multiple languages and frameworks must share one contract.

Prefer a normal API, event schema, workflow activity, or MCP tool when:

  • input and output are fully deterministic;
  • one short request always completes the operation;
  • there is no meaningful conversation or task lifecycle;
  • both sides are one tightly coupled application;
  • strong static domain schemas matter more than agent flexibility; or
  • adding autonomous behavior creates risk without user value.

Common Mistakes #

  1. Treating discovery as trust. An Agent Card describes claims; policy decides whether to trust them.
  2. Putting credentials in Messages. Use transport-level authentication and out-of-band authorization.
  3. Using a context ID as authorization. It is only an opaque grouping identifier.
  4. Sending all user context to every agent. Minimize data per delegated skill.
  5. Parsing prose when structured output is offered. Negotiate an appropriate media type.
  6. Restarting a terminal Task. Create a new Task in the same context and reference the prior Task.
  7. Assuming cancellation undoes side effects. Implement domain compensation.
  8. Trusting arbitrary push URLs. Prevent SSRF and authenticate callbacks.
  9. Assuming streaming is durable. Persist IDs and support resubscription or polling.
  10. Confusing A2A with orchestration. The client still owns workflow and failure policy.
  11. Confusing A2A with MCP. Agents collaborate through A2A; agents use bounded tools through MCP.
  12. Giving an orchestrating model final authority. Deterministic code must enforce permissions, budgets, and approval rules.
  13. Ignoring protocol negotiation. Cards can expose several bindings and versions.
  14. Using old pre-1.0 examples unchanged. The v1.0 canonical model changed field names, enums, and binding structure.

A2A’s value is not that agents can send JSON to each other; ordinary HTTP already does that. Its value is a shared model for discovering opaque agents, delegating stateful work, negotiating modalities, handling interruptions, and retrieving incremental or durable results. That common layer makes cross-framework collaboration possible while leaving business schemas, orchestration, trust, and safety in the applications that understand them.

Comments

Read or comment on GitHub (sign-in required to comment)