简单学习 --> Agent集群
随着生成式 AI 的普及,企业内部的 AI 系统正从“单点应用”向“集群化”演进。当我们需要管理数十个业务 Agent 和成百上千个功能接口时,传统的代码耦合方式将成为瓶颈。本文将探讨如何利用 MCP (Model Context Protocol) 协议,构建一套标准化、高可观测且安全隔离的 Agent 集群架构。
为什么需要 MCP 集群架构?
在 Agent 集群初期,每个 Agent 往往各自维护工具集、提示词和资源。当系统规模扩大至 10+ 业务系统和 80+ 工具服务时,这种“烟囱式”架构会带来巨大的维护成本。
1. 核心痛点与解决思路
-
路由与调度 (The Router Layer)
-
通俗理解:大模型的上下文窗口就像考场上有限的桌面面积,你不可能把 100 本参考书全摊在桌上。你需要一个“图书管理员”,根据当前考题动态递给你最相关的 3 本书。
-
核心实现:引入 Agent Router。在实际开发中,我们通常会让网关层大模型先做一次轻量级的“意图识别”,然后再将对应的 MCP Server 注入到业务 Agent 中。
-
伪代码示例:
async def route_mcp_servers(user_query: str):
# 1. 轻量级模型进行意图分类
intent = await llm.classify(user_query, categories=["draw", "search", "database"])# 2. 根据意图动态挂载 MCP Server
active_servers = []
if intent == "draw":
active_servers.append(registry.get("image-mcp"))
elif intent == "database":
active_servers.append(registry.get("sql-mcp"))return active_servers
-
统一记忆体 (Global Memory)
-
通俗理解:如果客服 Agent 知道用户对花生过敏,但推荐 Agent 不知道,用户就会感到系统十分“弱智”。记忆体就像是一个全公司共享的VIP档案室。
-
核心实现:构建独立的用户画像 MCP。在数据库层面,我们使用 PostgreSQL 的
UPSERT特性来实现高并发下的幂等写入,确保跨项目的数据同步不会产生脏数据。
-
SQL 示例 (ON CONFLICT DO UPDATE):
INSERT INTO user_profiles (user_id, allergies, preference)
VALUES ('u1001', '花生', '极简风格')
ON CONFLICT (user_id)
DO UPDATE SET
allergies = EXCLUDED.allergies,
preference = EXCLUDED.preference,
updated_at = NOW();
-
链路追踪 (Observability)
-
痛点:当一通 AI 语音电话延迟了 3 秒,你无法判断是网关卡住了,还是外部大模型 API 变慢了。通过注入全局的
trace_id,我们可以清晰地观测整个调用链路。
-
架构核心设计:REST 与 MCP 的协议桥接
为了让现有 Web 系统无感接入 AI,我们基于 FastAPI 设计了 REST → MCP 协议桥接网关。
1. 四层中间件设计
网关的核心是请求拦截与处理。我们通过 FastAPI 的中间件链(Middleware)来实现认证、日志、配额管控与全链路追踪。
代码:网关中间件的核心逻辑
from fastapi import Request
import uuid
import time
@app.middleware("http")
async def gateway_core_middleware(request: Request, call_next):
# 1. 生成全局 Trace ID
trace_id = request.headers.get("X-Trace-Id", str(uuid.uuid4()))
# 2. 鉴权与配额检查 (AuthZ & Quota)
api_key = request.headers.get("Authorization")
project_id = await verify_and_get_project(api_key)
if not await check_quota_limit(project_id):
return JSONResponse({"error": "Quota Exceeded"}, status_code=429)
# 3. 记录请求开始时间,将 trace_id 注入上下文
start_time = time.time()
request.state.trace_id = trace_id
# 4. 执行路由与实际业务
response = await call_next(request)
# 5. 耗时埋点与日志对齐
process_time = time.time() - start_time
logger.info(f"[Trace: {trace_id}] Project: {project_id} | Path: {request.url.path} | Time: {process_time:.3f}s")
response.headers["X-Trace-Id"] = trace_id
return response
2. 通信机制:Streamable HTTP
MCP 需要 Client 和 Server 频繁进行意图确认(“你有加法工具吗?” -> “有” -> “帮我算 1+1”)。相比于单向推送的 SSE,基于 Streamable HTTP 的长连接机制就像是对讲机,握手一次即可保持双向通道,极大降低了重复建立连接的延迟。
为什么选择 Streamable HTTP?
在通信机制上,我们放弃了传统的单次 HTTP 请求和 SSE,选择了 Streamable HTTP。
-
SSE(单向大喇叭):像看电视直播,服务器一直播报,你只能听,不能插嘴。
-
Streamable HTTP(双向对讲机):像打微信电话。MCP 需要 Client 和 Server 频繁进行意图确认(“你有加法工具吗?” -> “有” -> “那帮我算 1+1”)。Streamable HTTP 握手一次即可保持长连接通道,极大降低了重复建立连接的延迟。
代码示例:基于 Streamable HTTP 的 MCP Client 极简实现 在实际业务中,网关层通过以下方式与 MCP Server 建立持久连接,并连续调用多个工具:
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
# 这里的 URL 通常由网关 Router 动态分配
url = "http://127.0.0.1:9000/mcp"
print(f"正在连接 MCP Server: {url}")
# 1. 修筑一条“双向高速通道”
async with streamablehttp_client(url) as (read, write, _):
# 2. 建立长连接会话
async with ClientSession(read, write) as session:
await session.initialize()
print("握手成功,通道已建立!\n")
# 3. 获取并调用工具 (无需反复断开和重连)
tools = await session.list_tools()
print(f"当前节点可用工具 ({len(tools.tools)} 个)")
# 连续执行多个任务
await session.call_tool("hello", {"name": "MCP Client"})
await session.call_tool("add_record", {"uid": 1001, "action": "login"})
Agent 集群部署流水线
高质量的集群部署依赖于云原生的底座。我们完全抛弃了传统的手动部署,全面拥抱 Serverless 与 CI/CD 自动化。
1. 自动化构建与推流
我们在 GitLab CI/CD 的 Shell 脚本中,自动化了镜像打包与推流的过程。为了不影响本地开发,我们通常会区分不同环境的 Dockerfile。
代码示例:触发构建与上传阿里云镜像仓库
# 1. 登录云端容器镜像服务
docker login --username=$ALIYUN_USER $REGISTRY_URL -p $ALIYUN_PWD
# 2. 使用专用的 Dockerfile.aliyun 构建多架构镜像
echo "开始构建 MCP Backend 镜像..."
docker build -f Dockerfile.aliyun --platform linux/amd64 \
-t $REGISTRY_URL/my-namespace/agent-backend:v1.0.0 .
# 3. 推送镜像至云端
docker push $REGISTRY_URL/my-namespace/agent-backend:v1.0.0
echo "部署包上传完成,触发 Serverless 平台拉取更新..."
2. 负载均衡与安全管控
部署到 Serverless (如 SAE / 云函数) 后,我们需要在网络层把守大门:
-
反向代理(CLB/Nginx - 接线员):负责把海量外部请求分配给最空闲的后端容器,自动剔除处于“不健康”状态的实例,并统一处理 HTTPS 证书卸载。
-
NAT 网关(安全传达室):
-
SNAT(代拨电话):让内网的 Agent 服务器能安全地访问外部的 OpenAI/豆包 API,同时隐藏物理 IP。
-
DNAT(分机转发):将公网特定端口的安全请求,精准映射到内网某个 MCP 服务的监听端口上。
-
3. 高可用策略
-
优雅降级:当“高级深度检索引擎”超时,Agent 不应直接抛出
500 Error,而是自动切换至简易版模型或返回预设的兜底话术(如:“资料库正在维护,请稍后再试”)。 -
令牌桶限流:通过配额管控,防止某个“实验性质的侧边栏小助手”因为 Bug 死循环,把公司主账号的大模型 API 额度瞬间刷爆。
总结
在落地 Agent 集群时,我们总结了以下核心法则:
1. Prompt 的解耦与外置管理
千万不要把提示词写死在代码的字符串里!我们通过 YAML 将 Prompt 独立为资产,服务端渲染后返回。 代码示例:YAML 格式的 Prompt 模板
YAML
name: "CustomerService"
version: "v2.0"
parameters:
- user_name
- user_portrait # 动态注入的用户画像
template: |
你是金牌客服。你正在接待 {user_name}。
根据记忆中心的数据,该用户具有以下特征:{user_portrait}
请根据用户的性格特征,使用恰当的语气进行回复。
好处:运营人员调整话术时,无需研发重新打包发布代码,热更新即时生效。
2. Agent 编排七步法
我们将复杂的 Agent 运行逻辑拆解为一条标准的流水线,就像米其林餐厅的后厨标准化作业:
-
召回历史 (看老顾客以前点过啥)
-
读取画像 (确认顾客有没有忌口)
-
检索知识 (翻看最新的菜谱)
-
渲染 Prompt (写一张包含所有要求的备菜条)
-
LLM 推理 (主厨开始做菜)
-
保存记忆 (把今天的点单记录存进系统)
-
提取事实 (备注:这名顾客今天觉得口味偏淡,以后多加盐)
通过这套流水线,Agent 本身不再持有复杂状态,而是变成了“无状态”的计算单元,所有状态都下沉到 MCP 共享服务中,极大地提升了系统的可扩展性。
3. 人工介入的底线
记住:模型训练即封印。AI 编程确实能解决 99% 的问题,但对于向量嵌入(Embedding)等核心逻辑,如果前置给到 AI 的文档语义切分就是错的,模型必然产生幻觉。那最后的 1%,始终需要人工进行数据清洗与架构纠偏。
更多推荐



所有评论(0)