前两年聊AI落地,大家张口闭口还是RAG、微调;今年风向已经明显转向Agent(智能体)和MCP(模型上下文协议),对Web开发者来说,这已经不是“要不要跟进”的问题,而是“怎么在真实业务里把这两个东西组合起来用”的问题。
我最近被问得最多的一句话是:Agent Skills和MCP到底选哪个?听起来像选择题,但做过落地的人都知道,这是个伪命题。Agent Skills管的是“模型能做什么事”,MCP管的是“模型怎么连外部工具”,两者在企业级架构里往往同时出现。与其纠结选型,不如先把各自的核心机制、成本边界、权限治理、可观测性这几个问题讲透,再落到一个能直接抄作业的Web自动巡检场景里。
这篇文章适合三类人:刚接触Agent/MCP概念、正在做技术选型的Web后端或前端开发;已经在POC阶段尝试过MCP、准备推向生产环境的架构师;以及想搞明白“AI Agent在企业里到底怎么落地”的技术管理者。通篇是实操视角,不堆论文,遇到细节我会直接给配置、给代码、给排查清单。
1. 先找准问题:Agent Skills与MCP各自的生态位在哪
1.1 从Chat API到Agent Skills:模型能力的模块化封装
过去Web开发者接入大模型,最常见的姿势是调一个Chat接口:把用户问题拼进Prompt,传给模型,回收一段文本。这个模式对“问答”“摘要”“翻译”这类单轮任务够用,但一旦任务变复杂,比如“帮我查一下后台订单列表里最近30天的异常订单,再生成一份日报”,单纯靠Prompt已经撑不住。
Agent Skills解决的正是这个问题:它把一类可复用的能力封装成“技能包”,里面既包含任务描述、参数定义,也包含执行步骤和校验逻辑。可以理解成你不是让实习生自己摸索怎么做报表,而是给他一份带流程、带工具的标准化SOP。模型在对话中识别到用户意图后,会“调用”这个技能,而不是自己硬编一段内容。
对Web开发者来说,Agent Skills最接近我们熟悉的东西:函数、微服务、SDK。它把自然语言任务和确定性逻辑之间建立起一座桥,让AI的输出不再是一团不可控的文本,而是一组可预期的操作路径。这也是为什么很多团队会把“技能库”当作内部资产来管理,和沉淀代码组件是同一个思路。
1.2 MCP是连接协议,不是框架
MCP全称Model Context Protocol,Anthropic在2024年底推出的开放协议。它做的事情看起来很朴素:把“模型如何调用外部工具”这件事标准化了。MCP Server负责暴露工具,MCP Host(比如IDE、Agent应用)负责承载会话,MCP Client负责在两者之间建立通信。模型不再为每个工具写单独的适配代码,而是通过统一协议发现工具、获取Schema、调用工具并接收结果。
我用生活里更常见的类比来解释:你家里有很多电器,如果每个电器都自带专用插座,会很痛苦;MCP就是统一的USB-C接口。一个MCP Server暴露出来的工具可以被任何支持MCP的客户端复用,Figma MCP、Playwright MCP、蓝湖MCP、数据库MCP,本质都是把某个系统或某类能力包装成标准接口。
这里要特别强调一个容易踩坑的认知:MCP不是框架,它不规定你的Agent怎么编排任务,不限制你用什么模型,也不替你做权限管理。MCP只是解决了“连接”这一层。很多人以为接上MCP就等于做完一个Agent,结果发现效果不稳定、安全边界模糊,其实是因为MCP只负责“接线”,不负责“逻辑治理”。
1.3 一张表讲清Agent Skills与MCP如何组合
我做了个对比表格,方便大家在不同阶段做决策时直接看:
| 维度 | Agent Skills | MCP |
|---|---|---|
| 定位 | 模型侧的能力封装 | 系统侧的工具连接协议 |
| 核心解决的问题 | 让模型把复杂任务拆成可执行步骤 | 让模型与外部工具/数据源标准化通信 |
| 实现位置 | Agent运行时、技能包目录 | MCP Server、MCP Client、传输层 |
| 典型场景 | 日报生成、代码审查、巡检编排 | 操作浏览器、读数据库、调设计稿工具 |
| 可维护性 | 技能需要随业务迭代 | 工具接口需要版本管理、权限管理 |
| 组合方式 | Agent调用技能,技能内部可调用MCP工具 | 一个技能可以串联多个MCP Server |
在实际项目里,我见过比较理想的分工是:业务层用Agent Skills定义“做什么、按什么顺序做”,执行层用MCP解决“具体怎么和数据/工具交互”。比如一个“Web页面巡检”技能,技能本身规定要访问哪些页面、检查哪些元素、结果如何汇总,而访问URL、点击按钮、提取DOM内容这些动作,依赖Playwright MCP完成。
2. 企业级架构的真正权衡点:成本、安全与治理
2.1 上下文预算是硬约束:估算一次Agent任务的真实成本
企业级和玩具级Agent最大的分水岭,不是模型够不够聪明,而是成本能不能算清楚。Agent和单次Chat完全不同:一次任务可能要调用多个工具,每个工具的返回内容都会被塞进上下文窗口,上下文越长,延迟和费用都会显著上升。
我举个例子。假设你的MCP工具返回一个JSON结构,大小为10KB,换算成token大概在2500到3000之间(中文占比越高,token越多)。如果一次巡检任务要调用30次工具,光输入侧就积累了75K到90K token。再加模型自身生成的内容,单次任务成本很容易让人肉疼。
实操建议是:在MCP Server内部做返回裁剪,而不是等返回结果到了Agent之后再去截断。比如数据库类MCP,默认只返回前100行并带字段类型;浏览器类MCP,优先返回DOM摘要而不是整个页面HTML;文件类MCP,先返回文件名和大小,需要时才取全文。这个思路和Web后端做接口响应瘦身是一样的,只不过在AI架构里,“带宽”变成了上下文窗口。
2.2 权限边界与数据脱敏:让AI“有权限但不越权”
接MCP最危险的一件事,是工具能访问生产环境资源。内部试点时经常有人直接把数据库MCP接到线上库,让Agent执行一句SQL,结果SQL写得不严谨,全表扫描把库拖垮。这类事故我至少见过三次。
生产级方案必须加三层约束。第一层:MCP Server连接的数据源一律用只读副本或视图,严禁直连主库;写操作必须以审批流方式显式触发。第二层:在Agent运行时统一设置工具白名单,比如Playwright MCP只能访问内网指定域名列表,Figma MCP只能读取指定项目ID,其他一律拒绝。第三层:对包含手机号、身份证、密钥等敏感字段,在MCP Server返回前做脱敏或打码,不要在Agent侧再处理,因为模型可能把敏感信息原封不动复述出来,这是长期隐患。
2.3 可观测性和审计:把Agent变成可回放的系统
Web后端出了问题可以看日志、链路追踪、慢查询,Agent出问题凭什么不能?可Agent的复杂性往往被低估了:它既可能调错工具,也可能在一个工具里反复重试,还可能因为模型幻觉生成一段根本不该执行的指令。
我建议从第一天就埋点,至少记录五类信息:会话ID(一次Agent任务的唯一标识)、Prompt摘要、每次工具调用的请求和响应、每步耗时与token消耗、最终输出或报错原因。把这些数据接入OpenTelemetry或者公司现有的日志平台,再挂一个简单看板,就能做成本分析和故障回放。
单次工具调用的审计尤其重要。我习惯在记录里同时保存“模型指令”和“工具实际执行的操作”,两者对照就能看出模型是否跑偏。比如模型要求“打开订单详情页”,但工具实际访问的参数是order_id=abc123,和Prompt里的订单号不一致,这类差异只有在回放时才能发现。
3. 实操落地:用Agent Skills+Playwright MCP做企业Web自动巡检
3.1 起步组合与技术选型(含环境准备)
我建议刚起步的团队采用一个非常稳的组合:TypeScript或Python的MCP SDK做Client,Playwright MCP做浏览器操作,Agent Skills用JSON技能包维护。JSON技能包的优点是每个技能可以独立评审、独立测试,很像传统Web项目的接口文档。
环境准备只需要三件事:
- Node.js 20+环境,用于启动Playwright MCP(npx @playwright/mcp@latest)。
- Python 3.11+环境,跑MCP Client代码。
- 一个有内网访问权限的测试环境,不要一上来就打生产。
启动Playwright MCP时,我通常会在本地起一个进程,方便调试。命令行类似:
npx @playwright/mcp@latest --headless --browser chromium --port 8931这个命令会启动一个MCP Server,通过标准IO或HTTP暴露浏览器控制能力。注意headless模式在无图形界面的服务器上尤其重要,否则浏览器会起不来。
3.2 五步实现Web自动巡检
场景设定:企业内部有一个后台管理系统,需要每天巡检登录页、订单列表页、导出页能否正常打开,并记录关键性能指标。
第一步:定义Agent Skill。技能文件大概长这样:
{ "name": "daily_web_audit", "description": "对后台系统关键页面做每日巡检", "parameters": { "type": "object", "properties": { "base_url": { "type": "string", "description": "后台系统入口地址" }, "pages": { "type": "array", "items": { "type": "string" }, "description": "需要巡检的路径列表" } }, "required": ["base_url", "pages"] } }技能描述越具体,模型调用越精准。参数不要全都交给模型自由发挥,固定的配置项建议直接写到技能里,让模型只传少数动态参数。
第二步:写MCP Client,连接Playwright MCP。这里给一个简化的Python代码结构:
import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def main(): server_params = StdioServerParameters( command="npx", args=["-y", "@playwright/mcp@latest", "--headless", "--browser", "chromium"], ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools = await session.list_tools() # 在这里把tools列表注入Agent的可用工具集合 result = await session.call_tool( "browser_navigate", {"url": "https://example.com/login"} ) print(result) asyncio.run(main())真实落地时,这段代码不会独立存在,它会被封装成一个Callee服务,由Agent调度。重点在于:操作浏览器的能力从模型里剥离出来了,模型只负责根据页面状态做决策,而不是自己猜页面里有什么。
第三步:做页面状态检查。常见方式是调用Playwright MCP的browser_snapshot或browser_extract_content,拿到当前页面关键结构,再用Agent判断是否符合预期。比如登录页必须出现“用户名”输入框,订单列表页必须出现表格,导出页必须出现导出按钮。
第四步:把巡检结果结构化输出。不要只让Agent给一句“页面正常”,建议规定输出Schema:
{ "url": "https://example.com/login", "status": "ok", "error_message": "", "load_ms": 320, "key_elements_found": ["username_input", "password_input", "submit_button"] }结构化输出可以直接落库,也可以对接告警机器人。这一步能大大减少人工看报告的负担。
第五步:设置失败重试和告警隔离。网络抖动是常态,一次访问失败不代表页面挂了。我建议在Agent技能里写清楚:单个页面最多重试3次,每次间隔5秒;连续3次失败才记作真实故障。告警要按环境隔离,测试环境的告警收敛到工作群,生产环境的告警才允许触发短信或电话。
3.3 给巡检结果建立三层校验
很多团队让Agent“看”一下页面就算完了,结果某天登录接口悄悄改了返回字段,Agent却仍然说页面正常,因为页面渲染出来了但功能已经坏了。要避免这个问题,三层校验不能省。
第一层是数据结构校验。从MCP拿到的返回结果,必须用JSON Schema或Pydantic校验,字段缺失、类型不对直接判失败。第二层是业务规则校验。比如登录页不仅要出现输入框,还要在输入测试账号后能跳转首页;导出页不仅要出现按钮,还要能触发下载请求。规则要写死在技能里,不能依赖模型临场发挥。第三层是输出可靠性校验。让Agent把判断依据引用具体证据,比如“因为页面标题是订单管理,且存在表格行数=12,所以判断正常”,而不是简单回答“看起来没问题”。
三层校验做完,巡检结果基本可以当作可信数据源用。
4. 高频故障与排查速查表
4.1 MCP连接与认证问题
实际接入时,最恶心的不是代码本身,而是各种认证和连接报错。比如某个内部工具提示“dsh web authentication required; reopen the url printed by dsh web”,这类问题本质上都是:MCP Server需要先完成一次基于浏览器的认证,而当前会话没有保存有效凭证,客户端只拿到了一个URL却不知道如何自动打开。
排查思路分三步:先看MCP Server是否有独立的登录态,和操作系统或终端登录态是否共享;再看认证URL是否需要指定回调端口,防火墙是不是把回调端口拦掉了;最后看凭证刷新机制,很多内部工具的有效期只有几小时,Agent不能长期复用缓存。
我一般会在MCP客户端里加一个“凭证失效检测”:当返回401或认证相关关键字时,先暂停任务,通知管理员处理,而不是让Agent原地重试。Agent的重试逻辑一旦碰上有状态的服务,很可能把认证锁死。
4.2 上下文膨胀与工具返回失控问题
提示词写得再好,也架不住一个MCP工具返回10万字符的HTML。这个问题在浏览器场景尤其常见:你以为只是拿一个按钮文本,结果Playwright返回了整个DOM树。
对策是在MCP Server层做结果过滤。拿Playwright MCP举例,可以用选择器指定目标区域再提取文本,避免全量快照:
# 通过MCP调用时的参数示例 { "selector": "div.order-table", "operation": "extract_text", "max_chars": 2000 }如果MCP Server自己没有过滤参数,就只能在客户端做个Wrapper,对返回结果截断、摘要或只保留schema校验需要的字段。记住一个原则:上下文窗口是用来做决策的,不是用来装原材料的。
4.3 浏览器执行环境的坑
很多Web开发者第一次跑Playwright MCP就翻车,最常见的问题是报“A WebGL context could not be created”。这个和浏览器设备模拟有关,服务器上没有GPU,WebGL无可用上下文。
解决方案通常是启动时关闭硬件加速,或者把浏览器参数调成软件渲染:
npx @playwright/mcp@latest --headless --browser chromium --launch-options='{"args":["--disable-gpu","--disable-software-rasterizer"]}'另一个坑是WebSocket/长连接场景。如果你的Web应用本身用WebSocket实时推送数据,浏览器自动化和真实浏览器有差异,巡检脚本经常因为连接未建立就断言失败。我的建议是:在技能里给WebSocket预留等待时间,同时把“实时推送是否到达”作为独立检查点,而不是混在页面加载里一起判断。
还有Linux服务器上常见的中文字体缺失问题,会导致页面文字变成方块,让Agent误判页面异常。需要在服务器上安装中文字体包,或使用dind(docker in docker)镜像时额外带一层字体依赖。
4.4 安全测试类工具的边界问题
用Burp Suite MCP这类工具做合规渗透测试,是现在很多企业都在尝试的方向。能力很强,但边界必须提前划死。
我踩过的坑是:Agent拿到Burp Suite工具后,会尝试扫描配置里出现过的所有域名,包括生产环境。这不是模型坏,而是工具权限太宽。正确做法是把目标域名白名单写死在MCP Server里,并且只允许一个或多个明确标注为“测试环境”的域名。还可以加一层人工审批:高危操作(扫描、爆破、文件上传)必须经过人为确认才能执行,Agent只负责出具测试方案和汇总结果。
安全测试属于高敏感场景,建议从企业制度层面也走一遍合规,别让技术先行但制度滞后。
5. 踩坑心得与后续演进
5.1 我踩过的坑与应对策略
第一,让Agent全自主跑业务流程,看起来很美,实际一碰真实业务就崩。最稳的模式是“确定性流程骨架+Agent局部决策”。也就是:整体步骤先由工程师用代码或技能定义清楚,Agent只在某个岔路口做判断,比如页面是否异常、是否重试、提取哪一段信息。完全自由式的Agent,生产环境现阶段最好别碰。
第二,MCP Server版本更新频繁,破坏性变更很常见。和依赖锁版本一样,MCP Server的版本也必须锁定。我见过Playwright MCP从旧版升到新版后,browser_navigate的参数从url改成target_url,所有Agent任务直接无效。在POC阶段不要追最新版,挑一个稳定版本跑1-2周再说。
第三,工具返回值的校验不能只交给模型“脑补”。模型倾向于给用户一个“看起来合理的回答”,即使工具返回的数据根本不合逻辑。前面说的三层校验,等于给模型加了个安全护栏。
5.2 从单Agent到多Agent协作:MCP网关与技能注册中心
单个Agent做完一个巡检任务只是起步,企业级架构最终会走向多个Agent共享工具和技能。这时候最值得做的不是写一堆定制集成,而是搭一个MCP网关,统一接入内网的Figma MCP、蓝湖MCP、数据库MCP、Playwright MCP等。
MCP网关的核心职责有四块:统一鉴权(按Agent或按用户分配token)、协议转发(不同MCP Server可以走stdio、SSE或HTTP)、限流熔断(防止某个Agent把全部工具打爆)、审计留痕(所有工具调用统一落日志)。做好网关之后,新接入一个工具从一个开发任务变成一个配置任务,这才有平台化的味道。
Agent Skills同样需要注册中心。我倾向于用一个内部Package Registry存技能包,每个技能包包含JSON描述、校验逻辑、测试用例。这样任何一个Agent都可以在注册中心发现并调用技能,和微服务架构里的服务发现是同一个套路。
5.3 与算力资源池化、调度系统的关系
聊到更深的架构层,Agent不可能只跑在一台微薄的计算实例上。企业级AI算力集群通常由GPU推理服务、KV Cache内存池、弹性调度器、向量检索等模块组成。MCP和Agent Skills主要解决应用层,但它们对底层算力有一个很直接的影响:上下文越长、并行Agent越多,KV Cache和显存压力越大。
所以你会看到很多做Agent平台的公司,后来都开始建设更细粒度的调度能力:大上下文请求走特殊路由,高频低延迟任务走独立副本,任务与任务之间做算力隔离。这是未来的演进方向,但我给大多数团队的建议是:在没搞清楚成本和治理之前,先不要把“多Agent高并发”当成必选项,把单个Agent的可靠性跑出来,比什么都重要。
最后再说个我体会比较深的事。Web开发者一直有一个优势,就是我们对“接口、协议、缓存、鉴权、幂等、重试”这些东西有肌肉记忆。Agent和MCP进入企业后,本质上是在让模型也能享受这些工程保障。不要轻易被概念圈住,Agent Skills和MCP不是魔法,它们是让我们过去写的这套工程方法论,从Web服务延伸到AI编排上。先把一个巡检任务跑稳,再把权限、审计、成本控制补齐,你的企业级AI架构就已经比大多数团队走得扎实了。