隔离内网AI Agent工程实战:MCP协议与Skills封装落地指南

发布时间:2026/10/4 15:10:48
隔离内网AI Agent工程实战:MCP协议与Skills封装落地指南
1. 为什么要在隔离内网里折腾 AI Agent先把场景说清楚。所谓隔离内网就是那种物理上跟公网断开、或者只允许单向数据流入的办公网、生产网、研发专网。很多做金融、制造、政企交付的团队日常开发机根本连不上外网npm、pip、docker hub 全部走不通更别提直接调用云端大模型 API。但偏偏这类团队对 AI Agent 的需求又特别真实——代码补全、日志分析、工单自动分类、内部知识库问答这些都是能实打实省人力的活。我前后在三个隔离环境里落地过 AI Agent 工程踩的坑从模型权重怎么搬进去到MCP 服务在内网怎么注册发现全踩了一遍。这篇就把整套打法摊开讲包括模型侧、Agent 框架侧、MCP 工具协议侧、Skills 能力封装侧以及最容易被忽略的内网服务发现和依赖离线化。适合两类人看一类是被内网限制卡住、不知道从哪下手的中高级工程师另一类是已经能跑通单机 Demo、但一到工程化就散架的团队负责人。核心关键词先摆出来AI Agent、MCP、Skills、内网、工程实战。这五个词基本就是整条链路的骨架。Agent 是大脑MCP 是手脚工具调用协议Skills 是可复用的能力包内网是约束条件工程实战是把前四者捏成一个能长期跑、能维护、能扩展的系统。下面按这个顺序一层层拆。2. 整体架构设计与选型思路2.1 隔离内网给 Agent 工程带来的四个硬约束在公网环境搭 Agent你随手pip install langchain就完事了。内网不行约束是成体系的依赖不可在线拉取所有 Python 包、Node 包、模型权重、甚至字体文件都得提前离线打包带进去。带漏一个间接依赖整个构建就卡死。模型只能本地部署云端 API 调不通必须在内网 GPU 机器上跑本地推理。这就涉及显存规划、量化选型、推理框架选择。服务发现靠手工没有 DNS 泛解析、没有服务注册中心或者有但没接 AgentMCP Server 的地址得写死或用内网配置文件维护。网络策略严格端口开放要走审批跨网段访问可能被防火墙拦Agent 调工具时的超时和重试策略必须比公网环境更保守。理解这四条后面所有设计决策就都有依据了。我见过太多团队直接照搬公网教程结果卡在模型下载这一步就放弃了。2.2 分层架构把大脑、手脚、记忆拆开我的推荐架构是四层从下往上层级职责典型组件模型层本地推理提供 LLM 能力vLLM / Ollama / TGI 量化模型协议层工具调用标准化MCP Server / MCP Client能力层可复用技能封装Skills提示词工具校验编排层任务规划与执行LangGraph / 自研状态机这么分的好处是每层可以独立替换。模型从 7B 换到 14B上层不用动MCP 工具加一个编排逻辑不用改Skills 迭代模型层完全无感。内网环境最怕的就是牵一发动全身分层是保命设计。2.3 为什么选 MCP 而不是自己写函数调用很多人会问我直接写个def search_docs(query)让模型调不就行了为什么要上 MCP区别在于标准化和可发现性。自己写函数调用工具定义散落在代码各处加一个工具要改 Agent 主逻辑多个 Agent 之间没法共享工具。MCPModel Context Protocol把工具定义、参数 schema、调用入口统一成协议任何支持 MCP 的客户端都能挂载同一个 Server。在内网场景下这个优势被放大你可能有代码助手 Agent、运维 Agent、知识库 Agent 三个应用它们都需要查内部 Wiki这个能力。用 MCP写一个 Wiki MCP Server三个 Agent 都挂上不用 MCP你得写三遍还得维护三份。这就是工程化和玩具的分界线。2.4 Skills 的定位比工具更高一层的封装MCP 解决的是工具怎么被调用Skills 解决的是一类任务怎么做。举个例子生成周报这个 Skill内部可能调用了三个 MCP 工具查 Git 提交、查 Jira 工单、查日历加上一段固定的提示词模板再加一个输出格式校验。这些打包在一起就是一个 Skill。Skills 的价值在于把领域知识固化下来。新人不用懂底层工具怎么调选对 Skill 就能干活。内网环境里Skills 还能承担合规检查的角色——比如所有对外输出必须过一遍敏感词过滤 Skill这是硬性要求。3. 模型层内网本地推理的落地细节3.1 模型选型不是越大越好内网 GPU 资源通常紧张选模型要算三笔账显存账、速度账、效果账。显存估算的粗略公式FP16显存 ≈ 参数量 × 2GB KV Cache。7B 模型约 14GB14B 约 28GB32B 约 64GB。如果做 4bit 量化显存能压到约 1/4。KV Cache 跟上下文长度和并发数正相关长上下文场景要额外留 20%~40%。我的经验值单张 24GB 卡如 4090跑 7B FP16 或 14B 4bit并发 4~8 路。单张 48GB 卡如 A6000跑 14B FP16 或 32B 4bit并发 8~16 路。多卡优先考虑张量并行但内网机器往往没有 NVLink走 PCIe 通信会拖慢不如直接选小模型。提示内网环境优先选社区生态好、量化版本全的模型比如 Qwen 系列、DeepSeek 系列。冷门模型一旦量化出问题你在内网连个求助的地方都没有。3.2 推理框架vLLM 还是 Ollama这两个我都用过场景不同Ollama部署极简一条命令拉起适合单机、低并发、快速验证。缺点是并发能力弱生产环境扛不住。vLLMPagedAttention 连续批处理吞吐量高适合多用户共享。缺点是配置复杂依赖 CUDA 版本严格。内网生产环境我基本都上 vLLM。关键配置项python -m vllm.entrypoints.openai.api_server \ --model /models/Qwen2.5-14B-Instruct-AWQ \ --served-model-name qwen-local \ --quantization awq \ --tensor-parallel-size 1 \ --max-model-len 8192 \ --gpu-memory-utilization 0.90 \ --port 8000--gpu-memory-utilization 0.90是留 10% 给系统和其他进程内网机器往往还跑着别的服务别贪心设 0.98。--max-model-len按实际需求设设太大 KV Cache 吃显存并发就上不去。3.3 模型权重怎么搬进内网这是最容易被低估的一步。流程是在能联网的机器上用huggingface-cli download或modelscope把权重下到本地目录。校验文件完整性sha256sum对比官方清单内网传输出错很常见。用移动硬盘或内网文件摆渡系统拷进去。内网机器上确认目录结构vLLM 需要的是 HuggingFace 格式config.json、tokenizer.json、*.safetensors。注意量化模型AWQ/GPTQ的权重和原始权重不通用下载时认准带-AWQ、-GPTQ后缀的仓库。我踩过一次坑下了原始权重却按量化参数启动vLLM 直接报错退出。4. MCP 协议在内网的工程化落地4.1 MCP 是什么一句话讲透MCP 是一套让 LLM 应用和外部工具/数据源通信的开放协议。你可以把它理解成AI 世界的 USB 接口——工具方按协议实现 Server应用方按协议实现 Client两边一插就能用不用为每个工具单独写适配。协议核心就三样Resources可读数据、Tools可调函数、Prompts预设提示模板。Agent 最常用的是 Tools。4.2 内网 MCP Server 的部署形态公网教程里 MCP Server 常用 stdio 模式进程间通信但内网多 Agent 共享场景下我更推荐SSE/HTTP 模式把 Server 做成常驻服务# 一个极简的内网 Wiki 查询 MCP Server from mcp.server.fastmcp import FastMCP mcp FastMCP(wiki-server, host10.0.1.50, port9100) mcp.tool() def search_wiki(keyword: str, top_k: int 5) - list: 在内网 Wiki 中检索关键词返回最相关的 top_k 条。 # 实际实现走内网 ES 或数据库 return do_search(keyword, top_k) if __name__ __main__: mcp.run(transportsse)启动后监听10.0.1.50:9100其他 Agent 通过这个地址挂载。好处是 Server 独立部署、独立升级Agent 重启不影响工具可用性。4.3 服务发现内网没有注册中心怎么办内网往往没有 Consul、Nacos 这类注册中心或者有但没给 AI 团队用。我的做法是配置文件 环境变量双保险# mcp_servers.yaml servers: wiki: url: http://10.0.1.50:9100/sse timeout: 30 retry: 2 gitlab: url: http://10.0.1.51:9101/sse timeout: 60 retry: 1Agent 启动时读这个文件把 Server 列表注入 MCP Client。地址变更只改配置文件不用动代码。如果内网有配置中心哪怕是最土的 etcd优先接进去能省很多运维沟通成本。提示内网防火墙策略要提前申请。MCP Server 的端口、Agent 所在机器的出站规则都得走审批。我见过项目卡在端口没开整整一周代码早就写完了。4.4 工具调用的超时与重试设计内网网络抖动比公网少但一旦出问题恢复慢。工具调用必须设超时且超时值要按工具类型区分工具类型建议超时重试次数说明本地数据库查询10s1内网 DB 快超时基本是慢查询内部 API 调用30s2留足服务处理时间文件/日志检索60s1大文件扫描慢重试意义不大模型推理120s0推理超时重试会雪上加霜重试要加指数退避别傻乎乎地立刻重试容易把下游打挂。5. Skills 能力封装与复用体系5.1 Skill 的组成提示词 工具 校验一个完整的 Skill 包含四部分元信息名称、描述、适用场景、输入输出 schema。提示词模板告诉模型这个任务怎么做包含 few-shot 示例。工具依赖声明需要哪些 MCP 工具。输出校验格式检查、合规过滤、失败兜底。用 YAML 描述一个 Skill 大概长这样name: weekly_report description: 根据 Git 提交和工单生成周报 tools: - gitlab.list_commits - jira.list_issues prompt: | 你是周报助手。根据以下数据生成结构化周报 提交记录{commits} 工单记录{issues} 要求分完成事项进行中风险三部分每部分不超过5条。 output_schema: type: object required: [done, doing, risks]5.2 Skills 的分类与推荐清单内网环境里我按用途把 Skills 分四类每类推荐几个高频的研发类代码审查、单测生成、Commit 信息规范化、接口文档生成。运维类日志异常聚类、告警根因初判、变更影响分析。知识类内部文档问答、规范查询、新人引导。办公类周报生成、会议纪要整理、工单分类。不要一上来就做二十个 Skill先做三个跑通闭环验证效果和稳定性再横向扩展。我见过团队一口气定义三十个 Skill结果一半没人用维护成本还高。5.3 Skill 的版本管理与灰度Skills 是会被频繁修改的必须有版本管理。我的做法是每个 Skill 带version字段Agent 加载时记录版本号出问题能快速回滚。灰度则通过配置控制新版本先给 10% 的请求用观察一周没问题再全量。内网没有成熟的 A/B 平台就用最土的办法——配置文件里写个权重Agent 按权重随机选版本。简单但有效。6. 完整实操从零搭一个内网代码助手 Agent6.1 环境准备与离线依赖打包第一步是把依赖备齐。在联网机器上建一个干净的虚拟环境装好所有包然后导出pip download -r requirements.txt -d ./offline_pkgs --platform manylinux2014_x86_64 --python-version 310 --only-binary:all:--platform和--python-version必须和内网目标机一致否则下到的 wheel 装不上。这一步最容易翻车建议在内网找一台同配置的测试机先验证。requirements.txt 大致包含vllm0.6.3 mcp1.0.0 langgraph0.2.45 fastapi0.115.0 uvicorn0.32.0 pydantic2.9.2 httpx0.27.2版本号全部锁死内网环境不允许这种模糊约束。6.2 模型服务启动与连通性验证模型权重拷进去后先起 vLLM用 curl 验证curl http://10.0.1.40:8000/v1/models返回模型列表说明服务正常。再用一个最小请求测推理curl http://10.0.1.40:8000/v1/chat/completions \ -H Content-Type: application/json \ -d {model:qwen-local,messages:[{role:user,content:你好}]}能返回内容就说明模型层通了。这一步不通后面全白搭务必先验证。6.3 MCP Server 注册与 Agent 挂载按 4.2 的方式起两个 MCP Server比如 Wiki 和 GitLab然后在 Agent 侧挂载from mcp import ClientSession from mcp.client.sse import sse_client async def load_tools(server_url): async with sse_client(server_url) as (read, write): async with ClientSession(read, write) as session: await session.initialize() return await session.list_tools()把返回的 tools 列表转成模型能理解的 function schema注入到 LLM 的 tools 参数里。这一步是 MCP 和 Agent 框架的粘合点不同框架写法不同但本质都是拉工具列表 → 转 schema → 注入。6.4 编排逻辑用状态机管住多步任务单轮工具调用简单多步任务就得上状态机。我用 LangGraph 定义节点规划 → 选工具 → 执行 → 观察 → 判断是否完成 → 循环或结束。关键是要设最大步数防止 Agent 陷入死循环MAX_STEPS 10 def should_continue(state): if state[steps] MAX_STEPS: return end if state[done]: return end return continue内网环境尤其要防死循环因为模型效果可能不如云端大模型规划能力弱一些容易反复调同一个工具。6.5 端到端联调与压测联调时按单工具 → 多工具 → 多轮 → 并发的顺序推进。压测用locust或简单的asyncio脚本重点看三个指标首 token 延迟、端到端延迟、工具调用成功率。内网压测要注意别把模型服务打挂从 2 并发开始逐步加到 8、16观察 GPU 利用率和显存。一旦出现 OOM 或延迟飙升就说明到瓶颈了要么加卡要么降并发。7. 常见问题与排查技巧实录7.1 依赖装不上间接依赖缺失现象pip install报某个包找不到。原因通常是pip download时没把间接依赖下全。解决用pip download时加--no-deps逐个下或者用pipdeptree先理清依赖树确保每个都下到。更稳的办法是用pip wheel把整个环境打成 wheelhouse。7.2 模型加载 OOM现象vLLM 启动时报 CUDA out of memory。排查顺序先看--gpu-memory-utilization是不是设太高降到 0.85 试试再看--max-model-len是不是过大KV Cache 吃显存最后确认量化参数和权重是否匹配。我遇到过一次是权重是 GPTQ 但参数写了 AWQ加载时按 FP16 分配显存直接爆。7.3 MCP 工具调用超时现象Agent 调工具卡住最后超时。排查先用 curl 直接打 MCP Server 的 SSE 端点确认服务活着再检查防火墙规则内网跨网段访问经常被拦最后看 Server 日志可能是工具内部逻辑慢。超时值要按工具类型设别一刀切。7.4 Agent 陷入循环现象Agent 反复调同一个工具不收敛。原因通常是提示词没写清什么算完成或者工具返回的信息模型理解不了。解决在提示词里明确终止条件给工具返回值加结构化说明设最大步数兜底。7.5 常见问题速查表问题可能原因快速排查模型服务起不来显存不足/权重不匹配看启动日志降 utilization工具调不通防火墙/地址错curl 直连 ServerAgent 不收敛提示词模糊/无终止条件加最大步数明确完成定义输出格式乱缺 schema 约束加 output_schema 校验并发上不去KV Cache 吃显存降 max-model-len 或加卡提示内网排查最大的障碍是信息不透明日志、监控往往不完善。建议 Agent 侧自己做详细日志把每次工具调用、模型输入输出都记下来出问题能复盘。8. 我踩过的坑和几条实在建议第一个坑是低估了依赖打包的工作量。第一次做的时候以为pip download一把梭结果内网装的时候缺了七八个间接依赖来回摆渡文件折腾了两天。后来学乖了直接在联网机器上建一个和内网完全一致的 Docker 镜像把镜像导出成 tar 带进去一步到位。第二个坑是MCP Server 地址写死在代码里。一开始图省事url http://10.0.1.50:9100直接写死后来 Server 换机器改代码、重新打包、重新部署折腾一下午。改成配置文件后改一行重启就完事。第三个坑是没设最大步数。有个 Agent 处理一个模糊需求时反复调同一个查询工具十几次把模型服务拖垮了。加了MAX_STEPS10之后最多浪费十步就退出可控多了。几条实在建议内网做 Agent先把模型层和 MCP 层跑通再碰编排别一上来就写复杂逻辑所有配置外置地址、超时、并发数都别写死日志要全内网排查全靠日志Skills 从少到多先跑通三个再扩展。这套打法我在三个隔离环境里验证过从零到能用大概两周稳定运行半年没出过大问题。