隔离内网这个场景,我在项目里碰过不止一次。不少团队在公网上把 Agent 玩得很顺,一旦落到生产环境的隔离内网,第一个动作往往是打开模型厂商的 API 文档,然后发现请求根本发不出去——网络不通,一切白搭。这篇内容就是把我在隔离内网下搭建 AI Agent 工程的完整过程、选型理由和踩坑记录整理出来,给要往这类环境里部署的团队做一个参照。
先说清楚这里的“隔离内网”指什么:不是办公室局域网这种还能访问公网的办公网,而是真正物理隔离或逻辑隔离的生产网络,没有外网出口,数据不能出域,模型、代码、依赖全得在本地跑。这种环境下做 Agent,核心命题就从“怎么调用最强的云端模型”变成了“怎么在有限算力里把一个能自主规划、能调用工具、能记住上下文的智能体养活”。
1. 为什么要在隔离内网里跑 Agent:需求与边界
如果你只是需要一个能聊天的对话机器人,隔离内网里搭一个 ChatUI 就够了,根本不需要 Agent。真正逼着团队上 Agent 的,是“对话之后还要干活”的需求。
1.1 三类典型场景
我遇到并验证过的大概这三类:
第一类是域内知识问答加自动归档。内部知识库分散在多个系统里,有的在 Wiki,有的在 OA,有的在工单系统,业务人员想找一个流程文档,得翻三四个系统。Agent 的价值在于把“搜哪里”变成“问一句”,它自己去各个系统捞数据、汇总答案。这类场景对实时性要求不高,但对检索准确率要求很高,答错了会直接影响业务操作。
第二类是运维与值班辅助。内网环境里服务器告警、日志排查、工单初步分类,都是在隔离网络内发生的。过去这些事靠人去盯着群消息和监控大屏,上了 Agent 之后,可以让它定时拉取告警信息、汇总成简报、对常见故障给出初步排查建议,再自动提单。这类场景对工具调用的稳定性要求极高,跑一天是 demo,跑一个月才是工程。
第三类是内容生成与多语言处理。比如产品说明书、合同初步审查、多语言翻译初稿,数据不能出域,所以必须本地部署模型。这类场景对模型的语言能力和指令跟随能力要求高,但工具调用相对简单,一个文生文的循环就能解决。
1.2 隔离内网给 Agent 带来的真实约束
很多人以为隔离内网只是“少了外网”,其实它的约束远比想象中多:
- 模型能力天花板下移:云端能用 70B 甚至更大参数规模的模型,内网很多时候只能跑 7B、14B 级别的量化模型,推理能力的差距是硬性的。
- 依赖获取困难:Python 包、Node 模块、前端资源,都不能直接 pip install 或 npm install,必须提前准备离线包或私有镜像源。
- 工具生态不统一:公网上有大量 SaaS 工具可以直接挂给 Agent,内网里的系统往往是老旧的 Java 应用、Oracle 数据库、自定义协议的服务,接起来比接公网 API 费劲得多。
- 迭代周期拉长:每次改完模型配置或者框架代码,测试环境的搭建、数据的导入、模型的重新加载都比公网慢,问题定位也困难。
这些约束意味着,在隔离内网里做 Agent,本质上是在做“资源受限环境下的智能体工程”,一切设计和选型都要围绕“省”、“稳”、“可维护”来展开。
2. 底座选型:内网能跑的本地大模型与推理框架
Agent 的上限由底座模型决定,但隔离内网里的模型选型往往不是“越大越好”,而是“够用且能跑”。
2.1 模型尺寸、量化档位与显存预算
内网部署首先要解决硬件预算问题。以 7B 模型为例,FP16 精度大约需要 14GB 显存,加上推理时的 KV Cache 和中间激活,一张 24GB 的显卡刚好能跑起来,但余量很小。我的建议是至少按以下档位评估:
| 模型尺寸 | 建议精度/量化 | 最低显存(推理) | 适用场景 |
|---|---|---|---|
| 7B | AWQ 4bit | 8~10GB | 简单问答、意图分类 |
| 13B~14B | AWQ 4bit / GPTQ 4bit | 14~16GB | 工具调用、中等复杂度生成 |
| 32B | AWQ 4bit | 24~32GB | 复杂推理、长文本工具调用 |
| 70B | AWQ 4bit | 48~64GB | 高质量写作、复杂多步规划 |
以我实际项目的经验,Agent 场景下不要盲目追求小模型。7B 模型在公网上聊天看起来还行,但一旦牵扯多步工具调用、参数提取、结果归纳,非常容易“前言不搭后语”。如果显存允许,直接上 14B 级别的量化模型是性价比最高的起点。预算充足的话,32B 级别的模型在工具调用上的稳定性会让人省心很多。
2.2 推理引擎对比:vLLM、Ollama、llama.cpp
同一份模型权重,用不同的推理引擎跑,效果一样,但性能、并发和稳定性差别很大。我按场景拆一下:
- vLLM:适合生产环境做高并发服务化部署。它对连续批处理(continuous batching)支持很好,显存利用率高,支持 OpenAI 兼容接口,Agent 框架对接最省事。缺点是部署相对重,依赖 PyTorch 环境,首次启动加载模型时间长。
- Ollama:适合快速验证和单机场景。一条命令就能启动服务,也支持 OpenAI 兼容接口,但如果需要很高并发、很长的多轮对话、精细的显存控制,它不如 vLLM 稳。
- llama.cpp / llama-server:适合 CPU 推理或混合部署,以及显存特别紧张的环境。它对量化格式(GGUF)支持最好,但也意味着你需要额外处理模型格式转换。
我最终的选择是vLLM 作为底座推理服务。原因很简单:Agent 场景下,同一个模型可能会被多个会话并发调用,模型还要处理带工具定义的请求,这类请求的输入长度普遍偏长,vLLM 的吞吐量和显存复用明显优于其他方案。
2.3 为什么建议在前面加一层“模型网关”
这是一个很多人忽略的工程细节。Agent 框架和模型之间,不要直接建立强绑定,而是加一个模型网关层。网关的作用有三点:
- 统一接口协议:所有 Agent 组件都只认一个 OpenAI 兼容的 base_url,底层今天用 vLLM,明天换推理引擎,Agent 侧完全不用动。
- 做 Key 转发和限流:内网环境虽然没有公网的那些鉴权压力,但多个业务方共用同一套模型服务时,还是要区分租户、限制并发,否则一个业务方的突发流量会把其他人的推理任务全部堵死。
- 记录请求日志:模型输入输出全部过网关,方便后续做评测、追溯和审计。这部分在隔离内网尤其重要,因为安全审计要求“所有数据流转可回溯”。
网关本身不需要多复杂,基于 FastAPI 包一层转发,约 200 行代码就能完成。但有了这一层,后续排查问题的成本会低非常多。
3. Agent 框架的内网化适配:从云端基操到本地闭环
框架选型决定了你开发 Agent 的效率。隔离内网里选框架,除了看功能,更要看它能不能在不联网的情况下跑通全链路。
3.1 框架选型与内网兼容性评估
目前主流的几个选择:
- LangChain / LangGraph:生态最全,内置大量工具接入和调用链编排能力,但依赖很重,且默认很多能力默认指向云端服务。内网部署需要把大量内置工具拆掉,只保留本地可用的核心组件。
- LlamaIndex:强在索引和检索,适合做知识密集型 Agent,同样存在依赖精简问题。
- CrewAI:多 Agent 协作编排体验好,适合做角色分工。缺点是对底层模型的指令跟随能力要求高,模型太弱时非常容易演变成“多人会议没有结论”。
- 自研轻量框架:如果 Agent 的工作流相对固定,不追求花哨的插件生态,自研一个几十行核心循环的框架反而更可控。
我的实际经验是:框架的复杂度要和业务复杂度匹配。如果 Agent 就干三件事——理解问题、调工具、汇总结果,那就没必要上重框架,用最朴素的循环加结构化输出就能搞定。如果确实需要多 Agent 分工、状态流转、人机审批,架设 LangGraph 这类框架是值得的,但一定要提前做好内网依赖离线打包。
3.2 模型接入:把 SDK 指到内网网关
这是最基础也最关键的适配。所有框架默认都会指向官方的 API 地址,你需要把 base_url 改成内网模型网关的地址。
以 Python 生态为例,不管是 OpenAI SDK 还是 LangChain 的 ChatOpenAI,都支持显式指定 base_url。需要注意的点是:
- 不要直接改第三方依赖包的源码,那样后续升级会很痛苦。用环境变量或初始化参数覆盖 base_url 是最干净的做法。
- Agent 请求模型时,默认会在请求体里带上工具定义(tools 参数)。本地部署的模型服务必须确认支持 tools / function calling 的请求格式,否则工具调用会退化成一堆 JSON 字符串,而不是结构化的函数调用对象。
注意:隔离内网环境里,很多开箱即用的插件会试图访问公网做 Telemetry 或模型评测,部署前务必检查并关闭这些默认行为。一个常见的坑是框架启动后后台自动请求外网地址,导致启动超时。
3.3 把“联网搜索”改造成“内网检索”
公网上的 Agent 默认工具里一定有联网搜索,但内网里没有搜索引擎这个说法。你需要做的是把搜索工具整体替换成内网检索工具,常见方案:
- 检索 Elasticsearch 或 OpenSearch,适合文档类数据;
- 检索关系型数据库,适合结构化的业务数据;
- 检索内部 Wiki / 工单系统的 HTTP API,适合业务系统集成。
改造的核心是让工具描述告诉模型“这个工具能在哪里搜到什么东西”,否则模型不知道何时该调用它。举个例子,工具描述写“search_es(query: str) 在内部文档库中搜索相关内容”,模型才会在用户问“查一下报销流程”时主动调用它。
3.4 工具调用的内网化:从 HTTP 到进程内调用
公网 Agent 的工具往往是 HTTP 调用外部 API,内网里这些 API 可能根本不存在,或者只在内网某个非标准端口上提供服务。如果你的 Agent 和工具系统在同一台机器上,可以考虑进程内函数调用,省去 HTTP 开销和网络不稳定因素。如果跨机器,则优先使用内网 HTTP 或消息队列。
这里要特别关注超时设置。内网系统很多是老服务,接口响应经常又慢又不稳定,Agent 在调用工具时,默认超时往往只有 10 秒。实测中我遇到过很多次模型报“工具调用失败”,真正原因只是内网接口响应了 30 秒,直接把请求超时了。把工具调用的超时时间放宽到 60~120 秒,并做好重试策略,是内网适配里性价比最高的一步。
4. 工具接驳实战:把存量系统变成 Agent 的双手
Agent 光会说是没有意义的,它的价值在“能调工具”。隔离内网里最大的工程量和最容易出问题的地方,都在这块。
4.1 工具描述与参数 Schema:不要偷懒,直接决定成败
模型本身不会“记住”你的系统有哪些接口,它只能根据工具描述和参数 Schema 来决定调不调、怎么调。很多团队在这上面翻车,要么是工具描述太敷衍,要么是参数定义和实际接口脱节。
我总结的实践规范是:
- 工具描述必须写明“什么场景下用”和“用什么参数能解决什么问题”。比如不要把描述写成“获取订单信息”,而要写成“根据订单号或用户手机号获取订单状态、商品列表、支付信息,适用于查询订单进度、处理售后问题”。
- 参数 Schema 要给出枚举和格式示例,比如状态字段注明支持“待支付/已支付/已发货/已完成”,日期格式注明“YYYY-MM-DD”。否则模型经常自己发挥,传一个看不懂的格式。
- 返回结果要结构化。不能让工具返回一大段无格式的文本让模型自己解析,而应该返回 JSON,并在工具描述里把返回结构写清楚。
4.2 三类接入模式:直连、队列、旁路
内网系统千差万别,接驳方式我建议按下面的口径选择:
| 接入模式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| HTTP API 直连 | 存量系统本身提供接口 | 实现简单,链路短 | 老接口稳定性差时容易拖垮 Agent |
| 消息队列 + 异步任务 | 耗时操作,如查询报表、生成文档 | 解耦,Agent 不阻塞等待 | 交互链路复杂,需要结果回传机制 |
| 旁路代理 / 旁路协议转换 | 系统只有客户端协议,没有开放接口 | 不改老系统也能接 | 协议适配成本高,稳定性依赖抓包分析 |
我在实际的运维 Agent 项目里,90% 的工具都走了 HTTP API 直连,剩下 10% 的耗时操作用了消息队列异步化。不要一上来就搞复杂架构,先把直连跑通,再根据耗时和稳定性优化成异步。
4.3 不可逆操作的审批流
隔离内网里工具可能操作的是生产系统,比如发工单、改配置、执行命令,这类操作一旦做错,影响面很大。所以为 Agent 配置不可逆工具时,强烈建议加一道人工审批闸门。
实现上不复杂:Agent 对危险工具发起调用时,先不真正执行,而是把“准备执行的参数”推送到审批队列,由人在一个非常简单的审批界面点“允许/拒绝”,点了允许之后才真正调接口。这一步几乎是隔离内网内部署 Agent 的默认要求,因为它同时解决了安全、合规和信任三个问题。
5. 记忆与知识库的内网落地
公网 Agent 可以轻松挂载云端向量库和对话记忆服务,内网里这些也需要本地化。这块我没有用复杂的方案,反而是用了一套比较轻的基础设施就满足了生产需求。
5.1 RAG 检索:Embedding 模型、向量库、索引更新
要给 Agent 挂知识库,第一步是本地化 Embedding 模型。不要用公网 API 做向量化,数据出域在隔离内网直接就是违规。本地化部署 Embedding 模型的好处是延迟低、成本可控,尤其是文档量大时,用 GPU 批量向量化的速度远超云端 API 按条调用的限制。
向量库我评估过 Milvus、Qdrant、pgvector,最后在中小规模项目里选了pgvector。原因很直接:如果知识库只有几十万条文档,没必要为了向量检索专门多部署一套数据库系统。Postgres 本身就在内网里承担业务数据存储,加一个扩展就能同时存业务数据和向量数据,运维成本最低。
索引更新要注意的坑是:内网知识库的数据变更往往没有公网那样稳定的同步机制。我这边是用定时任务每夜从业务库增量抽取变更数据,重新向量化并更新索引。如果知识库更新频繁,可以把周期缩短到分钟级,但要注意控制向量化对 CPU/GPU 的压力。
5.2 短期记忆、长期记忆与存储分层
Agent 的记忆不是单一的“聊天记录”,我把它拆成两层:
- 会话级记忆:保存在会话上下文中,用于多轮对话的指代消解(比如“把刚才那个单子再查一下”)。这部分直接存在框架的上下文对象里,随会话生命周期结束而释放。
- 长期记忆:包括用户的偏好、常用的业务实体、历史关键决策。这部分我建议单独存一张表,每次对话结束后由 Agent 自己决定是否提取出“值得长期记住的事实”写入记忆表。下次对话时,先检索相关记忆再拼接到系统提示词里。
长期记忆的存储结构不用很复杂,字段就够用:记忆内容、关联用户或项目、创建时间、更新时间、来源会话ID。但在隔离内网这种多人多角色共享 Agent 的环境里,一定要注意记忆的隔离,不能出现 A 部门看到 B 部门数据的情况,权限标签要随记忆一起存储和校验。
5.3 知识库更新的权限与版本控制
知识库里的数据如果来自多个人维护的文档,就会遇到版本不一致的问题。我的经验是给知识库索引加一层来源时间戳,每次检索时优先返回最新来源;同时在更新索引时,保留上一个完整版本,索引构建失败时能快速回滚,避免线上 Agent 出现“检索不到之前明明有的数据”的诡异问题。
6. 踩坑实录:内网环境最折磨人的五个问题
这个章节写的是我在项目里真实踩过的坑。每个坑都花了不少时间定位,也是内网 Agent 工程最容易被人低估的部分。
6.1 工具描述不够清晰,模型在混乱中反复横跳
最初上线时,我挂了三四个数据查询工具,其中一个工具描述写得很宽泛,比如“查询客户数据”。结果模型经常把应当路由到订单查询的请求,错误地调用了这个宽泛工具。后来我把所有工具描述按照“触发条件 + 参数含义 + 返回结构”重新改写了一遍,把宽泛的“客户数据”拆成了“客户基本信息 / 客户合同 / 客户回款”,路由准确率立刻从 70% 左右提升到 95% 以上。
这个坑的本质是:模型不是靠直觉选择工具的,它靠的是描述字符串的语义匹配度。你给它的描述含糊,它就只能瞎猜。
6.2 推理引擎与模型文件版本不匹配
vLLM 的版本迭代很快,某些版本的 vLLM 对特定模型结构的支持是有问题的。我遇到过 AWQ 量化模型在某个 vLLM 版本上加载后,工具调用时输出的 parameters 字段全部是空对象,模型响应看着正常,就是不会真正触发函数。最后排查了很久,发现是 vLLM 与 transformers 版本不匹配。
给这类问题的两个建议:其一,在离线打包阶段就把依赖版本固定并做回归测试,而不是用安装时的最新版;其二,模型上线前必须跑一组固定用例,包含至少 10 次工具调用,全部通过才算就绪。
6.3 超时设置:内网老接口的反击
前面提到过超时问题,这里再展开一次。老系统的接口慢是常态,而不是异常。当时运维 Agent 里有个查询历史告警的工具,底层要跨两个系统聚合数据,最快也要 12 秒才返回。Agent 框架默认的 HTTP 超时是 10 秒,于是每次 Agent 都认为工具调用失败,甚至自己脑补出一个“接口故障”的结论。把超时统一调整到 60 秒,并增加重试机制后,问题彻底消失。
这也提醒了一点:Agent 在工具调用失败时会产生“幻觉解释”,它会基于失败的半截信息继续编下去,而不是老老实实说“不知道”。所以工具层埋点、超时标记、和失败日志的完整记录,比在公网环境里更重要。
6.4 跨网段调用:网关、Proxy 与 DNS 解析
隔离内网往往按安全域划分网段,Agent 服务在一个网段,业务系统在另一个网段。这不是简单的“能 ping 通就行”,有些中间有防火墙或网关,只放行特定端口。项目初期我在调试时发现一个诡异现象:用 curl 从 Agent 服务器手动调用业务接口能通,但 Agent 框架里 Python requests 调用却超时。最终定位到,是环境变量里配了一个只对某些域名生效的代理设置,Python requests 在无感间走了代理,代理不通导致失败。
排查这类网络问题的思路是:先手动测试直连、再检查进程环境变量、再检查框架层是否自动设置了代理。隔离内网里的网络问题往往不是硬不通,而是各种软配置搅在一起。
6.5 多 Agent 协作时的状态同步:别让分工变成分家
CrewAI 这类多 Agent 框架里,Coordinator Agent 和 Worker Agent 之间通过消息传递协作,但如果双方对“任务完成”的定义不统一,很容易出现 Worker 已经干完活,Coordinator 还在等下一个回复的情况。尤其在模型能力不是最强的前提下,多 Agent 协作的对话很容易变得又臭又长。
我的建议是,隔离内网里的多 Agent 协作一定要给“任务状态”一个明确的结构化定义:待执行、执行中、完成、失败、需人工介入。消息里必须携带当前状态,上层调度根据状态转移,而不是靠模型自由发挥语言来表达状态。
7. 内网不等于保险箱:权限、审计与评测
最后谈谈运营。隔离内网不是“绝对安全”的代名词,Agent 的引入反而可能带来新的风险,只不过风险口径和公网不同。
7.1 权限最小化与工具沙箱
给 Agent 分配工具权限时,不要给“全部工具可用”的权限。理想做法是按角色划分工具集。比如问答 Agent 只有只读工具的权限,运维 Agent 默认只有告警查询的权限,写配置的权限必须单独审批开通。
另一个细节是,Agent 执行外部命令、读写文件这类工具,尽量跑在独立的沙箱容器里,并对 CPU、内存、磁盘空间做限制,防止一次异常的代码生成直接拖垮宿主机器。隔离内网里最怕的不是外部的攻击,而是内部的失控。
7.2 全链路审计:谁在什么时间让 Agent 做了什么
Agent 的使用过程必须有完整审计。至少要记录以下几个维度:哪个用户/哪个会话、调用了哪个模型、请求了哪些工具、传入了什么参数、返回了什么结果、是否经过人工审批、对应的任务耗时是多少。这些日志本身也要存到独立的审计库中,禁止普通业务人员访问。
有了审计链路之后,出问题才能回溯到具体是哪个环节、哪条 Prompt、哪个工具定义导致的,这在隔离内网的环境下非常关键。
7.3 持续评测:不要让模型悄悄“退化”
模型在本地跑,没有云端自动更新,但 Prompt 和工具定义在持续变更,每次变更都可能对最终行为产生不可预知的影响。所以我建议专门维护一套回归测试集,覆盖典型问题和边界问题,比如:
- “查一下昨天的销量”是否准确路由到数据查询工具;
- 一个含糊的问题是否会被拆成合理的子任务;
- 工具返回空结果时,Agent 是否能如实告知用户而不是编造;
- 连续多轮对话时,指代消解是否正确;
- 请求带敏感词或越权内容时,是否被拒绝或提示无权限。
每次修改 Prompt 或新增工具后,跑一遍回归集,再决定是否上线。这套机制成本不高,但避免了无数次“线上模型突然不听使唤”的尴尬。
隔离内网下的 Agent 工程,难点不在于 Agent 这个概念本身,而在于把一个依赖云端生态的智能体,改造成能在封闭环境里独立运转的可靠系统。工具接驳要耐心,网络适配要细致,权限审计要闭环。这些工作做完之后,Agent 在隔离网内的表现其实可以很稳,因为它完全不受外网抖动和限流的干扰。希望这份实战记录,能帮你少走我走过的那些弯路。