☰
隔离内网AI Agent实战:MCP与Skills工程化落地
2026/10/8 4:04:30 网站建设 项目流程

1. 为什么要在隔离内网里折腾 AI Agent

先把场景说清楚。所谓“隔离内网”,就是一台或者一组机器,物理上或者逻辑上跟公网断开,没有外网出口,DNS 解析不了外部域名,pip、npm、apt 这些包管理器全部失效。很多做金融、工业控制、医疗设备、涉密研发的团队都是这种环境,代码不能出网,数据不能出网,连截图都得走审批。在这种地方谈 AI Agent,第一反应通常是“不可能”,因为大家习惯了 Agent 要调云端大模型 API、要拉各种在线工具、要实时联网检索。

但实际情况是,隔离内网恰恰是 AI Agent 最能体现价值的场景之一。原因很直接:内网里有大量重复、繁琐、需要跨系统操作的活儿,比如从一堆 SQLite 数据库里捞数据做日报、把工单系统里的记录整理成结构化文档、对本地代码仓库做批量静态检查、把散落的日志按规则归类。这些活儿人做起来枯燥且容易出错,而 Agent 擅长的是“理解意图 + 调用工具 + 循环执行”,只要把工具和模型都搬进内网,它就能干活。

我这次实战的核心目标,是在一台完全断网的 Linux 机器上,搭起一套能跑起来的 AI Agent 工程:模型本地部署或者走内网模型服务,工具层用 MCP 协议统一接入,技能层用 Skills 做能力封装,数据层用 SQLite 做轻量存储,整个链路不依赖任何外网。热词里出现的 MCP、Skills、API、SQLite 这几个词,基本就是这套工程的四大支柱。下面我会把这四个东西怎么在内网里落地、怎么串起来、踩了哪些坑,一条条讲清楚。

这篇文章适合三类人看:一是在内网环境做开发、被“不能联网”卡住的工程师;二是想搞清楚 AI Agent 工程化到底怎么落地、而不是停留在 demo 阶段的技术负责人;三是刚接触 MCP 和 Skills、想知道这俩概念在实际项目里怎么用的人。我会尽量用大白话,把每个选择的理由讲透,把能直接抄的配置和步骤给出来。

2. 整体架构设计与选型思路

2.1 隔离内网带来的三个硬约束

在动手之前,得先认清内网环境的约束,这决定了后面所有选型。第一个约束是没有外网依赖,意味着任何需要在线下载模型权重、拉取依赖包、调用云端 API 的方案直接出局。第二个约束是算力有限,内网机器通常不是 GPU 集群,可能就一两张消费级显卡,甚至纯 CPU,所以模型不能太大。第三个约束是数据不能出网,这反而是好事,因为数据留在本地,用 SQLite 这种文件型数据库最合适,不需要额外部署数据库服务。

这三个约束推导出来的架构就很清晰了:模型层用本地量化模型或者内网已有的模型服务;工具层用 MCP 做标准化接入,因为 MCP 是协议,不依赖外网;技能层用 Skills 把常用操作封装成可复用单元;数据层用 SQLite,单文件、零配置、跨平台。整套东西跑在一台机器上,或者内网几台机器之间互相调用。

2.2 为什么选 MCP 而不是自己写工具调用

很多人第一反应是:我直接写 Python 函数,让模型输出 JSON 然后我解析不就行了,为什么要引入 MCP?我一开始也这么想,直到工具数量超过五个之后,问题就来了。自己写的工具调用,每个工具的入参格式、返回格式、错误处理都不一样,模型稍微换个说法就解析失败,维护成本极高。

MCP 的价值在于它把“工具”抽象成了一个标准协议。你可以把它理解成 USB 接口:以前每个设备都有自己的专用接口,现在统一成 USB,插上就能用。MCP 定义了工具的描述格式(叫什么、干什么、需要什么参数)、调用方式、返回结构,模型只要按这个标准来,就能调用任何符合 MCP 的工具。在内网环境里,这意味着你可以把 SQLite 查询、文件操作、代码检查、日志分析都封装成 MCP Server,Agent 端统一接入,不用为每个工具写适配代码。

热词里提到的“ida mcp”“x32dbg 的 mcp 插件”“altium designer ai 接口 mcp”,其实都是这个思路的延伸——把专业软件的能力通过 MCP 暴露出来,让 Agent 能调用。内网里你完全可以自己写一个 MCP Server 包装内部系统。

2.3 Skills 的定位:比工具更高一层的封装

MCP 解决的是“能不能调用”的问题,Skills 解决的是“怎么用得更好”的问题。一个 Skill 通常是一段提示词加一组工具的组合,针对某个具体任务场景。比如“生成数据库日报”这个 Skill,内部可能包含:先调 SQLite MCP 查询当日数据,再调文件 MCP 写入 Markdown,最后调格式化工具。用户只需要说“帮我出今天的日报”,Agent 就按这个 Skill 的流程走。

Skills 和 MCP 的关系,有点像“菜谱”和“厨具”。MCP 是锅碗瓢盆,Skills 是菜谱。内网环境里,Skills 特别适合把那些固定的、重复的、有明确步骤的活儿固化下来,减少每次都要重新描述需求的麻烦。热词里的“claude agent skills”“agent skills 测试”“skills 推荐”“ai skills 免费库”,说的都是这个层面的东西。

2.4 数据层为什么是 SQLite 而不是别的

内网里做数据存储,选择其实不多。MySQL、PostgreSQL 要装服务、要配权限、要维护,对于 Agent 这种轻量场景太重。CSV 和 JSON 又太散,查询能力弱。SQLite 刚好卡在中间:单文件、零配置、支持完整 SQL、有 Python 内置支持,而且性能对于十万条级别的数据完全够用。

热词里有人问“sqlite 查询十万条数据需要多久”,我实测下来,在普通机械硬盘上,十万条带索引的查询基本在几十毫秒级别,SSD 上更快。这个性能对 Agent 来说绰绰有余。另外 SQLite 的文件可以直接拷贝、备份、迁移,内网里没有网络传输的顾虑,一个 .db 文件拷来拷去就行。热词里的“db browser for sqlite”是个很好用的图形化工具,内网机器上装一个,调试数据非常方便。

3. 核心组件在内网里的落地细节

3.1 模型层:本地部署还是内网服务

模型是 Agent 的大脑,内网里没有云端 API 可用,所以只有两条路:本地部署,或者内网已经有一台模型服务器。如果内网有 GPU 服务器,优先走内网 API,因为本地部署小模型的效果通常不如大模型。如果只能本地部署,那就要在模型大小和效果之间做权衡。

我的建议是,如果显存有 24G 以上,可以跑 14B 到 32B 的量化模型,效果基本能支撑 Agent 的工具调用。如果只有 8G 显存,那就跑 7B 量化模型,但要接受它在复杂任务上容易出错。纯 CPU 的话,只能跑 3B 以下的小模型,适合做简单的分类和抽取任务,复杂的 Agent 循环会很吃力。

部署工具方面,内网里没法用在线下载,所以要提前在有网的机器上把模型权重和推理框架的离线包准备好,通过内网文件传输搬进去。推理框架推荐用支持 OpenAI 兼容接口的,这样 Agent 端代码不用改,只要把 base_url 指向内网地址就行。热词里提到的“智谱 api”“免费大模型 api”“mineru api”这些,在内网里都用不了,但它们的接口格式可以作为参考,自己搭的内网服务尽量兼容同样的格式。

3.2 MCP Server 的内网部署要点

MCP Server 本质就是一个本地进程,通过标准输入输出或者本地端口跟 Agent 通信。内网部署 MCP Server 有几个要点。

第一,依赖要提前打包。MCP Server 通常用 Python 或 Node 写,依赖包在内网里装不了,所以要提前在有网环境用 pip download 或者 npm pack 把依赖下下来,做成离线安装包。我一般会建一个内网的私有 PyPI 镜像或者直接用 pip 的 --find-links 指向本地目录。

第二,通信方式选 stdio 还是 SSE。stdio 最简单,Agent 直接启动 MCP Server 进程,通过标准输入输出通信,不需要网络端口。SSE 适合 MCP Server 要独立部署、多个 Agent 共享的场景。内网里如果就一台机器,stdio 足够;如果要跨机器,用 SSE,但要注意内网防火墙端口要放开。

第三,工具描述要写清楚。MCP 的工具描述是给模型看的,写得越清楚,模型调用越准。我见过很多人工具描述就写一句“查询数据库”,结果模型根本不知道该传什么参数。正确的写法是把参数含义、格式、示例都写进去,比如“查询指定日期的订单数据,参数 date 格式为 YYYY-MM-DD,返回订单列表”。

3.3 Skills 的设计与复用

Skills 的设计核心是“可复用”和“可组合”。一个设计得好的 Skill,应该能覆盖一类任务,而不是一个具体任务。比如“数据查询与报表生成”这个 Skill,可以用于日报、周报、月报,只要参数不同就行。

在内网里,Skills 通常以文件形式存在,比如一个目录下放一堆 .md 或者 .yaml 文件,每个文件定义一个 Skill。Agent 启动时加载这些文件,根据用户输入匹配对应的 Skill。热词里的“skills 安装包下载”“skills ui”“reasonix 如何安装新 skills”,说的都是 Skills 的管理和加载机制。内网里没有在线 Skills 市场,所以要自己建一个 Skills 仓库,用 Git 或者共享目录管理,团队里谁写了好用的 Skill 就提交进去。

Skills 的测试也很重要。热词里的“agent skills 测试”是个关键环节。我的做法是给每个 Skill 准备一组测试用例,输入固定的用户语句,看 Agent 是否按预期调用工具、返回结果是否正确。这个测试可以在内网里自动化跑,不依赖外网。

3.4 SQLite 作为 Agent 记忆与数据层

SQLite 在 Agent 工程里有两个用途:一是作为业务数据存储,二是作为 Agent 的记忆存储。业务数据存储好理解,就是把内网系统里的数据导进 SQLite,Agent 通过 MCP 查询。记忆存储则是把 Agent 的历史对话、执行记录、中间结果存起来,方便后续检索和复盘。

SQLite 的表结构设计要注意几点。第一,给经常查询的字段建索引,比如日期、ID。第二,用合适的数据类型,SQLite 虽然动态类型,但显式声明类型能让查询更快。第三,大文本字段和结构化字段分开存,避免单表过宽。热词里的“sqlite 修改字段的类型”是个常见需求,SQLite 改字段类型不像 MySQL 那么直接,通常要新建表、导数据、删旧表、改名,这个操作要小心,先备份。

Agent 记忆表我一般设计成三张:会话表存会话元信息,消息表存每条消息,工具调用表存每次工具调用的入参和结果。这样查询历史的时候可以按会话、按时间、按工具类型灵活检索。

4. 完整实操流程与关键步骤

4.1 环境准备:离线包的制作与搬运

第一步是在有网的机器上准备离线包。需要准备的东西包括:Python 运行环境(如果内网机器没有)、模型推理框架、模型权重、MCP Server 的依赖、SQLite(通常系统自带)、以及一些辅助工具。

Python 依赖的离线打包,我习惯用 pip download 把所有依赖下到一个目录:

pip download -r requirements.txt -d ./offline_packages --platform manylinux2014_x86_64 --python-version 310 --only-binary=:all:

这里要注意 --platform 和 --python-version 要跟内网机器匹配,否则下下来的包装不上。如果有些包没有预编译版本,要去掉 --only-binary 参数,但那样就需要在内网机器上有编译环境。

模型权重的下载,如果用的是 HuggingFace 上的模型,可以用 huggingface-cli 或者 git lfs 下到本地,然后整个目录拷进内网。注意模型文件通常很大,几个 G 到几十个 G,搬运的时候用移动硬盘或者内网文件服务器。

搬进内网后,安装 Python 依赖:

pip install --no-index --find-links=./offline_packages -r requirements.txt

--no-index 表示不走在线索引,--find-links 指向本地目录,这样 pip 就只从本地找包。

4.2 模型服务的内网启动

模型服务启动的方式取决于用的推理框架。以常见的兼容 OpenAI 接口的框架为例,启动命令大概是这样:

python -m vllm.entrypoints.openai.api_server \ --model /path/to/local/model \ --served-model-name local-model \ --host 0.0.0.0 \ --port 8000 \ --max-model-len 8192

这里 --max-model-len 要根据显存调整,太长会 OOM,太短会导致长对话被截断。热词里提到的“maximum context length is 1048576 tokens”这种报错,就是因为请求的上下文超过了模型支持的长度,内网部署时要根据实际显存设置合理的值。

启动后,用 curl 测试一下:

curl http://localhost:8000/v1/models

能返回模型列表就说明服务起来了。然后 Agent 端配置 base_url 为 http://localhost:8000/v1,api_key 随便填一个非空值(本地服务通常不校验)。

4.3 MCP Server 的编写与注册

写一个 SQLite 查询的 MCP Server,核心是定义工具和处理调用。用 Python 的 mcp 库大概长这样:

from mcp.server import Server from mcp.server.stdio import stdio_server import sqlite3 app = Server("sqlite-mcp") @app.tool() def query_orders(date: str) -> str: """查询指定日期的订单数据。 参数 date: 日期,格式 YYYY-MM-DD 返回: 订单列表的 JSON 字符串 """ conn = sqlite3.connect("/data/business.db") cursor = conn.cursor() cursor.execute("SELECT * FROM orders WHERE order_date = ?", (date,)) rows = cursor.fetchall() conn.close() return str(rows) async def main(): async with stdio_server() as (read, write): await app.run(read, write, app.create_initialization_options()) if __name__ == "__main__": import asyncio asyncio.run(main())

这个 Server 定义了一个 query_orders 工具,Agent 调用时会传入 date 参数。工具描述写清楚了参数格式和返回内容,模型就能正确调用。

注册到 Agent 端,通常是在配置文件里加一段:

{ "mcpServers": { "sqlite": { "command": "python", "args": ["/path/to/sqlite_mcp_server.py"] } } }

Agent 启动时会自动拉起这个 MCP Server 进程,通过 stdio 通信。

4.4 Skills 的编写与加载

一个 Skill 文件通常包含名称、描述、触发条件、执行步骤。以“生成订单日报”为例:

name: daily_order_report description: 生成指定日期的订单日报 trigger: 用户要求生成某天的订单日报 steps: - 调用 sqlite MCP 的 query_orders 工具,传入日期 - 对返回的订单数据做汇总统计 - 调用 file MCP 的 write_file 工具,把结果写入 /reports/日期.md

Agent 加载这个 Skill 后,用户说“帮我出昨天(2024-01-15)的订单日报”,Agent 就会按步骤执行。Skills 的加载通常是在 Agent 启动时扫描指定目录,把所有 Skill 文件读进来,构建成一个技能库。

热词里的“前端开发 skills”“ai agent 开发”“用 ai agent 开发 django”,其实都是把特定领域的操作流程封装成 Skill。内网里你可以把内部系统的操作流程都封装成 Skill,让 Agent 成为内网操作的统一入口。

4.5 端到端联调与验证

所有组件就位后,做一次端到端测试。启动模型服务,启动 Agent,Agent 自动拉起 MCP Server,加载 Skills。然后输入一个测试指令:“查询 2024-01-15 的订单并生成日报”。

观察 Agent 的执行过程:它应该先匹配到 daily_order_report 这个 Skill,然后调用 sqlite MCP 的 query_orders,拿到数据后做汇总,再调用 file MCP 写文件。整个过程在内网里闭环,不依赖任何外网。

如果中间某一步失败,看 Agent 的日志,通常会显示是哪个工具调用出错、错误信息是什么。常见的问题包括:MCP Server 没启动、工具参数格式不对、SQLite 文件路径不对、模型输出的工具调用格式解析失败。

5. 常见问题与排查技巧实录

5.1 模型不调用工具怎么办

这是最常见的问题。模型收到用户请求后,直接用自己的知识回答,而不是调用 MCP 工具。原因通常有三个:一是模型本身能力不够,小模型对工具调用的理解有限;二是工具描述写得不好,模型不知道什么时候该用;三是提示词里没有明确要求使用工具。

解决办法:首先在系统提示词里明确写“你有以下工具可用,当用户请求涉及数据查询时必须调用工具,不要凭记忆回答”。其次把工具描述写详细,包括使用场景。最后如果模型还是不行,考虑换更大的模型,或者在 Skill 里把工具调用步骤写死,减少模型的自由发挥空间。

5.2 SQLite 查询慢或者锁库

SQLite 默认是写锁,多个进程同时写会锁库。Agent 场景下,如果 MCP Server 和别的程序同时访问同一个 .db 文件,就可能出现 database is locked 错误。解决办法是开启 WAL 模式:

PRAGMA journal_mode=WAL;

WAL 模式下读写可以并发,写操作不会阻塞读。另外给查询字段建索引,十万条数据的查询能从几百毫秒降到几十毫秒。如果数据量真的很大,考虑分表或者定期归档。

5.3 MCP Server 启动失败排查

MCP Server 启动失败,Agent 端通常只会显示“工具不可用”,具体原因要看 MCP Server 自己的日志。常见原因:Python 路径不对、依赖没装全、脚本有语法错误、端口被占用(SSE 模式)。排查方法是手动运行 MCP Server 脚本,看报什么错。如果是 stdio 模式,手动运行可能看不到输出,可以在脚本里加日志写文件。

5.4 上下文超长导致请求失败

Agent 执行多轮工具调用后,上下文会越来越长,最终超过模型的 max context length,报错“maximum context length is xxx tokens”。解决办法:一是设置合理的 max_model_len,不要超过显存能承受的范围;二是在 Agent 端做上下文裁剪,只保留最近几轮对话和关键的工具调用结果;三是把中间结果存到 SQLite,需要时再查,而不是全部塞进上下文。

5.5 常见问题速查表

问题现象可能原因排查方向解决办法
模型不调用工具模型能力不足/描述不清看模型输出换大模型/改提示词/写死 Skill
database is locked并发写冲突看 SQLite 日志开 WAL 模式/加索引
MCP 工具不可用Server 启动失败手动运行脚本检查依赖/路径/语法
上下文超长对话轮次太多看 token 数裁剪上下文/存 SQLite
工具参数错误描述不清晰看调用日志完善工具描述/加示例
模型服务 OOMmax_model_len 太大看显存占用调小 max_model_len

5.6 几个踩过的坑

第一个坑是路径问题。内网机器上,MCP Server 脚本里的相对路径可能跟预期不一样,因为 Agent 启动 MCP Server 时的工作目录不一定是脚本所在目录。解决办法是全部用绝对路径,或者在脚本开头 os.chdir 到脚本目录。

第二个坑是编码问题。SQLite 默认 UTF-8,但如果导入的数据是 GBK 编码,查询出来会乱码。导入前统一转成 UTF-8,或者在连接时指定编码。

第三个坑是模型输出的工具调用格式。不同模型输出的工具调用格式可能不一样,有的用 JSON,有的用特定标记。Agent 端要做好兼容,或者选一个格式规范的模型。热词里提到的“llm-deepseek: no api key for provider route”这种报错,就是配置问题,内网里要确保 api_key 配置正确,即使是本地服务也要填一个占位值。

第四个坑是Skills 冲突。如果两个 Skill 的触发条件太相似,Agent 可能匹配错。解决办法是给 Skill 写清晰的触发条件,避免重叠,或者在 Skill 里加优先级。

6. 内网 Agent 工程的扩展方向

6.1 把更多内部系统封装成 MCP

内网里通常有一堆自研系统,每个系统都有自己的接口。把这些接口都封装成 MCP Server,Agent 就能统一调用。比如工单系统、监控系统、代码仓库、文档系统,都可以包装。封装的时候注意统一错误处理和返回格式,让 Agent 端不用为每个系统写特殊逻辑。

6.2 Skills 的团队协作与版本管理

Skills 多了之后,管理就成了问题。建议用 Git 管理 Skills 仓库,每个 Skill 一个文件,提交时写清楚变更内容。团队里可以约定 Skill 的命名规范、目录结构、测试要求。定期 review Skills,把没人用的删掉,把常用的优化。

6.3 性能优化:缓存与批处理

Agent 执行过程中,有些查询是重复的,可以加缓存。比如 SQLite 查询结果缓存到内存或者另一个 SQLite 表,下次同样查询直接返回。批处理则是把多个小操作合并成一个大操作,减少工具调用次数。这些优化在内网算力有限的情况下特别有价值。

6.4 安全与权限控制

内网虽然相对安全,但 Agent 能调用工具就意味着它能操作数据,所以权限控制不能少。MCP Server 层面可以做权限校验,比如某些工具只允许特定用户调用。SQLite 层面可以用视图限制可见数据。Skills 层面可以设置哪些 Skill 对哪些人开放。这些机制在内网里尤其重要,因为一旦 Agent 误操作,影响可能很大。

我在实际项目里最大的体会是,内网 Agent 工程的难点不在模型,而在工程化。模型选型、MCP 封装、Skills 设计、SQLite 调优,每一块都有坑,但每一块都有成熟的解法。关键是先把最小闭环跑通,再逐步扩展。别一上来就追求大而全,先让 Agent 能查一个 SQLite 表、生成一个简单报表,跑通了再往上加。这个过程中积累的配置、脚本、Skill 模板,就是团队最宝贵的资产。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询