
1. 先理解隔离内网下的 Agent 到底难在哪1.1 所谓隔离隔离的是哪些东西先说一个很多人容易忽略的事实隔离内网并不是没有网络而是没有外网。在政企、能源、金融这些行业里核心业务系统跑在完全封闭的网络环境里物理上跟公网断开或者只能通过单向光闸做数据摆渡。这类环境下AI Agent 落地要面对的不是能不能上网这一个问题而是整套技术栈都跟互联网生态脱节了。拿我最近做的一个项目举例。客户环境是等保四级要求下的完全物理隔离网络服务器能互相访问但整网出不去。这意味着几个很现实的问题HuggingFace 上模型权重文件下载不下来PyPI 上几百个依赖包装不了Docker Hub 镜像拉不了连 GitHub 上的源码都要走离线审批流程才能导进去。以前在公网环境里一条 pip install 就能解决的事在这里每一步都变成了人工拷贝、校验、审批的体力活。更要命的是模型服务。Agent 的核心是 LLM 推理而 LLM 推理在公网环境通常直接调 API 就行了但隔离内网里调用外部 API 这个选项直接不存在。你得自己把模型权重、推理框架、运行依赖全部搬进内网自己搭一套 OpenAI 兼容的推理服务还要考虑显存、并发、量化这些以前根本不需要关心的问题。所以隔离内网下 AI Agent 工程实战本质上是一个把公网 AI 生态整体搬迁、自建、适配到封闭环境里的系统工程。起步之前先把困难想全后面做方案才不会动不动返工。1.2 难点的本质从依赖外网到自带生态我在开工前梳理过一遍隔离内网里部署 AI Agent跟公网部署最大的区别可以归纳成四类模型获取难开源大模型的权重动辄几十到几百 GB比如 Qwen2.5-72B 的 FP16 权重超过 140GB。公网直接下载就行隔离环境必须走光盘、移动硬盘等摆渡介质经过安全审查后拷入整个流程可能要一周。依赖安装难Agent 框架依赖的面很宽。LangGraph、LangChain 一堆 Python 包装FastAPI、Pydantic 这类基础库又有多少传递依赖粗略统计没有 200 个 wheel 包下不来。必须在外网一台同架构、同 Python 版本的机器上把所有依赖下载好连同校验信息一起摆渡进去。知识获取难Agent 要回答业务问题往往需要检索领域知识库。在公网可以直接用在线 API 或者搜索引擎增强隔离内网里这些全都没有得自己构建知识库、自己部署向量模型、自己搭向量数据库。工具对接难Agent 的价值在调用工具、操作业务系统。内网系统接口五花八门权限模型复杂统一封装成 Agent 可调用的形式比公网场景多很多安全性和可控性的约束。说到底公网部署 AI Agent 是在已有生态上做搭建而隔离内网部署是从零开始把一个完整生态搬进去并让它自洽运行。这两个事情的复杂度完全不是一个量级的所以从架构设计第一天起就要以离线可运维、全链路可审计为前提来考虑而不是先跑通再说。2. 架构设计与方案选型2.1 模型选型内网 Agent 的地基模型选型是整个项目里最不能拍脑袋定的事。我在做选型时先拉了一组约束条件客户的 GPU 是 8 张 A80080GB可以接受单机多卡部署Agent 的用途偏向内部知识问答和工单处理对延迟的要求是单轮对话不超过 8 秒数据不出内网所以只能选可商用的开源模型考虑到后续运维团队的水平模型推理框架尽量要成熟、社区活跃、出问题有人能接。在这些条件下我圈定了几个候选Qwen2.5 系列、DeepSeek、Yi 等国产开源模型。最终选了 Qwen2.5-72B-Instruct原因有三点中英文混合场景能力强做内部知识问答足够。Agent 场景里模型要频繁输出 JSON 结构给工具调用Qwen 系列的 JSON 稳定性和指令遵循在开源模型里是拔尖的。7B 到 72B 有完整的系列后续如果单机显存不够可以从 72B 降到 32B训练微调生态也成熟。官方有对应的量化版本AWQ、GPTQ方便在显存受限时做取舍。推理框架上我对比了 Ollama、vLLM、TGI、SGLang 这几个主流方案。Ollama 部署简单但高并发和在线扩缩容能力弱不适合正经的 Agent 服务TGI 依赖 HuggingFace 的生态适配内网缺少部分组件SGLang 性能好但社区相对小。最终选了 vLLM因为它的 OpenAI 兼容 API 最成熟吞吐量高有内建的 continuous batching对多路 Agent 并发的支持好。这里有个经验可以分享选模型不要只盯着榜单跑分一定要在 Agent 的真实任务流里测。我在选型阶段做了个快速 MVP拿同一批问题分别喂给 7B、14B、72B 三档模型看它们对工具调用指令的遵循率。结果 7B 输出 JSON 经常格式崩14B 偶尔丢字段72B 稳得多。Agent 场景对输出格式的要求比闲聊场景严格得多小了真不行。2.2 Agent 框架选型从 Dify 到 LangGraph 的取舍框架选型是另一个重要决策。市面上主流的 Agent 开发框架我分了三类来看低代码平台比如 Dify、Coze 这类界面化编排 Agent、工作流、知识库。优点是上手快业务人员也能参与缺点是定制能力弱在隔离内网里要做深度权限集成和私有 API 对接时容易碰天花板。编码框架LangChain、LangGraph、LlamaIndex 这类通过代码组织 Agent 的逻辑。灵活度高可审计性强适合复杂工程落地但对团队的代码能力有要求。自研编排完全自己控制 Agent 的循环适合逻辑非常简单、且对依赖包数量有严格限制的场景。缺点是时间成本高后来维护的人压力大。考虑再三我选了 LangGraph 作为主线部分场景用自研轻量编排补充。这个选择的核心逻辑是隔离内网项目的需求不会写在表面前期省下的框架学习成本后期都会以想要加个状态流转但平台不支持的方式还回去。LangGraph 的好处在于它把 Agent 的规划、执行、工具调用、人机确认等流程做成了一张可控制的状态图每个节点都能打印日志、控制并发、插入断点这对内网环境的运维审计来说太重要了。当然LangGraph 的学习曲线不低核心概念StateGraph、Node、Edge、State刚开始会让人困惑。但一旦理解了它节点是动作、边是转移、状态是全局数据的模型整个 Agent 的复杂度就完全可控了。下图是我最终采用的编排思路接收任务 - 规划 - 检索知识库 - 调用工具 - 生成回答 - 审计记录整体是一个带状态管理的有向图流程。2.3 整体架构三层的离线 AI 中台我把整个系统的架构抽象成了三层这个结构后来在多个项目里复用效果一直不错模型服务层vLLM 部署 Qwen2.5-72B-Instruct对外提供 OpenAI 兼容的 /v1/chat/completions 和 /v1/embeddings 接口。Embedding 换成了 bge-m3 模型58GB 对显存压力不算大它支持中文检索和稠密/稀疏混合检索对 RAG 的召回质量帮助明显。多个模型分散部署在不同 GPU 上避免互相抢占显存。Agent 编排层LangGraph 构建的 Agent 主体。包含规划节点、RAG 检索节点、工具调用节点、回答生成节点。每个节点之间的状态流转清晰可见出问题直接把某一段的 state 打出来看就行。接入层封装内部系统的 API 为 Agent 可调用的工具提供统一的接口网关同时负责权限校验和请求审计。这一层对隔离内网尤其重要后面会详细讲。基础设施上向量数据库用了 Milvus它支持百万级向量检索对内网知识库规模来说足够用任务队列用 Redis 的 Stream 实现支撑多路 Agent 的并发调度。整条链路里除了模型服务是显存大户其他组件都是常规配置。3. 核心工程实操从外网搬运到内网跑通3.1 离线部署模型、依赖、镜像的三重搬运隔离内网部署的第一个大工程就是搬运。这个环节如果没做好规划后面装依赖能装到你怀疑人生。先说模型搬运。Qwen2.5-72B-Instruct 的官方权重是 FP16 格式光模型文件就有约 140GB用 GPT 量化到 INT4 还有约 45GB。我们最终选了 AWQ 量化的 INT4 版本因为经过测试它在保持 95% 以上语义准确率的同时能把显存降到 48GB 左右单卡 A800 就能跑还留出 context 内存余量。模型文件通过摆渡机拷入内网后要核对 SHA256 校验码确保搬运过程中没有损坏。这个步骤一点不能省略我遇到过模型文件在移动硬盘上拷贝一半中断导致的奇怪推理结果排查了很久最后发现是权重文件损坏。然后是Python 依赖搬运。方案是在外网找一台跟内网目标机器同架构x86_64、同操作系统CentOS 7、同 Python 版本3.10的环境用 pip download 把所有依赖连传递依赖一起拉下来pip download -r requirements.txt -d ./offline-packages --platform manylinux2014_x86_64 --python-version 310 --only-binary:all:这里有个关键细节--platform 和 --python-version 参数一定要指定否则 pip 会下载跟目标环境不匹配的包。拉下来之后所有 wheel 和 tarball 打包拷入内网用 pip install --no-index --find-links 离线安装。我在这个环节试过不少坑比如某个包在 PyPI 上只发布了源码包没有编译好的 wheel离线装的时候需要目标机器上有对应的编译工具链不然直接报错。所以项目早期就要排查哪些包是纯 Python、哪些需要编译需要编译的包尽量提前在外网找到合适的 wheel。镜像搬运则是把 Docker 镜像导出成 tar 文件拷入内网后再 docker load。vLLM 官方镜像、Milvus 镜像、Redis 镜像每个都有几百 MB加起来小几个 GB。docker save 的时候建议按单个镜像分别导出不要打成一个超大包内网的网络带宽通常有限传大文件很痛苦。另外一个经常被忽略的点是内网环境的 NTP 时钟同步和 DNS 配置。Docker 容器默认会用宿主机的 DNS内网如果没有内网 DNS容器启动后域名解析会失败导致组件之间互相访问不了。这个看似不起眼的问题曾经让我排查了一下午。3.2 知识库构建让 Agent 说内网的语言Agent 要真正有用离不开领域知识而知识库就是它的大脑外挂。隔离内网场景下没法用在线搜索RAG检索增强生成就变成了唯一的选择。我在这部分做了三步第一步确定知识来源。客户的知识散落在 Word、PDF、Excel 甚至老的 Lotus Notes 里第一步是统一清洗转成 Markdown 或纯文本。这里有个现实问题很多内部文档是旧格式转出来全是乱码和表格错位。我写了一套预处理脚本先转 PDF 再 OCR还是乱码的就人工处理。OCR 这个环节如果文档质量差后续的检索准确率会直线下降宁可多花时间在清洗上也不能图快直接切块后入库。第二步切块策略。切块这个环节直接决定 RAG 的召回质量。我对比了几种方案最终选择的是按章节标题层级切块而不是固定 token 数切块。固定切片容易把语义截断导致检索引擎召回一堆残缺内容。按标题切块的问题在于不同文档的标题格式不统一需要先用正则和语义标题识别做归一化。每个切块控制在 300-800 token 之间超过的再按段落边界切小。切完之后做 embeddingbge-m3 生成的向量维度是 1024存进 Milvus 库。这里还要做元数据标记比如来源文档、章节路径、更新时间便于后续追问溯源。第三步混合检索策略。我最终的检索链路是向量检索 关键词检索的结果融合Milvus 走向量召回ES 走关键词召回再用 RRFReciprocal Rank Fusion把两边结果合并取 TopK。一开始我只用向量检索结果发现文档里的专有名词、代码符号这类对向量不敏感的词召回效果很差加上关键词召回后提升非常明显。Agent 拿到检索结果后先在 prompt 里要求只基于给定的知识片段回答无法回答就说明再结合大模型的指令理解生成答案幻觉明显少了很多。3.3 工具调用把内部系统封装成 Agent 的手脚Agent 不能只会聊天它必须能干活。这里的干活就是调用内部系统的接口比如查工单、改配置、发消息、查数据库。隔离内网对工具调用的要求是权限要够细、过程要有留痕。我采用的方案是把内部系统的 OpenAPI 接口逐一封装为Agent 工具。每个工具定义好名称、描述、入参 JSON Schema然后把它们注册到工具的 registry 里。vLLM 原生支持 OpenAI 风格的 Function CallingQwen2.5 也针对 function call 做了训练所以模型能比较稳定地把自然语言映射到工具调用上。工具调用的流程是这样的Agent 规划节点判断当前任务需要哪个工具在模型请求里带上工具定义模型返回 structured output工具名和参数然后调用节点执行真实 API。执行结果塞回上下文交给下一步生成回答。这里要特别强调一个细节不要让模型直接拿着真实 token 去做外部调用。比如查数据库这个工具不要让模型自由拼接 SQL更安全的做法是让模型输出查询意图 参数再由后端引擎翻译成经过白名单校验的 SQL。隔离内网里数据安全是第一优先级宁可多写几层校验也不能把原始接口暴露给模型。权限和审计这块我也踩了一些坑。Agent 的调用权限不能做得太粗最好细化到用户级别同一个 Agent不同用户进来能调用的工具范围不一样。实现方式是在请求经过 API 网关时注入用户身份Agent 编排层根据身份动态裁剪工具集工具执行时再做一次二次校验。所有工具调用都记录一条审计日志包含调用时间、用户、工具名、输入参数、返回结果摘要方便出问题时回溯。这套机制在后续试运行阶段救了我好几次因为业务方经常来问这个数据它怎么能查到一查审计日志就清楚了。3.4 记忆与权限工程化的最后一公里Agent 工程跟纯模型评测的最大区别在于模型只负责思考铺垫状态、上下文、记忆、权限这些工程环节决定了它在一套系统里能不能稳定工作。在隔离内网环境里会话记忆我直接用 Redis 存短期记忆每条会话保存最近的 10 轮对话摘要长期记忆则落到业务数据库里按用户维度存储偏好和历史决策这些内容同样可以做权限隔离。关键是把记忆也当作数据来管理该脱敏脱敏、该分级分级绝对不能因为 Agent 内部数据就放松安全要求。这里必须提一下 token 管理的问题。经常有新手问AI Agent token 是什么意思简单说token 是模型处理文本的最小单位一次对话里你发给模型的所有内容、模型生成的所有内容甚至工具调用的定义和结果都要换算成 token 计入上下文。Context 长度是有限制的比如 32K、128K所以 Agent 的 prompt 要精心设计系统提示词精简、知识库片段做摘要、工具定义用精简描述。我在项目里用了一个简单的 token 预算控制机制整个上下文的 30% 留给系统提示和工具定义50% 留给检索片段和对话历史剩下 20% 留给模型生成回答的余量。一旦超过预算就触发历史摘要压缩。没有这个机制好的模型也容易忘事或者输出不稳定。权限隔离之前已经说了这里再补一个体验层面的建议Agent 的回答里一定要带来源引用。RAG 检索出来的内容要标注来自哪份文档工具调用返回的数据要标注来自哪个系统。一方面用户会更信任 Agent另一方面也方便运维人员核查问题。我在生成节点做了后处理对回答里的关键结论自动添加来源标记这个小改动用户反馈非常好。4. 常见问题与排查实录4.1 推理性能与并发问题隔离内网的 GPU 配置通常比公网云环境紧张性能问题是跑起来之后反馈最多的一类。我在项目里遇到的第一个问题就是并发一上来vLLM 的响应时间急剧变长。排查后发现是显存碎片化导致的 KV Cache 利用率下降解决方式是分批重启服务并给 vLLM 显式设置了 --gpu-memory-utilization 参数比如 0.9让推理引擎能更充分地规划显存。另一个高频问题是多路 Agent 并发调用同一个模型端口导致请求排队。我的处理方式是在 Agent 编排层做了一层请求级的并发控制同一会话的请求串行不同会话的请求并行再根据上游模型的实测吞吐量设置最大并发数。这是个很朴素的限流策略但是很有效——模型生成慢的时候不会后面疯狂堆请求把服务打挂。还有一个容易忽略的坑是context length。Qwen2.5 默认支持 32K context但如果你一次性塞满 32K推理时间会成倍增长。我在实际使用中发现把单次请求的 max context 限制到 16K已经能满足绝大多数 Agent 任务而响应时间几乎减半。如果你的任务确实需要很长的上下文就要考虑用摘要压缩或者滑动窗口而不是无限拉长。4.2 输出质量与幻觉问题Agent 返回的内容偶尔会一本正经地胡说八道尤其在知识库覆盖不到的问题上。这类问题我总结了一些有效的手段限定话题边界在系统提示词里把 Agent 的能力范围写清楚不允许回答知识库和工具之外的问题宁可直接说我不知道也不能编。给出拒绝模板当用户问的问题不在权限范围内要求模型明确回绝。例如你无权访问该资源比让模型绕弯子提示要安全得多。双段校验Agent 生成回答后用一个独立的校验模型小一点的 7B 模型也行检查回答与检索到的知识片段是否一致出现明显矛盾就重生成。结构化输出需要模型输出表格或 JSON 时强制使用 response_format 的 json_object 模式并在 prompt 里给出输出样例。Qwen 在这方面的稳定性很强7B 有时候还是会有小瑕疵72B 基本一次到位。这些手段组合使用后我这边试运行阶段实测的回答事实准确率能到 95% 以上。不要追求 100%而是要把不确定的部分挡在回答之外让用户看到 Agent 的置信度边界。4.3 依赖与环境问题速查表很多问题不是模型的问题而是环境的问题。整理一张我遇到的高频问题和排查思路供大家参考现象可能原因排查思路vLLM 容器启动即崩溃显存不足或显卡驱动不匹配检查 nvidia-smi、容器内 ls /dev/nvidia*、确认 GPU 直通配置模型推理速度极慢量化格式不兼容或 GPU 利用率低对比 torch 是否启用了 CUDA检查 --dtype确认量化加载组件之间网络不通容器网络模式或内网 DNS 问题先用 curl 测 IP再测域名逐层排查 DNS/防火墙中文回答乱码模型 tokenizer 不匹配或环境编码问题检查容器 locale 与模型分词器配置RAG 检索引擎召回为空embedding 模型未正确加载或向量库为空先单独测试 embedding 接口再查 Milvus 是否有数据这个表格里的最后一列我写得比较简略但排查思路是通用的隔离内网环境下首先要确认基础环境是好的再去怀疑业务逻辑。很多你以为的模型问题最后查出来是机器资源或者网络配置的问题这些排查要趁早做。5. 运维体系与后续扩展5.1 日志、审计与监控隔离内网环境的运维不能依赖任何外部 SaaS 监控服务全部要自建。我在项目里搭了一套轻量监控方案Prometheus 采集 GPU 显存、CPU、内存、API 延迟和错误率Grafana 做可视化面板日志用 Loki 统一收集。这套方案在离线环境完全可用成本也低一台小服务器跑得动。监控指标里我特别关注三个推理服务端到端时延、token 输出速率、工具调用成功率。前两个直接反映模型服务健康度第三个反映的是 Agent 对接业务系统的稳定性。工具调用成功率一旦掉下来大概率不是模型的问题而是内部系统接口变了或者权限配置出错了。这个指标做好了能在业务方发现问题之前就提前处理。更重要的是安全审计日志。Agent 的每一次工具调用、每一次知识库检索、每一次敏感信息询问都要记录日志并定期审计。隔离内网的安全要求决定了我们不能像公网产品那样先上线再补安全必须从一开始就把审计做进去。5.2 从单机到集群的扩展路径最后聊聊扩展。我们最初是单机 8 卡 A800跑一个 72B 模型加记忆服务就基本到头了。随着业务量上来模型推理和 Agent 编排需要拆开扩展。我的规划路径是这样的第一阶段单机多卡模型和 Agent 编排在同一台机器适合刚上线验证业务价值。第二阶段把模型推理独立成推理集群比如 2 台推理机做负载均衡Agent 编排层和知识库/数据库独立到业务服务器。模型服务无状态可以横向加节点。第三阶段多模型并行不同的业务场景用不同大小的模型。比如高频的简单问答用 7B 模型复杂推理和工具调用用 72B 模型用路由器做模型分发。这条路我在另外一个项目上验证过成本能降一半大部分场景效果完全够用。扩展时要注意的是模型版本和配置的版本管理。隔离内网不能在线拉镜像所以任何环境变更都要有完整的版本记录和回滚方案。我给模型服务、Agent 服务、知识库都打了版本标签每次变更都记录了变更时间和验证结果这对后续维护太重要了。根据我的经验从单机到集群最容易出问题的反而不是模型性能而是配置漂移和数据一致性。比如两台的 vLLM 启动了不同的 quantization 配置导致行为不一致这在测试阶段根本发现不了上线后才暴露。所以从一开始就要把配置当成代码管理统一分发、统一校验。