
1. 隔离内网下 AI Agent 工程实战从零搭建到落地的完整复盘隔离内网这四个字做过企业级交付的兄弟应该都懂——不是网络不太好而是物理隔离、协议受限、外网依赖全部切断。你手里只有一台能连内网的跳板机一个离线的包管理源以及一堆需要想办法搞进去的依赖。在这种环境下搞 AI Agent 工程跟在公网环境里完全是两码事。公网环境下你pip install一把梭docker pull随便拉MCP 服务想连哪个连哪个到了内网每一个依赖包、每一个模型权重、每一个 MCP Server 的二进制文件都得提前规划好怎么进去、怎么部署、怎么在断网状态下跑起来。这篇文章要聊的就是我在几个隔离内网项目里踩过的坑和总结出来的工程方法。核心关键词AI Agent、MCP、Skills、内网、工程实战。适合谁看如果你正在做企业内网的 AI Agent 落地或者你所在的环境有网络隔离要求又或者你单纯想搞清楚在内网里怎么把 Agent 跑起来那这篇内容应该能帮你省掉不少试错时间。先说清楚一个前提内网环境下的 AI Agent 工程核心矛盾不是模型够不够聪明而是工程链路能不能通。模型可以用内网部署的开源模型也可以用提前导出的推理服务但 Agent 的编排层、工具调用层、状态管理层这些才是真正卡脖子的地方。下面我按实际项目的推进顺序把整个工程拆开来讲。2. 内网 AI Agent 的整体架构设计与选型逻辑2.1 为什么不能照搬公网那套架构公网环境下搭 AI Agent大多数人习惯的套路是LangChain 或 LangGraph 做编排OpenAI 或 Claude 做推理MCP 协议做工具调用再配一堆 SaaS 化的可观测性工具。这套东西在内网里基本跑不通原因有三第一外部 API 全部不可达。你没法调用任何公网的模型推理接口所有推理必须在内网完成。这意味着你要么在内网部署开源模型比如 Qwen、DeepSeek 的蒸馏版本要么用提前申请好的内网推理服务。第二依赖安装链路断裂。内网的 pip 源、npm 源、Docker Registry 通常都是私有化的很多包不一定有。你需要的 Python 依赖、Node 依赖、系统级库都得提前确认私有源里有没有没有的话要走离线导入流程。第三MCP Server 的部署方式完全不同。公网环境下 MCP Server 很多是远程服务直接配个 URL 就能用。内网里你必须把 MCP Server 本地化部署而且要考虑它依赖的外部资源怎么解决。所以内网 AI Agent 的架构设计核心思路是全链路本地化、依赖提前化、通信内网化。2.2 推荐的分层架构我在实际项目里用的架构大致分四层层级组件内网适配要点推理层内网部署的开源模型推理服务提前确认 GPU 资源模型权重离线导入编排层LangGraph / 自研 Agent 框架依赖包提前打入私有源避免运行时拉取工具层MCP Server 集群全部本地部署走内网 HTTP 或 stdio 通信状态层内网数据库 本地文件存储避免依赖外部对象存储用内网 MinIO 或直接挂载盘这个分层的好处是每一层都可以独立验证。推理层通了再搞编排层编排层通了再接工具层出问题的时候排查范围可控。我见过有人一上来就把四层全串起来调结果一个环节不通整条链路都卡住排查起来非常痛苦。2.3 模型选型的现实考量内网环境下选模型不要追求最强要追求最稳。我一般按这几个维度来筛显存占用内网 GPU 资源通常紧张7B 到 14B 的模型是甜点区量化后能在单卡上跑起来推理框架兼容性vLLM、SGLang 这些框架在内网的部署难度要提前评估工具调用能力Agent 场景下模型必须支持 Function Calling 或类似的工具调用格式不然 MCP 接不上中文能力如果业务场景是中文的模型的中文指令遵循能力要重点测实测下来Qwen 系列和 DeepSeek 系列在内网部署的性价比比较高工具调用的稳定性也够用。具体选哪个版本取决于你的显存和延迟要求。3. MCP 与 Skills 在内网环境下的落地细节3.1 MCP Server 的本地化部署MCP 协议本身是标准化的问题在于 MCP Server 的实现。公网上很多 MCP Server 是 Node 写的通过 npx 直接跑内网里 npx 拉不到包就废了。我的做法是提前在公网环境把 MCP Server 的依赖全部装好包括 node_modules 或 Python 的 site-packages把整个目录打包通过内网允许的文件传输方式导入在内网机器上直接跑本地入口文件不走 npx 或 pip 的在线安装举个例子一个典型的文件系统 MCP Server公网上的用法是npx -y modelcontextprotocol/server-filesystem /path。内网里你要做的是# 公网环境准备 mkdir mcp-fs-server cd mcp-fs-server npm init -y npm install modelcontextprotocol/server-filesystem # 打包整个目录 tar czf mcp-fs-server.tar.gz . # 内网环境部署 tar xzf mcp-fs-server.tar.gz -C /opt/mcp/ # 直接跑本地入口 node /opt/mcp/mcp-fs-server/node_modules/modelcontextprotocol/server-filesystem/dist/index.js /data这样就不依赖任何在线拉取。其他 MCP Server 同理核心思路就是公网准备、离线打包、内网直跑。3.2 Skills 的工程化管理Skills 这个概念在 Agent 工程里越来越重要本质上是把 Agent 的能力模块化、可配置化。内网环境下管理 Skills我建议用一套统一的目录规范/opt/agent-skills/ ├── registry.json # Skills 注册表 ├── file-ops/ # 文件操作类 │ ├── skill.yaml │ └── handler.py ├── db-query/ # 数据库查询类 │ ├── skill.yaml │ └── handler.py └── http-call/ # 内网 HTTP 调用类 ├── skill.yaml └── handler.pyregistry.json里记录每个 Skill 的元信息Agent 启动时加载这个注册表运行时按需调用。这样做的好处是新增 Skill 不需要改 Agent 核心代码只需要在目录里加文件、更新注册表就行。skill.yaml的典型结构name: file-ops description: 内网文件读写操作 version: 1.0.0 entry: handler.py functions: - name: read_file description: 读取指定路径的文件内容 parameters: path: type: string required: true - name: write_file description: 写入内容到指定路径 parameters: path: type: string required: true content: type: string required: true这套规范看起来简单但实际项目里非常管用。尤其是当你有几十个 Skill 的时候没有统一规范会乱成一锅粥。3.3 MCP 和 Skills 的关系怎么理很多人搞不清楚 MCP 和 Skills 的区别。我的理解是MCP 是通信协议Skills 是能力封装。MCP 解决的是Agent 怎么和外部工具通信的问题Skills 解决的是Agent 有哪些能力、怎么组织这些能力的问题。在实际工程里两者可以结合使用用 MCP 协议对接外部的工具服务用 Skills 管理 Agent 内部的能力模块。也可以只用其中一种取决于你的架构复杂度。内网环境下如果工具服务不多直接用 Skills 管理就够了如果工具服务很多、需要标准化对接那就上 MCP。注意内网环境下 MCP Server 的通信方式优先选 stdio比 HTTP 更稳定不依赖端口和网络配置。如果必须用 HTTP确保内网防火墙策略提前开通。4. 内网 Agent 工程的实操流程与关键环节4.1 环境准备离线依赖的完整清单内网部署最耗时的环节就是环境准备。我的经验是提前列一份完整的依赖清单逐项确认内网私有源里有没有。清单至少包含Python 依赖Agent 框架、模型推理客户端、数据库驱动、HTTP 库等Node 依赖如果 MCP Server 是 Node 写的node_modules 要完整打包系统级依赖CUDA 驱动、cuDNN、特定版本的 glibc 等模型权重提前下载好通过内网允许的方式导入配置文件所有服务的配置文件模板提前准备好我一般会写一个check_deps.sh脚本在内网机器上跑一遍逐项检查依赖是否就位#!/bin/bash echo Python 依赖检查 python3 -c import langgraph; print(langgraph OK) 2/dev/null || echo langgraph MISSING python3 -c import mcp; print(mcp OK) 2/dev/null || echo mcp MISSING echo Node 依赖检查 node -e require(modelcontextprotocol/sdk); console.log(mcp-sdk OK) 2/dev/null || echo mcp-sdk MISSING echo 模型服务检查 curl -s http://localhost:8000/v1/models /dev/null echo model service OK || echo model service DOWN这个脚本看起来简单但能帮你快速定位环境问题避免部署到一半才发现缺东西。4.2 Agent 编排层的实现编排层我用 LangGraph 比较多原因是它的状态管理比较清晰适合内网这种需要精细控制的场景。一个典型的 Agent 编排流程from langgraph.graph import StateGraph, END from typing import TypedDict, Annotated import operator class AgentState(TypedDict): messages: Annotated[list, operator.add] next_action: str def planner_node(state: AgentState): # 调用内网模型服务做规划 response call_internal_model(state[messages]) return {next_action: response.action, messages: [response]} def executor_node(state: AgentState): # 执行 Skill 或 MCP 调用 result execute_skill(state[next_action]) return {messages: [result]} def should_continue(state: AgentState): if state[next_action] finish: return END return executor graph StateGraph(AgentState) graph.add_node(planner, planner_node) graph.add_node(executor, executor_node) graph.set_entry_point(planner) graph.add_conditional_edges(planner, should_continue) graph.add_edge(executor, planner) agent graph.compile()这段代码的关键点在于call_internal_model走的是内网推理服务execute_skill走的是本地 Skills 目录。整个链路不依赖任何外部网络。4.3 并发处理的实际方案内网 Agent 的并发问题跟公网不太一样。公网环境下你可以靠弹性扩容来解决内网里资源是固定的只能靠工程手段来扛。我的做法是推理层做请求队列模型推理服务前面加一层队列控制并发数避免 GPU OOMAgent 层做异步编排用 asyncio 或线程池处理多个 Agent 实例的并发请求工具层做连接池数据库查询、HTTP 调用这些操作用连接池复用资源实测下来单张 A100 跑 7B 模型推理并发控制在 4 到 8 之间比较稳。超过这个数延迟会明显上升。Agent 层的并发可以更高因为大部分时间在等推理结果用异步就能扛住。4.4 日志与可观测性内网环境下没有公网那套 SaaS 化的可观测性工具得自己搭。我的方案是结构化日志所有 Agent 操作输出 JSON 格式日志方便后续分析本地日志聚合用 Loki 或简单的文件聚合方案把多台机器的日志收集到一起关键指标埋点推理延迟、工具调用成功率、Agent 任务完成率这些指标必须埋import logging import json from datetime import datetime def log_agent_event(event_type, payload): log_entry { timestamp: datetime.utcnow().isoformat(), event_type: event_type, payload: payload } logging.info(json.dumps(log_entry, ensure_asciiFalse))这套东西看起来朴素但实际排查问题的时候非常管用。尤其是 Agent 这种多步骤、多工具调用的场景没有详细日志根本没法定位问题。5. 内网 Agent 工程的常见问题与排查实录5.1 依赖缺失类问题这是内网部署最高频的问题。典型表现是Agent 启动时报ModuleNotFoundError或者 MCP Server 跑不起来报Cannot find module。排查思路先确认内网私有源里有没有这个包没有的话在公网环境下载 whl 或 tgz 文件离线导入导入后确认版本兼容性尤其是 Python 包的依赖树我踩过的一个坑某个 MCP Server 依赖的 Node 包版本和 Agent 框架依赖的版本冲突导致两边都跑不起来。最后的解决方案是用独立的 Node 环境隔离MCP Server 用自己的 node_modulesAgent 框架用另一套。5.2 模型服务连接问题内网模型服务跑起来了但 Agent 连不上常见原因有现象可能原因排查方法Connection refused服务没启动或端口不对netstat -tlnp确认端口监听Timeout防火墙拦截检查内网防火墙策略401 UnauthorizedAPI Key 配置错误确认配置文件里的 Key模型加载失败显存不足或权重损坏查看模型服务日志提示内网模型服务的地址建议用环境变量注入不要硬编码在代码里。不同环境切换的时候会方便很多。5.3 Agent 任务执行异常Agent 跑着跑着卡住或者报错这类问题最难排查。我的经验是分三步走第一步看日志。Agent 的每一步操作都要有日志从 planner 到 executor 到最终输出每一步的输入输出都记下来。第二步复现问题。把出问题的输入单独拿出来手动跑一遍 Agent 流程看在哪一步卡住。第三步隔离验证。如果是工具调用的问题单独测那个 Skill 或 MCP Server如果是推理的问题单独测模型服务。我遇到过一个典型案例Agent 在执行文件操作 Skill 时一直超时日志显示 Skill 调用发出去了但没返回。最后发现是 Skill 里的文件路径写的是相对路径Agent 的工作目录和预期不一致导致文件找不到一直重试。改成绝对路径后问题解决。5.4 性能瓶颈定位内网 Agent 的性能瓶颈通常出现在三个地方推理、工具调用、状态管理。推理瓶颈表现为 Agent 响应慢但工具调用正常。解决方法是优化模型推理参数或者换更小的模型工具调用瓶颈表现为某个 Skill 或 MCP 调用特别慢。解决方法是优化工具实现或者加缓存状态管理瓶颈表现为 Agent 步骤多了之后越来越慢。解决方法是优化状态存储避免每次全量读写我一般会用 cProfile 或 py-spy 做性能分析定位到具体的热点函数再优化。6. 几个实战中总结的避坑经验6.1 离线包管理要建立版本台账内网环境最怕的就是这个包是谁导进来的、什么版本、什么时候导的没人知道。我的做法是维护一个offline_packages.md记录每个离线包的名称、版本、导入时间、导入人、用途。看起来是个笨办法但实际项目里能省掉大量沟通成本。6.2 MCP Server 优先选 stdio 模式内网环境下MCP Server 的通信方式优先选 stdio。原因是 stdio 不依赖网络配置不需要开端口不需要考虑防火墙策略。HTTP 模式虽然更灵活但内网里网络策略往往很严格开通端口要走流程能省则省。6.3 Skills 的粒度要适中Skills 拆得太细Agent 编排会变得很复杂拆得太粗复用性又差。我的经验是一个 Skill 对应一个明确的业务能力比如查询数据库是一个 Skill发送内网消息是一个 Skill。不要把多个不相关的操作塞进一个 Skill 里。6.4 提前做压力测试内网环境的资源是固定的上线前一定要做压力测试。我一般会模拟 10 到 50 个并发 Agent 任务观察推理延迟、工具调用成功率、内存占用这些指标。测试中发现的问题比上线后发现的成本低得多。6.5 配置文件与代码分离所有环境相关的配置——模型服务地址、数据库连接、MCP Server 路径——全部放到配置文件或环境变量里不要硬编码。内网环境经常需要在不同机器之间迁移配置分离能省掉大量改代码的时间。# config.yaml model: base_url: http://internal-model:8000/v1 api_key: ${MODEL_API_KEY} model_name: qwen-7b-chat mcp: servers: - name: filesystem transport: stdio command: node args: [/opt/mcp/filesystem/dist/index.js, /data] skills: registry_path: /opt/agent-skills/registry.json这套配置结构在实际项目里用了好几个版本基本没怎么大改过说明抽象层次是合理的。6.6 建立内网专属的调试工具链公网环境下调试 Agent 有很多现成工具内网里得自己搭。我一般会准备几个小工具模型服务健康检查脚本定时 ping 模型服务确认可用性MCP Server 连通性测试工具单独测试每个 MCP Server 是否能正常调用Skill 单元测试框架每个 Skill 写独立的测试用例不依赖 Agent 整体运行Agent 回放工具把历史任务的输入输出录下来出问题时可以回放复现这些工具单个看起来都不复杂但组合起来能大幅提升排查效率。尤其是 Agent 回放工具在排查偶发问题时特别有用。6.7 关于内网穿透的说明有些场景下需要从外部访问内网服务做调试这时候会用到内网穿透工具。但要注意内网穿透的使用必须严格遵守所在组织的安全规范不能随意开通通道。我的建议是优先用内网跳板机做调试确实需要穿透的走正规审批流程并且只开放必要的端口和服务。安全合规永远是第一位的不要为了图方便留下隐患。6.8 模型输出的稳定性处理内网部署的开源模型输出稳定性通常不如公网的商业模型。Agent 场景下模型输出的格式错误会导致整个流程失败。我的处理方式是输出格式校验模型返回后先校验格式不符合的重试重试机制设置合理的重试次数和退避策略降级方案重试多次仍失败的走降级逻辑比如返回默认值或转人工import time from tenacity import retry, stop_after_attempt, wait_exponential retry(stopstop_after_attempt(3), waitwait_exponential(multiplier1, min1, max10)) def call_model_with_retry(messages): response call_internal_model(messages) if not validate_response_format(response): raise ValueError(Invalid response format) return response这套重试机制在实际项目里救过很多次场。开源模型的输出偶尔会抽风有了重试和校验整体稳定性会好很多。6.9 关于 Agent 并发扛量的实际数据回到热词里提到的AI Agent 怎么扛并发我分享一组实测数据供参考。在单张 A100 80G 上部署 7B 量化模型配置如下推理框架vLLMtensor_parallel_size1最大并发请求数8平均单次推理延迟1.2sAgent 层并发32异步等待推理结果工具调用并发16连接池大小在这个配置下系统能稳定处理约 6 到 8 QPS 的 Agent 任务。超过这个量推理延迟会明显上升任务完成时间变长。如果要扛更高的并发要么加 GPU要么换更小的模型要么优化 Agent 编排逻辑减少推理调用次数。这个数据不是绝对的不同模型、不同任务复杂度下会有差异。但大致的量级可以参考帮助你在内网资源规划时有个底。6.10 内网 Agent 项目的交付清单最后分享一份我常用的交付清单确保项目移交时不会漏东西Agent 核心代码及依赖清单模型权重及推理服务部署文档MCP Server 离线包及部署脚本Skills 目录及注册表配置文件模板及环境变量说明数据库初始化脚本日志采集配置健康检查脚本压力测试报告常见问题排查手册这份清单看起来繁琐但内网项目移交时少任何一项都可能导致接手的人卡住。我吃过亏后来每次都按这个清单逐项确认省了很多事。内网 AI Agent 工程这件事技术难度其实不算特别高难的是工程细节的把控。每一个依赖、每一个配置、每一个通信链路都需要提前想到、提前验证。公网环境下可以先跑起来再说内网环境下必须想清楚了再动手。希望这些经验能帮到正在做类似项目的兄弟少踩几个坑早点把 Agent 在内网里跑起来。