ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

隔离内网部署AI Agent实战:MCP与Skills离线落地指南

隔离内网部署AI Agent实战:MCP与Skills离线落地指南 1. 为什么要在隔离内网里折腾 AI Agent先把场景说清楚。所谓隔离内网就是那种物理上跟公网断开、或者只允许单向数据流入的办公网、生产网、实验室网。你在这种环境里想跑一个 AI Agent第一反应通常是模型调不到、依赖装不上、MCP 连不通、Skills 拉不下来。我最早接这类需求的时候客户给的条件是一台内网跳板机 一个离线的模型权重包 不许开任何外网端口当时我盯着屏幕想了半天感觉像是让你用一把螺丝刀去修一台没有螺丝的机器。但真做下来会发现隔离内网跑 AI Agent 不是能不能的问题而是怎么拆的问题。核心思路就一句话把 Agent 拆成能离线固化的部分和必须联网的部分然后把必须联网的部分用内网服务替代掉。模型可以本地部署MCP 可以内网自建Skills 可以打包成离线资源工具调用可以走内网 API 网关。整套东西跑通之后稳定性反而比公网方案高因为没有任何外部抖动。这篇文章适合三类人看一是在内网环境做自动化、运维、数据分析的工程师二是想把 AI Agent 落到实际业务里但被网络限制卡住的技术负责人三是刚开始接触 MCP、Skills 这些概念想搞清楚它们在内网里到底怎么落地的人。我会把整套工程拆成设计思路、核心组件、实操步骤、踩坑排查四个部分每个部分都给出可以直接抄的配置和参数不讲空话。先给一个整体判断隔离内网下的 AI Agent本质是一个离线优先的工程问题而不是一个模型能力问题。你把这句话记住后面所有的取舍都会变得清晰。2. 整体架构设计与方案选型2.1 隔离内网 Agent 的三层拆解模型我在实际项目里习惯把整个系统拆成三层这个拆法不是教科书上的是被内网环境逼出来的。第一层是推理层负责跑模型。内网里没有 API 可调所以必须本地部署。常见选择是 Ollama、vLLM、LM Studio 这类可以离线加载权重的方案。模型大小取决于你的硬件7B 到 32B 是比较现实的区间再大就要考虑量化或者多卡。第二层是编排层负责 Agent 的逻辑也就是想什么、调什么工具、怎么循环。这一层是纯代码Python 或 TypeScript 都行LangChain、LangGraph、Spring AI 这些框架都能用但前提是依赖包要提前在内网镜像源里准备好。第三层是能力层也就是 MCP 和 Skills 所在的位置。MCP 负责把外部工具数据库、文件系统、浏览器、内部系统暴露成 Agent 能调用的接口Skills 负责把怎么做某件事的流程固化下来。这一层是内网改造的重点因为公网方案里它们通常依赖远程服务。三层之间的关系是编排层调用推理层生成决策决策触发能力层的工具调用工具返回结果再回到编排层。整个链路里唯一不能离线的是模型推理的算力其他全部可以内网自建。2.2 为什么选 MCP 而不是自己写工具函数很多人会问我直接写 Python 函数给 Agent 调用不就行了为什么要上 MCP这个问题我在内网项目里被问过至少五次。自己写工具函数的问题在于耦合。你的 Agent 逻辑和工具实现绑死在一个进程里工具一多代码就变成一团。更麻烦的是内网环境里工具往往分散在不同机器上——数据库在一台文件服务在另一台内部 API 网关在第三台。你不可能把所有工具都塞进 Agent 进程。MCP 的价值就在这里它把工具调用标准化成一种协议Agent 通过 MCP Client 连接 MCP ServerServer 可以在任意内网机器上跑。你换工具、加工具、改工具Agent 侧几乎不用动。这在内网这种改一次要走变更流程的环境里价值极大。提示内网部署 MCP Server 时优先选 stdio 传输方式而不是 SSE 或 WebSocket。stdio 不依赖网络端口进程间直接通信内网防火墙基本不会拦排查也简单。2.3 Skills 在内网里的定位与打包方式Skills 这个概念最近很热但很多人理解偏了。Skills 不是模型能力也不是工具它是流程知识的结构化封装。比如如何排查一个 Java 服务的 OOM 问题这是一套步骤、判断条件、常用命令的组合把它写成 SkillAgent 就能按这个流程走而不是每次自由发挥。内网里 Skills 的难点是分发。公网方案通常从某个市场拉取内网没有这个条件。我的做法是把 Skills 做成一个内网 Git 仓库或者共享目录Agent 启动时从本地路径加载。每个 Skill 是一个目录里面放SKILL.md描述文件加若干脚本或模板。这样版本可控审计也方便。组件公网常见方案内网替代方案关键差异模型推理云端 APIOllama / vLLM 本地部署无网络依赖算力受限工具调用远程 MCP 服务内网 stdio MCP Server传输方式改为进程间Skills 分发在线市场内网 Git / 共享目录手动同步版本自管依赖安装pip / npm 公网源内网镜像源 / 离线 wheel 包需提前准备这张表是我做内网项目时的标准对照每次方案评审都拿它过一遍能快速定位哪些环节需要改造。3. 核心组件在内网里的落地细节3.1 本地模型部署的参数取舍内网部署模型第一个决策是选哪个推理框架。我实测下来Ollama 适合快速验证vLLM 适合生产。Ollama 装完就能跑但并发能力弱vLLM 配置麻烦一点但吞吐量高一个量级。模型选型上我的经验是Agent 场景不要盲目追大模型。Agent 的核心是工具调用和流程控制对模型的指令遵循能力要求高对知识广度要求反而没那么高。7B 到 14B 的指令微调模型配合好的 Prompt 和 Skills效果往往比 70B 的通用模型更稳。关键参数上temperature建议设 0.1 到 0.3Agent 需要稳定输出不需要创意。context length要按你的 Skills 和工具描述总长度来定一般 8K 到 32K 够用。max_tokens别设太大Agent 的单步输出通常很短设大了反而容易跑偏。# Ollama 内网部署示例指定模型和并发参数 ollama serve ollama pull qwen2.5:14b-instruct # 启动时限制并发避免内网机器被打满 OLLAMA_NUM_PARALLEL2 OLLAMA_MAX_LOADED_MODELS1 ollama serve注意内网机器往往是共享的模型加载会吃满内存。我踩过的坑是没限制OLLAMA_MAX_LOADED_MODELS结果同时加载两个模型直接把机器搞挂。生产环境一定要显式限制。3.2 MCP Server 的内网自建与注册MCP Server 在内网里怎么建我的标准做法是每个能力域建一个 Server。比如数据库操作一个 Server文件系统一个 Server内部 API 调用一个 Server。每个 Server 用 stdio 方式启动Agent 侧通过配置文件注册。配置文件通常长这样{ mcpServers: { internal-db: { command: python, args: [/opt/mcp/db_server.py], env: { DB_HOST: 10.0.1.20, DB_PORT: 5432 } }, file-service: { command: python, args: [/opt/mcp/file_server.py] } } }这个配置的关键点是command和args都指向内网本地路径不涉及任何网络请求。Server 进程由 Agent 启动时拉起用完就退不占端口。MCP 的工具描述要写得克制。我见过有人把一个 Server 塞了三十个工具结果模型选择困难调用准确率暴跌。每个 Server 控制在 5 到 8 个工具描述写清楚什么时候用和什么时候不用比堆数量有用得多。3.3 Skills 的目录结构与加载机制Skills 的目录结构我固定成一套模板团队里所有人都按这个来skills/ java-oom-troubleshoot/ SKILL.md scripts/ collect_heap.sh analyze_dump.py templates/ report.mdSKILL.md是核心里面写清楚这个 Skill 解决什么问题、适用场景、执行步骤、每步的判断条件。Agent 加载时读这个文件把它作为上下文的一部分。加载机制上我建议按需加载而不是全量加载。内网模型上下文有限把所有 Skills 塞进去会挤爆。做法是先用一个轻量的路由 Skill 判断当前任务属于哪个领域再动态加载对应的 Skill。这个路由逻辑可以用关键词匹配也可以用一个小模型做分类看你的资源情况。提示Skills 里的脚本要写绝对路径内网环境的工作目录经常变相对路径是排查噩梦。我因为这个吃过两次亏脚本在测试环境跑得好好的上线就找不到文件。4. 完整实操流程与关键环节4.1 环境准备与离线依赖打包内网部署的第一步不是写代码是准备离线依赖。这一步做不好后面全是坑。我的标准流程是在一台能联网的机器上用pip download把所有依赖下载成 wheel 包连同 Python 解释器一起打包拷进内网。# 在联网机器上准备离线包 pip download -r requirements.txt -d ./offline_packages --platform manylinux2014_x86_64 --python-version 3.11 --only-binary:all: # 打包 tar -czf agent_deps.tar.gz offline_packages/进内网后用pip install --no-index --find-links./offline_packages安装。这里的关键是--platform和--python-version要跟内网机器完全一致否则会出现包下载了但装不上的情况。模型权重也是同样处理提前下载好 GGUF 或 safetensors 文件拷进内网。一个 14B 的量化模型大概 8 到 10 GBU 盘或者内网文件服务器都能传。4.2 Agent 主循环的代码实现Agent 的主循环是整个系统的骨架。我用 LangGraph 写过一个内网版本核心逻辑是这样的from langgraph.graph import StateGraph, END from langchain_community.llms import Ollama llm Ollama(modelqwen2.5:14b-instruct, base_urlhttp://localhost:11434) def decide_node(state): # 模型决策是调用工具还是直接回答 prompt build_prompt(state[messages], state[skills]) response llm.invoke(prompt) return {next_action: parse_action(response)} def tool_node(state): # 执行 MCP 工具调用 result mcp_client.call(state[tool_name], state[tool_args]) return {messages: state[messages] [result]} graph StateGraph(AgentState) graph.add_node(decide, decide_node) graph.add_node(tool, tool_node) graph.add_conditional_edges(decide, route_fn, {tool: tool, end: END}) graph.add_edge(tool, decide) app graph.compile()这个循环的关键是设置最大迭代次数。内网模型能力有限偶尔会陷入调工具-看结果-再调同一个工具的死循环。我一般设max_iterations10超过就强制返回当前结果并提示任务未完成请人工介入。4.3 内网工具调用的参数传递与鉴权内网工具调用有个特殊问题鉴权。公网方案里通常用 token内网里很多系统用的是 IP 白名单或者域账号。我的做法是在 MCP Server 侧统一处理鉴权Agent 侧不感知。具体来说Server 启动时从环境变量读取凭据调用内部系统时自动带上。Agent 只需要传业务参数比如查询订单 12345不用管怎么鉴权。# MCP Server 侧统一鉴权 import os from internal_sdk import InternalClient client InternalClient( hostos.environ[INTERNAL_HOST], credentialos.environ[INTERNAL_CRED] ) mcp_tool def query_order(order_id: str) - dict: 查询内网订单系统的订单详情 return client.get(f/api/order/{order_id})这样设计的好处是凭据不进入模型上下文避免泄露风险也避免模型把 token 写进日志。4.4 日志、审计与可观测性内网环境对审计要求高Agent 的每一步决策和工具调用都要留痕。我在项目里固定记录三类日志决策日志模型输入输出、工具日志调用参数和返回、异常日志错误堆栈。日志格式用 JSON Lines方便后续用脚本分析。每条日志带上trace_id把一次完整任务的所有步骤串起来。import json, uuid, logging trace_id str(uuid.uuid4()) logger.info(json.dumps({ trace_id: trace_id, step: tool_call, tool: query_order, args: {order_id: 12345}, duration_ms: 230 }))注意日志里绝对不能记录完整的模型输入因为里面可能包含敏感业务数据。我一般只记录输入的哈希值和长度需要排查时再单独开启详细模式。5. 常见问题与排查技巧实录5.1 模型加载失败与显存不足内网机器最常见的问题是显存不够。14B 模型 FP16 需要约 28 GB 显存量化到 Q4 大概 9 GB。如果机器只有一张 16 GB 的卡就必须用量化版本。排查顺序是先看nvidia-smi确认显存占用再看模型加载日志确认是否 OOM。如果是 OOM换更小的量化版本或者用 CPU 推理慢但能跑。问题现象可能原因排查方法解决方案模型加载卡住权重文件损坏校验文件 MD5重新拷贝权重显存 OOM模型太大nvidia-smi 看占用换量化版本推理极慢用了 CPU看进程 CPU 占用确认 GPU 可用输出乱码模型格式不匹配看加载日志换对应格式权重5.2 MCP 连接超时与工具调用失败MCP 用 stdio 方式时连接问题通常是进程启动失败。排查方法是手动执行配置里的command和args看能不能正常启动。常见原因是 Python 路径不对、依赖缺失、脚本权限不够。工具调用失败则要看 Server 侧日志。我遇到过工具描述写得太模糊模型传了错误的参数类型Server 直接抛异常。解决办法是在工具定义里加严格的类型校验参数不对就返回明确的错误信息让模型能自我纠正。5.3 Skills 加载异常与上下文溢出Skills 加载异常一般是路径问题或者格式问题。SKILL.md的格式要固定我建议用 YAML front matter 加 Markdown 正文解析起来稳定。上下文溢出是内网 Agent 的高频问题。模型上下文 8KSkills 加工具描述加对话历史很容易超。解决办法是分层加载基础 Skills 常驻领域 Skills 按需加载对话历史做摘要压缩。我一般保留最近 5 轮完整对话更早的压缩成一句话摘要。5.4 内网环境下的性能调优经验内网 Agent 的性能瓶颈通常在模型推理不在工具调用。调优方向有三个一是减少模型调用次数。能用规则判断的不要问模型比如用户输入是否为空这种判断直接代码处理。二是缓存高频结果。同样的工具调用参数短时间内重复出现直接返回缓存。我做过统计内网 Agent 有 30% 左右的工具调用是重复的。三是批处理。多个独立的工具调用可以并行发起不要串行等待。LangGraph 支持并行节点用好了能省一半时间。提示内网机器资源紧张时把模型推理和 Agent 编排放在不同机器上。推理机器专心跑模型编排机器跑轻量逻辑互不干扰。这个拆分我在三个项目里都用过效果稳定。6. 我在内网 Agent 项目里的几点真实体会做了几个内网 Agent 项目之后我最大的体会是别把公网方案直接往里搬。公网那套模型随便调、工具随便连、Skills 随便拉的思路在内网里每一步都是坑。你得反过来想哪些东西是必须的哪些是可以砍的砍完之后剩下的才是真正要解决的。第二个体会是文档比代码重要。内网环境变更慢一个 Agent 上线后可能半年不动。半年后你回来看如果没有清晰的 Skills 文档和 MCP 工具说明根本不知道当时为什么这么设计。我现在每个项目都强制要求 Skills 和工具描述写到新人能看懂的程度。第三个体会是留人工兜底。内网 Agent 再稳也会出错尤其是模型能力有限的时候。我的做法是在关键节点设置人工确认比如即将执行删除操作请确认。这个设计看起来笨但在内网这种出错代价高的环境里是最实用的保险。最后分享一个具体技巧内网 Agent 的 Prompt 要写得更啰嗦。公网模型聪明一句话能懂内网小模型需要你把边界条件、异常处理、输出格式都写清楚。我一般把 Prompt 写成角色 任务 步骤 约束 输出格式五段式虽然长但调用准确率能提升一大截。这个技巧不优雅但管用。
返回列表