Blog

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.

A2A- und MCP-Protokollagenten-Workflow

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_response

Der 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_check

Schritt 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 feedback

Der 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

Zugehörige Inhalte

Agent Builder, jenseits der Chatbox: Einführung von Augmented Infrastructure

Alexander Wert

Verwaltung von agentischem Gedächtnis mit Elasticsearch

Someshwaran Mohankumar

Die Verwendung der Elasticsearch Inference API zusammen mit Hugging Face-Modellen

Jeffrey Rengifo

Entwicklung eines KI-Agenten für die Personalabteilung mit Elastic Agent Builder und GPT-OSS

Tomás Murúa

Erstellung eines Elasticsearch MCP-Servers mit TypeScript

Jeffrey Rengifo

Sind Sie bereit, hochmoderne Sucherlebnisse zu schaffen?

Eine ausreichend fortgeschrittene Suche kann nicht durch die Bemühungen einer einzelnen Person erreicht werden. Elasticsearch wird von Datenwissenschaftlern, ML-Ops-Experten, Ingenieuren und vielen anderen unterstützt, die genauso leidenschaftlich an der Suche interessiert sind wie Sie. Lasst uns in Kontakt treten und zusammenarbeiten, um das magische Sucherlebnis zu schaffen, das Ihnen die gewünschten Ergebnisse liefert.

Probieren Sie es selbst aus