Agent2Agent (A2A) is an open standard designed to enable seamless communication and collaboration between AI agents. Deploying an A2A server in Knative leverages features such as automatic scaling—including scale-in to zero—to enable on-demand resource usage and rapid version iteration.
How it works
AI agents possess inference, planning, and memory capabilities, allowing them to learn autonomously and complete tasks on behalf of users. Similar to how MCP provides a data access standard for LLMs, the Agent2Agent (A2A) protocol defines a standardized framework for interoperability between agents.
Deploying an A2A server in Knative involves the following core interactions:
-
Discovery: After deployment, the service exposes its interface through a standard agent card, allowing other agents to query its skills (AgentSkill) and capabilities (AgentCapabilities).
-
Communication: Use Knative’s gateway and service routing capabilities to handle standard message exchanges over HTTP or gRPC.
-
Collaboration: Agents delegate tasks and coordinate actions through APIs.
See the A2A specification for the protocol architecture and key concepts of agent communication.
Preparations
-
You have deployed Knative in the ACS cluster.
-
You have obtained the gateway access address.
You can find it on the Add-ons or Services page. The following example shows how to locate it.
At the bottom of the Service Management page, view the Access Gateway address. It follows this format:
alb-<instance ID>.cn-hangzhou.alb.aliyuncsslb.com.
Step 1: Deploy the A2A server
This example deploys a basic agent service named helloworld-agent-server.
-
Create
a2a-service.yaml.apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-agent-server # Update the namespace as needed namespace: default annotations: # Use a wildcard domain for quick validation knative.aliyun.com/serving-ingress: / spec: template: spec: containers: # Replace {region} with your actual region, such as cn-hangzhou - image: registry-{region}-vpc.ack.aliyuncs.com/acs/knative-samples-a2a:v1.0-952c112 name: user-container env: # INVOKE defines the invoke URL returned in the Agent Card. Replace it with your gateway address. - name: INVOKE value: http://<YOUR_GATEWAY_ADDRESS>/invoke ports: - containerPort: 9001 name: http1 protocol: TCP -
Deploy the service.
kubectl apply -f a2a-service.yaml -
Check the Knative Service status.
kubectl get ksvc helloworld-agent-serverExpected output:
NAME URL LATESTCREATED LATESTREADY READY REASON helloworld-agent-server http://helloworld-agent-server.default.example.com helloworld-agent-server-00001 helloworld-agent-server-00001 True
Step 2: Verify the service and retrieve the agent card
After deployment, verify that the service correctly returns an agent card compliant with the A2A protocol.
-
Get the gateway address and the service’s default domain name.
-
Log on to the ACS console. In the left navigation pane, click Clusters.
-
On the Clusters page, click the name of the target cluster. In the left navigation pane, choose .
-
On the Services page, get the Default Domain of the service.
The following shows the Gateway and the Default Domain.
The gateway address follows this format:
alb-<instance ID>.cn-hangzhou.alb.aliyuncsslb.com. The service helloworld-agent-server is in the successful state, and its default domain name ishelloworld-agent-server.default.example.com.
-
-
Access the service’s metadata endpoint.
# Replace <GATEWAY_ADDRESS> with your actual gateway address curl http://<GATEWAY_ADDRESS>/.well-known/agent-card.json | jq .Review the expected output.
The output must include the agent’s capabilities (capabilities), description (description), and list of skills (skills).{ "capabilities": { "streaming": true }, "defaultInputModes": [ "text" ], "defaultOutputModes": [ "text" ], "description": "Just a hello world agent", "name": "Hello World Agent", "preferredTransport": "JSONRPC", "protocolVersion": "", "skills": [ { "description": "Returns a 'Hello, world!'", "examples": [ "hi", "hello" ], "id": "hello_world", "name": "Hello, world!", "tags": [ "hello world" ] } ], "url": "http://XXX/invoke", "version": "" }
Step 3: Call the service using an A2A client
Write client code in Golang to simulate another agent communicating with the deployed A2A server.
-
Set up your development environment and install Go.
-
Create a file named main.go and add the following code.
package main import ( "context" "flag" "log" // Import core libraries for the A2A protocol "github.com/a2aproject/a2a-go/a2a" "github.com/a2aproject/a2a-go/a2aclient" "github.com/a2aproject/a2a-go/a2aclient/agentcard" // Import gRPC-related libraries "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) // Replace <GATEWAY_ADDRESS> with your actual gateway address var cardURL = flag.String("card-url", "http://<GATEWAY_ADDRESS>", "Base URL of AgentCard client.") func main() { flag.Parse() ctx := context.Background() // Service discovery card, err := agentcard.DefaultResolver.Resolve(ctx, *cardURL) if err != nil { log.Fatalf("Failed to resolve an AgentCard: %v", err) } // Configure the transport layer withInsecureGRPC := a2aclient.WithGRPCTransport(grpc.WithTransportCredentials(insecure.NewCredentials())) // Create the client client, err := a2aclient.NewFromCard(ctx, card, withInsecureGRPC) if err != nil { log.Fatalf("Failed to create a client: %v", err) } // Build the message msg := a2a.NewMessage(a2a.MessageRoleUser, a2a.TextPart{Text: "Hello, world"}) resp, err := client.SendMessage(ctx, &a2a.MessageSendParams{Message: msg}) if err != nil { log.Fatalf("Failed to send a message: %v", err) } log.Printf("Server responded with: %+v", resp) } -
Run the code to test.
go mod init a2a-demo go mod tidy go run main.goThe following output indicates that the client successfully connected to the Knative service and received a response from the server.
2025/11/27 17:24:21 Server responded with: &{ID:019ac4a0-c386-7cdc-9aad-d40fb8f98ae2 ContextID: Extensions:[] Metadata:map[] Parts:[{Text:Hello, world! Metadata:map[]}] ReferenceTasks:[] Role:agent TaskID:}
Production environment recommendations
-
Custom domain and HTTPS: Do not use test domains in production. Configure a custom domain name and enable an HTTPS certificate to secure agent-to-agent communication.
-
Cold start optimization: If agent calls are infrequent, Knative scales instances down to zero. To avoid cold-start latency on the first request, configure a minimum instance count (MinScale) .
Billing
Knative itself does not incur additional charges. However, you are billed for the cloud services that you use, such as computing and network resources. For more information, see and Billing.