
1. 为什么“隔离内网”是 AI Agent 工程化的分水岭很多人第一次听到“隔离内网下跑 AI Agent”脑子里浮现的画面是一台没有外网的服务器上面跑着一个大模型然后通过某种方式把任务丢进去。这个理解只对了一半。真正做过内网交付的人都知道隔离内网不是简单的“断网”而是一整套从网络拓扑、依赖管理、模型部署到工具链适配的工程约束集合。你在公网环境里习以为常的pip install、npm install、docker pull、git clone到了内网全部失效。更麻烦的是AI Agent 这类应用天然依赖外部工具调用、模型推理服务和向量数据库这些组件在内网里都需要重新设计部署方案。我参与过几个内网 AI Agent 的交付项目踩过的坑从“模型权重传不进去”到“MCP 服务在内网无法发现工具”几乎把能踩的都踩了一遍。这篇文章不是理论科普而是把我实际交付中验证过的方案、绕过的弯路、以及那些文档里不会写的细节完整地摊开来讲。无论你是刚接触 AI Agent 的开发者还是正在准备内网交付的工程师这些内容都能帮你少走至少两周的弯路。先明确一个核心判断内网 AI Agent 的难点不在模型本身而在“工程链路的重建”。公网环境下你可以用 OpenAI API、可以用 LangChain 的在线工具、可以用各种 SaaS 化的向量数据库。内网环境下这些全部要替换成可离线部署的替代方案而且替换之后还要保证 Agent 的推理质量不出现断崖式下降。这才是真正的挑战。1.1 隔离内网到底“隔离”了什么很多人以为内网隔离就是不能上外网实际上隔离的维度比这复杂得多。我整理了一张表把常见的隔离维度和我实际遇到的影响列出来隔离维度具体表现对 AI Agent 的影响网络出口隔离无法访问公网 API、无法拉取镜像模型服务、工具调用全部需要内网自建包管理隔离pip/npm/apt 源不可用依赖需要离线打包版本冲突排查困难域名解析隔离内网 DNS 不解析外部域名所有服务地址必须用 IP 或内网域名证书信任隔离自签名证书不被信任HTTPS 调用需要手动导入 CA硬件资源隔离GPU 资源有限且不可弹性扩展模型量化和并发策略需要重新设计数据流转隔离数据不能出内网日志、监控、向量化全部本地化这张表里最容易被低估的是“包管理隔离”。我见过一个团队在内网部署 Agent 时因为一个 Python 包的间接依赖版本不对排查了整整三天。公网环境下pip install会自动解析依赖树内网环境下你只能手动维护一个requirements.txt而且这个文件里的每个包都要提前下载好 wheel 文件。1.2 内网 Agent 和公网 Agent 的本质差异公网 Agent 的架构通常是“轻客户端 重云端”Agent 本身只负责编排逻辑模型推理和工具执行都在云端完成。内网 Agent 则必须是“重客户端 轻服务端”因为内网的服务端资源往往有限而且网络延迟虽然低但服务发现机制不完善。这个差异带来的直接后果是你不能直接把公网的 Agent 代码搬到内网运行。我试过把一个基于 LangChain 的 Agent 直接搬到内网结果发现它依赖的langchain-community里有大量在线工具的封装这些工具在内网全部不可用而且它们的导入语句会在启动时直接报错。解决办法是要么把这些工具模块剥离要么用内网的等价工具替换。另一个差异是模型选择。公网可以用 GPT-4 级别的模型内网通常只能用 7B 到 14B 的开源模型。模型能力下降之后Agent 的提示词工程、工具调用格式、错误处理逻辑都需要重新调优。我实测下来同一个任务在 GPT-4 上成功率 90%换到内网的 14B 模型上可能只有 60%剩下的 40% 需要通过更严格的输出格式约束和重试机制来弥补。2. 内网 Agent 的模型服务选型与量化部署模型服务是整个 Agent 的地基。内网环境下你不可能调用外部 API必须自己部署推理服务。这一步的选型直接决定了后续 Agent 的响应速度、并发能力和输出质量。2.1 推理框架的对比与选择我实际用过的内网推理框架主要有四个vLLM、TGI、Ollama 和 llama.cpp。它们各有适用场景不能一概而论。vLLM 的优势在于吞吐量它实现了 PagedAttention显存利用率高适合多并发场景。但它的部署依赖比较多需要 CUDA 环境、需要编译内网离线安装时容易卡在依赖上。TGI 是 HuggingFace 出的部署相对简单但吞吐量不如 vLLM。Ollama 最适合快速验证一条命令就能跑起来但它的并发能力弱不适合生产环境。llama.cpp 的量化支持最好CPU 也能跑但推理速度慢。我的建议是如果内网有 GPU 且并发要求高选 vLLM如果只是做原型验证选 Ollama如果只有 CPU 资源选 llama.cpp。这个选择没有绝对优劣关键看你的硬件条件和业务需求。2.2 模型量化的实操细节内网部署模型量化是绕不开的环节。一个 14B 的模型FP16 精度需要约 28GB 显存量化到 INT4 之后只需要约 8GB。这个差距直接决定了你能不能在单张消费级显卡上跑起来。我常用的量化方案是 GPTQ 和 AWQ。GPTQ 的量化速度慢但推理速度快AWQ 的量化速度快推理速度略慢于 GPTQ但精度保持更好。实测下来14B 模型量化到 INT4 之后在通用问答任务上的质量下降大约 5% 到 8%在代码生成任务上下降更明显大约 10% 到 15%。量化过程中有几个坑要注意。第一量化校准集的选择很重要用通用语料校准和用领域语料校准结果差异很大。我建议用你的业务数据做校准哪怕只有几百条。第二量化后的模型要重新做一遍 Agent 的工具调用测试因为量化会改变模型输出的 token 分布原本能正确输出的 JSON 格式可能会变形。# 以 vLLM 部署量化模型为例内网离线启动命令 python -m vllm.entrypoints.openai.api_server \ --model /data/models/qwen-14b-int4 \ --served-model-name qwen-14b \ --quantization gptq \ --max-model-len 8192 \ --gpu-memory-utilization 0.9 \ --port 8000这个命令里--max-model-len控制上下文长度内网场景下建议不要设太大因为长上下文会显著增加显存占用。--gpu-memory-utilization控制显存利用率0.9 是一个比较激进的设置如果遇到 OOM 可以降到 0.85。2.3 模型服务的并发扛压设计热词里有人问“AI Agent 怎么扛并发”这个问题在内网场景下更尖锐因为内网的 GPU 资源通常只有一两张卡。我的经验是Agent 的并发瓶颈往往不在模型推理而在工具调用的等待时间。一个 Agent 处理一个请求可能要调用三到五个工具每个工具调用都要等待网络往返。如果模型推理是 2 秒工具调用总共 3 秒那么单个请求的耗时是 5 秒。在 10 并发的情况下如果模型服务只能同时处理 4 个请求剩下的 6 个就要排队。我的优化方案是把模型推理和工具调用做成异步流水线。当模型在生成工具调用参数时前一个工具调用的结果已经在返回路上。这样可以把总耗时压缩到接近模型推理时间。具体实现上可以用 Python 的asyncio配合 vLLM 的异步接口。注意内网环境下异步流水线的调试比同步调用困难得多。建议先用同步方式跑通全流程再逐步改造成异步不要一上来就追求高性能。3. MCP 协议在内网环境下的落地改造MCP 是当前 AI Agent 领域最热的话题之一它定义了一套标准化的工具调用协议。但在内网环境下MCP 的默认实现会遇到几个硬伤服务发现依赖外部注册中心、工具描述需要在线获取、传输层默认走公网可访问的地址。3.1 MCP 的核心机制回顾MCP 的本质是“让模型知道有哪些工具可用以及怎么调用这些工具”。它分为三个部分工具描述、调用请求、调用结果。工具描述是一个 JSON Schema告诉模型这个工具叫什么、需要什么参数。调用请求是模型生成的参数 JSON。调用结果是工具执行后的返回值。在公网环境下MCP 服务通常注册在一个中心化的服务器上Agent 启动时去拉取工具列表。内网环境下这个中心化服务器不存在你需要自己实现一个内网的工具注册表。我的做法是在内网起一个轻量的注册服务用文件或者 Redis 存储工具描述Agent 启动时从本地加载。这样既保留了 MCP 的协议格式又去掉了对外部注册中心的依赖。3.2 内网 MCP 服务发现的替代方案内网没有服务发现机制这是一个现实问题。我试过三种方案第一种是静态配置把所有 MCP 服务的地址写死在 Agent 的配置文件里。这种方案最简单但扩展性差新增一个工具就要改配置重启。第二种是基于文件系统的服务注册每个 MCP 服务启动时在共享目录里写一个描述文件Agent 定期扫描这个目录。这种方案适合工具数量不多的场景实现简单但实时性差。第三种是基于 Redis 的注册中心MCP 服务启动时把自己的地址和工具描述写入 RedisAgent 订阅 Redis 的变更通知。这种方案实时性好但需要额外部署 Redis。我最终选择的是第二种方案因为内网环境下的工具数量通常不多而且变更频率低。共享目录可以用 NFS 或者 SMB 实现部署成本低。3.3 MCP 工具调用的超时与重试策略内网环境下MCP 工具调用的超时设置很关键。公网环境下网络抖动是常态超时通常设得比较长。内网环境下网络延迟低但服务可能不稳定超时设太长会导致 Agent 卡死设太短会导致误判。我的经验值是内网 MCP 调用的超时设为 10 秒重试 2 次重试间隔 1 秒。这个配置在大多数内网场景下都能工作。如果工具本身执行时间较长比如数据库查询可以单独为这个工具设置更长的超时。# MCP 工具调用的超时与重试封装示例 import asyncio from typing import Any async def call_mcp_tool(tool_name: str, params: dict, timeout: int 10, retries: int 2) - Any: for attempt in range(retries 1): try: result await asyncio.wait_for( mcp_client.call(tool_name, params), timeouttimeout ) return result except asyncio.TimeoutError: if attempt retries: raise await asyncio.sleep(1) except Exception as e: if attempt retries: raise await asyncio.sleep(1)这段代码的关键点是asyncio.wait_for它能在超时后主动取消任务避免协程泄漏。内网环境下协程泄漏是一个容易被忽视的问题因为服务重启成本高泄漏的协程会慢慢耗尽资源。4. Skills 体系在内网 Agent 中的工程化实践Skills 是最近半年 AI Agent 领域最火的概念之一。简单说Skills 就是把 Agent 的能力拆成一个个可复用的模块每个模块封装一类任务的处理逻辑。在内网环境下Skills 的工程化有几个特殊考量。4.1 Skills 的粒度设计原则Skills 的粒度太粗复用性差粒度太细组合复杂度高。我的经验是一个 Skill 应该对应一个完整的业务动作而不是一个技术步骤。比如“查询订单状态”是一个 Skill“调用订单 API”是一个技术步骤。前者是业务动作后者是技术实现。Agent 应该调用业务动作技术实现封装在 Skill 内部。这样设计的好处是当订单 API 变更时只需要改 Skill 内部实现Agent 的提示词不用动。在内网环境下Skills 的粒度设计还要考虑部署的便利性。如果一个 Skill 依赖特定的内网服务它应该独立部署避免和其他 Skill 耦合。我见过一个项目把所有 Skill 打包成一个服务结果其中一个 Skill 依赖的数据库升级导致整个服务不可用。4.2 Skills 的注册与发现机制内网环境下Skills 的注册和发现可以用和 MCP 类似的机制。每个 Skill 启动时向本地注册表写入自己的描述Agent 启动时加载所有 Skill 描述构建工具列表。这里有一个细节Skill 的描述要包含输入输出示例。模型在调用 Skill 时如果有示例参考成功率会显著提高。我实测下来加上输入输出示例之后工具调用的参数正确率从 75% 提升到了 92%。{ name: query_order_status, description: 查询订单状态, input_schema: { type: object, properties: { order_id: {type: string, description: 订单编号} }, required: [order_id] }, examples: [ { input: {order_id: ORD-2024-001}, output: {status: shipped, estimated_delivery: 2024-01-15} } ] }这个 JSON 结构里examples字段是我强烈建议加的。它不占用太多存储空间但对模型理解工具用途帮助很大。4.3 Skills 的版本管理与灰度发布内网环境下Skills 的版本管理容易被忽视。公网环境下你可以用容器镜像的 tag 来管理版本内网环境下如果用的是物理机部署版本管理就要靠目录结构或者软链接。我的做法是每个 Skill 的每个版本放在独立目录用一个current软链接指向当前生效的版本。升级时先部署新版本目录测试通过后再切换软链接。回滚时只需要把软链接切回旧版本。这个方案的好处是回滚速度快不需要重新部署。内网环境下重新部署一个服务可能要几分钟而切换软链接只需要一秒。提示软链接方案在 Windows 环境下支持不好如果内网服务器是 Windows建议用目录重命名的方式实现类似效果。5. 内网 Agent 的可观测性与日志体系内网环境下Agent 出问题之后排查困难因为没有公网的监控服务可以用。你需要自己搭建一套可观测性体系包括日志、指标和链路追踪。5.1 日志的分级与结构化Agent 的日志和普通应用的日志不一样它需要记录模型的输入输出、工具调用的参数和结果、以及每一步的耗时。这些信息如果都用文本日志记录排查时很难检索。我的做法是用 JSON 格式记录结构化日志每条日志包含 trace_id、step、input、output、duration 字段。这样可以用 jq 或者 Python 脚本快速过滤和分析。import json import logging import time logger logging.getLogger(agent) def log_step(trace_id: str, step: str, input_data: dict, output_data: dict, duration: float): logger.info(json.dumps({ trace_id: trace_id, step: step, input: input_data, output: output_data, duration: duration, timestamp: time.time() }, ensure_asciiFalse))这个日志格式的关键是trace_id它贯穿一个请求的所有步骤。排查问题时用grep trace_id就能把整个链路串起来。5.2 关键指标的采集与告警内网 Agent 需要监控的指标主要有四类模型推理延迟、工具调用成功率、Agent 任务完成率、资源使用率。模型推理延迟反映模型服务的健康状态。如果延迟突然升高可能是显存不足或者请求排队。工具调用成功率反映内网服务的稳定性。如果某个工具的成功率下降可能是对应的内网服务出了问题。Agent 任务完成率反映整体效果。如果完成率下降可能是模型输出格式变了或者工具描述需要更新。资源使用率包括 GPU 显存、CPU、内存、磁盘。内网环境下资源有限这些指标需要重点监控。我用的方案是 Prometheus Grafana这两个都可以离线部署。Agent 暴露一个/metrics接口Prometheus 定期拉取Grafana 做可视化。告警用 Prometheus 的 Alertmanager通过内网的邮件或者即时通讯工具发送。5.3 链路追踪在内网的轻量化实现完整的链路追踪需要 Jaeger 或者 Zipkin这两个在内网部署都比较重。我的做法是用 trace_id 结构化日志实现轻量级链路追踪。具体来说Agent 在处理一个请求时生成一个 trace_id然后把这个 trace_id 传递给所有下游服务。每个服务在处理请求时把 trace_id 记录到日志里。排查问题时用 trace_id 把所有服务的日志串起来就能还原整个调用链路。这个方案的缺点是缺少可视化的调用图但对于内网场景来说够用了。如果确实需要可视化可以用 Python 脚本把日志解析成调用图输出成 DOT 格式再用 Graphviz 渲染。6. 内网交付的打包与部署实战内网交付是整个工程中最考验细节的环节。公网环境下你可以写个 Dockerfile然后docker build就完事了。内网环境下你需要把所有依赖提前打包好而且要考虑目标机器的操作系统、Python 版本、CUDA 版本。6.1 离线依赖包的完整打包流程离线打包的核心是“在公网环境准备好所有依赖然后拷贝到内网”。这个过程听起来简单但实际操作中有很多细节。第一步是确定依赖清单。用pip freeze导出当前环境的包列表但这个列表通常包含很多不必要的包。我建议手动维护一个requirements.txt只列出直接依赖然后用pip download下载所有依赖的 wheel 文件。# 下载所有依赖的 wheel 文件到指定目录 pip download -r requirements.txt -d ./offline_packages --platform manylinux2014_x86_64 --python-version 310 --only-binary:all:这个命令的关键参数是--platform和--python-version它们确保下载的 wheel 文件和目标环境兼容。如果目标环境是 ARM 架构--platform要改成manylinux2014_aarch64。第二步是处理模型权重。模型权重文件通常很大几个 GB 到几十个 GB。拷贝到内网时建议用分卷压缩避免单个文件过大导致拷贝失败。第三步是准备配置文件。内网环境的 IP 地址、端口、路径都和公网不同配置文件需要提前改好。我建议用环境变量或者配置模板避免硬编码。6.2 内网部署的目录结构规范内网部署的目录结构要清晰方便后续维护。我用的目录结构是这样的/opt/agent/ ├── bin/ # 启动脚本 ├── conf/ # 配置文件 ├── models/ # 模型权重 ├── skills/ # Skills 目录 │ ├── skill_a/ │ │ ├── v1.0.0/ │ │ ├── v1.0.1/ │ │ └── current - v1.0.1 │ └── skill_b/ ├── logs/ # 日志目录 ├── data/ # 数据目录 └── packages/ # 离线依赖包这个结构的关键是skills目录下的版本管理用软链接指向当前版本。logs和data目录要定期清理避免磁盘占满。6.3 部署后的验证清单部署完成后需要做一轮验证。我整理了一个验证清单每次交付都会过一遍验证项验证方法预期结果模型服务curl 模型接口返回正常推理结果MCP 服务调用工具列表接口返回所有注册的工具Skills 加载查看 Agent 启动日志所有 Skill 加载成功工具调用执行一个简单任务工具调用成功结果正确并发能力用 ab 或 wrk 压测达到预期 QPS日志输出查看日志文件结构化日志正常写入资源占用查看 GPU/CPU/内存在合理范围内这个清单看起来简单但每一项都可能出问题。我遇到过模型服务正常但 MCP 服务连不上、Skills 加载成功但工具调用超时、并发压测时显存溢出等各种情况。每次交付前过一遍清单能避免大部分低级问题。7. 那些文档里不会写的踩坑记录这一节是我个人经验的集中分享都是实际交付中踩过的坑文档里不会写但每一个都让我多花了不少时间。7.1 模型输出格式漂移导致工具调用失败内网模型的能力比公网模型弱最直接的表现是输出格式不稳定。公网模型能稳定输出 JSON内网模型可能输出带 markdown 代码块的 JSON或者 JSON 前后带解释文字。我的解决方案是在提示词里明确要求“只输出 JSON不要任何其他内容”同时在解析时做容错处理。容错处理包括去掉 markdown 代码块标记、提取第一个{到最后一个}之间的内容、用json.loads解析失败时尝试用正则提取关键字段。import json import re def parse_tool_call(text: str) - dict: # 去掉 markdown 代码块 text re.sub(rjson\s*, , text) text re.sub(r\s*, , text) # 提取 JSON 部分 match re.search(r\{.*\}, text, re.DOTALL) if match: try: return json.loads(match.group()) except json.JSONDecodeError: pass raise ValueError(f无法解析工具调用: {text})这个函数看起来简单但它把工具调用的成功率从 70% 提升到了 90% 以上。7.2 内网 DNS 解析失败导致服务不可达内网环境下DNS 解析是一个容易被忽视的问题。我遇到过一次Agent 配置里写的是服务域名但内网 DNS 不解析这个域名导致所有工具调用失败。解决办法是所有服务地址都用 IP或者在 Agent 启动时把域名解析结果缓存下来。如果必须用域名要确保内网 DNS 配置正确或者在/etc/hosts里加静态映射。这个坑的隐蔽性在于服务本身是正常的只是 Agent 找不到它。排查时容易误判为服务故障实际上是 DNS 问题。7.3 显存碎片导致长稳运行后 OOM模型服务跑一段时间后突然 OOM这是内网部署的常见问题。原因是显存碎片化虽然总显存够用但没有连续的大块显存可用。我的解决方案是定期重启模型服务或者在 vLLM 启动时设置--gpu-memory-utilization留出余量。另外避免频繁加载和卸载模型每次加载都会产生碎片。如果业务允许可以设置一个定时任务在低峰期重启模型服务。重启前要确保没有正在处理的请求可以用优雅关闭的方式等当前请求处理完再重启。7.4 Skills 热更新导致的状态不一致Skills 热更新时如果 Agent 正在处理请求可能会出现状态不一致。比如 Agent 已经加载了旧版 Skill 的描述但实际调用的是新版 Skill参数格式不匹配。我的做法是Skills 更新时先更新描述等所有 Agent 实例都重新加载描述后再更新实现。这个过程中新旧版本的接口要保持兼容。如果接口不兼容需要做灰度发布先让一部分 Agent 用新版观察一段时间再全量。内网环境下Agent 实例通常不多这个流程手动操作也能接受。但如果实例多建议写个脚本自动化。8. 从单机到集群内网 Agent 的扩展路径单机部署跑通之后下一步就是考虑扩展。内网环境下的扩展和公网不同没有云服务的弹性伸缩只能靠增加物理机或者优化现有资源。8.1 模型服务的横向扩展模型服务的横向扩展有两种方式数据并行和模型并行。数据并行是每个 GPU 跑一个完整的模型副本请求分发到不同副本。模型并行是把模型切分到多个 GPU 上每个 GPU 跑一部分。内网环境下如果模型能装进单张 GPU优先用数据并行。数据并行的实现简单用 vLLM 的多副本模式或者前面加一个负载均衡就行。如果模型装不进单张 GPU才考虑模型并行。模型并行的通信开销大内网网络虽然延迟低但带宽可能不够。8.2 Agent 服务的无状态化改造Agent 服务要横向扩展必须做成无状态的。这意味着 Agent 不能把状态存在本地内存或者本地文件里要存到共享存储或者 Redis 里。需要无状态化的状态包括会话上下文、任务队列、工具调用缓存。会话上下文可以存 Redis任务队列可以用 Redis 的 List 或者 Stream工具调用缓存可以用 Redis 的 KV。改造过程中要注意Redis 的持久化配置要合理。内网环境下Redis 如果挂了Agent 的状态就丢了。建议开启 AOF 持久化并且定期备份。8.3 内网负载均衡的选型内网负载均衡可以用 Nginx、HAProxy 或者 LVS。Nginx 最常用配置简单支持 HTTP 和 TCP 负载均衡。HAProxy 的性能更好但配置复杂一些。LVS 是四层负载均衡性能最好但配置最复杂。我的建议是如果只是 HTTP 接口的负载均衡用 Nginx 就够了。如果需要 TCP 层面的负载均衡比如模型服务的 gRPC 接口可以用 HAProxy。LVS 一般用不上除非并发量特别大。Nginx 的配置要注意健康检查。内网环境下服务可能因为各种原因不可用健康检查能及时把故障节点摘除。配置示例upstream agent_backend { server 192.168.1.10:8000 max_fails3 fail_timeout30s; server 192.168.1.11:8000 max_fails3 fail_timeout30s; server 192.168.1.12:8000 max_fails3 fail_timeout30s; }这个配置里max_fails3表示连续失败 3 次后摘除节点fail_timeout30s表示 30 秒后重新尝试。这两个参数要根据实际情况调整设得太激进会导致节点频繁摘除和恢复。9. 内网 Agent 的安全边界与权限控制内网不等于安全这是我在交付中反复强调的一点。内网 Agent 能调用各种工具如果权限控制不当可能造成数据泄露或者误操作。9.1 工具调用的权限分级不是所有工具都应该对所有 Agent 开放。我建议把工具分成三个级别只读工具、写入工具、管理工具。只读工具可以自由调用写入工具需要确认管理工具需要审批。实现上可以在 MCP 的工具描述里加一个permission_level字段Agent 在调用工具前检查权限。如果权限不足返回错误信息让模型知道这个工具不可用。9.2 敏感数据的脱敏处理Agent 在处理数据时可能会接触到敏感信息比如用户手机号、身份证号、银行卡号。这些信息在传给模型之前应该脱敏。脱敏的实现可以在 Agent 的输入处理层做用正则匹配敏感信息替换成占位符。模型处理完之后再把占位符还原。这个过程对模型透明模型看到的是脱敏后的数据。注意脱敏规则要覆盖全面不能只处理手机号。我见过一个项目只脱敏了手机号结果身份证号泄露了。建议用成熟的脱敏库比如presidio它支持多种敏感信息的识别和脱敏。9.3 操作审计与回溯内网 Agent 的每一步操作都应该记录审计日志包括谁发起的请求、调用了什么工具、传了什么参数、返回了什么结果。这些日志要保存足够长的时间以便事后回溯。审计日志和普通日志的区别是审计日志不能修改而且要独立存储。我建议把审计日志写到独立的文件或者数据库设置只追加权限防止被篡改。10. 写在最后内网 Agent 工程的几个真实体会做了几个内网 Agent 项目之后我最大的体会是内网环境的限制反而逼着你把工程做得更扎实。公网环境下你可以用各种现成的服务出了问题换个服务就行。内网环境下每个组件都要自己搭每个问题都要自己排查这个过程虽然痛苦但你对整个系统的理解会深刻得多。另一个体会是内网 Agent 的交付不是终点而是起点。交付之后业务方会提出各种新需求你需要在不联网的环境下快速迭代。这就要求你的部署方案足够灵活Skills 的更新足够方便日志足够详细以便远程排查。最后分享一个实用技巧在内网部署 Agent 时准备一个“诊断脚本”一键收集所有必要的信息包括服务状态、日志摘要、资源占用、配置快照。当业务方反馈问题时让他们先跑这个脚本把输出发给你。这个脚本能帮你省掉大量来回沟通的时间。我现在的诊断脚本已经迭代到第五版覆盖了 90% 的常见问题。