|
| 1 | +--- |
| 2 | +sidebar_position: 190 |
| 3 | +--- |
| 4 | + |
| 5 | +# AgentRun 探秘:为什么要对 MCP 做进一步的拓展(智能路由,规则路由,Hook能力) |
| 6 | + |
| 7 | +MCP(Model Context Protocol)正在成为 Agent 应用中工具调用的事实标准。它提供了一套统一的协议,让 Agent 可以标准化地调用各种工具和 API。但当我们真正开始构建企业级 Agent 应用时,发现**原生 MCP 协议解决了"如何调用"的问题,却没有解决"如何用好"的问题。** |
| 8 | + |
| 9 | +## 企业级 Agent 应用面临的四大挑战 |
| 10 | +### 挑战一:相关工具太多,配置和管理成本高 |
| 11 | +用户说"写一段代码读取 data.csv 文件,处理后保存为 result.csv"。系统提供了代码解释器 Sandbox,包含多个独立的工具:`execute_code` 执行代码、`upload_file` 上传文件、`download_file` 下载文件、`delete_file` 删除文件、`list_files` 列出文件等。 |
| 12 | + |
| 13 | +问题是什么? 每个工具都需要单独配置 Sandbox 参数(超时时间、环境变量、资源限制等),5 个工具就要配置 5 次,容易遗漏或不一致。在 Agent 配置中需要逐一声明这 5 个工具,管理起来很繁琐。当 Sandbox 参数需要调整时(比如增加超时时间),需要修改 5 处配置。更头疼的是,Agent 的 Prompt 需要详细描述这 5 个工具的用途和使用方法,Prompt 变得冗长复杂。 |
| 14 | + |
| 15 | +**本质问题:原生 MCP 把一个完整能力拆成了多个孤立工具,但这些工具本应作为一个整体被使用和管理。** |
| 16 | + |
| 17 | +### 挑战二:工具越来越多,Agent 不知道该用哪个 |
| 18 | +平台上有几十个甚至上百个 MCP 工具:`code-executor-mcp`、`browser-automation-mcp`、`cloud-logs-mcp`、`database-query-mcp`……当用户发起请求,Agent 如何选择? |
| 19 | + |
| 20 | +传统做法是在 Prompt 中详细描述每个工具的用途,让大模型自己判断。但这会导致:Prompt 过长影响理解和成本;更致命的是,无法处理模糊请求——用户说"跑个脚本"、"看看服务有没有问题",这些表达没有明确关键词,单纯靠 Prompt 描述很难准确匹配。 |
| 21 | + |
| 22 | +**本质问题:原生 MCP 是纯协议,不关心"该用哪个工具",只关心"如何调用工具"。** |
| 23 | + |
| 24 | +### 挑战三:需要用户的云服务密钥,但绝对不能暴露 |
| 25 | +构建云厂商智能助手,用户 A 说"查询我的错误日志",需要调用云厂商 API,这需要用户 A 的 AccessKey 和 SecretKey。密钥不能硬编码(每个用户不同),不能让 Agent 持有(安全风险),不能让用户每次输入(体验差),也不能明文存储(合规风险)。 |
| 26 | + |
| 27 | +**需要的是:在工具调用前动态获取并注入密钥,调用后清理痕迹,全程对 Agent 和大模型透明,还要记录审计日志满足合规要求。** |
| 28 | + |
| 29 | +**本质问题:原生 MCP 没有提供在工具调用前后插入自定义逻辑的机制。** |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +这四大挑战可以总结为一个核心问题:**原生 MCP 提供了标准化的调用协议,但缺乏企业级场景所需的工具协作、智能选择、安全治理和状态管理能力。** |
| 34 | + |
| 35 | +```mermaid |
| 36 | +graph TB |
| 37 | + A[原生 MCP 协议] --> B[标准化的工具调用] |
| 38 | + |
| 39 | + B -.-> C1[❌ 挑战1<br/>工具孤立,状态不共享] |
| 40 | + B -.-> C2[❌ 挑战2<br/>工具选择依赖 Prompt] |
| 41 | + B -.-> C3[❌ 挑战3<br/>无法插入安全逻辑] |
| 42 | + B -.-> C4[❌ 挑战4<br/>无状态,无法连续操作] |
| 43 | + |
| 44 | + C1 --> D[企业级 Agent 应用<br/>无法落地] |
| 45 | + C2 --> D |
| 46 | + C3 --> D |
| 47 | + C4 --> D |
| 48 | + |
| 49 | + style A fill:#e3f2fd |
| 50 | + style D fill:#ffebee,color:#c62828 |
| 51 | + style C1 fill:#fff3e0 |
| 52 | + style C2 fill:#fff3e0 |
| 53 | + style C3 fill:#fff3e0 |
| 54 | + style C4 fill:#fff3e0 |
| 55 | +``` |
| 56 | + |
| 57 | +## AgentRun 的解决方案:三大扩展机制 |
| 58 | +面对这些挑战,AgentRun 对 MCP 进行了三个方向的深度扩展,每个扩展都是为了解决一类核心问题。 |
| 59 | + |
| 60 | +### 解决方案一:MCP 打包机制 - 让工具协作成为可能 |
| 61 | +**核心思路:将相关的工具打包成一个完整的能力单元,共享实例和状态。** |
| 62 | + |
| 63 | +**如何实现?** 创建 MCP 工具时,指定类型(sandbox、browser、memory 等),配置参数,选择要包含的工具列表。所有包含的工具自动共享同一个底层实例。 |
| 64 | + |
| 65 | +```yaml |
| 66 | +{ |
| 67 | + "name": "code-executor-mcp", |
| 68 | + "type": "sandbox", |
| 69 | + "description": "完整的代码执行环境", |
| 70 | + "sandboxId": "sandbox-xxx", |
| 71 | + "includedTools": [ |
| 72 | + "execute_code", |
| 73 | + "upload_file", |
| 74 | + "download_file", |
| 75 | + "delete_file" |
| 76 | + ], |
| 77 | + "config": { |
| 78 | + "timeout": 30000, |
| 79 | + "pythonVersion": "3.10" |
| 80 | + } |
| 81 | +} |
| 82 | +``` |
| 83 | + |
| 84 | +**对于 Browser 的特殊支持:** Browser MCP 支持配置 CDP 端点,包含的 18 个浏览器工具(点击、输入、导航、截图等)自动共享同一个浏览器实例,保持 cookies 和 session。 |
| 85 | + |
| 86 | +```yaml |
| 87 | +{ |
| 88 | + "name": "browser-automation-mcp", |
| 89 | + "type": "browser", |
| 90 | + "config": { |
| 91 | + "cdpEndpoint": "ws://browser.example.com/cdp", |
| 92 | + "browser": "chrome", |
| 93 | + "viewportSize": "1280x720" |
| 94 | + }, |
| 95 | + "includedTools": [ |
| 96 | + "browser_navigate", "browser_type", |
| 97 | + "browser_click", "browser_screenshot" |
| 98 | + ] |
| 99 | +} |
| 100 | +``` |
| 101 | + |
| 102 | +**解决了什么?** 配置集中管理,一次配置所有工具继承;状态自动共享,文件路径、环境变量在工具间保持;降低 Agent 复杂度,从"理解 4 个独立工具"变成"使用一个完整能力"。 |
| 103 | + |
| 104 | +### 解决方案二:智能路由 - 让工具选择自动化 |
| 105 | +**核心思路:通过规则路由和语义路由的组合,自动将用户请求匹配到最合适的 MCP 工具。** |
| 106 | + |
| 107 | +**规则路由:处理明确意图** |
| 108 | + |
| 109 | +配置关键词或正则表达式,快速匹配常见场景。 |
| 110 | + |
| 111 | +```yaml |
| 112 | +routing: |
| 113 | + rules: |
| 114 | + - condition: |
| 115 | + keywords: ["执行代码", "运行Python"] |
| 116 | + target: code-executor-mcp |
| 117 | + |
| 118 | + - condition: |
| 119 | + regex: ".*打开网页.*|.*浏览器.*" |
| 120 | + target: browser-automation-mcp |
| 121 | +``` |
| 122 | +
|
| 123 | +**语义路由:处理模糊意图** |
| 124 | +
|
| 125 | +当规则路由无法匹配时,使用 embedding 模型计算用户请求与每个 MCP 工具描述的语义相似度,选择最匹配的工具。 |
| 126 | +
|
| 127 | +```yaml |
| 128 | +semantic: |
| 129 | + enabled: true |
| 130 | + threshold: 0.75 |
| 131 | + modelConfig: |
| 132 | + type: "system" |
| 133 | + modelName: "text-embedding-3-small" |
| 134 | +``` |
| 135 | +
|
| 136 | +**工作流程:** |
| 137 | +
|
| 138 | +```mermaid |
| 139 | +graph LR |
| 140 | + A[用户请求] --> B{规则路由} |
| 141 | + B -->|命中关键词| C[立即路由到目标 MCP] |
| 142 | + B -->|无匹配| D[语义路由] |
| 143 | + D --> E[计算语义相似度] |
| 144 | + E --> F{相似度 > 0.75?} |
| 145 | + F -->|是| G[路由到最相似的 MCP] |
| 146 | + F -->|否| H[提示无法处理] |
| 147 | + |
| 148 | + style B fill:#51cf66,color:#fff |
| 149 | + style D fill:#51cf66,color:#fff |
| 150 | + style C fill:#4169e1,color:#fff |
| 151 | + style G fill:#4169e1,color:#fff |
| 152 | +``` |
| 153 | + |
| 154 | +**解决了什么?** 不需要在 Prompt 中描述所有工具,减轻大模型负担;规则路由快速处理常见场景,语义路由兜底处理边缘情况;支持自然语言多样性,用户怎么说都能匹配;降低 Token 成本,工具选择不消耗大模型资源。 |
| 155 | + |
| 156 | +### 解决方案三:Hook 机制 - 让企业级需求落地 |
| 157 | +**核心思路:在 MCP 调用前后提供标准化的拦截点,插入自定义逻辑。** |
| 158 | + |
| 159 | +**前置 Hook:Token 换密钥并注入** |
| 160 | + |
| 161 | +```javascript |
| 162 | +async function beforeExecute(context) { |
| 163 | + const { token, params } = context; |
| 164 | + |
| 165 | + // 1. 验证 Token,获取用户身份 |
| 166 | + const user = await TokenService.verify(token); |
| 167 | + |
| 168 | + // 2. 从密钥管理服务获取该用户的云服务密钥 |
| 169 | + const credentials = await SecretManager.get(user.id, 'cloud-api'); |
| 170 | + |
| 171 | + // 3. 动态注入到工具参数中 |
| 172 | + params.accessKey = credentials.accessKey; |
| 173 | + params.secretKey = credentials.secretKey; |
| 174 | + |
| 175 | + return params; |
| 176 | +} |
| 177 | +``` |
| 178 | + |
| 179 | +**后置 Hook:审计和清理** |
| 180 | + |
| 181 | +```javascript |
| 182 | +async function afterExecute(context, result) { |
| 183 | + // 记录审计日志 |
| 184 | + await AuditLog.create({ |
| 185 | + userId: context.user.id, |
| 186 | + action: context.toolName, |
| 187 | + timestamp: Date.now() |
| 188 | + }); |
| 189 | + |
| 190 | + // 清理敏感信息(如果结果中包含) |
| 191 | + delete result.credentials; |
| 192 | + |
| 193 | + return result; |
| 194 | +} |
| 195 | +``` |
| 196 | + |
| 197 | +**完整流程:** |
| 198 | + |
| 199 | +```mermaid |
| 200 | +sequenceDiagram |
| 201 | + participant U as 用户 A |
| 202 | + participant A as Agent |
| 203 | + participant Pre as 前置 Hook |
| 204 | + participant SM as 密钥服务 |
| 205 | + participant Tool as MCP 工具 |
| 206 | + participant Post as 后置 Hook |
| 207 | + |
| 208 | + U->>A: "查询我的错误日志"<br/>(携带 Token) |
| 209 | + A->>Pre: 调用 cloud-logs-mcp |
| 210 | + |
| 211 | + rect rgb(200, 230, 200) |
| 212 | + Note over Pre,SM: 安全处理 |
| 213 | + Pre->>Pre: 验证 Token |
| 214 | + Pre->>SM: 获取用户密钥 |
| 215 | + SM-->>Pre: AccessKey + SecretKey |
| 216 | + Pre->>Pre: 注入到参数 |
| 217 | + end |
| 218 | + |
| 219 | + Pre->>Tool: 执行工具<br/>(使用用户密钥) |
| 220 | + Tool-->>Post: 返回结果 |
| 221 | + |
| 222 | + rect rgb(200, 220, 240) |
| 223 | + Note over Post: 审计和清理 |
| 224 | + Post->>Post: 记录审计日志 |
| 225 | + Post->>Post: 清理敏感信息 |
| 226 | + end |
| 227 | + |
| 228 | + Post-->>A: 返回安全结果 |
| 229 | + A-->>U: 展示错误日志 |
| 230 | + |
| 231 | + Note over U,Post: 密钥从未暴露给 Agent 和大模型 |
| 232 | +``` |
| 233 | + |
| 234 | +**解决了什么?** 密钥零暴露,从未出现在 Agent、大模型、日志中;多租户自动隔离,每个用户获取各自的密钥;关注点分离,鉴权、凭证、审计等横切逻辑统一处理;满足合规要求,审计日志自动记录。 |
| 235 | + |
| 236 | +--- |
| 237 | + |
| 238 | +## AgentRun 的完整技术架构 |
| 239 | +三大扩展机制协同工作,形成完整的企业级 MCP 调用体系: |
| 240 | + |
| 241 | +```mermaid |
| 242 | +graph TB |
| 243 | + A[用户请求] --> B[智能路由层] |
| 244 | + |
| 245 | + subgraph route[智能路由] |
| 246 | + B --> C1[规则路由<br/>关键词/正则] |
| 247 | + B --> C2[语义路由<br/>相似度计算] |
| 248 | + end |
| 249 | + |
| 250 | + C1 & C2 --> D[选定 MCP 工具] |
| 251 | + |
| 252 | + D --> E[前置 Hook] |
| 253 | + |
| 254 | + subgraph hook1[前置处理] |
| 255 | + E --> E1[Token 验证] |
| 256 | + E1 --> E2[获取密钥] |
| 257 | + E2 --> E3[参数注入] |
| 258 | + end |
| 259 | + |
| 260 | + E3 --> F[MCP 工具包] |
| 261 | + |
| 262 | + subgraph mcp[MCP 打包 - 状态共享] |
| 263 | + F --> F1[工具 1] |
| 264 | + F --> F2[工具 2] |
| 265 | + F --> F3[工具 3] |
| 266 | + F1 & F2 & F3 --> F4[共享实例] |
| 267 | + end |
| 268 | + |
| 269 | + F4 --> G[后置 Hook] |
| 270 | + |
| 271 | + subgraph hook2[后置处理] |
| 272 | + G --> G1[结果处理] |
| 273 | + G1 --> G2[审计日志] |
| 274 | + G2 --> G3[清理敏感信息] |
| 275 | + end |
| 276 | + |
| 277 | + G3 --> H[返回结果] |
| 278 | + |
| 279 | + style B fill:#51cf66,color:#fff |
| 280 | + style E fill:#51cf66,color:#fff |
| 281 | + style G fill:#51cf66,color:#fff |
| 282 | + style F fill:#4169e1,color:#fff |
| 283 | + style H fill:#ffd700 |
| 284 | +``` |
| 285 | + |
| 286 | +**协同工作流程:** |
| 287 | + |
| 288 | +1. **智能路由层**:用户请求进来,先尝试规则路由快速匹配,如果没有命中则启用语义路由分析 |
| 289 | +2. **选定 MCP**:确定要调用哪个 MCP 工具 |
| 290 | +3. **前置 Hook**:验证身份、获取密钥、注入参数、记录日志 |
| 291 | +4. **MCP 打包**:调用工具包内的一个或多个工具,所有工具共享底层实例和状态 |
| 292 | +5. **后置 Hook**:处理结果、记录审计、清理敏感信息 |
| 293 | +6. **返回结果**:给 Agent 和最终用户 |
| 294 | + |
| 295 | +## 如何使用 AgentRun 的 MCP 能力 |
| 296 | +基于以上技术架构,AgentRun 提供了三种使用 MCP 的方式: |
| 297 | + |
| 298 | +### 方式一:从工具市场直接使用 |
| 299 | + |
| 300 | +<img width="3024" height="1714" alt="image" src="https://github.com/user-attachments/assets/4cca00ca-6eff-4baa-88fc-2f074d68f206" /> |
| 301 | + |
| 302 | + |
| 303 | +AgentRun 提供了工具市场,包含大量预制的 MCP 工具,涵盖代码执行、浏览器自动化、数据库查询、云服务操作等常见场景。**用户可以直接搜索、预览、一键添加**,无需从零配置。工具市场中的 MCP 都经过测试优化,包含完善的描述和示例。 |
| 304 | + |
| 305 | +**适用场景**:快速上线,使用标准能力,不需要深度定制。 |
| 306 | + |
| 307 | +### 方式二:导入已有 MCP 并通过代理增强 |
| 308 | + |
| 309 | +<img width="2158" height="1378" alt="image" src="https://github.com/user-attachments/assets/08a5f81b-8f9e-45a2-b927-29a08bff1315" /> |
| 310 | + |
| 311 | + |
| 312 | +如果你已经有现成的 MCP 工具(开源社区的、第三方的、自己开发的),可以通过 **MCP 代理**导入到 AgentRun。 |
| 313 | + |
| 314 | +**MCP 代理的核心价值**:让原生 MCP 工具也能享受 AgentRun 的扩展能力。导入后自动获得: |
| 315 | + |
| 316 | ++ Hook 支持(前置/后置处理) |
| 317 | ++ 智能路由(参与规则和语义路由) |
| 318 | ++ 统一治理(凭证管理、审计日志、监控告警) |
| 319 | + |
| 320 | +**适用场景**:已有 MCP 工具,希望增强企业级能力,不想重复开发。 |
| 321 | + |
| 322 | +### 方式三:多个 API 打包成 MCP |
| 323 | + |
| 324 | +<img width="2104" height="1312" alt="image" src="https://github.com/user-attachments/assets/ff26ca21-7d1a-42b4-a506-3707fcbc0292" /> |
| 325 | + |
| 326 | + |
| 327 | +AgentRun 支持**将多个相关的 API 打包成一个 MCP 工具**。比如云服务的多个 API:`ListFunctions`、`GetFunction`、`InvokeFunction`、`GetLogs`,可以打包成一个 `cloud-functions-mcp`。 |
| 328 | + |
| 329 | +打包时可以: |
| 330 | + |
| 331 | ++ 配置统一的鉴权方式(通过 Hook) |
| 332 | ++ 配置智能路由规则 |
| 333 | ++ 添加通用的错误处理和重试逻辑 |
| 334 | ++ 统一管理超时、限流等参数 |
| 335 | + |
| 336 | +**适用场景**:企业内部系统集成,把分散的 API 整合成 Agent 容易理解的能力单元。 |
| 337 | + |
| 338 | +AgentRun 对 MCP 的扩展,本质上是将 MCP 从一个工具调用协议升级为一个企业级的工具治理平台。 |
| 339 | + |
| 340 | +## 核心价值:从协议到平台的进化 |
| 341 | +MCP 打包让工具从孤立的能力点变成完整的能力单元,状态共享、配置统一。 |
| 342 | + |
| 343 | +智能路由让工具选择从手工配置 Prompt 变成系统自动决策,支持模糊意图和自然语言多样性。 |
| 344 | + |
| 345 | +Hook 机制让企业级需求(鉴权、凭证、审计、合规)从分散在各处的重复代码变成统一的治理策略。 |
| 346 | + |
| 347 | +MCP 代理让已有的原生 MCP 工具也能享受这些能力,不需要推倒重来。 |
| 348 | + |
| 349 | +工具市场和打包能力让 MCP 的创建、分享、复用变得简单,形成生态闭环。 |
| 350 | + |
| 351 | +更重要的是,这些扩展是渐进式的、非侵入的。你可以先用工具市场的现成 MCP 快速上线,随着需求复杂再导入自己的 MCP 并配置 Hook,最后将内部 API 打包成定制 MCP。每一步都有价值,每一步都不需要推倒重来。 |
| 352 | + |
| 353 | +当我们谈论 Agent 应用的企业级落地时,标准化的协议只是第一步,真正的挑战在于:**如何让工具好用、好管、好优化。**AgentRun 对 MCP 的扩展,正是在回答这个问题。从真实场景出发,提供完整的解决方案,这才是一个基础设施平台应有的价值。 |
| 354 | + |
0 commit comments