tRPC-Agent-Go provides a complete A2A (Agent-to-Agent) solution with two core components:
A2A Server: Exposes local Agents as A2A services for other Agents to call
A2AAgent: A client proxy for calling remote A2A services, allowing you to use remote Agents as if they were local
Core Capabilities
Zero Protocol Awareness: Developers only need to focus on Agent business logic without understanding A2A protocol details
Automatic Adaptation: The framework automatically converts Agent information to A2A AgentCard
Message Conversion: Automatically handles conversion between A2A protocol messages and Agent message formats
A2A Server: Exposing Agents as Services
Concept Introduction
A2A Server is a server-side component provided by tRPC-Agent-Go for quickly converting any local Agent into a network service that complies with the A2A protocol.
Core Features
One-Click Conversion: Expose Agents as A2A services through simple configuration
Automatic Protocol Adaptation: Automatically handles conversion between A2A protocol and Agent interfaces
AgentCard Generation: Automatically generates AgentCards required for service discovery
Streaming Support: Supports both streaming and non-streaming response modes
Automatic Conversion from Agent to A2A
tRPC-Agent-Go implements seamless conversion from Agent to A2A service through the server/a2a package:
The framework automatically extracts Agent metadata (name, description, tools, etc.) to generate an AgentCard that complies with the A2A protocol, including:
- Basic Agent information (name, description, URL)
- Capability declarations (streaming support)
- Skill lists (automatically generated based on Agent tools)
Message Protocol Conversion
The framework includes a built-in messageProcessor that implements bidirectional conversion between A2A protocol messages and Agent message formats, so users don't need to worry about message format conversion details.
A2A Server Quick Start
Exposing Agent Services with A2A Server
With just a few lines of code, you can convert any Agent into an A2A service:
packagemainimport("trpc.group/trpc-go/trpc-agent-go/agent/llmagent""trpc.group/trpc-go/trpc-agent-go/model/openai"a2aserver"trpc.group/trpc-go/trpc-agent-go/server/a2a")funcmain(){// 1. Create a regular Agentmodel:=openai.New("gpt-4o-mini")agent:=llmagent.New("MyAgent",llmagent.WithModel(model),llmagent.WithDescription("An intelligent assistant"),)// 2. Convert to A2A service with one clickserver,_:=a2aserver.New(a2aserver.WithHost("localhost:8080"),a2aserver.WithAgent(agent),// Pass in any Agent)// 3. Start the service to accept A2A requestsserver.Start(":8080")}
import("trpc.group/trpc-go/trpc-a2a-go/client""trpc.group/trpc-go/trpc-a2a-go/protocol")funcmain(){// Connect to A2A serviceclient,_:=client.NewA2AClient("http://localhost:8080/")// Send message to Agentmessage:=protocol.NewMessage(protocol.MessageRoleUser,[]protocol.Part{protocol.NewTextPart("Hello, please help me analyze this code")},)// Agent will automatically process and return resultsresponse,_:=client.SendMessage(context.Background(),protocol.SendMessageParams{Message:message})}
A2AAgent: Calling Remote A2A Services
Corresponding to A2A Server, tRPC-Agent-Go also provides A2AAgent for calling remote A2A services, enabling communication between Agents.
Concept Introduction
A2AAgent is a special Agent implementation that doesn't directly handle user requests but forwards them to remote A2A services. From the user's perspective, A2AAgent looks like a regular Agent, but it's actually a local proxy for a remote Agent.
Simple Understanding:
- A2A Server: I have an Agent and want others to call it → Expose as A2A service
- A2AAgent: I want to call someone else's Agent → Call through A2AAgent proxy
Core Features
Transparent Proxy: Use remote Agents as if they were local Agents
Automatic Discovery: Automatically discover remote Agent capabilities through AgentCard
Protocol Conversion: Automatically handle conversion between local message formats and A2A protocol
Streaming Support: Support both streaming and non-streaming communication modes
State Transfer: Support transferring local state to remote Agents
Error Handling: Comprehensive error handling and retry mechanisms
Use Cases
Distributed Agent Systems: Call Agents from other services in microservice architectures
Agent Orchestration: Combine multiple specialized Agents into complex workflows
Cross-Team Collaboration: Call Agent services provided by other teams
packagemainimport("context""fmt""trpc.group/trpc-go/trpc-agent-go/agent/a2aagent""trpc.group/trpc-go/trpc-agent-go/runner""trpc.group/trpc-go/trpc-agent-go/model""trpc.group/trpc-go/trpc-agent-go/session/inmemory")funcmain(){// 1. Create A2AAgent pointing to remote A2A servicea2aAgent,err:=a2aagent.New(a2aagent.WithAgentCardURL("http://localhost:8888"),)iferr!=nil{panic(err)}// 2. Use it like a regular AgentsessionService:=inmemory.NewSessionService()runner:=runner.NewRunner("test",a2aAgent,runner.WithSessionService(sessionService))// 3. Send messageevents,err:=runner.Run(context.Background(),"user1","session1",model.NewUserMessage("Please tell me a joke"),)iferr!=nil{panic(err)}// 4. Handle responseforevent:=rangeevents{ifevent.Response!=nil&&len(event.Response.Choices)>0{fmt.Print(event.Response.Choices[0].Message.Content)}}}
packagemainimport("context""fmt""time""trpc.group/trpc-go/trpc-agent-go/agent/a2aagent""trpc.group/trpc-go/trpc-agent-go/agent/llmagent""trpc.group/trpc-go/trpc-agent-go/model/openai""trpc.group/trpc-go/trpc-agent-go/runner""trpc.group/trpc-go/trpc-agent-go/server/a2a""trpc.group/trpc-go/trpc-agent-go/session/inmemory")funcmain(){// 1. Create and start remote Agent serviceremoteAgent:=createRemoteAgent()startA2AServer(remoteAgent,"localhost:8888")time.Sleep(1*time.Second)// Wait for service to start// 2. Create A2AAgent connecting to remote servicea2aAgent,err:=a2aagent.New(a2aagent.WithAgentCardURL("http://localhost:8888"),a2aagent.WithTransferStateKey("user_context"),)iferr!=nil{panic(err)}// 3. Create local AgentlocalAgent:=createLocalAgent()// 4. Compare local and remote Agent responsescompareAgents(localAgent,a2aAgent)}funccreateRemoteAgent()agent.Agent{model:=openai.New("gpt-4o-mini")returnllmagent.New("JokeAgent",llmagent.WithModel(model),llmagent.WithDescription("I am a joke-telling agent"),llmagent.WithInstruction("Always respond with a funny joke"),)}funccreateLocalAgent()agent.Agent{model:=openai.New("gpt-4o-mini")returnllmagent.New("LocalAgent",llmagent.WithModel(model),llmagent.WithDescription("I am a local assistant"),)}funcstartA2AServer(agentagent.Agent,hoststring){server,err:=a2a.New(a2a.WithHost(host),a2a.WithAgent(agent,true),// Enable streaming)iferr!=nil{panic(err)}gofunc(){server.Start(host)}()}funccompareAgents(localAgent,remoteAgentagent.Agent){sessionService:=inmemory.NewSessionService()localRunner:=runner.NewRunner("local",localAgent,runner.WithSessionService(sessionService))remoteRunner:=runner.NewRunner("remote",remoteAgent,runner.WithSessionService(sessionService))userMessage:="Please tell me a joke"// Call local Agentfmt.Println("=== Local Agent Response ===")processAgent(localRunner,userMessage)// Call remote Agent (via A2AAgent)fmt.Println("\n=== Remote Agent Response (via A2AAgent) ===")processAgent(remoteRunner,userMessage)}funcprocessAgent(runnerrunner.Runner,messagestring){events,err:=runner.Run(context.Background(),"user1","session1",model.NewUserMessage(message),agent.WithRuntimeState(map[string]any{"user_context":"test_context",}),)iferr!=nil{fmt.Printf("Error: %v\n",err)return}forevent:=rangeevents{ifevent.Response!=nil&&len(event.Response.Choices)>0{content:=event.Response.Choices[0].Message.Contentifcontent==""{content=event.Response.Choices[0].Delta.Content}ifcontent!=""{fmt.Print(content)}}}fmt.Println()}
AgentCard Automatic Discovery
A2AAgent supports automatically obtaining remote Agent information through the standard AgentCard discovery mechanism:
// A2AAgent automatically retrieves AgentCard from the following path// http://remote-agent:8888/.well-known/agent.jsontypeAgentCardstruct{Namestring`json:"name"`Descriptionstring`json:"description"`URLstring`json:"url"`CapabilitiesAgentCardCapabilities`json:"capabilities"`}typeAgentCardCapabilitiesstruct{Streaming*bool`json:"streaming,omitempty"`}
State Transfer
A2AAgent supports transferring local runtime state to remote Agents:
a2aAgent,_:=a2aagent.New(a2aagent.WithAgentCardURL("http://remote-agent:8888"),// Specify state keys to transfera2aagent.WithTransferStateKey("user_id","session_context","preferences"),)// Runtime state is passed to remote Agent through A2A protocol metadata fieldevents,_:=runner.Run(ctx,userID,sessionID,message,agent.WithRuntimeState(map[string]any{"user_id":"12345","session_context":"shopping_cart","preferences":map[string]string{"language":"en"},}),)
Custom Converters
For special requirements, you can customize message and event converters: