大家好,我是专注于分享前沿技术实战经验的博主。最近在探索AI Agent协同工作时,一个核心痛点浮出水面:如何让运行在不同环境、不同网络下的Agent能够安全、高效地发现彼此并建立通信?传统的中心化注册服务或复杂的网络穿透方案往往带来额外的运维负担和单点故障风险。本文将围绕一个创新的开源方案展开—— 利用Cloudflare Worker作为轻量级、全球化的“信标”,结合Model Context Protocol(MCP)实现Agent间的去中心化发现 。无论你是正在构建多Agent系统的开发者,还是对Serverless和AI应用集成感兴趣的工程师,这篇文章都将为你提供一套从原理到部署的完整实操指南。

1. 背景与核心概念:为什么需要Agent发现?

在构建复杂的AI应用时,单个Agent的能力是有限的。我们常常需要多个具备不同专长(如数据分析、代码执行、网络搜索)的Agent协同工作,形成一个“智能体团队”。这就引出了一个基础且关键的问题: Agent之间如何找到对方?

1.1 传统方案的挑战

  • 中心化注册表 :所有Agent启动时向一个中心服务器注册自己的地址和元数据。问题在于中心服务器成了单点故障和性能瓶颈,且需要维护。
  • 静态配置 :在配置文件中硬编码其他Agent的地址。这在动态伸缩、故障转移或Agent临时上线/下线的场景下极不灵活。
  • 复杂的服务网格 :引入如Consul、Etcd等服务发现组件,虽然功能强大,但也带来了显著的学习成本和运维复杂度,对于轻量级AI应用来说可能“杀鸡用牛刀”。

1.2 新方案的核心组件

本方案巧妙地结合了两个现代技术,提供了一个优雅的解决方案:

  1. Model Context Protocol (MCP)

    • 是什么 :MCP是由Anthropic提出的一种开放协议,旨在标准化AI应用(如Claude)与外部工具、数据源之间的通信方式。它定义了一套基于JSON-RPC的接口,用于资源发现、内容读取和工具调用。
    • 在本方案中的作用 :我们将MCP进行“创造性复用”。不仅用于AI与工具的交互,更将其作为 Agent之间通信的“标准语言” 。每个Agent都实现一个MCP服务器,对外提供自身的“能力”(作为工具)和“状态”(作为资源)。
  2. Cloudflare Worker

    • 是什么 :Cloudflare提供的无服务器函数计算平台,在全球数百个边缘节点运行,具备超低延迟、高可用的特性。
    • 在本方案中的作用 :作为轻量级的 发现信标和消息中转站 。它不存储Agent的长期状态,而是作为一个无状态的“公告板”和“邮局”,帮助Agent相互发现并传递初始连接信息。

核心思路 :每个Agent启动后,向一个公共的Cloudflare Worker“报到”。Worker记录下Agent的临时联系信息。当其他Agent需要寻找伙伴时,也询问同一个Worker,从而获得当前在线的Agent列表。后续的Agent间直接通信(通过MCP协议)则无需再经过Worker。

2. 环境准备与版本说明

在开始实战之前,请确保你的开发环境满足以下要求。本文示例将主要使用Node.js环境进行演示,但原理适用于任何能实现HTTP服务器和客户端的语言。

  • 操作系统 :Windows 10/11, macOS, 或 Linux (Ubuntu 20.04+)。方案与系统无关。
  • Node.js :版本 18.0.0 或更高。这是运行示例Agent和工具链的基础。
  • 包管理器 :npm 或 yarn。本文使用 npm
  • Cloudflare 账户 :你需要一个免费的Cloudflare账户来创建和部署Worker。
  • 命令行工具
    • wrangler :Cloudflare的官方Worker命令行工具。通过 npm install -g wrangler 安装。
    • curl httpie :用于测试API。
  • 代码编辑器 :VS Code 或其他你熟悉的IDE。

版本兼容性说明 :MCP协议本身处于快速发展中,本文基于其核心的、稳定的JSON-RPC规范进行设计。Cloudflare Worker的API保持向后兼容。请确保你的 wrangler 工具是最新版本。

3. 核心原理与架构拆解

让我们深入看看这个“Agent通过Worker发现彼此”的系统是如何工作的。

3.1 架构全景图

整个系统包含三个核心角色:

  1. Agent :实现特定功能的AI智能体。它同时扮演两个角色:
    • MCP服务器 :对外提供标准的 /mcp HTTP端点,供其他Agent或客户端查询其能力和资源。
    • Worker客户端 :定期或在启动时向Discovery Worker注册/更新自己的信息,并从Worker拉取其他Agent的信息。
  2. Discovery Worker (Cloudflare Worker) :一个无状态的Serverless函数,提供两个核心API:
    • POST /register :接收Agent的注册请求,将其元数据(如ID、名称、MCP服务器地址)存储在一个短暂的KV存储或内存中(可设置TTL)。
    • GET /discover :返回当前所有已注册且未过期的Agent列表。
  3. MCP协议 :作为Agent间通信的“普通话”。一旦Agent A通过Worker发现了Agent B的地址,它就可以直接向Agent B的MCP服务器发起标准的JSON-RPC调用,例如 tools/list 来查询B提供了哪些工具,然后调用 tools/call 来使用这些工具。
+----------------+      1. 注册       +----------------------+
|    Agent A     |------------------->|                      |
| (MCP Server @  |                   |   Discovery Worker    |
|  192.168.1.10) |<-------------------|   (Cloudflare Edge)  |
+----------------+      2. 发现列表   +----------------------+
         |                                      |
         | 3. 获取到B的地址                    | 4. 提供B的地址
         | (e.g., 192.168.1.20:8000)           |
         V                                      V
+----------------+      5. 直接MCP调用        +----------------+
|    Agent B     |<---------------------------|                |
| (MCP Server @  |                           |                |
| 192.168.1.20)  |--------------------------->|                |
+----------------+      6. MCP响应            +----------------+

3.2 关键设计决策

  • 去中心化通信 :Discovery Worker只负责最初的“介绍”。一旦Agent们互相认识,它们就会建立直接的P2P连接,避免了Worker成为后续所有通信的瓶颈。
  • 心跳与TTL :Agent定期向Worker发送心跳(通过再次调用 /register )以保持其注册信息有效。Worker为每个注册项设置一个生存时间(TTL,如30秒)。如果一个Agent崩溃了,它的注册信息会在TTL后自动过期并从发现列表中移除,实现了故障自愈。
  • 无状态Worker :Worker本身不持久化数据。我们使用Cloudflare的 KV命名空间 Durable Objects 来存储短暂的注册信息。KV更适合本例,因为它天然支持TTL。
  • 安全性考虑 :在生产环境中,需要对 /register 端点进行认证(例如使用共享密钥或JWT),以防止恶意Agent注册。Agent间的MCP通信也可以考虑使用TLS。

4. 完整实战:构建一个微型多Agent系统

现在,让我们动手搭建一个包含两个Agent和一个Discovery Worker的迷你系统。Agent A是一个“计算器”,Agent B是一个“天气查询员”。我们将让它们互相发现并调用对方的功能。

4.1 步骤一:创建并部署Discovery Worker

首先,我们创建负责Agent发现的Cloudflare Worker。

  1. 初始化Worker项目

    mkdir agent-discovery-worker && cd agent-discovery-worker
    npm create cloudflare@latest . -- --type=hello-world
    # 按照提示登录你的Cloudflare账户
    
  2. 绑定KV命名空间 : Worker需要存储Agent信息。在Cloudflare Dashboard中创建一个KV命名空间,命名为 AGENT_REGISTRY 。记下其ID。 在 wrangler.toml 文件中添加绑定:

    # wrangler.toml
    name = "agent-discovery-worker"
    main = "src/index.js"
    compatibility_date = "2024-08-01"
    
    [[kv_namespaces]]
    binding = "AGENT_REGISTRY" # 在Worker代码中使用的变量名
    id = "your-kv-namespace-id-here" # 替换为你的KV命名空间ID
    
  3. 编写Worker核心代码

    // src/index.js
    // 定义Agent信息的结构
    const AGENT_TTL = 30; // 注册信息存活时间(秒)
    
    export default {
      async fetch(request, env) {
        const url = new URL(request.url);
        const path = url.pathname;
    
        // 处理注册请求
        if (path === '/register' && request.method === 'POST') {
          try {
            const agentInfo = await request.json();
            // 基础验证
            if (!agentInfo.id || !agentInfo.name || !agentInfo.mcpEndpoint) {
              return new Response(JSON.stringify({ error: 'Missing required fields: id, name, mcpEndpoint' }), { status: 400 });
            }
    
            const key = `agent:${agentInfo.id}`;
            // 将Agent信息存入KV,并设置TTL
            await env.AGENT_REGISTRY.put(key, JSON.stringify(agentInfo), { expirationTtl: AGENT_TTL });
    
            return new Response(JSON.stringify({ success: true, message: 'Registered successfully', ttl: AGENT_TTL }), {
              status: 200,
              headers: { 'Content-Type': 'application/json' },
            });
          } catch (error) {
            return new Response(JSON.stringify({ error: 'Invalid JSON or processing error' }), { status: 500 });
          }
        }
    
        // 处理发现请求
        if (path === '/discover' && request.method === 'GET') {
          try {
            // 列出KV中所有以 `agent:` 为前缀的键
            const keys = await env.AGENT_REGISTRY.list({ prefix: 'agent:' });
            const agents = [];
    
            // 并行获取所有Agent的详细信息
            for (const key of keys.keys) {
              const value = await env.AGENT_REGISTRY.get(key.name);
              if (value) {
                agents.push(JSON.parse(value));
              }
            }
    
            return new Response(JSON.stringify({ success: true, agents }), {
              status: 200,
              headers: { 'Content-Type': 'application/json' },
            });
          } catch (error) {
            return new Response(JSON.stringify({ error: 'Discovery failed' }), { status: 500 });
          }
        }
    
        // 健康检查或未匹配的路由
        return new Response(JSON.stringify({ message: 'Agent Discovery Worker. Use POST /register or GET /discover' }), {
          headers: { 'Content-Type': 'application/json' },
        });
      },
    };
    
  4. 部署Worker

    npx wrangler deploy
    

    部署成功后,你会获得一个类似 https://agent-discovery-worker.<your-subdomain>.workers.dev 的URL。记下它,我们称之为 WORKER_URL

4.2 步骤二:创建“计算器”Agent A

我们创建一个简单的Node.js HTTP服务器,它既是一个MCP服务器,也会向Discovery Worker注册自己。

  1. 初始化项目并安装依赖

    mkdir calculator-agent && cd calculator-agent
    npm init -y
    npm install express cors
    
  2. 编写Agent A的代码

    // server.js
    const express = require('express');
    const cors = require('cors');
    const app = express();
    const PORT = process.env.PORT || 8001;
    const AGENT_ID = 'calc_agent_001';
    const AGENT_NAME = 'Advanced Calculator';
    // 替换为你的实际Worker URL
    const DISCOVERY_WORKER_URL = 'https://agent-discovery-worker.<your-subdomain>.workers.dev';
    
    app.use(cors());
    app.use(express.json());
    
    // 1. 实现MCP服务器端点
    app.post('/mcp', (req, res) => {
      const { method, params, id } = req.body;
    
      if (method === 'tools/list') {
        // 声明自己提供的工具
        res.json({
          jsonrpc: '2.0',
          id,
          result: {
            tools: [
              {
                name: 'add_numbers',
                description: 'Add two numbers together.',
                inputSchema: {
                  type: 'object',
                  properties: {
                    a: { type: 'number', description: 'First number' },
                    b: { type: 'number', description: 'Second number' },
                  },
                  required: ['a', 'b'],
                },
              },
              {
                name: 'multiply_numbers',
                description: 'Multiply two numbers.',
                inputSchema: {
                  type: 'object',
                  properties: {
                    a: { type: 'number' },
                    b: { type: 'number' },
                  },
                  required: ['a', 'b'],
                },
              },
            ],
          },
        });
      } else if (method === 'tools/call') {
        // 处理工具调用
        const { name, arguments: args } = params;
        let result;
        if (name === 'add_numbers') {
          result = args.a + args.b;
        } else if (name === 'multiply_numbers') {
          result = args.a * args.b;
        } else {
          return res.status(400).json({ jsonrpc: '2.0', id, error: { code: -32601, message: 'Method not found' } });
        }
        res.json({ jsonrpc: '2.0', id, result: { content: [{ type: 'text', text: String(result) }] } });
      } else {
        // 其他MCP方法(如resources/list)可以在此扩展
        res.status(400).json({ jsonrpc: '2.0', id, error: { code: -32601, message: 'Method not found' } });
      }
    });
    
    // 2. 向Discovery Worker注册自己的函数
    async function registerWithDiscovery() {
      const agentInfo = {
        id: AGENT_ID,
        name: AGENT_NAME,
        mcpEndpoint: `http://localhost:${PORT}/mcp`, // 注意:生产环境需用公网地址
        capabilities: ['arithmetic'],
        timestamp: new Date().toISOString(),
      };
    
      try {
        const response = await fetch(`${DISCOVERY_WORKER_URL}/register`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(agentInfo),
        });
        const data = await response.json();
        console.log(`[${AGENT_NAME}] Registration response:`, data);
      } catch (error) {
        console.error(`[${AGENT_NAME}] Failed to register:`, error.message);
      }
    }
    
    // 3. 定期发送心跳以维持注册
    setInterval(registerWithDiscovery, 20 * 1000); // 每20秒注册一次,小于TTL(30秒)
    
    // 4. 启动服务器并立即注册
    app.listen(PORT, async () => {
      console.log(`[${AGENT_NAME}] MCP server listening on http://localhost:${PORT}`);
      await registerWithDiscovery();
    });
    
  3. 运行Agent A

    node server.js
    

    控制台应输出服务器启动和注册成功的日志。

4.3 步骤三:创建“天气查询员”Agent B

Agent B的代码结构与A类似,但提供不同的工具。

  1. 创建新项目

    mkdir weather-agent && cd weather-agent
    npm init -y
    npm install express cors node-fetch
    
  2. 编写Agent B的代码

    // server.js
    const express = require('express');
    const cors = require('cors');
    const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args)); // 动态导入
    const app = express();
    const PORT = process.env.PORT || 8002;
    const AGENT_ID = 'weather_agent_001';
    const AGENT_NAME = 'City Weather Fetcher';
    const DISCOVERY_WORKER_URL = 'https://agent-discovery-worker.<your-subdomain>.workers.dev'; // 同上,替换
    // 模拟天气数据,真实场景可调用第三方API
    const mockWeatherData = {
      'Beijing': { temp: 22, condition: 'Sunny' },
      'Shanghai': { temp: 25, condition: 'Cloudy' },
      'New York': { temp: 18, condition: 'Rainy' },
    };
    
    app.use(cors());
    app.use(express.json());
    
    app.post('/mcp', (req, res) => {
      const { method, params, id } = req.body;
    
      if (method === 'tools/list') {
        res.json({
          jsonrpc: '2.0',
          id,
          result: {
            tools: [
              {
                name: 'get_weather',
                description: 'Get current weather for a city.',
                inputSchema: {
                  type: 'object',
                  properties: {
                    city: { type: 'string', description: 'City name' },
                  },
                  required: ['city'],
                },
              },
            ],
          },
        });
      } else if (method === 'tools/call') {
        const { name, arguments: args } = params;
        if (name === 'get_weather') {
          const city = args.city;
          const weather = mockWeatherData[city] || { temp: null, condition: 'Unknown city' };
          const resultText = weather.temp !== null 
            ? `Current weather in ${city}: ${weather.temp}°C, ${weather.condition}.`
            : `Sorry, weather data for ${city} is not available.`;
          res.json({ jsonrpc: '2.0', id, result: { content: [{ type: 'text', text: resultText }] } });
        } else {
          res.status(400).json({ jsonrpc: '2.0', id, error: { code: -32601, message: 'Method not found' } });
        }
      } else {
        res.status(400).json({ jsonrpc: '2.0', id, error: { code: -32601, message: 'Method not found' } });
      }
    });
    
    // 注册与心跳逻辑(与Agent A完全相同)
    async function registerWithDiscovery() {
      const agentInfo = {
        id: AGENT_ID,
        name: AGENT_NAME,
        mcpEndpoint: `http://localhost:${PORT}/mcp`,
        capabilities: ['weather'],
        timestamp: new Date().toISOString(),
      };
      try {
        const response = await fetch(`${DISCOVERY_WORKER_URL}/register`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(agentInfo),
        });
        const data = await response.json();
        console.log(`[${AGENT_NAME}] Registration response:`, data);
      } catch (error) {
        console.error(`[${AGENT_NAME}] Failed to register:`, error.message);
      }
    }
    setInterval(registerWithDiscovery, 20 * 1000);
    
    app.listen(PORT, async () => {
      console.log(`[${AGENT_NAME}] MCP server listening on http://localhost:${PORT}`);
      await registerWithDiscovery();
    });
    
  3. 运行Agent B

    node server.js
    

4.4 步骤四:测试发现与交互

现在,我们有两个Agent在运行并已向Worker注册。让我们验证发现机制,并模拟一个Agent调用另一个Agent工具的过程。

  1. 测试Discovery Worker : 在终端中,使用 curl 查询所有已注册的Agent。

    curl -X GET https://agent-discovery-worker.<your-subdomain>.workers.dev/discover
    

    你应该会收到一个JSON响应,包含两个Agent的信息,类似于:

    {
      "success": true,
      "agents": [
        {
          "id": "calc_agent_001",
          "name": "Advanced Calculator",
          "mcpEndpoint": "http://localhost:8001/mcp",
          "capabilities": ["arithmetic"],
          "timestamp": "..."
        },
        {
          "id": "weather_agent_001",
          "name": "City Weather Fetcher",
          "mcpEndpoint": "http://localhost:8002/mcp",
          "capabilities": ["weather"],
          "timestamp": "..."
        }
      ]
    }
    

    这表明发现服务工作正常。

  2. 模拟Agent间调用 : 我们写一个简单的测试脚本,模拟“计算器Agent”在发现了“天气Agent”后,去查询天气。

    // test_discovery_and_call.js
    const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
    const DISCOVERY_WORKER_URL = 'https://agent-discovery-worker.<your-subdomain>.workers.dev';
    
    async function discoverAndCall() {
      console.log('1. Discovering available agents...');
      const discoverRes = await fetch(`${DISCOVERY_WORKER_URL}/discover`);
      const discoverData = await discoverRes.json();
      
      if (!discoverData.success || discoverData.agents.length === 0) {
        console.log('No agents found.');
        return;
      }
    
      console.log(`Found ${discoverData.agents.length} agent(s):`);
      discoverData.agents.forEach(agent => console.log(` - ${agent.name} (${agent.id})`));
    
      // 2. 找到天气Agent
      const weatherAgent = discoverData.agents.find(a => a.capabilities.includes('weather'));
      if (!weatherAgent) {
        console.log('No weather agent found.');
        return;
      }
      console.log(`\n2. Found weather agent at: ${weatherAgent.mcpEndpoint}`);
    
      // 3. 直接调用天气Agent的MCP接口查询工具列表
      console.log('3. Fetching tools from weather agent...');
      const listToolsReq = {
        jsonrpc: '2.0',
        id: 1,
        method: 'tools/list',
        params: {},
      };
      const toolsRes = await fetch(weatherAgent.mcpEndpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(listToolsReq),
      });
      const toolsData = await toolsRes.json();
      console.log('Tools available:', JSON.stringify(toolsData.result.tools, null, 2));
    
      // 4. 调用天气查询工具
      const callToolReq = {
        jsonrpc: '2.0',
        id: 2,
        method: 'tools/call',
        params: {
          name: 'get_weather',
          arguments: { city: 'Beijing' },
        },
      };
      console.log('\n4. Calling weather tool for Beijing...');
      const callRes = await fetch(weatherAgent.mcpEndpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(callToolReq),
      });
      const callData = await callRes.json();
      console.log('Weather result:', callData.result.content[0].text);
    }
    
    discoverAndCall().catch(console.error);
    
  3. 运行测试脚本

    node test_discovery_and_call.js
    

    输出应展示完整的发现和调用流程:

    1. Discovering available agents...
    Found 2 agent(s):
     - Advanced Calculator (calc_agent_001)
     - City Weather Fetcher (weather_agent_001)
    
    2. Found weather agent at: http://localhost:8002/mcp
    3. Fetching tools from weather agent...
    Tools available: [...]
    4. Calling weather tool for Beijing...
    Weather result: Current weather in Beijing: 22°C, Sunny.
    

恭喜! 你已经成功搭建了一个基于Cloudflare Worker和MCP协议的去中心化Agent发现与协作系统。Agent A和B通过Worker找到了彼此,并成功进行了直接的服务调用。

5. 常见问题与排查思路

在实际部署和运行中,你可能会遇到以下问题:

问题现象 可能原因 排查步骤与解决方案
Agent注册到Worker失败( Failed to register 1. Worker URL错误。
2. Worker代码部署失败或存在语法错误。
3. KV命名空间未正确绑定或权限不足。
4. 网络问题。
1. 检查 DISCOVERY_WORKER_URL 变量是否正确。
2. 运行 wrangler tail 查看Worker实时日志,排查错误。
3. 在Cloudflare Dashboard确认KV命名空间已绑定,且 wrangler.toml 中的ID正确。
4. 使用 curl 直接测试Worker的根路径,看是否返回预期信息。
发现列表为空( No agents found 1. Agent的注册逻辑未执行或报错。
2. Agent注册的TTL已过期,且心跳未维持。
3. Worker的 /discover 接口逻辑有误。
1. 检查Agent控制台,确认 registerWithDiscovery 函数被调用且无报错。
2. 确保Agent的心跳间隔(如20秒)小于Worker设置的TTL(如30秒)。
3. 直接调用 GET /discover ,并检查Worker日志,看KV列表操作是否成功。
Agent间直接MCP调用失败(网络错误) 1. mcpEndpoint 地址不可达(如使用了 localhost )。
2. 目标Agent的MCP服务器未运行或端口被占用。
3. 防火墙或安全组规则阻止了连接。
1. 这是开发中最常见的问题 。确保 mcpEndpoint 是其他Agent能访问的地址。在本地开发时,可使用内网IP(如 http://192.168.1.x:port/mcp )或借助内网穿透工具(如ngrok)。生产环境必须使用公网域名或IP。
2. 检查目标Agent的进程是否存活,端口是否监听。
3. 检查本地和服务器防火墙设置。
MCP调用返回 Method not found 1. JSON-RPC method 字段拼写错误。
2. Agent的MCP服务器未实现对应的 tools/list tools/call 方法。
3. 请求体格式不符合JSON-RPC 2.0规范。
1. 仔细对照MCP协议规范,检查 method 字符串(如 tools/list )。
2. 确保目标Agent的 /mcp 端点正确解析了 method 并实现了对应分支逻辑。
3. 使用工具(如Postman)检查发送的请求体格式,确保包含 jsonrpc , id , method , params 等必需字段。
Worker返回 520 5xx 错误 Cloudflare Worker运行时错误。 1. 使用 wrangler tail --format pretty 查看详细的错误堆栈。
2. 常见原因:未处理的异常、异步操作未 await 、KV操作超限(免费计划有速率限制)。
3. 简化代码,逐步调试。

6. 最佳实践与工程建议

将本方案用于实际生产环境时,需要考虑以下方面以提升系统的可靠性、安全性和可维护性。

6.1 安全加固

  • 认证与授权
    • 在Worker的 /register 端点添加认证。例如,要求Agent在注册时提供一个预共享密钥(PSK),Worker验证该密钥后才接受注册。
    // Worker端
    const EXPECTED_AUTH_HEADER = 'Bearer your-shared-secret-token';
    const authHeader = request.headers.get('Authorization');
    if (authHeader !== EXPECTED_AUTH_HEADER) {
      return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401 });
    }
    
    • 考虑使用JWT,使Token可以包含更多元数据(如Agent角色、权限)并设置有效期。
  • 通信安全
    • Agent间的MCP通信应使用HTTPS(TLS)加密,防止中间人攻击。确保 mcpEndpoint https:// 开头。
    • 在内部网络中,可以考虑使用mTLS(双向TLS)进行更严格的认证。

6.2 可扩展性与可靠性

  • 使用Durable Objects替代KV :对于更复杂的状态管理(如需要强一致性、实时通知Agent下线),可以考虑使用Cloudflare Durable Objects。它可以维护WebSocket连接,在Agent下线时立即通知其他Agent。
  • 多区域与高可用 :Cloudflare Worker天然在全球边缘运行,已具备高可用性。对于Agent本身,可以考虑部署多个实例,并在注册时带上健康检查端点,Worker可以定期检查Agent健康状态,只返回健康的Agent。
  • 元数据与版本控制 :在Agent注册信息中增加 version 字段。这样,请求方可以发现并选择兼容版本的Agent进行调用,避免API不匹配的问题。

6.3 生产环境部署要点

  • 服务发现 mcpEndpoint 必须是一个 稳定的、可被其他所有Agent访问的网络地址 。可以是:
    • 公网IP+端口(需配置安全组和防火墙)。
    • 域名(通过DNS解析)。
    • 内部服务网格中的服务名(如Kubernetes Service)。
  • 优雅下线 :Agent在关闭前,应主动向Worker发送一个注销请求(例如 DELETE /register/{agent_id} ),让Worker立即将其从发现列表中移除,而不是等待TTL过期。
  • 监控与日志
    • 为Worker和每个Agent添加详细的日志,记录注册、发现、调用关键事件和错误。
    • 利用Cloudflare的Analytics监控Worker的调用次数和错误率。
    • 为Agent设置健康检查接口,便于运维。

6.4 协议扩展与生态集成

  • 丰富MCP内容 :除了 tools ,MCP协议还定义了 resources (资源)和 prompts (提示词)。你可以让Agent对外提供数据资源(如数据库连接)或可复用的提示模板,进一步增强协作能力。
  • 与现有MCP客户端集成 :本方案中的Agent本身就是一个MCP服务器。这意味着它可以被任何支持MCP协议的 客户端 (如Claude Desktop、支持MCP的IDE插件)直接连接和使用。这极大地扩展了Agent的用途。
  • 定义通用接口 :为你的多Agent系统定义一些通用的工具接口(例如 ask_question , process_data ),让不同类型的Agent都能以统一的方式被调用,促进异构Agent间的协作。

这个基于Cloudflare Worker和MCP的Agent发现方案,为我们构建灵活、松散耦合、可扩展的多智能体系统提供了一个强大的基础框架。它巧妙地将无服务器的全球网络与标准化的AI协议相结合,降低了分布式AI应用的入门门槛。你可以在此基础上,继续探索更复杂的路由策略、负载均衡、语义发现(根据能力描述而非ID发现)等高级特性,打造出真正智能的Agent网络。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐