diff --git a/_posts/2025-09-15-quarkus-a2a-multi-agent-content-creation.adoc b/_posts/2025-09-15-quarkus-a2a-multi-agent-content-creation.adoc new file mode 100644 index 0000000000..5ef9cfc07b --- /dev/null +++ b/_posts/2025-09-15-quarkus-a2a-multi-agent-content-creation.adoc @@ -0,0 +1,248 @@ +--- +layout: post +title: 'Multi-Language Agent Collaboration and Interoperability with A2A' +date: 2025-09-15 +tags: ai a2a +synopsis: Let's learn how to build a multi-agent system where agents written in different languages and with different LLM frameworks can seamlessly collaborate using A2A. +author: fjuma +--- +:imagesdir: /assets/images/posts/quarkus-a2a-multi-agent-content-creation + +Building a multi-agent system can involve using different languages to meet specific needs. The https://a2a-protocol.org/latest/[Agent2Agent (A2A) protocol] is an open standard that enables AI agents to communicate and collaborate with one another, regardless of each agent's underlying technology stack. + +In this post, we'll see how to create a multi-agent system, where agents written in Java, Python, and TypeScript work together to accomplish a goal: content creation. The multi-agent system uses A2A for communication between the AI agents. + +image::ContentCreationDiagram.png[scaledwidth=100%] + +== Content Creation Sample + +We're going to do a deep dive into the https://github.com/a2aproject/a2a-samples/tree/main/samples/python/hosts/content_creation[Content Creation] sample from the https://github.com/a2aproject/a2a-samples[a2a-samples] project. + +This sample showcases a content creation pipeline with a `Host` agent that acts as the central orchestrator, +dynamically routing requests to a set of specialized agents. + +=== Agents + +Here's a quick overview of all the agents in our multi-agent system: + +[cols="a,a,a,a",options=header] +|=== +| Agent | Role | Technology Stack | Description + +| *Host* +| A2A Client +| Python, Google ADK, A2A Python SDK +| Serves as the central orchestrator, routing requests to the appropriate agent based on the task at hand. + +| *Content Planner* +| A2A Server +| Python, Google ADK, A2A Python SDK +| Receives a high-level content request and creates a detailed content outline. + +| *Content Writer* +| A2A Server +| Java, Quarkus LangChain4j, A2A Java SDK +| Generates engaging content from a content outline. + +| *Content Editor* +| A2A Server +| TypeScript, Genkit, A2A JS SDK +| Proofreads and polishes the given content. +|=== + +Notice that the agents are written in different programming languages and make use of different LLM frameworks. +This is to demonstrate what's possible with the A2A protocol. + +=== Handling a Content Creation Request + +Upon receiving a content creation request from the user, the `Host` agent breaks down the content creation task +into a few different sub-tasks: planning, writing, and editing. + +==== Dynamic Agent Selection +The `Host` agent uses an LLM and the agent cards from our specialized A2A server agents to determine which agent to assign a particular sub-task to. For example, let's take a look at the agent card for our `Content Writer` agent: + +[source,json] +---- +{ + "name": "Content Writer Agent", + "description": "An agent that can write a comprehensive and engaging piece of content based on the provided outline and high-level description of the content", + "url": "http://localhost:10002", + "version": "1.0.0", + "documentationUrl": "http://example.com/docs", + "capabilities": { + "streaming": true, + "pushNotifications": false, + "stateTransitionHistory": false + }, + "defaultInputModes": [ + "text" + ], + "defaultOutputModes": [ + "text" + ], + "skills": [ + { + "id": "writer", + "name": "Writes content using an outline", + "description": "Writes content using a given outline and high-level description of the content", + "tags": [ + "writer" + ], + "examples": [ + "Write a short, upbeat, and encouraging twitter post about learning Java. Base your writing on the given outline." + ] + } + ], + "supportsAuthenticatedExtendedCard": false, + "additionalInterfaces": [ + { + "transport": "JSONRPC", + "url": "http://localhost:10002" + } + ], + "preferredTransport": "JSONRPC", + "protocolVersion": "0.3.0" +} +---- + +[NOTE] +==== +The agent card for an A2A server agent can be found using its Well-Known URI, e.g., for the `Content Writer` agent, we can fetch its agent card using http://localhost:10002/.well-known/agent-card.json. +==== + +The description and skills specified in the agent card for the `Content Writer` agent allow the `Host` agent's LLM to determine that the writing sub-task should be sent to the `Content Writer` agent. + +==== Agent Communication + +The `Host` agent communicates with each A2A server agent using an A2A client. Notice that an A2A client +does not need to be written in the same programming language as an A2A server since all that matters is +that both are using the A2A protocol to communicate with each other. + +Later on in this post, we'll see how we can easily swap out the TypeScript `Content Editor` agent for +an equivalent agent written in Java, highlighting the flexibility and interoperability that's made +possible by the A2A protocol. + +=== Running the Agents + +Let's get this multi-agent system running locally. + +==== Content Planner + +In a terminal: + +[source,shell] +---- +cd samples/python/agents/content_planner +---- + +Follow the instructions in the `content_planner` https://github.com/a2aproject/a2a-samples/blob/main/samples/python/agents/content_planner/README.md[README.md] to start the `Content Planner` agent. + +==== Content Writer + +In a terminal: + +[source,shell] +---- +cd samples/java/agents/content_writer +---- + +Follow the instructions in the `content_writer` https://github.com/a2aproject/a2a-samples/blob/main/samples/java/agents/content_writer/README.md[README.md] to start the `Content Writer` agent. + +==== Content Editor + +In a terminal: + +[source,shell] +---- +cd samples/js/src/agents/content-editor +---- + +Follow the instructions in the `content-editor` https://github.com/a2aproject/a2a-samples/blob/main/samples/js/src/agents/content-editor/README.md[README.md] to start the `Content Editor` agent. + +==== Host + +In a terminal: + +[source,shell] +---- +cd samples/python/hosts/content_creation +uv run . +---- + +[NOTE] +==== +As mentioned in the agent `README.md` files, don't forget to create a `.env` file for each agent with your +`GOOGLE_API_KEY`. This is needed since the agents in this sample make use of Gemini. You can create a +Google AI Studio API Key for free https://aistudio.google.com/[here]. +==== + +=== Access the Content Creation Application + +Now that all of our agents are up and running, from your browser, navigate to http://localhost:8083. + +Try asking questions like: + +* Create a short, concise LinkedIn post about getting started with the Agent2Agent protocol +* Create a short, upbeat X post about Quarkus LangChain4j + +image::UI.png[scaledwidth=100%] + +=== Swap Out an Agent + +One of the most powerful features of the A2A protocol is its interoperability. Let's see this in +action by swapping out the TypeScript-based `Content Editor` agent for an equivalent agent written +in Java. + +image::ContentCreationSwapped.png[scaledwidth=100%] + +==== Stop the TypeScript Content Editor Agent and Host Agent + +First, stop the `Host` agent and the `Content Editor` agent so we can swap out the `Content Editor` agent for +an equivalent agent written with Java instead of TypeScript. + +==== Start the Java Content Editor Agent + +In a terminal: + +[source,java] +---- +cd samples/java/agents/content_editor +---- + +Follow the instructions in the `content_editor` https://github.com/a2aproject/a2a-samples/blob/main/samples/java/agents/content_editor/README.md[README.md] to start the `Content Editor` agent. + +==== Start the Host Agent + +In a terminal: + +[source,shell] +---- +cd samples/python/hosts/content_creation +uv run . +---- + +==== Access the Content Creation Application + +From your browser, navigate to http://localhost:8083 and try asking some questions. + +This time, the `Host` agent will seamlessly use the Java-based `Content Editor` agent for editing +content instead of the TypeScript-based `Content Editor` agent. This flexibility is made possible +because the A2A protocol is language-agnostic. This can be really useful for prototyping agents +in one language to get things up and running quickly and then migrating to another language for +a production environment. + +== Conclusion + +In this post, we saw how to use the A2A protocol to enable agents written in different programming +languages and with different LLM frameworks to collaborate seamlessly to accomplish a goal. We also +saw how easy it is to swap out one of the agents for an equivalent agent written in a different language. + +=== Further Reading + +* https://github.com/a2aproject/a2a-samples/blob/main/samples/python/hosts/content_creation/README.md[Content Creation Sample] +* https://quarkus.io/blog/quarkus-a2a-java-0-3-0-alpha-release/[Getting Started with Quarkus and A2A Java SDK 0.3.0] +* https://github.com/a2aproject/a2a-samples/tree/main/samples/java/agents[A2A Java SDK Samples] +* https://github.com/a2aproject/a2a-java/blob/main/README.md[A2A Java SDK Documentation] +* https://a2a-protocol.org/latest/specification/[A2A Specification] + + diff --git a/assets/images/posts/quarkus-a2a-multi-agent-content-creation/ContentCreationDiagram.png b/assets/images/posts/quarkus-a2a-multi-agent-content-creation/ContentCreationDiagram.png new file mode 100644 index 0000000000..2eb2a69a9b Binary files /dev/null and b/assets/images/posts/quarkus-a2a-multi-agent-content-creation/ContentCreationDiagram.png differ diff --git a/assets/images/posts/quarkus-a2a-multi-agent-content-creation/ContentCreationSwapped.png b/assets/images/posts/quarkus-a2a-multi-agent-content-creation/ContentCreationSwapped.png new file mode 100644 index 0000000000..1ea6de98ed Binary files /dev/null and b/assets/images/posts/quarkus-a2a-multi-agent-content-creation/ContentCreationSwapped.png differ diff --git a/assets/images/posts/quarkus-a2a-multi-agent-content-creation/UI.png b/assets/images/posts/quarkus-a2a-multi-agent-content-creation/UI.png new file mode 100644 index 0000000000..5616cb5e0c Binary files /dev/null and b/assets/images/posts/quarkus-a2a-multi-agent-content-creation/UI.png differ