隔离内网环境下做 AI Agent,最直接的感受是:外面那些“开箱即用”的方案,在真正落地时几乎全都要打上问号。模型不能调云端 API,依赖包没法随时 pip install,甚至连一份训练好的权重文件,都可能在传输环节折腾一整天。但这类需求恰恰是政企、军工、金融等场景最普遍的刚需——数据不出域、模型不出网、系统全栈自建。这篇文章我会以“隔离内网 AI Agent 工程实战”为主线,把从模型获取、推理服务搭建、知识库增强,到 Agent 编排、权限控制、以及最后的踩坑排查,完整串一遍。不聊概念,只讲我在这种受限环境下怎么真正把 Agent 跑起来。
1. 隔离内网下的技术选型与整体设计思路
1.1 先想清楚约束,再谈架构设计
很多人一上来就开始选 Agent 框架,这其实是本末倒置。隔离内网环境的第一原则是“约束驱动设计”。你要先搞清楚自己手里有什么牌,再决定打法。我把最常见的约束条件列一下,你可以对号入座:
- 没有公网出口:OpenAI、阿里云百炼、智谱开放平台这类 API 全部不可用,所有模型必须私有化部署。
- 外网依赖不可达:pip、npm、apt 的默认源全部失效,GitHub 也无法访问,必须走内网私服或离线安装包。
- 算力资源通常紧张:可能只有单机 1~2 张消费级显卡或几块 A10/A30,别指望 72B 这种大模型的“满血版”。
- 数据敏感度高:企业内部制度、业务数据、生产库表、代码资产都不能出境,甚至不能跨网段传输。
- 系统环境碎片化:存在老的 CentOS、国产化系统、容器平台、物理机混合部署,跨部门协调成本极高。
这些约束叠加在一起,逻辑上就直接决定了技术路线的走向:必须采用全栈私有化的开源模型 + 本地知识库 + 自托管 Agent 服务。注意,这里说的是“服务”,不一定是某个重量级框架。隔离内网里,你可以先把所有组件拆成独立服务,再用标准的 HTTP/gRPC 接口串联,这样即使某个组件替换掉,影响面也能控制住。
1.2 模型选型:别只看参数规模,要看显存账
模型选型是整个项目里最决定体验的一步。我在实际项目中反复权衡后,得到一个比较稳妥的经验:7B~14B 这个量级的模型,才是隔离内网里性价比最高的区间。比如 Qwen2.5-7B-Instruct、Qwen2.5-14B-Instruct、DeepSeek-R1-Distill-Qwen-14B 这一类。原因也简单:这个规模的模型可以在 1~2 张 24GB 显存的卡上跑 FP16/BF16 推理,兼顾上下文长度和并发能力;如果做量化,一张 16GB 的卡就能带起来,部署门槛大幅降低。
模型规模与资源的大致对照表如下(以单卡推理、BF16 精度估算):
| 模型参数量 | 权重存储 | 推理显存需求 | 单机可部署条件 | 适用场景 |
|---|---|---|---|---|
| 1.5B ~ 3B | 3~8GB | 8~12GB | 单卡家用卡也能跑 | 简单分类、摘要、脚本辅助 |
| 7B ~ 8B | 15~17GB | 20~28GB | 单卡 24GB | 问答、中等推理、工具调用 |
| 14B | 28~32GB | 40~56GB | 双卡 24GB 或单卡 80GB | 较复杂推理、长文本理解 |
| 32B ~ 72B | 65GB~150GB | 100GB+ | 多卡集群 | 高难度推理,但运维成本陡增 |
在 Agent 场景里,模型不仅要“会聊天”,还得会“看工具描述、做计划、处理 JSON 输出”。我做过对比测试,7B 模型在简单工具调用上问题不大,但在多步规划、API 参数纠错上明显弱于 14B。如果你的 Agent 要处理比较复杂的业务流程(比如跨系统查数据、自动填报),尽可能选择 14B 这个档位。如果预算实在有限,再退回 7B 并配合优质提示词兜底。
1.3 Agent 框架选型:重度框架未必是优解
目前市面上的 Agent 框架很多,LangChain、LlamaIndex、Dify、Coze 开源版、FastGPT 都各有拥趸。但在隔离内网里,我发现一个很容易被忽略的问题:框架本身的依赖树和插件体系,可能比你的业务逻辑还要重。比如某个组件底层要拉一个在线模型配置,某个工具插件要连某个云端服务,在离线环境下要么绕开,要么自己改,一个不小心就卡死在环境依赖上。
从项目实战角度,我更倾向于一个“分层组合”的思路:
- 流程编排层:用 Dify 或自研轻量工作流引擎,负责 Agent 的状态管理、节点调度、多轮对话。
- 模型接入层:统一封装为 OpenAI 兼容的 HTTP 接口,后端接 vLLM / Ollama,这样上层框架永远通过一个标准接口对话。
- 工具层:按照统一的函数调用规范(名称、描述、参数 JSON Schema)注册内部接口,可以是 Python 装饰器,也可以是一个独立的工具网关服务。
这么做的好处是:每一层之间解耦,如果 Dify 太重,你可以随时替换成自研的调度器;如果推理框架性能不行,你也只改接入层,上层业务代码完全不用动。隔离内网环境里,模块化、低耦合的优先级永远高于“单一框架全家桶”。
2. 模型落地:从公网下载到内网推理服务
2.1 模型获取的完整搬运动线
这一节是最容易被新手低估的。很多人以为“把模型下载下来,拷贝进去就能跑”,结果在传输环节反复踩坑。先给出一条我在多个项目中验证过的完整路径:
- 在能访问外网的办公机上下载模型。首选 ModelScope 魔搭社区,国内源速度快、断点续传友好;如果必须用 Hugging Face,建议配置 hf-mirror 镜像,下载速度会好一些。这里提一个细节:下载前先记录模型的 SHA256 校验值,模型文件在传输过程中一旦损坏,后面跑到一半报错会非常难排查。
- 打包传输而非直接拷目录。transformers 模型目录里少则几百个、多则上千个 shard 文件,直接拷贝会产生大量小文件 IO,内网带宽再快也会被拖垮。建议在办公机上先打包成一个大文件(tar 包,或带 .tar.zst 压缩),然后通过移动硬盘、FTP、内网共享等方式搬到隔离区的存储节点。
- 传输完成后立即校验。在隔离区 compute 节点上做
sha256sum比对。如果走的是移动硬盘,还要检查磁盘空间是否足够,别出现“拷了一半才发现空间不足”的尴尬局面。
我实操中遇到过一个非常典型的坑:某次在 Hugging Face 下载的是 symlink 解引用后的文件树,里面有个别 GB 级文件因为网络原因被截断,但下载工具没有报错。拷到内网加载模型时,死活报"safe_open failed"。最后排查了整整两天,才用校验发现权重文件头尾不完整。所以“下载后核对 checksum”这件事,无论如何不要省。
2.2 推理服务端选型:vLLM、Ollama 还是 SGLang
模型文件到位之后,推理服务的选择直接影响 QPS、显存利用率和接口复杂度。三者我都用过,各有适用场景,直接给结论:
| 推理框架 | 核心优势 | 适用场景 | 内网部署难度 |
|---|---|---|---|
| vLLM | PagedAttention、连续批处理、高吞吐、OpenAI 兼容接口 | 生产级 Agent 服务,并发要求高 | 中,需要 Python 环境、CUDA 版本匹配 |
| Ollama | 开箱即用、GGUF 格式友好、模型管理简单 | 快速验证、单机小并发、资源受限机器 | 低,几乎零配置 |
| SGLang | RadixAttention、复杂采样控制、多模态支持 | 长上下文、复杂 Agent 推理 | 中高,依赖较新 |
从工程化角度,我强烈建议在生产环境用vLLM。原因有三:一是它原生提供/v1/chat/completions接口,上层 Agent 框架零改造接入;二是它在高并发多路推理时的吞吐表现明显优于 Ollama;三是它内置了 OpenTelemetry 监控,方便接日志链路。
Ollama 更适合做原型验证或给测试组快速出一版效果。在最终交付时,如果业务并发要求不高,Ollama 也能胜任,但要注意它的并发控制不如 vLLM 精细,单个长请求可能阻塞其他请求。
2.3 vLLM 启动参数与量化选择的经验值
这里贴一份我在内网环境常用的 vLLM 启动命令模板:
python -m vllm.entrypoints.openai.api_server \ --model /data/models/Qwen2.5-14B-Instruct-AWQ \ --served-model-name qwen14b \ --max-model-len 8192 \ --gpu-memory-utilization 0.92 \ --tensor-parallel-size 2 \ --enable-auto-tool-choice \ --tool-call-parser hermes \ --port 8001几个关键参数的注意点:
--max-model-len不是越大越好。它决定模型能处理的最长上下文,但也会直接吃掉显存。如果你的 Agent 场景单轮交互在 4K tokens 以内,设 8192 足够了,不必盲目追求 32K。--gpu-memory-utilization建议留出 8%~15% 的显存余量给 KV Cache 碎片和临时张量,否则高并发下容易 OOM。我一般推荐 0.9~0.93。--tensor-parallel-size在多卡场景下设为卡数,但注意单卡显存小于 20GB 时,建议优先用量化模型而不是强行 TP。--enable-auto-tool-choice和--tool-call-parser是给 vLLM 开启原生工具调用解析用的,如果你的模型不是专门的 tool-call 微调版本,可能不稳定,需要自己做一层工具调用解析。
关于量化,很多人在内网环境纠结模型精度。我的建议是:如果显存足够,优先 BF16/FP16 原始权重,量化是“显存不够时不得不做”的方案,不是“一劳永逸优化性能”的方案。以 Qwen2.5-14B 为例,BF16 权重约 32GB,推理显存需求约 56GB;如果用 AWQ 4bit 量化,权重大约 9GB,推理显存需求约 20GB。后者能落到单张 24GB 显卡上,但推理质量和复杂工具调用的准确性会有下降。如果 Agent 场景对逻辑要求高,我宁愿用 7B 原始精度,也不用 14B 的激进量化版本。
2.4 服务可用性验证与性能压测
模型服务启动后,不要急着接 Agent。先做一轮简单的 smoke test,确保接口响应正常:
curl http://127.0.0.1:8001/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen14b", "messages": [{"role": "user", "content": "1+1等于几?"}], "max_tokens": 64, "temperature": 0.1 }'然后观察首 token 延迟、总生成时长这两个指标。内网环境如果是单卡 14B 模型,首 token 延迟通常在 300~800ms 之间(取决于上下文预填充长度)。如果明显偏高,优先检查是否做满了 KV Cache,或是否被其他任务占用显存。
压测阶段,我建议直接用 5~10 个并发线程请求不同问题,观察 vLLM 日志中的排队时间和吞吐。如果 Agent 在后续运行时总报“token 耗尽”或“请求排队超时”,八成不是模型问题,而是业务侧的频繁长上下文请求把服务打满了。
3. 知识库与 RAG:让 Agent 在内网里“有据可查”
3.1 为什么内网 Agent 一定绕不开 RAG
坦白说,Agent 在隔离内网最早落地的业务形态,往往不是“自由对话”,而是私有知识库问答。原因天然成立:企业制度文档、设备手册、代码库注释、历史故障记录,这些数据本身就存在内网,对外部模型来说是完全不可见的。如果让 Agent 直接“空对空”回答,它只能靠训练记忆里的常识,碰到专属名词和内部流程,几乎必然产生幻觉。
RAG(检索增强生成)的运作逻辑本质上是“先查资料,再写答案”。Agent 收到用户问题后,先转换成向量和关键词去检索本地知识库,把命中的文本片段作为上下文塞给模型,让模型基于这些材料组织回答。这个链路全部在内网完成,既满足数据不出域的要求,又大幅提升了回答的准确性和可解释性。
3.2 文档解析与分块:内网文档的隐藏难题
很多人在做 RAG 时把精力都花在向量化模型上,结果忽略了最基础的文档解析。实际上,内网文档的质量参差不齐,常见的坑包括:
- 扫描版 PDF:很多制度文件是扫描件,没有内嵌文字层,直接解析出来是一张空纸。必须接 OCR 工具,比如 PaddleOCR、Tesseract(离线安装),先识别再走后续流程。
- 复杂表格:PDF 里排版歪七扭八的表格,直接文本抽取会丢失行列结构。优先用 camelot、pdfplumber 提取表格结构,再按行转成 Markdown 或 JSON。
- Word 和 Markdown 混排:建议统一转成 Markdown 或 JSON 再入库,后续分块时能利用标题层级信息。
分块策略上,我采用的是一套比较稳妥的经验参数:
- chunk_size 设为 400~600 个中文字符,overlap 设为 50~100 字符。这个大小既能保证单块语义完整,又不至于让向量检索时“语义稀释”。
- 如果文档本身有清晰的标题层级,优先按“章节+段落”的结构化方式切分,而不是机械按固定长度切。例如一句“3.2 续费流程”下面的一段内容,应该被切为独立一块,而不是和上一节混杂。
- 对代码类、配置类知识,chunk_size 可以适当调大到 800~1000,但 overlap 也要跟着加,避免把关键语句截断。
为什么要强调 overlap 这个参数?因为检索阶段按向量相似度召回片段时,如果恰好问题命中了两个 chunk 的边界处,overlap 区域可以保证关键句至少完整地出现在某一个 chunk 中,减少“总是差半句话”的尴尬。
3.3 Embedding 模型选型与向量库落地
内网环境没法调用公网向量化 API,所以 Embedding 模型也必须本地部署。我在中文场景下最推荐的是BGE-M3,它同时支持稠密向量和稀疏向量,还能做多语言,对中文长文本的语义理解比很多同量级模型都稳。如果显存紧张,可以用 bge-large-zh-v1.5 或 text2vec-large-chinese。
| Embedding 模型 | 维度 | 显存需求(推理) | 中文效果 | 备注 |
|---|---|---|---|---|
| bge-m3 | 1024 | 约 2GB | 优秀 | 支持稠密+稀疏,可混合检索 |
| bge-large-zh-v1.5 | 1024 | 约 1.5GB | 良好 | 体积小、部署简单 |
| text2vec-large-chinese | 1024 | 约 1GB | 中上 | 资源最省,适合极简环境 |
向量数据库方面,如果只是几百份文档级别的知识库,用轻量的Qdrant或Milvus Lite就足够了。如果内网里已有 Elasticsearch,也可以直接利用它的 kNN 检索能力,少维护一个组件。说到底,向量库不是重点,关键是在索引字段里同时保存文本原文、来源路径、分块序号,这样命中之后才能拼引用、给追溯,而不是只给一段裸文本。
3.4 混合检索:关键词和向量必须两条腿走路
纯向量检索最大的硬伤,是对“精确字面词”不敏感。比如员工查“请休假管理办法第十二条”,向量搜索很可能找出一堆“请假”相关却完全没提“第十二条”的段落,而 BM25 关键词检索能精准命中带星号条款编号的段落。所以生产环境里,我的默认配置是向量检索 + BM25 关键词检索并行,然后做分数融合。
融合公式不一定要复杂,我常用的一个简单方案如下:
score = alpha * normalized_vector_score + beta * normalized_bm25_score其中 alpha、beta 根据业务调优,一般在 0.6~0.8 和 0.2~0.4 之间。如果场景里“严谨条款查询”居多,就把 beta 调高;如果“开放式问答”居多,就把 alpha 调高。实际操作里,我会用一组验证集跑一遍不同参数组合下的召回率,再固化到配置文件中,而不是拍脑袋定。
注意:如果知识库里的文档有大段重复内容,比如同一篇制度在多个月度版本中各出现一次,检索时要加一层“按文档名+分块序号去重/过滤”的逻辑,否则 Agent 的上下文里塞满了互相矛盾的内容,回答很容易出问题。
4. Agent 工具调用与权限控制的工程化设计
4.1 Agent 从“问答”到“行动”的跃迁
RAG 解决的问题是“让 Agent 知道”,真正让 Agent 产生价值的是“让它能做事”——调用内部接口、查数据库、操作工单系统、生成报表。这时候系统就不再是简单的“我问你答”,而是进入经典的 ReAct 循环:模型根据用户意图生成计划,选择工具,执行工具,观察结果,再决定下一步动作。
在内网环境里,Agent 要触达的工具五花八门:可能是内部的 HTTP API、数据库连接、脚本编排、甚至某个老旧系统的 CLI。我个人的工程经验是:不要让 Agent 直接连内部系统,在中间加一层标准的“工具网关”。所有 Agent 可调用的动作,都由工具网关统一暴露为“名称 + 描述 + 入参 JSON Schema”的形式。这样做有几层好处:
- 对 Agent 来说,它只需要理解统一的函数调用协议,不需要关心后端是 REST、gRPC 还是 RPC。
- 对平台方来说,工具权限、限流、审计可以在网关统一管控。
- 对业务方来说,新接入一个内部系统时,开发量被压缩到“写一个适配器”,而不是改 Agent 框架。
4.2 一个可复用的工具注册与调用实现
下面我用 Python 给出一个简化但可直接落地的工具注册示例。核心思想是用装饰器把普通函数变成 Agent 可调用的工具,并在运行时自动生成描述和参数 JSON Schema:
from pydantic import BaseModel from typing import Optional TOOL_REGISTRY = {} def register_tool(name: str, description: str, params_model: type[BaseModel]): def decorator(func): schema = params_model.model_json_schema() TOOL_REGISTRY[name] = { "function": func, "description": description, "parameters": schema, } return func return decorator class QueryOrderParams(BaseModel): order_id: str env: Optional[str] = "prod" @register_tool( name="query_order_status", description="根据订单编号查询订单当前状态,支持生产/测试环境", params_model=QueryOrderParams, ) def query_order_status(params: QueryOrderParams): # 内部实现:调用后端订单服务的HTTP接口 return {"order_id": params.order_id, "status": "已发货", "env": params.env}这里有个很重要的细节:description 必须写得像“给另一个工程师看的说明”,要包含这个工具是干嘛的、什么时候用它、入参含义。因为 Agent 选择工具时完全依赖这段文本,写得太抽象(比如“查询订单”),模型很可能摸不准该不该调用,也容易填错参数。
工具执行的返回结果建议统一为 JSON 序列化文本,长度尽量控制在 1~2KB 内。如果工具返回值太长(比如数据库查出一百行记录),Agent 的上下文窗口会被瞬间塞满,既费 token 又拖慢后续推理。正确做法是先在工具内部做摘要、截断、分页,只把关键字段返回给模型。
4.3 权限管控:Agent 的“能动范围”必须有红线
这一点我必须单独拿出来强调。隔离内网里 Agent 接触的都是核心系统,一旦控制不好,后果比在公网环境更严重。我的原则非常简单:Agent 默认只读,写操作必需显式授权。
具体落地时,我会把工具分成三类:
- 只读工具:查询类接口、检索类脚本、报表生成,Agent 可以自主调用,不需要人工介入。
- 受控写工具:比如创建工单、发送消息、修改配置。Agent 生成调用请求后,必须先进入一个“人工审批”节点,由用户在管理界面确认后才会真正执行。
- 高风险写工具:删除数据、批量修改、资金操作。这类工具我干脆不对 Agent 开放,或者仅在极少数白名单会话中临时开放。
权限控制不仅是功能开关,还要落到审计链路。每个工具调用记录都要带全局 trace_id,把用户问题、Agent 计划、工具入参、返回结果、审批人、执行时间串成一条完整的日志链。这也是隔离内网项目验收时审查方最看重的部分,没有审计日志的 Agent 系统,架构评审大概率过不了。
实践建议:在 Agent 的 System Prompt 里,明确写入“只能在允许的工具列表中执行操作,当用户请求超出能力范围时,必须明确拒绝并给出原因”。这是兜底防线。模型幻觉不可避免,但你可以通过提示词和工具层双重约束,把风险控制在可接受范围内。
4.4 多轮对话与上下文管理
Agent 一旦开始干活,就涉及多轮对话和中间状态管理。隔离内网里跑模型,上下文越长推理越慢、越占显存,而且费用(如果按内部资源计价)也会上涨。所以上下文管理不是可选项,是必选项。
我的做法是按 session 维度维护消息历史,同时在每次 Agent 进入推理前做一次“上下文裁剪”:
- 只保留最近 N 轮对话(比如最近 5 轮),老内容如果涉及关键信息,可以用摘要取代原文。
- 工具调用记录单独存储。模型上次调用某工具返回了很长结果,这次推理时就没必要把完整历史再塞一遍,而是用一个简短的“工具结果缓存”替换。
- 设定最大迭代轮数上限,比如单任务最多 8 轮 tool call。超过上限强制结束,返回“任务超限,请简化目标”,防止 Agent 陷入死循环空耗资源。
关于 token 的理解,简单说一句:大模型每次推理能处理的文本长度以 token 为单位,一个中文汉字大约等于 1~2 个 token。Agent 场景里 token 消耗不只是用户问题,还包括系统提示词、工具描述、历史消息、检索片段和模型输出。所以做一个上下文管理器非常关键,否则一次看似普通的任务,可能把 8K 的上下文窗口全部塞满,模型反而“迷失”在信息海里。
4.5 工作流编排:可控优先,自由 Agent 为辅
最后一层是编排策略。我强烈建议生产环境采用“工作流为主、自由 Agent 为辅”的混合形态:凡是能预设路径的任务,全部显式编排成固定泳道;只有那些需要发散推理的开放问题,才交给 Agent 自主规划。
固定工作流的优势在于可预测、可测试、可回滚。比如“查订单状态”这个任务,你可以直接画一个三步链路:解析订单号 → 调用订单服务 → 汇总返回。每一步的参数映射都是确定的,Agent 只是承担“语义理解 + 入口分发”的角色。而自由 Agent 的优势是灵活,适合“帮我分析这个系统日志异常的可能原因”这类开放式请求。生产项目中,自由 Agent 的任务占比我一般控制在 20%~30% 以内,再高就很容易出现不可控的行为。
5. 高频问题排查与落地经验总结
5.1 实战中最常见的 6 个坑
我把隔离内网 Agent 项目里踩过的典型问题整理成一个速查表,你在实施过程中可以直接对照:
| 现象 | 可能原因 | 解决思路 |
|---|---|---|
| 模型服务启动后很快 OOM | max-model-len 设太大,或未合理设置 gpu-memory-utilization | 调低 max-model-len,检查张量并行配置,必要时切换量化模型 |
| Agent 调用工具频繁参数错误 | 工具描述不够详细,或者入参 Schema 不合格 | 重写工具 description,给每个字段加示例值,字段尽量用字符串而非嵌套结构 |
| 回答引用了知识库内容,但答非所问 | 文档分块过粗或 embedding 效果差 | 调整 chunk_size/overlap,改用 bge-m3,增加混合检索 |
| Agent 在某类任务上反复执行同一工具 | 工具描述有歧义,或模型把工具选择当成了唯一正确答案 | 在启用工具前加“是否需要调用工具”的判断节点,限制最大迭代轮数 |
| vLLM 排队时间越来越长 | 请求并发高或上下文过长导致 GPU 吞吐下降 | 增加请求级超时,启用 continuous batching,必要时扩容多副本 |
| pip 安装依赖一直超时 | 内网无外网源,且未配置私有仓库 | 在外网机用 pip download 拉取全套依赖,传到内网后离线安装,或搭建 Nexus/PyPI 私服 |
5.2 内网依赖管理的完整方案
离线依赖安装是隔离内网项目里绕不开的“隐形工作量”。我的标准做法是:先在一台与目标环境同架构(同 CPU、同 CUDA 版本、同 Python 版本)的外网机器上,用 pip download 把项目依赖整体拉下来:
pip download -r requirements.txt -d ./offline_packages \ --platform manylinux2014_x86_64 \ --python-version 3.10 \ --only-binary=:all: \ -i https://pypi.tuna.tsinghua.edu.cn/simple然后连同离线包目录拷贝进内网,执行离线安装:
pip install --no-index --find-links=./offline_packages -r requirements.txt这里很容易忽略的一个点是:--platform和--python-version必须与实际运行环境匹配,否则拷进去的包可能因为二进制不兼容直接报错。更稳妥的做法是直接用 Docker 封装整个运行环境,把 Python 版本、CUDA 依赖、系统库都打进镜像,这样内网只需导入镜像,不需要挨个装依赖。这个方案在异地交付场景尤其好用。
5.3 从项目复盘看,隔离内网 Agent 的“真正难点”在哪里
最后聊一点个人体会。很多人以为隔离内网做 Agent,难在算法、难在模型调优,实际上做过一轮你会发现,最耗时的永远是环境适配、数据工程和稳定性治理。
比如模型在公网上一跑就出好效果,搬到内网后却因为一个 CUDA 版本不一致、一个 tokenizer 文件缺失,折腾一整天;知识库文档解析阶段,几百份 PDF 里各种奇葩版式,要一套容错性足够强的解析管线,而不是炫技式的处理代码;Agent 在演示环境能完成的任务,因为内部系统响应慢、超时时间没配好,到了生产环境就开始随机失败。这些问题没有一个是“模型不够聪明”导致的,全是工程问题。
所以我的建议很明确:如果你要在隔离内网正式落地 Agent,先别急着上大模型、上复杂框架,而是先跑通一条最小链路——单机部署 7B 模型 → 用 curl 验证接口 → 处理一份真实文档进知识库 → 封装一个只读查询工具 → 让 Agent 完成一次“查文档+调工具+生成答案”的完整调用。这条链路稳定跑一周,再考虑横向扩展工具数量和提升模型规模。善战者无赫赫之功,先让系统“稳下来”,比“堆功能”重要得多。
如果你手头正好也在做类似的项目,欢迎在实际部署时对照这篇文章里的参数和步骤做验证。碰到底层依赖、模型精度、工具调用这些具体问题,随时可以在评论区交流,我尽量给出当年踩坑之后的可用解法。