1. 隔离内网跑 AI Agent 的真实处境
先把场景说清楚。所谓隔离内网,就是一台或者一批机器,物理上或者策略上跟公网断开,装不了在线包,拉不了远程镜像,连 pip install 都得先想办法把 whl 文件搬进去。很多做金融、制造、能源、政企交付的兄弟都懂这个味道:你在外面用 Claude Code、Cursor 玩得飞起,一进客户机房,网络一断,全傻眼。
AI Agent 工程实战放在这个环境里,难度直接翻倍。因为 Agent 这个东西跟传统软件不一样,它天然依赖三样东西:模型推理服务、工具调用协议、以及一堆 Skills 能力包。这三样在公网环境下都是现成的,点一下就能用;到了内网,每一样都得自己搬、自己搭、自己调。
我前后在三个隔离环境里落地过 Agent 项目,踩的坑能写一本书。这篇就把整套打法拆开讲,从架构选型到 MCP 协议落地,从 Skills 部署到并发扛压,尽量给到能直接抄的方案。适合两类人看:一类是要在内网交付 Agent 项目的工程师,一类是想搞清楚 Agent 工程到底怎么回事、不想只停留在调 API 层面的开发者。
核心关键词先摆出来:AI Agent、MCP、Skills、内网、工程实战。这五个词基本就是整篇文章的骨架。MCP 解决工具调用标准化的问题,Skills 解决能力复用的问题,内网是约束条件,工程实战是落地方法。下面一层层拆。
2. 整体架构设计与选型思路
2.1 为什么内网 Agent 不能照搬公网方案
公网环境下搭 Agent,主流做法是:模型走云端 API,工具走 MCP 官方市场,Skills 直接从 GitHub 拉。这套东西在内网全部失效。模型 API 调不通,MCP 市场连不上,GitHub 更别想。
所以内网 Agent 的第一原则是:所有外部依赖必须本地化。模型要本地部署,MCP Server 要本地跑,Skills 要提前打包搬进去。这不是可选项,是硬约束。
第二个原则是:协议层要标准化。内网环境最怕的就是每个工具一套调用方式,今天接个数据库写一套代码,明天接个文件系统又写一套。MCP 协议的价值就在这里,它把工具调用抽象成统一接口,Agent 只需要会说 MCP 这一种"语言",就能调用所有工具。内网环境下,标准化带来的维护成本降低是巨大的。
第三个原则是:能力要可插拔。Skills 的本质就是把 Agent 的能力模块化,需要什么装什么,不需要的不装。内网环境资源有限,不可能把所有能力都堆上去,按需加载才是正解。
2.2 三层架构:模型层、协议层、能力层
我实际落地的架构分三层,从上到下依次是:
模型层:本地部署的推理服务。选型上,如果内网有 GPU 资源,优先考虑能跑得动的主流开源模型;如果只有 CPU,那就得选量化版本,牺牲一点效果换可用性。模型层对外暴露一个兼容 OpenAI 格式的接口,这样上层 Agent 框架不用改代码就能对接。
协议层:MCP Server 集群。每个 MCP Server 负责一类工具的封装,比如文件操作一个 Server,数据库查询一个 Server,代码执行一个 Server。Agent 通过 MCP 协议跟这些 Server 通信,拿到工具列表和调用结果。
能力层:Skills 包。Skills 是比工具更高一层的抽象,它把"完成某个具体任务"的流程固化下来,比如"生成一份周报"、"分析一个日志文件"、"重构一段代码"。一个 Skill 内部可能调用多个 MCP 工具,对 Agent 来说就是一个原子能力。
这三层的边界要清晰。模型层只管推理,协议层只管工具调度,能力层只管业务流程。混在一起的话,后期维护会非常痛苦。
2.3 选型对比:为什么最终选了这套组合
| 方案 | 优点 | 缺点 | 内网适配度 |
|---|---|---|---|
| 纯 API 调用 | 简单直接 | 依赖公网,内网不可用 | 差 |
| 自研工具协议 | 完全可控 | 每个工具都要写适配,维护成本高 | 中 |
| MCP 标准协议 | 生态成熟,工具复用度高 | 需要本地部署 Server | 优 |
| Skills 插件化 | 能力可插拔,复用性强 | 需要设计好接口规范 | 优 |
最终选 MCP + Skills 的组合,核心原因是这两个东西都是"一次投入、长期复用"的。MCP Server 写好一个,所有 Agent 都能用;Skill 封装好一个,所有项目都能调。内网环境最缺的就是这种可复用性,因为每次搬东西进去都很麻烦。
3. MCP 协议在内网的落地细节
3.1 MCP 到底是什么,用大白话讲
MCP 全称 Model Context Protocol,翻译过来叫模型上下文协议。名字很唬人,本质很简单:它定义了一套标准,让 AI 模型能以一种统一的方式调用外部工具。
打个比方。没有 MCP 之前,模型要调用工具,就像你去一个没有菜单的餐厅点菜,你得跟每个厨师单独沟通,这个厨师说"我要食材清单",那个厨师说"我要做法步骤",沟通成本极高。有了 MCP 之后,相当于餐厅有了一本标准菜单,你只需要说"我要宫保鸡丁",厨房内部怎么协作你不用管。
技术上,MCP 定义了三种核心能力:Tools(可调用的函数)、Resources(可读取的数据)、Prompts(预设的提示模板)。Agent 通过 MCP 客户端连接 MCP Server,拿到这些能力的清单,然后按需调用。
3.2 内网部署 MCP Server 的完整流程
内网部署 MCP Server,核心难点在于依赖打包。公网环境下npm install或者pip install一行命令搞定,内网得手动搬。
我的做法是分三步:
第一步,在公网机器上准备离线包。以 Python 写的 MCP Server 为例,用pip download把所有依赖下载到本地目录:
pip download -r requirements.txt -d ./offline_packages --platform manylinux2014_x86_64 --python-version 3.10 --only-binary=:all:这里要注意平台和 Python 版本必须跟内网机器一致,否则装不上。我踩过一次坑,公网机器是 ARM 架构,内网是 x86,包全白下了。
第二步,把离线包和 Server 代码一起搬进内网。用移动硬盘或者内部文件服务器都行。搬进去之后,用pip install --no-index --find-links=./offline_packages -r requirements.txt安装。
第三步,配置 MCP Server 启动。每个 Server 需要一个配置文件,指定监听端口、工具列表、权限范围。内网环境下权限要收紧,比如文件操作的 Server 只能访问指定目录,数据库 Server 只能读不能写。
{ "server_name": "file_ops", "transport": "stdio", "allowed_paths": ["/data/workspace"], "max_file_size": "10MB" }注意:内网 MCP Server 的传输方式优先选 stdio,比 HTTP 更安全,不占端口,也不怕被扫描。如果非要走网络,记得绑定 127.0.0.1,别开 0.0.0.0。
3.3 MCP 工具设计的三个原则
写 MCP 工具不是把函数包一层就完事,设计不好会让 Agent 用起来很别扭。我总结了三个原则:
原则一:工具粒度要适中。太细的话,Agent 完成一个任务要调十几次工具,token 消耗大还容易出错;太粗的话,灵活性不够。我的经验是,一个工具对应一个明确的动作,比如"读取文件"、"写入文件"、"列出目录"是三个工具,而不是一个"文件操作"工具带一堆参数。
原则二:参数描述要清晰。MCP 工具的 schema 里,每个参数都要写清楚类型、含义、是否必填。Agent 是靠这些描述来决定怎么调用的,描述模糊它就会瞎猜。我见过有人把参数描述写成"path: string",结果 Agent 传了个相对路径进来,直接报错。正确写法是"path: 文件的绝对路径,必须以 /data/workspace 开头"。
原则三:错误信息要可读。工具执行失败时返回的错误信息,Agent 是要读的。返回一堆堆栈信息没用,要返回"文件不存在,请检查路径是否正确"这种 Agent 能理解并自我纠正的信息。
3.4 MCP 与 Agent 框架的对接
MCP Server 跑起来之后,Agent 框架需要作为 MCP 客户端去连接。主流框架基本都支持 MCP,配置方式大同小异。核心是告诉框架:有哪些 MCP Server,怎么连。
mcp_servers: - name: file_ops transport: stdio command: python args: ["/opt/mcp/file_server.py"] - name: db_query transport: stdio command: python args: ["/opt/mcp/db_server.py"]配置好之后,Agent 启动时会自动拉取所有 Server 的工具列表,合并成自己的工具集。这时候你问 Agent"帮我看看 /data/workspace 下有哪些文件",它就知道该调 file_ops 的 list 工具。
内网环境下有个细节要注意:MCP Server 的启动命令里不要用相对路径,全部用绝对路径。因为 Agent 框架的工作目录可能跟你预期的不一样,相对路径会找不到文件。
4. Skills 能力包的开发与部署
4.1 Skills 和 MCP 的关系,别搞混
很多人搞不清 Skills 和 MCP 的区别,我用一句话说清楚:MCP 是工具,Skills 是用法。
MCP 提供的是原子能力,比如"读文件"、"查数据库"、"执行命令"。Skills 提供的是组合能力,比如"分析日志并生成报告",这个 Skill 内部可能先调 MCP 读日志文件,再调 MCP 执行分析脚本,最后调 MCP 写报告文件。
打个比方,MCP 是厨房里的锅碗瓢盆和食材,Skills 是菜谱。有了菜谱,新手也能做出像样的菜;没有菜谱,你得自己琢磨怎么搭配。
内网环境下 Skills 的价值更大,因为你可以把业务专家脑子里的流程固化成 Skill,让 Agent 照着执行。这样即使业务专家不在现场,Agent 也能干出专业水平的活。
4.2 Skill 的目录结构与核心文件
一个标准的 Skill 就是一个文件夹,结构大概是这样:
my_skill/ ├── SKILL.md # 技能描述文件,最重要 ├── scripts/ # 辅助脚本 │ └── analyze.py ├── templates/ # 输出模板 │ └── report.md └── config.yaml # 技能配置SKILL.md 是核心,它告诉 Agent 这个 Skill 是干什么的、什么时候用、怎么用。写法上要遵循一定的规范,通常包含:技能名称、适用场景、输入参数、执行步骤、输出格式。
# 日志分析技能 ## 适用场景 当用户需要分析应用日志、定位错误原因时使用。 ## 输入 - log_path: 日志文件的绝对路径 - time_range: 时间范围,格式为 "2024-01-01 to 2024-01-02" ## 执行步骤 1. 读取指定路径的日志文件 2. 按时间范围过滤 3. 统计各级别日志数量 4. 提取 ERROR 级别的堆栈信息 5. 生成分析报告 ## 输出 Markdown 格式的分析报告,包含统计表格和错误详情。这个文件写得好不好,直接决定 Skill 能不能被 Agent 正确调用。我的经验是,适用场景要写得具体,别写"用于日志分析"这种模糊描述,要写"当用户提到日志、报错、异常、排查等关键词时使用"。
4.3 内网部署 Skills 的实操步骤
Skills 部署比 MCP Server 简单,因为大部分 Skill 就是文本文件加脚本,没有复杂的依赖。但有几个坑要注意。
第一步,Skill 的存放位置。不同 Agent 框架对 Skill 目录的要求不一样,有的要求放在固定目录,有的支持配置多个搜索路径。内网环境下建议统一放在/opt/agent/skills/下,方便管理。
第二步,脚本依赖的处理。如果 Skill 里有 Python 脚本,脚本用到的第三方库也要提前打包。我一般会在 Skill 目录下放一个requirements.txt,部署时统一安装。
第三步,权限配置。Skill 里的脚本可能会执行敏感操作,内网环境下要限制权限。比如分析日志的脚本,只给它读日志目录的权限,别给写权限。
第四步,测试验证。部署完一定要测。我的测试方法是:给 Agent 一个典型任务,看它能不能正确识别该用哪个 Skill,能不能正确传参,能不能正确处理返回结果。三个环节任何一个出问题,都要回去改 SKILL.md。
4.4 好用的 Skills 推荐与自研思路
内网环境虽然拉不了官方市场的 Skills,但可以自己造。我常用的几类 Skill:
代码类:代码审查、单元测试生成、重构建议。这类 Skill 对开发团队价值很大,尤其是代码规范检查,把团队的规范固化成 Skill,Agent 就能按规范审代码。
文档类:周报生成、会议纪要整理、技术方案撰写。这类 Skill 的关键是模板要设计好,Agent 填内容就行。
数据类:日志分析、数据清洗、报表生成。这类 Skill 通常要配合 MCP 的数据库工具一起用。
运维类:配置检查、故障排查、变更影响分析。这类 Skill 在内网环境特别实用,因为运维人员往往不在现场。
自研 Skill 的思路是:先观察,再固化,后优化。先观察团队里重复性高的任务,把流程写下来,固化成 Skill,用一段时间后再根据实际效果优化。
5. 并发扛压与性能调优
5.1 AI Agent 的并发瓶颈在哪
Agent 扛并发跟传统 Web 服务完全不是一回事。传统服务的瓶颈通常在 CPU、内存、IO,Agent 的瓶颈主要在三个地方:
模型推理:这是最大的瓶颈。本地部署的模型,一张 GPU 同时只能处理有限数量的请求。并发一上来,请求就得排队。排队时间长了,用户体验直接崩。
工具调用:MCP 工具调用是串行的,一个任务里调五次工具,就是五次往返。如果工具本身还慢,比如数据库查询要几秒,整体延迟就上去了。
Token 消耗:Agent 的上下文会随着对话轮次增长,token 消耗是累积的。并发高的时候,token 消耗速度惊人,如果模型有速率限制,直接就被限流了。
5.2 实测有效的四个优化手段
手段一:请求队列 + 优先级调度。不要所有请求一视同仁,要分优先级。交互式的请求优先处理,批处理任务放后面。我用的是简单的优先级队列,实现不复杂,效果很明显。
手段二:模型推理批处理。如果模型支持批处理,把多个请求合并成一个 batch 送进去,吞吐量能提升好几倍。代价是单个请求的延迟会略微增加,但整体吞吐上去了。
手段三:工具调用缓存。很多工具调用结果是可缓存的,比如"读取配置文件"这种操作,同一个文件短时间内读多次,结果是一样的。加一层缓存,能省不少时间。
手段四:上下文压缩。Agent 的上下文不能无限增长,要定期压缩。把历史对话总结成摘要,只保留关键信息。这样既省 token,又加快推理速度。
| 优化手段 | 实现难度 | 效果提升 | 适用场景 |
|---|---|---|---|
| 请求队列 | 低 | 中 | 所有场景 |
| 批处理 | 中 | 高 | 模型支持批处理 |
| 工具缓存 | 低 | 中 | 读多写少 |
| 上下文压缩 | 中 | 高 | 长对话 |
5.3 压测方法与参数调优
压测 Agent 不能只测 QPS,要测端到端的任务完成时间。我的压测方法是:准备一批典型任务,用不同并发数跑,记录每个任务的完成时间和成功率。
关键参数有两个:最大并发数和超时时间。最大并发数要根据模型推理能力来定,一般设成 GPU 能同时处理请求数的 80%。超时时间要分层次,模型推理超时设长一点,工具调用超时设短一点。
调优是个迭代过程,先设一个保守值,跑压测,看瓶颈在哪,针对性优化,再跑压测。一般迭代三四轮就能找到比较优的配置。
6. 常见问题与排查技巧实录
6.1 内网 Agent 高频问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| Agent 启动报错找不到 MCP Server | 路径配置错误 | 检查配置文件里的路径 | 改用绝对路径 |
| 工具调用超时 | 工具执行慢或网络问题 | 单独测试工具 | 加超时和重试 |
| Skill 不被识别 | SKILL.md 格式错误 | 检查文件格式 | 按规范重写 |
| 模型推理慢 | 资源不足或请求排队 | 看 GPU 利用率 | 加批处理或限流 |
| 上下文溢出 | 对话轮次太多 | 看 token 计数 | 加压缩机制 |
6.2 三个我踩过的坑
坑一:依赖版本不一致。公网机器上装的依赖版本跟内网不一致,导致 MCP Server 在内网跑不起来。后来我养成了习惯,所有依赖都锁定版本号,用pip freeze导出精确版本。
坑二:文件编码问题。内网机器的默认编码可能跟公网不一样,导致读取中文文件乱码。解决方案是在所有文件操作里显式指定 UTF-8 编码。
坑三:权限配置过严。一开始为了安全,把 MCP Server 的权限卡得很死,结果 Agent 正常任务都完不成。后来调整了策略,按最小必要原则配置,既保证安全又不影响功能。
6.3 内网环境特有的注意事项
内网环境有几个特殊性,不注意会吃大亏。
时间同步问题。内网机器可能没有 NTP 服务,时间不准。Agent 的日志、缓存、超时判断都依赖时间,时间不准会出各种诡异问题。部署前先确认时间同步。
磁盘空间问题。内网机器磁盘往往不大,Agent 的日志、缓存、模型文件都很占空间。要定期清理,设置好日志轮转。
备份问题。内网环境出问题不好排查,一定要做好备份。配置文件、Skill 目录、MCP Server 代码,都要有备份。我一般会在内网里再搭一个备份目录,定期同步。
7. 从零到一的内网 Agent 交付清单
7.1 部署前的准备工作
交付前要确认的东西列个清单,照着检查一遍能省很多事。
- 内网机器的操作系统版本、Python 版本、架构(x86 还是 ARM)
- GPU 资源情况,显存大小,CUDA 版本
- 磁盘空间,至少留 50G 给模型和日志
- 网络策略,确认哪些端口能通
- 时间同步是否正常
- 是否有内部文件服务器用于搬东西
7.2 部署流程与验证方法
部署流程按顺序来:先装模型推理服务,再装 MCP Server,然后配 Agent 框架,最后装 Skills。每装完一步都要验证,别全装完再测,出问题不好定位。
验证方法很简单:模型层用 curl 测接口能不能通;MCP 层用官方提供的调试工具测工具能不能调;Agent 层给个简单任务看能不能完成;Skills 层给个典型任务看能不能正确调用。
7.3 交付后的维护建议
交付不是终点,是起点。内网环境维护有几个建议:
建立变更记录。每次改配置、加 Skill、升级模型,都要记录。内网环境排查问题全靠这些记录。
定期健康检查。写个脚本定期检查各组件状态,有问题提前发现。
保留回滚方案。每次变更前备份,出问题能快速回滚。
文档要写清楚。内网环境交接频繁,文档写得好,接手的人少踩坑。
我在实际交付中最大的体会是:内网 Agent 项目的成败,技术只占一半,另一半是工程管理。把依赖管好、把版本锁死、把文档写清楚,比追求技术先进性重要得多。见过太多项目,技术方案很漂亮,但因为一个依赖版本问题卡了一周。
最后分享一个小技巧:内网环境里,把所有需要的东西打成一个大包,包括模型、依赖、代码、配置、文档,一次性搬进去。别今天搬一点明天搬一点,来回折腾的时间成本太高。这个包我一般叫它"交付包",做好版本管理,下次交付直接复用,效率能提升一大截。