接到一个“必须在隔离内网里落地 AI Agent”的项目时,我一开始还是很乐观的,以为核心难点就是把对话模型换成私有化部署,让内网应用能调用而已。真正动起手来才发现,AI Agent 工程实战里最折磨人的部分,是在一个人进不去、数据也出不去、外网请求一律被掐断的环境里,把模型权重、Python 依赖、容器镜像、推理服务、Agent 编排框架、并发架构全部收敛成一整套能自己跑起来的东西。这篇文章就用我实际踩过的坑,把这整条链路怎么拆、怎么选型、怎么落地讲透。适合那些要在政企、制造、金融等网络环境受限场景里做 AI Agent 项目的同学参考,也适合打算把 Agent 从 Demo 推到生产环境的团队读一读。
1. 隔离内网做 AI Agent,卡脖子的从来不是模型本身
1.1 先分清两种隔离形态,再谈技术方案
很多第一次接触这类项目的工程师,听到“隔离内网”四个字,脑子里只有一个模糊的概念:不能访问外网。但真正做技术选型的时候,必须把隔离形态拆细,因为两种形态对物料搬运方式的影响是决定性的。
第一种是网络层面完全切断,内网设备与外网设备之间没有直连链路,所有数据只能通过受控的交换区域,比如一台经过审批的机器、一块硬盘、一个专用的传输通道进入内网。这种环境下,你没法用任何方式从内网主动拉取外网资源,所有软件包、模型文件、容器镜像都要提前在外网准备好,再用受控方式摆渡进去。一旦漏了一个依赖,你要么重新走一遍审批流程,要么就得半夜对着解析失败的 pip 日志发呆。
第二种是逻辑隔离,设备本身可以访问部分白名单地址,但限制严格,绝大多数外部服务不可达,DNS 解析也会被策略拦截。这种环境比第一种好一点,但也好得有限。你以为能访问某个下载源,结果第二天策略调整了,白名单里没有你要访问的域名,整个构建流程又歇菜。
我建议你接到项目的第一件事,不是选模型、不是画架构图,而是找网络管理员问清楚三件事:物料怎么进内网、内网能不能访问内部仓库、哪些目标机器上能开放对外端口。这个问题问得越早,后面省的时间越多。
1.2 三重约束:模型进不来、包拉不了、服务调不动
隔离内网做 AI Agent,表面上是在做一个“智能系统”,实际上先要做完一个“离线物流项目”。我总结下来,至少有三重约束会同时压到你身上。
第一重是模型权重。主流开源模型少则几个 G,多则几十个 G,还需要配套的分词器、推理配置、量化参数。这些文件必须在外网提前下载好,固化成特定版本,记录 SHA256 校验值,再进内网。你不可能进了内网之后才想起来“噢,我好像还需要那个 7B 模型的 tokenizer 文件”——那就只能再走一遍摆渡流程。
第二重是依赖包。你用 Python 写 Agent,必然要用 LangChain、FastAPI、requests、pydantic 这些包。在能上网的环境里,一条 pip install 就完事了;在隔离内网里,pip install 直接变成“网络无法连接”的报错。这还不是最坑的,最坑的是依赖之间还有版本兼容问题,你在外网装好的版本组合没问题,结果内网仓库里同步过来的版本缺了一个 patch,某个底层库的 C 扩展装不上,Agent 服务起不来。
第三重是外部服务。一个完整的 Agent 通常要调用多个工具,比如文档解析、OCR、向量检索、天气查询、地点查询。在隔离内网里,云端 OCR、云端地图这类服务统统不可用。你要么找内网的替代服务,要么就得把工具本身本地化重写。我见过不少项目卡在这一步——Agent 框架本身跑起来了,模型也在回答问题了,结果中间某一步调了个外部 API,直接超时,整个链路崩掉。
1.3 我把解法的整体思路总结成三条主线
在动手写代码之前,先想清楚宏观策略,后面会轻松很多。
我的做法是三条主线并行。第一条,物料离线化,所有模型权重、依赖包、容器镜像、内网仓库索引,全部提前在外部环境准备好,并且反复验证可安装、可加载、可推理,才允许进入内网。第二条,服务内网化,推理服务、向量数据库、Agent 编排服务、工具服务全部部署在内网,用内网地址互相访问,坚决不依赖任何外网域名。第三条,框架适配化,选择的 Agent 框架必须能脱离云端依赖运行,不能把工具的注册逻辑硬编码成外网 API 调用。
这三条主线说穿了就是一句话:把“随时上网拉取”的思维切换成“提前搬运、内网闭环”的思维。这是隔离内网 AI Agent 工程实战的第一课,不提模型能力,不提 Agent 框架,先把物流问题解决。
2. 模型底座怎么选:量化、推理服务与 API 兼容层
2.1 模型权重的前置准备:版本固化与硬件匹配
隔离内网里选模型底座,逻辑和能上网的时候不太一样。在外网,你可以随时比较新发布的开源模型,跑几个评测集再决定;在内网,模型文件一旦运进去,再想换就是一次完整的物流流程。所以前置阶段要把模型版本固定下来。
我的建议是:优先选架构成熟、生态完善、社区验证充分的开源模型,而不是最新最热的那个。因为内网没有反复试错的成本。落地时还要根据硬件实际情况匹配模型大小。如果推理机器是单卡 24G 显存,推荐量级是 7B 到 14B;如果有多卡 80G,可以考虑 32B 甚至更大。这一点不展开太多,但有一点务必记住:宁可选择一个稍微小一点但能在你的 GPU 上稳定跑起来的模型,也不要选择一个听起来很强但显存不够、部署之后频繁超时的模型。
2.2 量化路线对比:GGUF、AWQ、GPTQ 怎么选
隔离内网场景下,量化不是可选项,而是默认项,因为你需要用有限的显存承载更高的并发和更长的上下文。我实际对比过三种主流量化路线。
| 量化方式 | 典型社区支持 | 显存占用 | 精度表现 | 适合场景 |
|---|---|---|---|---|
| GGUF(Q4_K_M/Q5_K_M) | llama.cpp、Ollama | 较低,可部分跑在 CPU 上 | 中高,日常对话足够 | 单机小规模、CPU 辅助推理 |
| AWQ | vLLM、SGLang | 中,需 GPU | 高,损失较小 | 高并发服务、Agent 多轮调用 |
| GPTQ | vLLM、Transformers | 中,需 GPU | 高 | 老牌方案,生态成熟 |
我自己的偏好是:14B 以下模型用 GGUF 的 Q4_K_M 或 Q5_K_M,因为部署简单,内存占用可控,对 Agent 这种需要多轮对话、多次调用的场景来说,精度损失完全可以接受。如果机器是专用推理节点,要开高并发,那 AWQ 更合适,它在 vLLM 上配合连续批处理,吞吐量很稳。GPTQ 虽然老牌,但在 Agent 场景里没有明显优势,除非你的团队对这套流程很熟,否则我不建议首采。
2.3 推理服务选型:vLLM、Ollama、SGLang 的取舍
模型权重准备好之后,下一步就是把权重跑起来,对外提供推理服务。这一步在隔离内网里特别关键,因为 Agent 上层框架只关心“能不能通过 HTTP 拿到模型返回”,不关心底层是哪个推理引擎。
我个人首推 vLLM。它的显存管理、连续批处理、吞吐能力在开源方案里非常能打,而且原生支持 OpenAI 兼容接口,对上层 Agent 框架非常友好。Agent 场景下,单次任务会频繁调用模型多次,vLLM 的 PagedAttention 机制能让多个并发请求共享显存,这比传统的逐个推理方案高效得多。
Ollama 胜在部署省心,一条命令就能把模型跑起来,适合小规模验证和原型开发。但到了生产环境,尤其是并发压力上来之后,Ollama 的默认配置需要手动调优的地方不少,吞吐相比 vLLM 也有差距。我的建议是:原型阶段用 Ollama,生产化之后换成 vLLM,或者在此基础上套一层服务封装。
SGLang 在结构化输出和复杂推理场景上有独到优势,如果你的 Agent 任务频繁要求 JSON 结构化输出、JSON Schema 约束,可以认真评估一下 SGLang。整体来说,隔离内网里只要不是纯研究场景,vLLM 是性价比最高的底座。
2.4 OpenAI 兼容协议:把模型供应商从框架里抽象掉
隔离内网里最容易忽略的一环,是 API 兼容层。LangChain、LangGraph 这类框架默认情况下会去连云端模型服务的地址。你在外网写好的代码,进入内网后如果不改 base_url,它会一直尝试访问外网地址,然后超时。
这里我有一个核心经验:在内网模型服务入口上加一层统一的模型网关,对所有上层框架暴露 OpenAI 兼容协议。这样上层 Agent 框架只需要把 base_url 指向内网网关地址,模型名映射由网关层完成。以后你想换一个推理引擎、切一个模型版本,上层代码不用改,只需要调整网关的配置。这个抽象层在隔离内网里价值非常大,因为内网环境一旦固化,改造成本极高,你不想每次换模型都重新发一版 Agent 服务。
3. Agent 脚手架在断网下的选型:LangGraph、Spring AI、Rust 三条路线
3.1 先理解“Agent Harness”是什么
隔离内网里做 Agent,绕不开一个概念:Harness,也就是智能体脚手架。通俗讲,它就是那一层负责“工具调用循环、状态管理、任务拆解、记忆处理”的框架代码。没有 Harness 的话,模型只能单轮对话,干不了活;有了 Harness,模型才知道自己有哪些工具可用、当前任务处于什么状态、下一步该调用哪个工具、工具返回之后怎么更新上下文。
为什么要强调 Harness?因为在隔离内网里,你不可能依赖云端编排服务,所有编排逻辑都必须本地化运行。Harness 的设计直接决定了 Agent 在断网条件下能否稳定执行多步任务。我的看法是:与其追热门框架,不如先把 Harness 的核心机制理解清楚——工具注册表、状态机、任务循环、记忆容器。这四个组件无论用什么框架,最后都要落地实现。
3.2 路线 A:FastAPI + LangChain + LangGraph,Python 团队的首选
如果团队以 Python 为主,我强烈建议走 FastAPI + LangChain + LangGraph 这条路。FastAPI 负责对外提供 HTTP 服务和流式接口,LangChain 提供全套工具封装和模型接入抽象,LangGraph 负责定义 Agent 的状态图和编排逻辑。
为什么这个组合适合隔离内网?因为 LangGraph 的状态图机制非常灵活,你可以把“工具调用”“人工审核”“知识检索”“结果生成”都定义成独立的节点,节点之间的流转由状态控制。断网环境下,任何一步都可能失败,状态图能让你清晰地设计重试、降级、超时策略。
一个简化版的接入方式大概是这样的:
from fastapi import FastAPI from langchain_openai import ChatOpenAI app = FastAPI() llm = ChatOpenAI( model="internal-qwen14b", base_url="http://model-gateway:8000/v1", # 内网模型网关 api_key="internal-key", temperature=0.2, ) @app.post("/agent/run") async def run_agent(request: dict): # 调用 LangGraph 编译好的图,传入用户请求 result = await graph.ainvoke({"messages": request["messages"]}) return {"output": result}这里有个细节:base_url 必须显式指到内网网关,api_key 可以随便填一个占位符,因为内网网关可以关闭鉴权或使用内部令牌。ChatOpenAI 这个类本身并不校验 key 的真实性,它只是把 key 填到请求头里。所以我见过很多团队在内网里直接复用这套组件,只是把地址换成内网地址,异常顺利。
3.3 路线 B:Spring AI,Java 技术栈和既有基建最合拍
如果你是给银行、大型制造企业做项目,技术栈很可能被钉在 Java 上。这时候 Spring AI 会是相对顺手的选项。它在 Spring Boot 生态里提供了统一的模型接入、Prompt 模板、工具调用抽象,对已经在用 Spring Cloud 的团队来说,集成成本低很多。
隔离内网里用 Spring AI,要注意两个坑。一个是对 Maven 依赖做离线同步,Spring AI 相关的 starter 版本迭代很快,你在外网构建好 fat jar 再进内网是最稳妥的方式,省得在内网私服里缺这个缺那个。另一个是工具调用的实现方式,Spring AI 的 function calling 机制支持你自定义 Bean 作为工具,但你必须确保这些 Bean 不会依赖外网服务,否则 Agent 在执行工具调用时会直接失败。
3.4 路线 C:Rust,追求单二进制交付和低资源占用
如果你的部署环境是边缘设备,或者特别看重资源占用和交付简洁度,可以考虑用 Rust 写 Agent。Rust 生态里已经有比较完整的 Agent 开发框架,比如可用于构建工具调用循环的库,配合 Tokio 的异步运行时,整体占用非常低。
Rust 路线在隔离内网里的最大优势是:编译产物是一个静态链接的二进制文件,几乎没有运行时依赖。你不用搬 Python、不用装 CUDA 库、不用管一堆 pip 依赖,把二进制和各种工具脚本拷进内网就能直接跑。这对隔离内网来说简直是降维打击,因为很多内网环境对安装额外软件的限制很严格,一个二进制文件比一堆动态库和解释器好处理得多。当然,代价是开发效率比 Python 低,生态成熟度也弱一些。
三条路线我把它们的核心差异整理成一个表:
| 维度 | FastAPI + LangChain + LangGraph | Spring AI | Rust Agent 框架 |
|---|---|---|---|
| 团队门槛 | 低,Python 上手快 | 中,需要 Java 功底 | 高,Rust 上手慢 |
| 生态成熟度 | 高,工具类丰富 | 中,AI 生态仍在追赶 | 低,组件偏底层 |
| 离线依赖复杂度 | 需要打包大量 Python 依赖 | 需要 Maven 离线同步 | 极低,二进制交付 |
| 典型场景 | 通用 Agent 平台、快速迭代 | 既有 Java 体系改造 | 边缘设备、轻量部署 |
4. 物料离线化:从“能跑”到“可复现”的交付工程
4.1 Python 依赖怎么“搬”进内网
这一节是纯经验活,不少团队在模型上花了大力气,结果死在 Python 依赖上。我建议的方案是:在外网准备一台专用的同步机器,把这台机器作为“物料打包机”。所有 Python 依赖都在这台机器上用 pip download 命令下载到本地目录,然后把整个目录摆渡进内网。
命令大概是这样的:
pip download -r requirements.txt -d /packages --platform manylinux2014_x86_64 --only-binary=:all:这里有两个关键点。一是必须指定平台,因为你在外网下载的包可能带了平台标识,不同平台之间不能混用。二是能只下二进制包就只下二进制包,避免内网机器上因为没有编译器而无法安装源码包。如果个别包确实没有二进制版本,那就在外网机器上用相同 Python 版本编译成 wheel,再一起打包进去。
进了内网之后,我建议不要直接 pip install,而是搭一个内网私有源。Nexus、Devpi、或者简单的本地 wheelhouse 都可以。这样团队内部多台机器可以重复安装,不必每次都用离线文件。固定版本是关键,requirements.txt 里要把每个包都锁到精确版本,甚至可以加上哈希校验。
4.2 容器镜像同步:从外网拉取到内网私有仓库
Agent 系统通常不是单体,而是由多个服务组成的。推理服务、网关、向量库、编排服务都要容器化。隔离内网里没有公网镜像仓库可用,所以容器镜像也得走“外网拉取、内网导入”的流程。
在外网机器上,先把镜像拉好:
docker pull vllm/vllm-openai:latest docker save vllm/vllm-openai:latest -o vllm.tar然后把 tar 文件运进内网,在目标机器上导入并推送到内网镜像仓库:
docker load -i vllm.tar docker tag vllm/vllm-openai:latest internal-registry:5000/vllm-openai:latest docker push internal-registry:5000/vllm-openai:latest一个很容易踩的坑是镜像架构。如果你的外网下载机器是 ARM 架构,拉下来的镜像是 ARM 版本,内网 GPU 服务器是 x86,直接跑会报错或者性能异常。所以拉镜像的时候一定要用--platform linux/amd64显式指定架构。镜像管理上,我建议按照业务模块的发布节奏维护一个“镜像基线清单”,记录每个镜像的版本、SHA256、导入时间。以后排查问题时,这个清单就是救命稻草。
4.3 模型权重和向量模型的版本管理:越早建立目录规范越好
模型文件不是一次性运进去就结束的。随着业务迭代,你可能要升级模型版本、增加新的 embedding 模型、替换量化文件。所以在第一次搬运模型时,就应该建立清晰的目录规范。
我的做法是:在内网模型存储区按“业务/模型名/版本号/文件类型”的目录结构组织。比如:
/models/customer-service/qwen14b/v1.2/tokenizer.model /models/customer-service/qwen14b/v1.2/quantized-awq/ /models/embedding/bge-m3/v1.0/每个模型目录下放一个 manifest 文件,记录 SHA256、来源、搬运时间、部署注意事项。这个习惯初期看起来繁琐,但当某天有人告诉你“线上模型行为异常,可能是权重文件被损坏”的时候,你只需要对比 manifest 里的哈希值就能快速定位问题。隔离内网里没有自动更新通道,所有变更都靠人工记录,版本规范就是整个系统的记忆。
5. 隔离内网里 AI Agent 到底怎么扛并发
5.1 先认清 Agent 请求和普通 HTTP 请求的本质区别
很多人一听到“扛并发”,第一反应是加线程、加机器。但在 AI Agent 场景下,这个思路很容易出问题。普通 Web 接口一个请求通常在几十毫秒内返回,而一个 Agent 任务常常要跑几秒到几分钟,期间会发起多次模型调用、多次工具调用。你调用的不是“单次大模型接口”,而是一整条任务链。
假设一个 Agent 任务需要推理 5 次、调用 3 个工具,总共耗时 30 秒。如果每秒进来 2 个新任务,那系统里同时就只有 60 个任务在执行。看起来并发量不大,但每个任务内部都要占用 GPU 资源、内存和连接池。如果你按每秒 2 个请求来算,似乎没压力;但按“任务内部 5 次模型调用”来算,实际打到推理服务的请求量就是每秒 10 次,再加上重试机制,可能翻倍。所以 Agent 系统的并发评估,一定要按“任务级并发 × 每任务模型调用次数”来计算,而不是只看入口 QPS。
5.2 常见误区:开一堆线程和盲目加机器
我先说我踩过的坑。早期我把 FastAPI 服务用多 worker 跑起来,一个 Agent 任务的执行逻辑里直接调大模型 API。表面上看服务能接住请求,但很快发现 GPU 显存被占满,推理服务排队严重,Agent 任务超时率飙升。
这里面有个结构性矛盾:Agent 任务本身是 CPU 密集型、IO 密集型的混合体。一个 worker 线程在处理 Agent 任务时,大部分时间其实在等待模型响应。你开 100 个 worker,同时有 100 个任务在等模型,模型服务扛不住,整体吞吐照样上不去。所以“加线程”在入口层面是无效的,瓶颈在后面。
正确的思路是分层解耦。入口服务只负责接收任务、校验参数、把任务丢进队列,然后立刻返回“任务已受理”。后端 Worker 进程从队列里拉取任务,真正执行 Agent 逻辑。这样入口服务的并发能力可以很高,而 Worker 的数量可以由你根据 GPU 资源精细控制。
5.3 分层架构设计:异步入口、任务队列、Worker 池、模型服务
我最终采用的方案是一条典型的分层链路。
接入层是 FastAPI 异步接口,接收用户请求,把请求消息体写入 Redis 队列,返回一个 task_id。这样做的好处是,接入层的响应时间控制在毫秒级,即使 Agent 任务要跑几分钟,用户的 HTTP 连接也不会因为超时被切断。用户可以通过 WebSocket 或者轮询接口按 task_id 获取进度。
调度层使用任务队列,Celery 或者 Redis RQ 都可以。Agent 任务的特性是长耗时、可重试、状态化,用任务队列管理正好合适。任务进入队列之后,多个 Agent Worker 并发消费。每个 Worker 内部再执行 LangGraph 或自定义 Harness 的逻辑。
模型服务层由 vLLM 承担,它自带连续批处理和动态显存分配,能最大化 GPU 利用率。这里的关键参数是 max_num_seqs,它决定了一次最多同时处理多少个请求序列。用 Agent 场景时,我建议把 max_num_seqs 调高一些,因为 Agent 会产生大量短请求和流式请求,如果序列并发数太低,吞吐会很难看。
还有一层容易被忽略的是工具调用并发。Agent 任务内部经常会调用知识库检索、数据库查询。这些工具服务也要做连接池管理,否则模型调用没超时,工具调用反而成了瓶颈。
5.4 压测方法和参数建议
隔离内网里做压测,不能直接用公有云压测工具,通常就用内网机器跑 Locust 或者 JMeter。我建议压测分两步走。
第一步,先单独压模型服务。测出 vLLM 在给定显存和并发下的最优吞吐和延迟。在这阶段调整好 max_num_seqs、显存分配策略,保证模型服务本身处于健康状态。第二步,再压 Agent 总链路。这时候关注的不再是模型服务本身的指标,而是“任务成功率”“平均任务耗时”“任务排队时间”。
我实测下来的一组参考值是:单张 80G 显卡部署 14B AWQ 量化模型,max_num_seqs 设为 64,入口 QPS 控制在 5 以内,任务级并发控制在 30 左右,整体系统能稳定运行。如果你的任务涉及大量长文本生成,并发量还要再下降。这里的核心原则是:宁可让任务在队列里等一会,也不能让模型服务端过载。模型服务一旦进入长时间排队,用户的等待体验会断崖式恶化,甚至触发超时重试,把系统拖垮。
6. 一次真实排障全链路:断网环境里 Agent“响应超时”之谜
6.1 症状与背景:单测正常,上线就出问题
有一次上线一个文档问答 Agent。本地测试环境一切正常,单次问答两三秒返回;进入隔离内网生产环境后,小流量测试也说得过去。但压测一上来,挂着十几分钟,就开始出现大面积请求超时,错误日志里全是 “Read timeout” 和 “Task cancelled”。
当时团队里的第一反应是“网络问题”。隔离内网嘛,网络策略复杂,大家首先怀疑是防火墙拦截了某些端口。于是运维查了一圈网络打通情况,端口都通,白名单也都加了,问题还在。
6.2 第一轮排查:从日志入手定位超时层级
我没有急着抓包,先把 Agent 服务、模型服务、工具服务三方的访问日志打开。对比之后发现了一个很关键的现象:Agent 服务日志显示任务已经执行完毕,但在返回响应的瞬间,连接被客户端断开;模型服务日志显示单次推理耗时正常,没有达到超时阈值。
这个现象说明问题不在模型推理本身,而在“响应链路”上。Agent 服务把结果算出来了,但数据没法顺利交还给用户。结合压测时间点,我怀疑是接入层和任务层之间有超时配置冲突。
6.3 第二轮排查:连接管理配置里的坑
顺着链路往下查,我在接入层和任务 Worker 之间发现了一个配置问题。接入层用异步 HTTP 客户端等待 Worker 的返回结果,而 Worker 执行的是一个分钟级的长任务。接入层的 HTTP 客户端默认超时时间只有几十秒,一旦 Agent 任务执行时间超过这个阈值,接入层的连接就被迫中断,客户端自然看到 “Read timeout”。
说白了,这就是一个“长任务套短超时”的经典问题。Model 服务的接口没有因为长时间不返回而超时,反而是在你设置的网关层把连接掐断了。排查到这一步,思路一下就通了。
6.4 第三轮排查:工具调用里的“隐性外呼”隐患
超时问题修完之后,压测又冒出一个新异常:部分任务在工具调用阶段失败。细看日志发现,知识库检索模块里有一段旧的工具代码,默认请求了一个外网域名。隔离内网里这个域名根本不可达,每次调用都要等到 DNS 解析超时,然后触发重试,重试又超时,把整个 Agent 任务拖垮。
这也暴露了一个我在第三章强调过的问题:代码仓库里混入了依赖外网服务的工具调用。排查阶段我不得不在整个代码库里 grep 所有外网域名和可疑的 URL,逐个改成内网服务地址或纯本地实现。这个动作应该在项目初期就做,而不是等压测时被日志打脸。
6.5 复盘清单:断网环境下的排查顺序
经过这次排障,我总结了一个固定顺序,之后再遇到隔离内网 Agent 超时,就按这个顺序查:
先查任务链路里的超时配置,重点看接入层、网关层、HTTP 客户端三个位置有没有和任务时长不匹配的短超时。再查 DNS 解析,确认代码里没有隐藏的外网域名调用。然后查工具服务连接池,看是不是某个工具服务连接耗尽导致任务等待。最后才查模型服务本身,看是否过载和排队。
这个顺序的重要性在于:隔离内网里最隐蔽的问题几乎全是配置和依赖层面的,而不是模型推理能力层面的。你在外网开发时,各种外网服务随手就调,DNS 又快又稳,根本意识不到内网环境里一次失败的 DNS 解析会把整套系统拖到超时边缘。
7. 隔离内网里做 AI Agent 工程的几个基本盘
7.1 先做小闭环,再铺大图景
隔离内网项目的试错成本非常高,因为一次变更可能要经历完整的物料摆渡、部署、验证流程。所以我的铁律是:先做一个极小的业务闭环,从头到尾验证链路通畅,再扩展应用范围。
比如你要做智能客服 Agent,第一版就做一个意图识别 + 答案检索 + 兜底转人工的小场景。这个闭环里把模型推理、知识库检索、工具调用、日志链路全部跑通。跑通之后再往上加多轮对话、任务编排、多 Agent 协同。别一上来就做“十个 Agent 协同处理复杂任务”的大方案,那在隔离内网里的排障难度会指数级上升。
7.2 Agent 链路的可观测性:没有日志就没有话语权
隔离内网里的 Agent 系统比普通 Web 系统更需要可观测性,因为链路更长、状态更多。每次任务都应该记录完整的事件轨迹:任务 ID、输入摘要、每一步工具调用名称、工具耗时、模型调用次数、总 token 数、最终输出摘要。这些信息可以写入结构化日志,也可以落到本地表里。
我见过太多团队在排查 Agent 问题时靠“猜”。因为 Agent 内部的一连串工具调用过程是黑盒的,系统只报告“失败”,但不知道失败发生在哪一步。所以从一开始就要给每个 Agent 任务加上链路 ID,在日志里打印每一步的耗时和结果。这会在前期增加一点开发量,但后期排查问题时能省出数倍的时间。
7.3 内网不等于安全,权限和脱敏照样要做
很多人觉得内网环境天然安全,Agent 系统内可以自由调用各种数据。这个想法很危险。在隔离内网里,数据不出网确实降低了外部泄露风险,但内部越权访问、数据滥用的问题依旧存在。
Agent 能调用哪些工具、能查询哪些数据库、能把哪些数据拼装到系统提示词里,都应该按最小权限原则设计。尤其是知识库检索和数据库查询这两类工具,要在工具层做行级和列级过滤,不能直接把完整查询能力暴露给模型。输入和输出的内容检查节点也不能省,哪怕是在内网,也需要对敏感词、个人隐私信息做脱敏处理。
7.4 物料搬运清单:我养成的最实用的习惯
最后说一个最朴素也最实用的习惯:每次向隔离内网搬运物料,都写一份“搬运清单”。清单上记录这次搬运了哪些依赖包、哪些镜像、哪些模型文件,来源是什么,对应哪个应用版本。这个清单既是你自己的记忆,也是交接给团队其他成员最有效的工具。我见过的最惨的失败案例,就是某团队半年后要复现当初的构建环境,结果谁都不记得当时的依赖版本和模型文件是哪批的,整个项目在排查问题时毫无头绪。
我个人的体会是,隔离内网里做 AI Agent,核心不是炫技,而是把每一件“在外网两分钟就能解决的事”都提前想清楚、做扎实。模型能力可以慢慢调,依赖和工程链路必须一遍过。每次搬运物料都写清来源和版本,每次跑通链路都固化一份部署手册,这套习惯坚持下来,项目就越做越顺,后面的多 Agent 扩展、新业务接入,基本就是换一批物料、改一套工具而已。