Erstellung eines LLM-Agenten-Newsrooms mit A2A-Protokoll und MCP in Elasticsearch: Teil II
Erfahren Sie, wie Sie einen spezialisierten hybriden LLM-Agenten-Newsroom aufbauen, indem Sie das A2A-Protokoll für die Agentenzusammenarbeit und MCP für den Werkzeugzugriff in Elasticsearch verwenden.
A2A und MCP: Der Code in Aktion
Dies ist der Begleitartikel zum Artikel „Erstellung eines LLM-Agent-Newsrooms mit A2A-Protokoll und MCP in Elasticsearch!“, in dem die Vorteile der Implementierung von A2A- und MCP-Architekturen innerhalb desselben Agenten erläutert wurden, um die einzigartigen Vorteile beider Frameworks voll auszuschöpfen. Ein Repository steht zur Verfügung, falls Sie die Demo selbst ausführen möchten.

Lassen Sie uns gemeinsam durchgehen, wie unsere Redakteure mithilfe von A2A und MCP zusammenarbeiten, um einen Nachrichtenartikel zu erstellen. Das zugehörige Repository, um die Agenten in Aktion zu sehen, finden Sie hier.
Schritt 1: Aufgabenstellung für die Geschichte
Der Nachrichtenchef (in der Rolle des Auftraggebers) vergibt eine Story:
{
"message_type": "task_request",
"sender": "news_chief",
"receiver": "reporter_agent",
"payload": {
"task_id": "story_renewable_energy_2024",
"assignment": {
"topic": "Renewable Energy Adoption in Europe",
"angle": "Policy changes driving solar and wind expansion",
"target_length": 1200,
"deadline": "2025-09-30T18:00:00Z"
}
}
}Schritt 2: Der Reporter bittet um Recherche
Der Reporteragent erkennt, dass er Hintergrundinformationen benötigt und delegiert diese über A2A an den Rechercheagenten :
{
"message_type": "task_request",
"sender": "reporter_agent",
"receiver": "researcher_agent",
"payload": {
"task_id": "research_eu_renewable_2024",
"parent_task_id": "story_renewable_energy_2024",
"capability": "fact_gathering",
"parameters": {
"queries": [
"EU renewable energy capacity 2024",
"Solar installations growth Europe",
"Wind energy policy changes 2024"
],
"depth": "comprehensive"
}
}
}Schritt 3: Der Reporter bittet den Archivar um historischen Kontext.
Der Reporteragent erkennt, dass ein historischer Kontext die Geschichte stärken würde. Es delegiert über A2A an den Archivagenten (basierend auf dem A2A-Agenten von Elastic), um das Elasticsearch-basierte Artikelarchiv des Newsrooms zu durchsuchen:
{
"message_type": "task_request",
"sender": "reporter_agent",
"receiver": "archive_agent",
"payload": {
"task_id": "archive_search_renewable_2024",
"parent_task_id": "story_renewable_energy_2024",
"capability": "search_archive",
"parameters": {
"query": "European renewable energy policy changes and adoption trends over past 5 years",
"focus_areas": ["solar", "wind", "policy", "Germany", "France"],
"time_range": "2019-2024",
"result_count": 10
}
}
}Schritt 4: Der Archivierungsagent verwendet den Elastic A2A-Agenten mit MCP.
Der Archive Agent verwendet den A2A Agent von Elastic, der wiederum MCP nutzt, um auf die Elasticsearch-Tools zuzugreifen. Dies veranschaulicht die Hybridarchitektur, bei der A2A die Zusammenarbeit von Agenten ermöglicht, während MCP den Zugriff auf Werkzeuge bereitstellt:
# Archive Agent using Elastic A2A Agent
async def search_historical_articles(self, query_params):
# The Archive Agent sends a request to Elastic's A2A Agent
elastic_response = await self.a2a_client.send_request(
agent="elastic_agent",
capability="search_and_analyze",
parameters={
"natural_language_query": query_params["query"],
"index_pattern": "newsroom-articles-*",
"filters": {
"topics": query_params["focus_areas"],
"date_range": query_params["time_range"]
},
"analysis_type": "trend_analysis"
}
)
# Elastic's A2A Agent internally uses MCP tools:
# - platform.core.search (to find relevant articles)
# - platform.core.generate_esql (to analyze trends)
# - platform.core.index_explorer (to identify relevant indices)
return elastic_responseDer Archivagent empfängt umfassende historische Daten vom A2A-Agenten von Elastic und sendet sie an den Reporter zurück:
{
"message_type": "task_response",
"sender": "archive_agent",
"receiver": "reporter_agent",
"payload": {
"task_id": "archive_search_renewable_2024",
"status": "completed",
"archive_data": {
"historical_articles": [
{
"title": "Germany's Energiewende: Five Years of Solar Growth",
"published": "2022-06-15",
"key_points": [
"Germany added 7 GW annually 2020-2022",
"Policy subsidies drove 60% of growth"
],
"relevance_score": 0.94
},
{
"title": "France Balances Nuclear and Renewables",
"published": "2023-03-20",
"key_points": [
"France increased renewable target to 40% by 2030",
"Solar capacity doubled 2021-2023"
],
"relevance_score": 0.89
}
],
"trend_analysis": {
"coverage_frequency": "EU renewable stories increased 150% since 2019",
"emerging_themes": ["policy incentives", "grid modernization", "battery storage"],
"coverage_gaps": ["Small member states", "offshore wind permitting"]
},
"total_articles_found": 47,
"search_confidence": 0.91
}
}
}Dieser Schritt demonstriert, wie sich der A2A-Agent von Elastic in den Workflow der Nachrichtenredaktion integriert. Der Archive Agent (ein speziell für Redaktionen entwickelter Agent) koordiniert sich mit dem A2A Agent von Elastic (einem Drittanbieter-Spezialisten), um die leistungsstarken Such- und Analysefunktionen von Elasticsearch optimal zu nutzen. Der Elastic-Agent nutzt intern MCP für den Zugriff auf Elasticsearch-Tools, was die klare Trennung zwischen Agentenkoordination (A2A) und Toolzugriff (MCP) verdeutlicht.
Schritt 5: Der Forscher nutzt MCP-Server
Der Forschungsagent greift auf mehrere MCP-Server zu, um Informationen zu sammeln:
# Researcher Agent using MCP to access tools
async def gather_facts(self, queries):
results = []
# Use News API MCP Server
news_data = await self.mcp_client.invoke_tool(
server="news_api_mcp",
tool="search_articles",
parameters={
"query": queries[0],
"date_range": "2024-01-01 to 2024-09-30",
"sources": ["reuters", "bloomberg", "euractiv"]
}
)
# Use Statistics MCP Server
stats_data = await self.mcp_client.invoke_tool(
server="eurostat_mcp",
tool="get_energy_statistics",
parameters={
"metrics": ["solar_capacity_mw", "wind_capacity_mw"],
"countries": ["EU27"],
"year": 2024
}
)
# Use Fact-Checking MCP Server
verified_facts = await self.mcp_client.invoke_tool(
server="factcheck_mcp",
tool="verify_claims",
parameters={
"claims": [
"EU solar capacity increased 40% in 2024",
"Germany leads in wind installations"
]
}
)
return self._synthesize_research(news_data, stats_data, verified_facts)Schritt 6: Der Forscher übermittelt die Daten an den Reporter.
Der Rechercheagent sendet die umfassenden Rechercheergebnisse über A2A zurück:
{
"message_type": "task_response",
"sender": "researcher_agent",
"receiver": "reporter_agent",
"payload": {
"task_id": "research_eu_renewable_2024",
"status": "completed",
"research_data": {
"key_facts": [
{
"claim": "EU solar capacity reached 260 GW in 2024",
"source": "Eurostat Q3 2024 Report",
"confidence": 0.95,
"verified": true
},
{
"claim": "Germany installed 12 GW of wind capacity in 2024",
"source": "German Federal Network Agency",
"confidence": 0.92,
"verified": true
}
],
"statistics": {
"solar_growth_rate": "35%",
"wind_growth_rate": "28%"
},
"sources_count": 15
}
}
}Schritt 7: Der Reporter schreibt einen Artikel
Der Reporteragent nutzt die Forschungsdaten und seine eigenen LLM-Fähigkeiten, um den Artikel zu schreiben. Beim Schreiben nutzt der Reporter die MCP-Server für Stil und Vorlagen:
# Reporter Agent writing with MCP assistance
async def write_article(self, research_data, assignment):
# Get style guidelines via MCP
style_guide = await self.mcp_client.get_resource(
server="newsroom_mcp",
resource="style://editorial/ap_style_guide"
)
# Get article template via MCP
template = await self.mcp_client.get_resource(
server="newsroom_mcp",
resource="template://articles/news_story"
)
# Generate article using LLM + research + style
draft = await self.llm.generate(
prompt=f"""
Write a news article following these guidelines:
{style_guide}
Using this template:
{template}
Based on this research:
{research_data}
Assignment: {assignment}
"""
)
# Self-evaluate confidence in claims
confidence_check = await self._evaluate_confidence(draft)
return draft, confidence_checkSchritt 8: Geringes Vertrauen löst erneute Recherche aus
Der Reporteragent prüft den Entwurf und stellt fest, dass eine Behauptung nur geringes Vertrauen genießt. Es sendet eine weitere Anfrage an den Forschungsagenten:
{
"message_type": "collaboration_request",
"sender": "reporter_agent",
"receiver": "researcher_agent",
"payload": {
"request_type": "fact_verification",
"claims": [
{
"text": "France's nuclear phase-down contributed to 15% increase in renewable capacity",
"context": "Discussing policy drivers for renewable growth",
"current_confidence": 0.45,
"required_confidence": 0.80
}
],
"urgency": "high"
}
}Der Forscher überprüft die Behauptung mithilfe von Faktencheck-Servern von MCP und liefert aktualisierte Informationen zurück:
{
"message_type": "collaboration_response",
"sender": "researcher_agent",
"receiver": "reporter_agent",
"payload": {
"verified_claims": [
{
"original_claim": "France's nuclear phase-down contributed to 15% increase...",
"verified_claim": "France's renewable capacity increased 18% in 2024, partially offsetting reduced nuclear output",
"confidence": 0.88,
"corrections": "Percentage was 18%, not 15%; nuclear phase-down is gradual, not primary driver",
"sources": ["RTE France", "French Energy Ministry Report 2024"]
}
]
}
}Schritt 9: Der Reporter überarbeitet den Text und reicht ihn beim Redakteur ein.
Der Reporter integriert die verifizierten Fakten und sendet den fertigen Entwurf per A2A an den Redaktionsagenten :
{
"message_type": "task_request",
"sender": "reporter_agent",
"receiver": "editor_agent",
"payload": {
"task_id": "edit_renewable_story",
"parent_task_id": "story_renewable_energy_2024",
"content": {
"headline": "Europe's Renewable Revolution: Solar and Wind Surge 30% in 2024",
"body": "[Full article text...]",
"word_count": 1185,
"sources": [/* array of sources */]
},
"editing_requirements": {
"check_style": true,
"check_facts": true,
"check_seo": true
}
}
}Schritt 10: Redaktionelle Überprüfungen mithilfe von MCP-Tools
Der Redaktionsagent nutzt mehrere MCP-Server zur Überprüfung des Artikels:
# Editor Agent using MCP for quality checks
async def review_article(self, content):
# Grammar and style check
grammar_issues = await self.mcp_client.invoke_tool(
server="grammarly_mcp",
tool="check_document",
parameters={"text": content["body"]}
)
# SEO optimization check
seo_analysis = await self.mcp_client.invoke_tool(
server="seo_mcp",
tool="analyze_content",
parameters={
"headline": content["headline"],
"body": content["body"],
"target_keywords": ["renewable energy", "Europe", "solar", "wind"]
}
)
# Plagiarism check
originality = await self.mcp_client.invoke_tool(
server="plagiarism_mcp",
tool="check_originality",
parameters={"text": content["body"]}
)
# Generate editorial feedback
feedback = await self._generate_feedback(
grammar_issues,
seo_analysis,
originality
)
return feedbackDer Redakteur genehmigt den Artikel und leitet ihn weiter:
{
"message_type": "task_response",
"sender": "editor_agent",
"receiver": "reporter_agent",
"payload": {
"status": "approved",
"quality_score": 9.2,
"minor_edits": [
"Changed 'surge' to 'increased' in paragraph 3 for AP style consistency",
"Added Oxford comma in list of countries"
],
"approved_content": "[Final edited article]"
}
}Schritt 11: Der Herausgeber veröffentlicht über CI/CD
Schließlich veröffentlicht der Druckeragent den genehmigten Artikel mithilfe der MCP-Server für die CMS- und CI/CD-Pipeline:
# Publisher Agent publishing via MCP
async def publish_article(self, content, metadata):
# Upload to CMS via MCP
cms_result = await self.mcp_client.invoke_tool(
server="wordpress_mcp",
tool="create_post",
parameters={
"title": content["headline"],
"body": content["body"],
"status": "draft",
"categories": metadata["categories"],
"tags": metadata["tags"],
"featured_image_url": metadata["image_url"]
}
)
post_id = cms_result["post_id"]
# Trigger CI/CD deployment via MCP
deploy_result = await self.mcp_client.invoke_tool(
server="cicd_mcp",
tool="trigger_deployment",
parameters={
"pipeline": "publish_article",
"environment": "production",
"post_id": post_id,
"schedule": "immediate"
}
)
# Track analytics
await self.mcp_client.invoke_tool(
server="analytics_mcp",
tool="register_publication",
parameters={
"post_id": post_id,
"publish_time": datetime.now().isoformat(),
"story_id": metadata["story_id"]
}
)
return {
"status": "published",
"post_id": post_id,
"url": f"https://newsroom.example.com/articles/{post_id}",
"deployment_id": deploy_result["deployment_id"]
}Der Verlag bestätigt die Veröffentlichung via A2A:
{
"message_type": "task_complete",
"sender": "printer_agent",
"receiver": "news_chief",
"payload": {
"task_id": "story_renewable_energy_2024",
"status": "published",
"publication": {
"url": "https://newsroom.example.com/articles/renewable-europe-2024",
"published_at": "2025-09-30T17:45:00Z",
"post_id": "12345"
},
"workflow_metrics": {
"total_time_minutes": 45,
"agents_involved": ["reporter", "researcher", "archive", "editor", "printer"],
"iterations": 2,
"mcp_calls": 12
}
}
}Hier ist die vollständige Abfolge des A2A-Workflows im zugehörigen Repository unter Verwendung der oben beschriebenen Agenten.
# | Aus | Zu | Aktion | Protokoll | Beschreibung |
|---|---|---|---|---|---|
1 | Benutzer | Nachrichtenchef | Geschichte zuweisen | HTTP POST | Der Nutzer gibt Thema und Blickwinkel der Geschichte vor. |
2 | Nachrichtenchef | Intern | Geschichte erstellen | - | Erstellt einen Story-Datensatz mit eindeutiger ID |
3 | Nachrichtenchef | Reporter | Delegiertenzuweisung | A2A | Sendet die Story-Aufgabe über das A2A-Protokoll. |
4 | Reporter | Intern | Auftrag annehmen | - | Interne Zuordnung der Lagerbestände |
5 | Reporter | MCP-Server | Gliederung erstellen | MCP/HTTP | Erstellt Gliederungen für Artikel und Forschungsfragen |
6a | Reporter | Forscher | Forschungsanfrage | A2A | Sendet Fragen (parallel zu 6b) |
6b | Reporter | Archivar | Archiv durchsuchen | A2A JSONRPC | Durchsucht historische Artikel (parallel zu 6a) |
7 | Forscher | MCP-Server | Forschungsfragen | MCP/HTTP | Nutzt Anthropic über MCP, um Fragen zu beantworten |
8 | Forscher | Reporter | Forschung zurückgeben | A2A | Antworten zur Renditeforschung |
9 | Archivar | Elasticsearch | Suchindex | ES REST-API | Abfragen zum Nachrichtenarchivindex |
10 | Archivar | Reporter | Zurück zum Archiv | A2A JSONRPC | Gibt historische Suchergebnisse zurück |
11 | Reporter | MCP-Server | Artikel generieren | MCP/HTTP | Erstellt einen Artikel mit Recherche-/Archivkontext |
12 | Reporter | Intern | Entwurf speichern | - | Speichert den Entwurf intern. |
13 | Reporter | Nachrichtenchef | Entwurf einreichen | A2A | Reicht den fertigen Entwurf ein |
14 | Nachrichtenchef | Intern | Update zur Geschichte | - | Speichert den Entwurf, aktualisiert den Status auf "draft_submitted" |
15 | Nachrichtenchef | Editor | Entwurf prüfen | A2A | Automatische Weiterleitung an den Redakteur zur Überprüfung |
16 | Editor | MCP-Server | Rezensionsartikel | MCP/HTTP | Analysiert Inhalte mithilfe von Anthropic über MCP |
17 | Editor | Nachrichtenchef | Rückgabeprüfung | A2A | Sendet redaktionelles Feedback und Vorschläge |
18 | Nachrichtenchef | Intern | Ladenbewertung | - | Feedback der Ladenredaktion |
19 | Nachrichtenchef | Reporter | Änderungen anwenden | A2A | Feedback zur Routenbewertung an den Reporter |
20 | Reporter | MCP-Server | Änderungen anwenden | MCP/HTTP | Überarbeitet den Artikel basierend auf dem Feedback |
21 | Reporter | Intern | Entwurf aktualisieren | - | Aktualisiert den Entwurf mit den Überarbeitungen |
22 | Reporter | Nachrichtenchef | Rückgabe überarbeitet | A2A | Artikel über die Rückgabe überarbeitet |
23 | Nachrichtenchef | Intern | Update zur Geschichte | - | Die Geschäfte haben den Entwurf überarbeitet, der Status lautet nun „überarbeitet“. |
24 | Nachrichtenchef | Herausgeber | Artikel veröffentlichen | A2A | Automatische Weiterleitung zum Herausgeber |
25 | Herausgeber | MCP-Server | Tags generieren | MCP/HTTP | Erstellt Tags und Kategorien |
26 | Herausgeber | Elasticsearch | Indexartikel | ES REST-API | Indexiert Artikel im Nachrichtenarchivindex |
27 | Herausgeber | Dateisystem | Markdown speichern | Datei-E/A | Speichert den Artikel als .md-Datei Datei in /articles |
28 | Herausgeber | Nachrichtenchef | Veröffentlichung bestätigen | A2A | Rückgabestatus: Erfolgreich |
29 | Nachrichtenchef | Intern | Update zur Geschichte | - | Aktualisiert den Status der Story auf „veröffentlicht“. |
Fazit
Sowohl A2A als auch MCP spielen eine wichtige Rolle im modernen erweiterten LLM-Infrastrukturparadigma. A2A bietet Flexibilität für komplexe Multiagentensysteme, jedoch potenziell geringere Portabilität und höhere operative Komplexität. MCP bietet einen standardisierten Ansatz für die Tool-Integration, der einfacher zu implementieren und zu warten ist, ist jedoch nicht für die Orchestrierung mehrerer Agenten ausgelegt.
Die Wahl ist nicht binär. Wie unser Beispiel aus der Redaktion zeigt, kombinieren die anspruchsvollsten und effektivsten LLM-gestützten Systeme oft beide Ansätze: Agenten koordinieren und spezialisieren sich über A2A-Protokolle, während sie über MCP-Server auf ihre Tools und Ressourcen zugreifen. Diese Hybridarchitektur bietet die organisatorischen Vorteile von Multiagentensystemen sowie die Standardisierungs- und Ökosystemvorteile von MCP. Dies deutet darauf hin, dass möglicherweise gar keine Wahlmöglichkeit besteht: Man könnte einfach beide als Standardansatz verwenden.
Es liegt an Ihnen als Entwickler oder Architekt, die beste Mischung beider Lösungen zu testen und zu ermitteln, um das richtige Ergebnis für Ihren spezifischen Anwendungsfall zu erzielen. Das Verständnis der Stärken, Grenzen und geeigneten Anwendungsbereiche der einzelnen Ansätze ermöglicht es Ihnen, effektivere, wartungsfreundlichere und skalierbare KI-Systeme zu entwickeln.
Egal, ob Sie eine digitale Nachrichtenredaktion, eine Kundenserviceplattform, einen Forschungsassistenten oder eine andere LLM-gestützte Anwendung entwickeln – die sorgfältige Berücksichtigung Ihrer Koordinierungsbedürfnisse (A2A) und Ihrer Anforderungen an den Werkzeugzugriff (MCP) wird Sie auf den Weg zum Erfolg führen.
Weitere Ressourcen
Elasticsearch Agent Builder: https://www.elastic.co/docs/solutions/search/elastic-agent-builder
A2A-Spezifikation: https://a2a-protocol.org/latest/specification/
A2A- und MCP-Integration: https://a2a-protocol.org/latest/topics/a2a-and-mcp/
Model Context Protocol: https://modelcontextprotocol.io




