AI Gateway 设计:用 MCP 构建企业级 AI 服务网关
探讨如何基于 Model Context Protocol 设计企业级 AI Gateway,实现统一的工具管理、权限控制和流量调度。
当企业内部有数十个 MCP Server、数百个工具时,如何统一管理它们的访问、权限和监控?AI Gateway 是解决这个问题的关键基础设施。
为什么需要 AI Gateway
在小规模场景下,MCP Client 直接连接 Server 就够了。但在企业环境中,面临以下挑战:
服务发现——Server 可能分布在不同的机器和网络中,Client 需要知道去哪里连接。
权限控制——不同的用户和 Agent 有不同的工具访问权限。
流量管理——需要限流、熔断、负载均衡。
审计合规——所有工具调用需要记录和审计。
版本管理——Server 可能有多个版本同时运行。
AI Gateway 作为所有 MCP 通信的统一入口,解决这些问题。
架构设计
┌──────────────────────────────────────────────┐
│ AI Gateway │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌───────┐ │
│ │认证鉴权│ │限流熔断│ │路由分发│ │审计日志│ │
│ └────────┘ └────────┘ └────────┘ └───────┘ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ 工具注册中心 │ │
│ └─────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│ Server A│ │ Server B│ │ Server C│
│ v1.0 │ │ v2.0 │ │ v1.5 │
└─────────┘ └─────────┘ └─────────┘
核心组件实现
工具注册中心
interface ToolRegistration {
name: string;
description: string;
inputSchema: any;
serverName: string;
serverUrl: string;
version: string;
permissions: string[];
rateLimit: number;
}
class ToolRegistry {
private tools: Map<string, ToolRegistration> = new Map();
register(tool: ToolRegistration) {
this.tools.set(tool.name, tool);
console.error(`[Registry] 注册工具: ${tool.name} (${tool.serverName})`);
}
unregister(toolName: string) {
this.tools.delete(toolName);
}
get(toolName: string): ToolRegistration | undefined {
return this.tools.get(toolName);
}
list(filter?: { serverName?: string; permission?: string }): ToolRegistration[] {
let tools = Array.from(this.tools.values());
if (filter?.serverName) {
tools = tools.filter(t => t.serverName === filter.serverName);
}
if (filter?.permission) {
tools = tools.filter(t => t.permissions.includes(filter.permission));
}
return tools;
}
}
认证鉴权中间件
interface AuthContext {
userId: string;
roles: string[];
permissions: string[];
}
class AuthMiddleware {
private apiKeys: Map<string, AuthContext> = new Map();
registerApiKey(key: string, context: AuthContext) {
this.apiKeys.set(key, context);
}
authenticate(apiKey: string): AuthContext | null {
return this.apiKeys.get(apiKey) || null;
}
authorize(context: AuthContext, tool: ToolRegistration): boolean {
// 检查用户是否有权限调用该工具
return tool.permissions.some(p => context.permissions.includes(p));
}
}
限流器
class RateLimiter {
private windows: Map<string, number[]> = new Map();
check(key: string, limit: number, windowMs: number = 60000): boolean {
const now = Date.now();
const timestamps = this.windows.get(key) || [];
const recent = timestamps.filter(t => now - t < windowMs);
if (recent.length >= limit) {
return false;
}
recent.push(now);
this.windows.set(key, recent);
return true;
}
getRemaining(key: string, limit: number, windowMs: number = 60000): number {
const now = Date.now();
const timestamps = this.windows.get(key) || [];
const recent = timestamps.filter(t => now - t < windowMs);
return Math.max(0, limit - recent.length);
}
}
审计日志
interface AuditEntry {
timestamp: string;
userId: string;
toolName: string;
serverName: string;
arguments: any;
result: 'success' | 'error';
duration: number;
error?: string;
}
class AuditLogger {
private logFile: fs.WriteStream;
constructor(logPath: string) {
this.logFile = fs.createWriteStream(logPath, { flags: 'a' });
}
log(entry: AuditEntry) {
this.logFile.write(JSON.stringify(entry) + '\n');
}
}
Gateway 主体
import express from 'express';
class AIGateway {
private app = express();
private registry: ToolRegistry;
private auth: AuthMiddleware;
private rateLimiter: RateLimiter;
private audit: AuditLogger;
constructor() {
this.registry = new ToolRegistry();
this.auth = new AuthMiddleware();
this.rateLimiter = new RateLimiter();
this.audit = new AuditLogger('/var/log/ai-gateway/audit.log');
this.setupRoutes();
}
private setupRoutes() {
this.app.use(express.json());
// 工具列表
this.app.get('/tools', (req, res) => {
const apiKey = req.headers['x-api-key'] as string;
const context = this.auth.authenticate(apiKey);
if (!context) {
return res.status(401).json({ error: 'Unauthorized' });
}
const tools = this.registry.list({ permission: context.permissions[0] });
res.json({ tools });
});
// 工具调用
this.app.post('/tools/:name/call', async (req, res) => {
const startTime = Date.now();
const apiKey = req.headers['x-api-key'] as string;
const toolName = req.params.name;
// 认证
const context = this.auth.authenticate(apiKey);
if (!context) {
return res.status(401).json({ error: 'Unauthorized' });
}
// 查找工具
const tool = this.registry.get(toolName);
if (!tool) {
return res.status(404).json({ error: 'Tool not found' });
}
// 鉴权
if (!this.auth.authorize(context, tool)) {
return res.status(403).json({ error: 'Forbidden' });
}
// 限流
if (!this.rateLimiter.check(context.userId, tool.rateLimit)) {
return res.status(429).json({ error: 'Rate limit exceeded' });
}
// 调用
try {
const result = await this.callServer(tool, req.body.arguments);
this.audit.log({
timestamp: new Date().toISOString(),
userId: context.userId,
toolName,
serverName: tool.serverName,
arguments: req.body.arguments,
result: 'success',
duration: Date.now() - startTime,
});
res.json(result);
} catch (error) {
this.audit.log({
timestamp: new Date().toISOString(),
userId: context.userId,
toolName,
serverName: tool.serverName,
arguments: req.body.arguments,
result: 'error',
duration: Date.now() - startTime,
error: error.message,
});
res.status(500).json({ error: error.message });
}
});
}
private async callServer(tool: ToolRegistration, args: any): Promise<any> {
// 通过 HTTP 调用 MCP Server
const response = await fetch(`${tool.serverUrl}/tools/${tool.name}/call`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ arguments: args }),
});
return response.json();
}
start(port: number) {
this.app.listen(port, () => {
console.error(`[Gateway] 监听端口 ${port}`);
});
}
}
常见问题(FAQ)
Gateway 会增加多少延迟?
通常增加 5-10ms,主要是认证和路由的开销。在大多数场景下可以接受。
Gateway 如何处理 Server 的高可用?
Gateway 可以对同一个工具配置多个 Server 实例,实现负载均衡和故障转移。
如何扩展 Gateway?
Gateway 是无状态的,可以通过增加实例进行水平扩展。工具注册中心可以使用 Redis 等外部存储实现共享。
总结
AI Gateway 是企业级 MCP 部署的关键基础设施。它将安全、路由、监控等横切关注点从各个 Server 中抽离出来,形成统一的管理层。在构建大规模 Agent 系统时,Gateway 是不可或缺的组件。