-
Notifications
You must be signed in to change notification settings - Fork 395
Add a blog post about multi-language agent collaboration with A2A #2398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
248 changes: 248 additions & 0 deletions
248
_posts/2025-09-15-quarkus-a2a-multi-agent-content-creation.adoc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. | ||
cescoffier marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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 | ||
cescoffier marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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] | ||
|
|
||
cescoffier marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
Binary file added
BIN
+136 KB
...mages/posts/quarkus-a2a-multi-agent-content-creation/ContentCreationDiagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+140 KB
...mages/posts/quarkus-a2a-multi-agent-content-creation/ContentCreationSwapped.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.