博客

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

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

A2A 和 MCP:行动守则

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

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) 都将使您走上成功之路。

其他资源

相关内容

Agent Builder,超越聊天框:介绍增强型基础架构

Alexander Wert

使用 Elasticsearch 管理智能体记忆

Someshwaran Mohankumar

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

Jeffrey Rengifo

利用弹性代理生成器和 GPT-OSS 构建人力资源人工智能代理

Tomás Murúa

使用 TypeScript 构建 Elasticsearch MCP 服务器

Jeffrey Rengifo

准备好打造最先进的搜索体验了吗?

足够先进的搜索不是一个人的努力就能实现的。Elasticsearch 由数据科学家、ML 操作员、工程师以及更多和您一样对搜索充满热情的人提供支持。让我们联系起来,共同打造神奇的搜索体验,让您获得想要的结果。

亲自试用