基于MCP的智能体平台:重塑网络运维告警排查与变更管理
做网络运维的同学应该都有过类似的体验凌晨两点被告警电话叫醒爬起来登录设备敲十几条 show 命令翻路由表、查接口状态、比对变更记录最后发现是某条光纤链路抖动半个小时就这么过去了。如果是跨区域网络还得拉上好几个同事一起对日志、对时间线。更头疼的是这一套经验往往只存在于几个老师傅的脑子里新人来了根本接不住。我这次想聊的项目就是冲着这个痛点去的——做一套基于 MCPModel Context Protocol的智能体平台把大语言模型真正接进网络运维链路里让它可以读告警、查设备、跑诊断命令、分析根因甚至辅助生成变更方案和合规校验报告。项目代号就叫 Agent for Network从调研到落地大概用了两个多月。这篇文章会把整体设计、核心实现、三个落地场景、以及踩过的坑完整梳理一遍适合正在做网络运维自动化、或者想用大模型改造内部工具链的朋友参考。1. 项目概述MCP 智能体平台要解决什么问题1.1 网络运维的现状与痛点先说背景。我们团队负责的网络规模不算小核心网、数据中心、分支互联加起来有上千台设备监控平台每天产生的告警量在万条级别。表面看监控、工单、变更流程都有但实际上大家心里都清楚告警风暴严重。一个链路抖动能衍生出几十条告警真正需要人关注的根因可能就一条。值班人员大量的精力花在“把衍生告警过滤掉”上而不是判断故障影响。排障高度依赖个人经验。网络故障不像应用故障有完整的调用链追踪很多时候就是凭感觉先看接口 down/up 状态再看光功率、日志、路由邻居最后看变更窗口。这套排查顺序每个老师傅心里都有一本账但很少有人愿意把它沉淀成标准流程。变更操作风险高。网络设备不像服务器可以随便回滚一条命令敲错可能直接导致业务中断。变更窗口通常安排在深夜评审靠人工翻配置效率低不说还容易漏掉关联影响。我们最初的想法很简单能不能让大模型替我们把“信息收集 初步分析”这部分工作干了但试了一段时间发现光有模型还不够。模型不能自己登录设备不能查监控数据更不能执行命令。它需要一个标准化的“手脚”也就是工具调用能力。1.2 MCP 协议为什么适合做这件事在做 Agent for Network 之前我们其实已经做过一版基于某大模型私有工具调用接口的自动化脚本。那个版本最大的问题不是不好用而是太“私有化”了工具的注册方式、参数描述、调用协议全都绑在特定模型厂商的接口上换一个模型就要重写一遍对接层多个 Agent 之间也没法复用工具。MCP 协议的出现正好解决了这个痛点。它的核心思路很朴素把“模型能调用的工具”抽象成一套标准接口。工具方只需要实现一个 MCP Server把每个工具的描述、参数 Schema、调用方式暴露出来模型所在的 Agent 侧通过 MCP Client 就能动态发现并调用这些工具。模型和工具彻底解耦。用一句不太严谨但好理解的话说MCP 之于大模型应用有点像 USB 之于外设——你只要做出一台支持 USB 标准的设备插到任何电脑上都能用你只要写一个符合 MCP 标准的工具服务任何支持 MCP 的 Agent 都能调度它。MCP 协议本身的几个特点也和我们场景很匹配标准化的工具描述。每个工具用 JSON Schema 描述入参和出参大模型能基于这个描述自动决定何时调用、传什么参数不需要我们为每个模型单独写 prompt 来“教”它怎么调用。支持多种原语。除了最常用的 Tool可执行操作MCP 还定义了 Resource只读数据和 Prompt提示词模板。这三个原语配合起来既能做设备数据查询也能提供排障流程模板比单纯工具调用灵活得多。传输方式可选。本地进程用 stdio跨机器部署用 HTTP我们可以在安全性和灵活性之间做取舍。生态复用。一个工具服务写好后多个 Agent 都能接入。后面我们新接告警分析、变更影响评估等场景时底层的设备诊断工具全都直接复用没有额外开发成本。1.3 平台定位与目标用户在做架构之前我们明确了一点这不是要取代监控平台也不是要做一套新的运维系统。它更像是在现有监控、工单、设备管理之上加了一层“智能操作层”。监控平台负责发现问题Agent for Network 负责理解问题、收敛信息、产出判断把最终决策交给人。目标用户有三类一线值班的 NOC 人员他们用自然语言就能完成大部分日常排障信息收集二线网络专家他们用这个平台做变更前的配置预检和影响分析还有变更评审人员他们借助平台的合规校验和 diff 结果快速完成审批。定位明确之后很多设计决策就好做了只读诊断能力优先做写操作配置变更放在第二阶段且必须有人工审批每个工具能自动执行到什么程度、哪些命令允许模型调用都要在工具设计阶段就定清楚。2. 整体架构设计与工具集规划2.1 分层架构与模块职责整个平台我按四层来设计每一层只干自己那一摊事边界尽量清晰最上层是接入层提供 Web 对话界面和 IM 机器人入口值班人员直接在聊天框里提问比如“查一下核心交换机最近一小时有没有丢包”“这台设备的 CPU 使用率趋势如何”。往下是 Agent 编排层这是智能体的大脑所在。它负责理解用户意图、编排任务、维护多轮对话上下文并调用 MCP Client 去发现和调用工具。模型本身并不直接操作任何设备它只负责“思考”和“决策”。再往下是 MCP 工具层由一组 MCP Server 组成。我们拆了三个 Server设备诊断 Server登录设备执行 show 命令、SNMP 查询、监控数据 Server拉取告警、性能指标、工单与通知 Server创建工单、发送通知。拆分的依据是“归属域不同、安全等级不同”后面做权限控制时也方便。最底层是基础设施也就是现网已有的设备、监控平台、工单系统和 CMDB。这一层我们基本没动只是通过适配器把这些系统的能力封装成工具暴露给上层。为什么要单独加一个 MCP 工具层而不是让 Agent 直接连各种系统因为直接连的话每接一个新系统Agent 主流程就要改一次而且设备和监控系统的接口千差万别有的走 SSH、有的走 REST API、有的走 SNMP统一封装到 MCP Server 后Agent 侧看到的工具就是干干净净的“查询设备状态”“拉取告警列表”底层的协议差异完全被屏蔽了。这也是整个项目能快速迭代的关键。2.2 MCP 工具集设计原则工具设计是整个项目里最花心思的部分。工具粒度、参数设计、描述质量直接决定了模型能不能正确调用。我们踩了不少坑最后沉淀出几条原则工具粒度分两层。底层是原子工具比如 ping、查询接口状态、查看路由表一个工具只做一件事模型很好理解上层是组合工具比如“一键排障诊断”“告警根因分析”内部封装了多个原子步骤。模型先尝试用组合工具组合工具覆盖不了的时候会自动降级到原子工具。这个设计对模型非常友好也减少了调用次数。工具描述必须“说人话”。MCP 的工具描述是给模型看的不是给开发看的。我们在每个 tool 的 description 里写明什么时候该用这个工具触发条件、参数含义、返回内容示例。比如描述一个查光功率的工具我们写的是“当怀疑光模块异常或链路质量下降时使用返回端口收发光功率值”模型看到这个描述就很容易在故障场景中联想到调用它。参数尽量少而结构化。我们有个惨痛教训第一个版本的“执行设备命令”工具只给了两个参数设备地址、命令内容模型经常自己脑补一些不存在的命令去执行。后来改成“命令白名单枚举”的方式后模型只能从预先定义好的命令集合里选误调率大幅下降。对于必须自由输入的场景我们也加了命令正则校验不匹配直接拒绝。每个工具都要标注副作用。我们在工具元数据里加了一个自定义字段risk_level分成 read-only、low-risk、high-risk 三档。Agent 编排层读到 high-risk 的工具会自动进入人工审批流程模型绝对不能直接执行。2.3 工具清单与权限边界设备诊断 Server 是我们第一个做的也是后续所有场景的地基。它的核心工具如下工具名功能说明副作用等级get_device_status查询设备 CPU、内存、运行时长等基本状态只读get_interface_status查询端口 up/down 状态、速率、错误计数只读get_interface_metrics查询端口流量、光功率等性能指标只读get_routing_table查看路由表只读get_device_logs查询设备日志支持时间范围和关键字过滤只读ping_host从平台侧发起网络连通性探测只读exec_show_command在白名单内执行 show/display 类诊断命令只读deploy_config下发配置变更预检后高危需审批rollback_config回滚配置变更高危需审批这里要说明一下exec_show_command和上面那些结构化工具的区别。理论上我们尽量用结构化工具因为返回的是字段清晰的 JSON模型好理解但网络设备的诊断场景五花八门总有覆盖不到的查询所以保留一个白名单内的“自由命令”工具兜底。白名单的维护方式是把设备厂商和命令类别做成配置表新增命令要走评审防止模型拿到一把“万能钥匙”乱来。监控数据 Server 则是把现有监控平台的数据查询能力封装进来包括按时间范围拉取告警聚合告警查询性能指标趋势查询拓扑和依赖关系。工单通知 Server 比较简单就是创建工单、更新工单状态、发送 IM 通知。3. 核心环节实现从 MCP Server 到 Agent 工作流3.1 搭建 MCP Server 与工具注册实现 MCP Server 我们直接用官方 Python SDK里面提供了 FastMCP 这个高层封装写一个工具函数加一个装饰器就能完成注册开发效率非常高。下面这段代码是我们设备诊断 Server 的骨架做了简化from mcp.server.fastmcp import FastMCP from typing import Annotated mcp FastMCP(namenetwork-device-server) mcp.tool( description( 查询网络设备的基本状态信息。 当需要了解某台设备的存活情况、CPU/内存使用率、运行时长时使用。 返回结果为结构化 JSON。 ) ) def get_device_status( device_ip: Annotated[str, 设备管理地址如 192.0.2.10] ) - dict: 只读操作查询设备版本、CPU、内存、上线时长。 row cmdb.query_device(device_ip) snmp_data snmp_get(device_ip, OID_DEVICE_BASIC) return { device_ip: device_ip, device_name: row[name], device_model: row[model], uptime_seconds: snmp_data[uptime], cpu_usage_percent: snmp_data[cpu], memory_usage_percent: snmp_data[memory], } mcp.tool( description( 在目标设备上执行 show/display 类诊断命令。 命令必须在白名单内白名单外的命令会被拒绝。 适合在结构化工具无法覆盖的查询场景下使用。 ) ) def exec_show_command( device_ip: Annotated[str, 设备管理地址], command: Annotated[str, 要执行的诊断命令如 display interface GigabitEthernet0/0/1], ) - str: 只读操作执行白名单内的诊断命令。 return device_access.exec_show(device_ip, command)从代码里能看到工具函数本身很薄真正的逻辑都在device_access层。FastMCP 会自动根据函数的类型注解和 docstring 生成 MCP 协议需要的 JSON Schema。这一点特别重要因为 Schema 的描述质量直接决定模型的理解质量我们在 docstring 和 description 上花了大量精力反复打磨。启动 Server 的方式也值得说一下。开发阶段用 stdio 传输直接在本地起进程调试方便生产环境改成 HTTP 传输部署成独立服务多个 Agent 实例可以共享同一个 Server。切换只是换一下 serve 方式的参数工具代码一行都不用动# 开发环境stdio 传输 mcp.run(transportstdio) # 生产环境HTTP 传输监听 8085 端口 mcp.run(transporthttp, host0.0.0.0, port8085)3.2 网络设备接入层实现MCP Server 只是壳真正硬核的是设备接入层。网络设备的访问方式和互联网应用完全不一样没有 REST API最常见的还是 SSH 命令行。我们把这层单独立起来做核心解决三个问题会话管理、命令白名单、输出解析。会话管理方面设备连接不能每次现连SSH 握手一次好几秒故障场景下等不起。我们做了一个连接池按设备 IP 缓存 SSH session设置空闲超时和最大连接数复用已有连接。跳板机堡垒机场景也做了支持所有设备访问都经过跳板机平台自身不直接暴露在办公网之外。命令白名单不能只挡“明显危险”的命令还得防模型“无意”执行影响较大的查询——比如某些厂商的 show 命令在负载高时也会消耗设备 CPU。我们的白名单按设备型号分组维护每条命令都标注预计影响的等级。实现上用一个装饰器统一拦截def whitelist_guard(device_model: str): def decorator(func): def wrapper(device_ip: str, command: str, *args, **kwargs): allowed command_whitelist.get(device_model, set()) if command not in allowed: raise PermissionError( f命令 {command} 不在设备型号 {device_model} 的白名单内 ) if is_dangerous_pattern.search(command): raise PermissionError(命令命中危险模式已拦截) return func(device_ip, command, *args, **kwargs) return wrapper return decorator输出解析是另一个大坑。网络设备的 show 命令输出是纯文本表格不同厂商、不同型号的格式千差万别模型直接读原始文本容易错。我们在 agent 侧做了规范化处理每种白名单命令都配一个解析器把文本转成结构化 JSON。解析器维护在一个独立目录里命令格式变化时只改解析器不影响 Agent 逻辑。3.3 Agent 工作流编排与工具调度Agent 编排层要回答一个问题模型怎么在合适的时机调用合适的工具并且把多次调用的结果串起来。我们采用了 ReActReasoning Acting模式每一步让模型先思考再行动工具返回后带着观察结果继续思考直到得出结论。核心循环用伪代码描述就是这样async def run_agent(user_query: str): messages [{role: user, content: user_query}] # 最多执行 8 步防止模型陷入无限循环 for step in range(MAX_STEPS): # 让模型基于当前上下文决定下一步动作 response await llm.chat( messages, toolsawait session.list_tools(), # 动态获取 MCP Server 的工具列表 ) if not response.tool_calls: # 模型认为不需要再调用工具直接返回最终答案 return response.content messages.append(response) for call in response.tool_calls: result await session.call_tool(call.name, call.arguments) messages.append({ role: tool, tool_call_id: call.id, content: result.content, })实际实现比这个复杂不少比如多轮工具调用结果的缓存、上下文压缩、并行工具调用等。但我建议第一版一定从最简单的顺序执行开始先把链路跑通再优化性能。编排层里我们还加了三个“安全刹车”最大步数限制。任何任务最多执行 8 步工具调用超过就强制停止并汇总现有结果避免模型在错误方向上越走越远。这个限制来自实测正常排障流程 3-5 步就能收敛超过 8 步几乎都是模型跑偏了。写操作拦截。编排层识别到 high-risk 工具时不会直接执行而是先把完整操作方案做什么、影响什么、如何回滚生成成审批单推送给人工。人工确认后平台才继续执行执行结果会自动记录审计日志。关键结论必须附证据。模型给出“链路有问题”这类结论时我们要求它必须引用具体的工具输出片段作为依据并在界面展示引用来源。没有证据支撑的结论会被标记为“待确认”不会直接进入告警通知。3.4 安全管控与审计设计网络设备的操作权限非同小可安全这块我们几乎是按照“账号权限最小化 操作全程留痕”的原则来设计的。账号体系上平台连接设备使用的是专门的巡检账号账号权限只开放只读命令和部分低危命令没有配置修改权限。高危操作走独立的变更账号该账号的密码不落库使用时从密钥管理系统动态获取并且在执行完成后立即失效。审计日志分两层。MCP Server 层记录所有工具调用请求包括入参、出参、耗时、调用方标识Agent 编排层记录模型的思考过程、工具选择结果和最终结论。两层日志互相关联出了问题可以完整回放一次排障过程。这个设计后来在查问题时帮了大忙——有次模型生成了一个可疑的结论我们回溯日志发现是工具返回的数据源本身出了问题模型只是“忠实”地转述了错误数据。另外就是敏感信息治理。设备登录凭据、监控平台的 Token 都不会传给模型模型看到的只是脱敏后的设备别名和标号。涉及账号密码的对话内容平台会在落盘前做字段级脱敏。4. 场景落地实践从原型到可用4.1 场景一网络故障自动排查与根因收敛第一个上线的场景是告警驱动的自动排障。流程是这样的监控平台产生告警后把告警推送给 Agent for Network 的信息接收接口Agent 首先调用监控数据 Server 拉取该告警周边时间段内的所有相关告警做聚合去重然后基于告警涉及的设备调用设备诊断 Server 获取设备状态、接口状态、日志最后综合所有信息生成一份排障简报自动推到值班 IM 群。这里有个很关键的细节Agent 的判断结果不直接触发处置动作而是“建议”。比如它发现某接口 down、光功率为 0、日志里有大量 CRC 错误会给出“疑似物理链路或光模块故障建议现场检查光纤连接和光模块”的建议由值班人确认后再执行后续操作。我们拿一个真实故障案例做了复盘。某日上午 10 点 23 分监控平台收到核心交换机下联端口 down 的告警。Agent 在 40 秒内完成了这些动作拉取告警发现同一时间段还有对端设备端口 down 的告警这两条告警在监控平台上相隔几分钟值班人容易当成两次独立事件登录两端设备查看接口状态和光功率发现对端光功率为 0查看两端设备日志均无端口手动关闭记录。Agent 最终收敛判断为物理链路中断或光模块故障并生成了包含两端设备端口号、光功率读数、建议处理步骤的完整报告。值班同事拿到报告后直接安排现场人员带光模块和光纤过去处理整个响应时间从过去的半小时级别缩短到几分钟。说实话这个效果超出了我们预期。我们原本以为模型在这种场景下只能做“信息搬运工”实际跑下来发现它做告警收敛的价值最大——把分散在多个告警里的信息关联成一条时间线这是人类值班员最容易遗漏的。4.2 场景二配置变更辅助与合规校验网络变更的评审有两块最花时间一是对照基线检查新配置是否符合规范二是评估变更影响范围。这两块正好都是 Agent 的强项。变更前工程师把变更配置文本粘贴到平台上Agent 会自动完成三件事。第一语法检查——把配置逐条解析和不支持的命令模板比对提前暴露语法错误。第二合规校验——检查配置里是否有不符合规定的项比如 SNMP community 用了默认字符串、AAA 认证未配置、日志服务器地址写错等。第三影响分析——根据变更涉及的接口、VLAN、路由条目去 CMDB 和拓扑库里查关联业务输出“本次变更会影响哪些设备、哪些链路、哪些业务”的清单。这个场景做出来之后变更评审的通过率明显提高了。以前评审人面对复杂的 BGP 配置变更全靠经验判断影响范围现在 Agent 能自动列出受影响的对端 AS、涉及的网段和客户业务评审人只需要确认 Agent 的清单是否完整。最直接的收益是变更导致的“意外影响”投诉少了——因为大部分关联关系在变更前就被 Agent 识别出来了。需要说明的是Agent 在这个场景里不做自动下发。配置的下发和回滚仍然由工程师在变更窗口手动执行平台只提供预检和校验。我们一直坚持“模型不动配置”的原则宁可多一道人工确认也不给事故留口子。4.3 场景三网络变更影响分析与容量评估第三个场景是前两个的自然延伸Agent 不仅能做变更前的合规校验还能做容量评估和趋势预测。举个例子有一次网络团队要评估“能否在核心交换机上新增一个重要业务网段”传统做法是人工登录设备查 CPU、内存、带宽使用率的峰值再凭经验判断。Agent 的做法是拉取该设备过去 30 天的 CPU、内存、接口流量指标按天聚合计算峰值和均值对比同类设备的指标基线再结合新增网段的预估流量模型输出一份容量评估报告明确说明“当前设备 30 天 CPU 峰值为 X%内存峰值为 Y%按现有业务增速不建议在流量高峰时段实施变更建议扩容后再接入”。这个场景的价值不仅在于省人力更在于评估的客观性——指标数据都是真实采集的结论有数据支撑减少了“我觉得还行”“我估计没问题”这类拍脑袋判断。对我们这种设备资源接近饱和的网络这种数据化的容量评估非常实用。5. 常见问题与排查实录5.1 工具调用超时与连锁反应第一个线上问题就是超时。网络设备的 CLI 响应速度不稳定尤其在高负载时一条 show 命令可能卡几十秒。而大模型对工具调用有等待时限超时后模型会误判工具不可用甚至开始编造“可能的结果”。我们的解决办法是分两层处理工具执行层给每条命令设置独立的超时时间查询类 30 秒批量类 60 秒超时后立刻释放会话并返回明确的错误信息Agent 编排层接收到超时错误后会向用户说明“工具执行超时可能原因是设备负载过高或网络延迟”而不是让模型自行脑补。同时超时重试限制为最多一次二次超时直接放弃该工具避免反复点击拖垮设备。5.2 上下文膨胀与输出截断第二个坑是模型上下文被设备输出撑爆。一条完整的路由表 show 输出可能有几千行模型每调用一次工具输出就塞进上下文几轮下来就接近窗口上限了。更糟的是上下文被大量原始文本占据后模型的推理准确率明显下降。我们的解法是在工具层做“输出精简”解析器把文本转成 JSON 后还会做摘要处理——只保留关键字段和异常项。比如路由表不再返回完整表项而是返回“路由条目总数、BGP 邻居状态摘要、有异常的条目明细”。这样模型看到的始终是结构化摘要需要细节时再通过二级工具查具体条目。5.3 并发冲突与写操作竞态多 Agent 实例并发调用时出现过一次查配置的会话把另一个变更会话的会话池挤掉的问题。排查后发现是连接池的全局锁粒度太大一个长时间运行的查询把整个池子锁住了。后来把连接池按任务维度做了隔离查询类任务和变更类任务使用不同的连接池。写操作本身也加了分布式锁同一个设备同一时间只允许一个变更任务执行从根上避免并发下发配置导致的状态错乱。5.4 模型幻觉与危险操作防控幻觉是所有人最担心的问题。我们遇到过两次模型“一本正经地编造设备输出”——一次是模型说某台设备 BGP 邻居状态是 Established但实际上我们并没有调用过相关工具。原因是在多轮对话中模型丢失了工具调用的轨迹开始凭记忆补全。针对这个问题的排查和防治我们做了三件事。第一在提示词里强行约束没有工具输出的信息一律不得写入结论所有关键结论后必须附证据编号。第二界面上把工具调用轨迹和最终结论分开展示用户可以展开每条结论查看对应证据。第三抽样人工审核每周随机抽取一定比例的排障报告检查结论与工具输出的对应关系。上线的头一个月人工审核发现了十几处证据不完整的情况后面明显减少AI 生成痕迹重的结论基本被界面规则拦住了。5.5 常见问题速查表现象可能原因处理办法工具调用超时设备负载过高、CLI 响应慢超时分层设置、限制重试次数、返回明确超时信息模型输出与工具返回不一致上下文丢失工具轨迹强制证据引用、界面展示工具调用轨迹模型反复调用同一个工具工具描述不清晰、上下文信息不足优化工具描述、检查参数 Schema 是否准确多个变更任务互相影响连接池未隔离、缺少分布式锁读写连接池分离、设备级分布式锁上下文被撑爆工具输出太大解析器加摘要、只返回关键字段和异常项命令被误判危险而拦截危险命令正则过于严格白名单 正则双机制定期校准误杀率6. 踩坑之后的几点体会项目跑到现在最大的体会是写 MCP Server 本身不难难的是把网络设备的“脏活累活”处理好。设备输出解析、连接管理、命令白名单、超时处理这些看起来不起眼的底层能力决定了上层 Agent 的可用性。模型再聪明工具返回的是乱糟糟的文本它也分析不出什么有价值的东西。工具描述的质量直接决定 Agent 的智商。同一个工具描述写成“查询设备状态”和写成“当怀疑设备异常或需要了解设备基本健康度时使用返回 CPU、内存、运行时长”模型的调用准确率差一大截。如果你想做类似项目我建议把工具描述当成需求文档来写多花点时间绝对值得。还有一点想提醒后来者别急着放开写操作。我们最初也被“自动下发配置”吸引但冷静下来之后决定只读先行。现在平台 95% 的调用都是只读诊断和预检真正的高危操作全部走人工确认。这个克制让平台在团队里获得信任大家才敢放心把故障排查交给它。先把只读诊断做到足够可靠再考虑更进一步的自动化。这个平台后续还有几个方向可以扩展把流式遥测数据接进来做更实时的预测性分析把老师傅的排障手册知识库化让 Agent 在诊断时参考历史经验还有把平台开放给更多一线运维团队让每个团队可以自定义自己的工具集和流程模板。路还长但方向和效果已经跑出来了。