1. 为什么要在隔离内网里折腾 AI Agent
先把场景说清楚。所谓隔离内网,就是一台或者一批机器,物理上或者逻辑上跟公网断开,不能直接访问外部的大模型 API,不能随手 pip install 一个包就完事,甚至连 GitHub 都拉不下来。很多做金融、制造、政企交付的团队,日常就是在这样的环境里干活。而 AI Agent 这个东西,天生又是个"吃生态"的玩意儿——它要调模型、要跑工具、要读文件、要连各种 MCP Server,一旦断网,很多现成的方案直接趴窝。
我在过去一年里,前前后后在三四个完全隔离的环境里落地过 AI Agent 工程,踩的坑足够写一本小册子。这篇就把整套思路和实操细节摊开讲,从架构选型、依赖离线化、MCP 协议在内网的适配、Skills 的组织方式,一直到并发扛压和故障排查。目标读者是那些手里有一台内网服务器、想把 AI Agent 真正跑起来、而不是停留在 demo 阶段的工程师。看完你应该能照着搭出一套能用的东西,而不是又一篇"原理介绍"。
核心矛盾其实就一句话:Agent 的能力来自外部生态,而内网切断了这个生态。所以整套工程的核心任务,就是把这个生态"搬进来"——模型搬进来、依赖搬进来、工具协议搬进来、技能包搬进来,然后在封闭环境里让它们协同工作。下面按这个逻辑一层层拆。
2. 整体架构设计与方案选型
2.1 内网 Agent 的三层结构
我最终稳定下来的架构是三层:模型服务层、Agent 编排层、工具与技能层。这三层在内网里各自独立部署,通过本地网络通信,任何一层都不依赖公网。
模型服务层负责把大模型跑起来,对外暴露一个兼容 OpenAI 接口的 HTTP 服务。编排层是 Agent 的大脑,负责理解任务、规划步骤、调用工具。工具与技能层则是 Agent 的"手脚",包括文件操作、数据库查询、内部 API 调用,以及通过 MCP 协议挂载的各种能力。
为什么这么分?因为内网环境里,模型往往是最重、最难动的部分,把它单独抽出来做成服务,编排层就可以轻量化,换模型、升级模型都不影响上层逻辑。而工具层独立,是为了让不同 Agent 复用同一批工具,避免每个 Agent 都自带一套实现,维护起来是灾难。
2.2 编排框架怎么选:别迷信"全家桶"
选型这块我踩过最大的坑,就是一开始想用某个特别重的框架,结果它内部硬编码了一堆要联网的遥测和依赖下载逻辑,在内网里根本起不来。后来我的原则变成:编排层优先选依赖少、可离线、能自己掌控的。
具体来说,如果你团队是 Python 栈,LangChain 加 LangGraph 这套组合在内网是可行的,但要注意把它的遥测关掉,把模型调用指向本地服务。如果是 Java 栈,Spring AI 这两年成熟度上来了,配合本地模型服务也能跑,好处是跟企业现有的 Spring 体系融合度高。如果追求极致轻量和性能,用 Rust 自己写编排核心也是很多团队的选择,尤其是对并发和资源占用敏感的场景。
我的建议是:别一上来就上最复杂的框架。先用一个最小的编排循环(接收任务、调模型、解析工具调用、执行、回填结果)把链路跑通,再逐步引入框架能力。很多团队死在"框架还没跑通,业务需求已经堆成山"。
2.3 MCP 协议在内网里的定位
MCP 这两年火得一塌糊涂,本质上是给模型和外部工具之间定了一套标准通信协议。它的价值在内网里反而更明显:因为内网工具五花八门,有数据库、有内部系统、有文件服务,如果每个都单独写适配,工作量爆炸。用 MCP 统一成 Server,Agent 侧只需要一个 MCP Client,就能挂载所有工具。
但要注意,MCP Server 的部署在内网里要特别小心。很多现成的 MCP Server 实现默认会去连外部服务,或者依赖某些在线资源。我的做法是:只保留纯本地能力的 MCP Server,凡是需要外网的,要么改造,要么自己重写。比如文件系统 MCP、数据库 MCP、内部 HTTP 接口 MCP,这些都能纯本地跑,是内网 Agent 的主力。
2.4 Skills 的组织哲学
Skills 这个词最近被用得很泛,我的理解是:Skill 就是一段可被 Agent 发现、理解、调用的能力封装。它可能是一个脚本、一个提示词模板、一个工具组合。在内网里,Skills 的管理比公网更重要,因为你没法随时从市场拉新的。
我的组织方式是目录化加元数据。每个 Skill 一个目录,里面放一个描述文件(说明这个 Skill 干什么、需要什么参数、有什么限制),加上实际实现。Agent 启动时扫描目录,把描述注入到系统提示里,模型就知道有哪些能力可用。这套机制的好处是,新增 Skill 只需要丢一个目录进去,不用改 Agent 代码。
3. 依赖离线化与模型部署的实操细节
3.1 把依赖"搬"进内网的三种姿势
内网装不了包,这是第一道坎。我常用的三种方式,按推荐度排序:
第一种是在外网机器上完整构建,然后整体打包搬运。用 Docker 的话,直接在外网 build 好镜像,导出成 tar,拷进内网 load。这是最干净的,因为镜像里依赖齐全,内网不需要任何网络。缺点是镜像体积大,搬运耗时。
第二种是搭建内网私有源。把常用的 pip 包、npm 包、Maven 依赖,在外网用工具批量下载下来,在内网起一个私有的包索引服务。这样内网机器可以像正常一样装包,只是源指向本地。适合需要频繁装包的团队,前期搭建成本高,但长期省事。
第三种是离线 wheel 包加本地安装。把依赖的 wheel 文件全部下载,拷进内网,用pip install --no-index --find-links安装。适合依赖不多、变动不频繁的场景。
提示:不管用哪种方式,一定要在外网环境里把依赖装一遍并跑通,确认没有隐藏的运行时下载行为,再搬运。我见过太多"装的时候好好的,一跑就联网"的坑。
3.2 本地模型服务的部署要点
模型这块,内网里通常有两种选择:一是部署开源模型,二是如果有条件,用内部已有的推理集群。开源模型部署,主流是用推理框架把模型权重加载起来,暴露 OpenAI 兼容接口。
关键参数上,我一般会关注这几个:上下文长度、并发数、显存占用。上下文长度决定了 Agent 能处理多复杂的任务,但开太大显存吃不消。并发数直接关系到能同时服务多少个 Agent 请求。显存占用则决定了你能在一张卡上跑多大的模型。
举个实际的例子:一张 24G 显存的卡,跑一个 7B 级别的模型,量化到 4bit,上下文开到 8K,并发大概能撑到 8 到 16 路,具体看推理框架的调度效率。如果业务需要更长上下文,就得降并发或者上更大的卡。这个账一定要提前算,别等上线了才发现并发一高就排队。
3.3 模型接口的兼容层
内网模型服务暴露的接口,最好做成 OpenAI 兼容的。原因很简单:生态里绝大多数 Agent 框架、MCP 工具、客户端,默认都认这套接口。你只要把 base_url 指向本地服务,其他代码几乎不用改。
如果本地推理框架的原生接口不是 OpenAI 格式,中间加一层适配服务就行。这层适配服务很薄,主要做请求格式转换和流式响应处理。我一般用 FastAPI 写,几十行代码搞定,好处是可控,出问题好排查。
4. MCP 与 Skills 在内网的落地实操
4.1 MCP Server 的本地化改造
前面说了,MCP Server 要纯本地化。具体怎么做?以文件系统 MCP 为例,它本身就不依赖外网,直接部署即可。但像一些连接外部 SaaS 的 MCP,就得改造:把外部调用替换成内部接口调用,把认证方式换成内网 token。
改造的核心是把"出网"的调用全部替换成"内网可达"的调用。这一步没有捷径,只能一个个 Server 过。我的经验是,先列一个清单,把所有计划使用的 MCP Server 列出来,标注每个的依赖,然后逐个确认哪些能直接用、哪些要改、哪些直接放弃。
4.2 MCP Client 的接入与工具发现
Agent 侧作为 MCP Client,启动时要连接所有配置好的 MCP Server,拉取它们的工具列表。这个过程在内网里要加超时和重试,因为内网服务偶尔会抽风。
工具发现完成后,Agent 会得到一份"工具清单",每个工具带名称、描述、参数 schema。这份清单会被注入到模型的上下文里,模型据此决定调哪个工具。这里有个细节:工具太多会撑爆上下文。我一般会做一层筛选,只把跟当前任务相关的工具注入,或者用工具分组的方式,让模型先选组再选工具。
4.3 Skills 的编写与测试
写 Skill 有几个原则。第一,描述要写给模型看,不是写给人看。模型靠描述判断什么时候用这个 Skill,所以描述要清晰说明适用场景和输入输出。第二,实现要健壮,内网环境里参数错误、文件不存在、服务超时都是常态,Skill 内部要处理好异常,返回模型能理解的错误信息,而不是直接抛栈。
测试 Skill 我一般分两步:先单独测,脱离 Agent 直接调用,确认功能正常;再集成测,让 Agent 在真实任务里调用,看模型能不能正确选择和使用。很多 Skill 单独测没问题,一进 Agent 就翻车,往往是描述写得让模型误解了。
4.4 一个完整的 Skill 示例结构
假设我们要做一个"查询内部订单"的 Skill,目录结构大概是这样:
skills/ query_order/ skill.yaml # 元数据:名称、描述、参数 handler.py # 实际实现 README.md # 给人看的说明skill.yaml里写清楚这个 Skill 叫什么、干什么、需要哪些参数。handler.py里实现具体逻辑,连内部数据库或者内部 API。Agent 启动扫描skills/目录,把每个skill.yaml的描述注入上下文。模型看到"查询内部订单"这个能力,用户问订单相关问题时就会调用它。
5. 并发扛压与性能调优
5.1 Agent 并发的瓶颈到底在哪
很多人一上来就问"AI Agent 怎么扛并发",但没搞清楚瓶颈在哪。我实测下来,Agent 的并发瓶颈通常不在 Agent 本身,而在模型推理。Agent 编排逻辑本身很轻,就是些字符串处理和 HTTP 调用,真正吃资源的是模型那一侧。
所以扛并发的核心,是让模型服务能高效处理并发请求。这涉及推理框架的批处理能力、显存管理、请求队列调度。Agent 侧要做的,是做好请求的排队和限流,别把模型服务打爆。
5.2 请求队列与限流设计
我的做法是在 Agent 和模型服务之间加一层队列。所有模型调用请求先进队列,由固定数量的 worker 消费。worker 数量根据模型服务的实际并发能力设定,比如模型能扛 16 路并发,就开 16 个 worker。
这样做的好处是,突发流量不会直接冲击模型服务,而是堆在队列里慢慢消化。队列长度要设上限,超了就快速失败,返回"系统繁忙",而不是无限堆积导致雪崩。
5.3 缓存能省一大半算力
内网 Agent 场景里,很多请求是重复的。比如同一个查询、同一段文本处理,反复调用模型纯属浪费。我在编排层加了一层语义缓存:请求进来先算个特征,命中缓存直接返回,不命中才走模型。
缓存命中率在真实业务里往往能到 30% 到 50%,等于省了三分之一的算力。缓存要注意失效策略,内部数据变了,相关缓存要清掉,否则会返回过期结果。
5.4 长任务的处理
Agent 处理复杂任务时,可能一次要跑几十步,耗时几分钟甚至更久。这种长任务不能同步等,得做成异步。我的方案是任务提交后立即返回任务 ID,Agent 在后台跑,客户端轮询或者通过内网消息推送拿结果。
长任务还要考虑超时和中断。内网服务不稳定,某一步卡住了,整个任务就挂起。所以要给每一步设超时,超时后要么重试,要么降级,要么明确失败,别让任务永远卡在那。
6. 常见问题与排查技巧实录
6.1 内网 Agent 典型故障速查
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| Agent 启动就报错 | 依赖缺失或遥测联网 | 检查启动日志,关掉遥测 |
| 模型调用超时 | 模型服务过载或网络问题 | 看模型服务负载,测内网连通性 |
| 工具调用失败 | MCP Server 未启动或配置错 | 单独测 MCP Server |
| 模型选错工具 | Skill 描述不清 | 优化描述,加示例 |
| 并发一高就崩 | 无队列无限流 | 加队列和限流 |
| 结果时好时坏 | 缓存过期或数据不一致 | 检查缓存失效策略 |
6.2 几个我踩过的坑
第一个坑:以为内网就没有网络问题。内网虽然不出公网,但内部服务之间的网络照样会抖。DNS 解析慢、防火墙规则、服务发现失效,这些都会导致 Agent 莫名其妙失败。我的经验是,所有内网调用都要加超时和重试,别假设内网一定稳。
第二个坑:模型上下文被工具清单撑爆。工具一多,光工具描述就占了几千 token,留给实际任务的空间就少了。解决办法是工具分组和动态注入,只给模型看当前需要的。
第三个坑:Skill 描述写得太技术化。模型不是人,它靠描述里的关键词匹配场景。描述里堆术语,模型反而不知道啥时候用。要用人话写,把"什么时候用"说清楚。
6.3 日志与可观测性
内网环境里,出问题没法上网搜,全靠日志。所以日志一定要打全:每次模型调用的输入输出、每次工具调用的参数和结果、每步的耗时。我一般会把日志结构化,方便检索。
可观测性上,至少要有个简单的监控面板,看模型服务的 QPS、延迟、错误率,看 Agent 的任务成功率、平均步数。这些指标能帮你快速定位是模型的问题还是编排的问题。
7. 一些工程之外的体会
搭内网 Agent 这套东西,技术上其实没有特别高深的地方,难的是在受限环境里把每个环节都抠扎实。公网环境里,一个 pip install 能解决的事,内网里可能要折腾半天。但反过来,内网环境逼着你去理解每个依赖、每个调用到底在干什么,这对工程能力的提升是实打实的。
我现在做任何 Agent 项目,都会先问三个问题:模型在哪、工具怎么连、依赖怎么进。这三个问题想清楚了,剩下的就是体力活。内网环境只是把这三个问题放大了,逼你提前想清楚。
另外一点,别追求一步到位。我见过太多团队想一次性搭个"完美架构",结果卡在某个依赖上几个月动不了。正确的做法是先跑通最小闭环——一个模型、一个工具、一个任务,然后再往上加。能跑起来的东西,才有优化的价值。
最后分享一个实用的小技巧:在内网里调试 Agent,准备一套"离线测试集"特别重要。把常见的任务、预期的工具调用、期望的输出整理成用例,每次改动后跑一遍。内网里没法快速试错,这套测试集就是你的安全网。我现在的习惯是,每加一个 Skill,就补几个测试用例,日积月累,回归测试几分钟就能跑完,心里踏实。