博客

在 Elasticsearch 中使用 A2A 协议和 MCP 创建 LLM 代理新闻室:第二部分

了解如何使用 A2A 协议(用于代理协作)和 MCP(用于 Elasticsearch 中的工具访问)建立专门的混合 LLM 代理新闻室。

Agent Builder is available now GA. Get started with an Elastic Cloud Trial, and check out the documentation for Agent Builder here.

A2A 和 MCP:行动守则

本文是 "在 Elasticsearch 中使用 A2A 协议和 MCP 创建 LLM 代理新闻室!"一文的配套文章,该文章介绍了在同一个代理中同时实施 A2A 和 MCP 架构的好处,以真正获得这两种框架的独特优势。如果您希望自行运行演示,我们还提供了一个资源库

让我们来看看我们的新闻室代理是如何使用 A2A 和 MCP 协作来制作一篇新闻文章的。可在此处查看随附的存储库,了解代理的运行情况。

步骤 1:故事任务

新闻主管(作为客户)指定一篇报道:

{
  "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"
    }
  }
}

第 2 步:记者要求进行研究

报告代理认识到它需要背景信息,并通过 A2A 委托给研究代理

{
  "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"
    }
  }
}

第 3 步:报告人请求存档代理提供历史背景信息

记者代理认识到,历史背景会加强故事性。它通过 A2A 委托档案代理(由Elastic 的 A2A 代理提供支持)搜索新闻编辑室由 Elasticsearch 支持的文章档案:

{
  "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
    }
  }
}

步骤 4:归档代理使用带有 MCP 的弹性 A2A 代理

存档代理使用 Elastic 的 A2A 代理,而 A2A 代理又使用 MCP 访问 Elasticsearch 工具。这展示了混合架构,其中 A2A 实现了代理协作,而 MCP 提供了工具访问:

# 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

存档代理从 Elastic 的 A2A 代理接收全面的历史数据,并将其返回给报告器:

{
  "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
    }
  }
}

这一步骤演示了 Elastic 的 A2A Agent 如何集成到新闻编辑室的工作流程中。Archive Agent(新闻编辑室专用代理)与 Elastic 的 A2A Agent(第三方专家)协调,以利用 Elasticsearch 强大的搜索和分析功能。Elastic 的代理在内部使用 MCP 访问 Elasticsearch 工具,显示了代理协调 (A2A) 和工具访问 (MCP) 之间的明确分离。

步骤 5:研究人员使用 MCP 服务器

研究员代理访问多个 MCP 服务器以收集信息:

# 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)

步骤 6:研究人员将数据返回给报告人

研究员代理通过 A2A 发送综合研究结果:

{
  "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
    }
  }
}

第 7 步:记者撰写文章

报告代理利用研究数据和自身的 LLM 能力撰写文章。在撰写过程中,记者使用 MCP 服务器获取样式和模板:

# 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

第 8 步:信心不足引发重新研究

报告代理评估了其草稿,发现有一项索赔的可信度较低。它会向研究员代理发送另一个请求:

{
  "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"
  }
}

研究员使用事实核查 MCP 服务器核实索赔,并返回更新的信息:

{
  "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"]
      }
    ]
  }
}

第 9 步:记者修改并提交给编辑

记者将核实的事实纳入其中,并通过 A2A 将完成的草稿发送给编辑代理

{
  "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
    }
  }
}

步骤 10:编辑使用 MCP 工具进行审查

编辑代理使用多个 MCP 服务器来审核文章:

# 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

编辑批准文章并将其转发:

{
  "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]"
  }
}

第 11 步:发布者通过 CI/CD 发布

最后,打印机代理使用 CMS 和 CI/CD 管道的 MCP 服务器发布已批准的文章:

# 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"]
    }

出版商确认通过 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
    }
  }
}

下面是随附的资料库中使用上述相同代理的 A2A 工作流程的完整序列。

#

来自

行动

规程

描述

1

用户

新闻主管

指定故事

HTTP POST

用户提交故事主题和角度

2

新闻主管

内部

创建故事

-

创建具有唯一 ID 的故事记录

3

新闻主管

记者

代表任务

A2A

通过 A2A 协议发送故事任务

4

记者

内部

接受任务

-

内部存储任务

5

记者

MCP 服务器

生成大纲

MCP/HTTP

创建文章大纲和研究问题

6a

记者

研究员

申请研究

A2A

发送问题(与 6b 并行)

6b

记者

档案员

搜索档案

A2A JSONRPC

搜索历史文章(与 6a 并行)

7

研究员

MCP 服务器

研究问题

MCP/HTTP

通过 MCP 使用人类学来回答问题

8

研究员

记者

返回研究

A2A

返回研究答案

9

档案员

Elasticsearch

搜索索引

ES REST API

查询 news_archive 索引

10

档案员

记者

返回存档

A2A JSONRPC

返回历史搜索结果

11

记者

MCP 服务器

生成文章

MCP/HTTP

创建具有研究/档案背景的文章

12

记者

内部

商店草案

-

内部保存草稿

13

记者

新闻主管

提交草案

A2A

提交完成的草稿

14

新闻主管

内部

更新故事

-

存储草稿,将状态更新为"draft_submitted"

15

新闻主管

编辑

审查草案

A2A

自动路由至编辑器以供审核

16

编辑

MCP 服务器

评论文章

MCP/HTTP

通过 MCP 使用 Anthropic 分析内容

17

编辑

新闻主管

返回评论

A2A

发送编辑反馈和建议

18

新闻主管

内部

商店评论

-

存储编辑反馈

19

新闻主管

记者

应用编辑

A2A

将审查反馈意见转达给报告人

20

记者

MCP 服务器

应用编辑

MCP/HTTP

根据反馈意见修改文章

21

记者

内部

更新草案

-

对草案进行修订更新

220

记者

新闻主管

返回修订版

A2A

返回修订后的文章

23

新闻主管

内部

更新故事

-

存储修订草案,状态为"修订版"

24

新闻主管

出版商

发表文章

A2A

出版商自动路由

25

出版商

MCP 服务器

生成标签

MCP/HTTP

创建标记和类别

26

出版商

Elasticsearch

索引文章

ES REST API

将文章索引到 news_archive 索引

27

出版商

文件系统

保存标记

文件输入/输出

将文章保存为 .md文件在 /articles

28

出版商

新闻主管

确认出版

A2A

返回成功状态

29

新闻主管

内部

更新故事

-

将故事状态更新为"已发布"

结论

A2A 和 MCP 在现代增强型 LLM 基础设施范例中都可以发挥重要作用。A2A 为复杂的多代理系统提供了灵活性,但潜在的可移植性较差,操作复杂性较高。MCP 提供了一种标准化的工具集成方法,更易于实施和维护,但它并不是为处理多代理协调而设计的。

选择不是二元对立的。正如我们的新闻编辑室示例所示,最复杂、最有效的 LLM 支持系统往往将这两种方法结合在一起:代理通过 A2A 协议进行协调和专业化,同时通过 MCP 服务器访问其工具和资源。这种混合架构在提供多代理系统的组织优势的同时,还提供了 MCP 的标准化和生态系统优势。这表明可能根本不需要做出选择:只需将两者都作为标准方法使用即可

作为开发人员或架构师,您需要测试并确定这两种解决方案的最佳组合,从而为您的特定用例创造正确的结果。了解每种方法的优势、局限性和适当应用,将使您能够构建更有效、可维护和可扩展的人工智能系统。

无论您是要建立数字新闻编辑室、客户服务平台、研究助手,还是其他任何由 LLM 驱动的应用程序,仔细考虑您的协调需求 (A2A) 和工具访问要求 (MCP) 都将使您走上成功之路。

其他资源

相关内容

如何使用 Mastra 和 Elasticsearch 构建代理式 AI 应用程序

Enrico Zimuel

使用 TypeScript 构建 Elasticsearch MCP 服务器

Jeffrey Rengifo

shell 工具并非上下文工程的灵丹妙药

Leonie Monigatti

使用 Elasticsearch 推理 API 以及 Hugging Face 模型

Jeffrey Rengifo

适用 Elasticsearch 的 Gemini CLI 扩展及工具和技能

Walter Rafelsberger