1. 为什么要在局域网里自建 AI Agent 平台
很多人第一次接触大模型,习惯直接开个网页版用。但真到团队协作、数据敏感、或者需要把 AI 能力嵌进内部工具链的时候,网页版就明显不够用了。你没法控制它的上下文长度,没法接自己的知识库,更没法让多个同事共享同一套 Agent 配置。这时候,把模型跑在自己的局域网里,就成了一个很自然的选择。
DeepSeek 系列模型这两年在开源社区热度很高,尤其是它的推理能力和中文理解,在同类开源模型里属于第一梯队。而 Harness 这个词,在 AI Agent 语境下,指的是一套把模型、工具调用、记忆管理、任务编排串起来的运行框架。你可以把它理解成"模型的驾驶舱"——模型本身是发动机,Harness 是方向盘、仪表盘和油门刹车的集合体。没有 Harness,模型只能一问一答;有了 Harness,它才能自主规划、调用工具、多轮执行任务。
那为什么用 Docker 部署?因为 AI Agent 平台的依赖链条特别长:Python 版本、CUDA 驱动、各种推理后端、向量数据库、Web 服务框架,任何一个环节版本对不上,就是半天的排查。Docker 把这些全部封进镜像,换台机器照样跑,这对局域网内部署来说太重要了——你不可能要求每台服务器都手动配一遍环境。
这篇文章面向的是有一定 Linux 基础、想在局域网内搭建私有 AI Agent 平台的开发者或运维人员。我会从架构设计讲到具体部署,再到实际踩过的坑,尽量把每一步的"为什么"说清楚。整套方案的核心思路是:模型推理服务 + Agent 编排层 + 统一入口网关,三层解耦,各自独立升级。
提示:本文所有操作基于通用 Linux 服务器环境,涉及的具体镜像名称和配置参数请根据实际硬件情况调整。局域网部署的核心价值在于数据不出内网、多人共享、可定制工具链。
2. 部署前的架构拆解与硬件账本
2.1 三层架构到底怎么分
在动手敲命令之前,先把架构想清楚,不然后面改配置会非常痛苦。我推荐的局域网 AI Agent 平台分三层:
第一层是推理服务层,负责加载 DeepSeek 模型权重,对外暴露一个兼容 OpenAI 接口规范的 HTTP 端点。这一层是资源消耗大户,GPU 显存基本都吃在这里。第二层是Agent 编排层,也就是 Harness 本体,它负责接收用户请求、管理对话历史、决定是否调用工具、把工具结果拼回上下文再发给模型。第三层是接入网关层,提供 Web 界面和 API 入口,同时做鉴权和访问日志。
这三层分开的好处是:推理服务可以独立重启而不影响对话历史;Agent 编排层可以横向扩展多个实例;网关层可以换 UI 而不动底层。很多教程把三层塞进一个容器里,跑起来是快,但一旦要升级模型或者换工具,就得整体重建,维护成本反而更高。
2.2 显存和内存的粗略估算
DeepSeek 模型有多个尺寸,局域网部署最常见的是 7B、14B、32B 这几个量级。显存占用可以用一个粗略公式估算:显存 ≈ 参数量 × 精度字节数 × 1.2。比如 7B 模型用 FP16 精度,大约需要 7 × 2 × 1.2 ≈ 16.8GB 显存;如果用 INT8 量化,字节数变成 1,大约 8.4GB;INT4 量化则降到 4.2GB 左右。
但注意,这只是模型权重的占用。实际运行时还要加上 KV Cache,这个跟上下文长度和并发数直接相关。上下文开到 8K、并发 4 路的情况下,KV Cache 可能额外吃掉 2 到 4GB。所以选卡的时候,别卡着理论值买,留 30% 余量比较稳妥。
| 模型规模 | 精度 | 权重显存 | 建议显卡显存 | 适用场景 |
|---|---|---|---|---|
| 7B | INT4 | 约 4.2GB | 8GB | 个人开发、小团队试用 |
| 7B | FP16 | 约 16.8GB | 24GB | 小团队正式使用 |
| 14B | INT8 | 约 16.8GB | 24GB | 中等团队、复杂 Agent |
| 32B | INT4 | 约 19.2GB | 32GB | 对推理质量要求高的场景 |
内存方面,Agent 编排层和网关层本身不重,各给 4GB 就够。但如果你的工具链里有向量检索,向量库进程可能再吃 2 到 8GB,取决于知识库规模。磁盘上,模型权重文件动辄十几 GB,加上 Docker 镜像和日志,建议至少预留 100GB 空间。
2.3 网络规划里最容易忽略的事
局域网部署有个特点:服务器往往在机房或者某个角落,同事通过内网 IP 访问。这里有两个坑。第一,Docker 默认的 bridge 网络会给容器分配 172.17.0.0/16 网段的 IP,如果你的局域网本身也用这个网段,就会冲突。部署前先ip addr看一眼宿主机网段,避开冲突区间。第二,容器间通信用服务名而不是 IP,所以三层服务要放在同一个自定义 bridge 网络里,这样 Agent 层可以直接用http://inference:8000这样的地址访问推理服务,不用硬编码 IP。
还有一个实际经验:给推理服务容器单独绑一块网卡或者指定--network host有时候反而更简单,因为推理服务的端口不需要对外暴露,只在容器网络内可达就行。但host模式会失去端口隔离,看你的安全要求取舍。
3. 推理服务容器的落地细节
3.1 镜像选择与启动参数
推理服务这块,社区里有几种主流方案:一种是直接用官方或社区维护的推理镜像,另一种是自己基于 CUDA 基础镜像构建。对大多数团队来说,直接用维护良好的现成镜像更省事,因为 CUDA 驱动版本、推理后端编译这些事,自己搞很容易翻车。
启动推理服务容器时,有几个参数必须显式指定。--gpus all让容器能访问 GPU,这个依赖宿主机装好 NVIDIA Container Toolkit。--shm-size要调大,默认的 64MB 在处理大 batch 时会报共享内存不足,建议给到 2GB 以上。模型权重通过 volume 挂载进去,别打进镜像,不然镜像体积会爆炸,而且换模型还得重建镜像。
docker run -d \ --name inference \ --gpus all \ --shm-size 4g \ -v /data/models:/models \ --network ai-net \ -e MODEL_PATH=/models/deepseek-7b \ -e CONTEXT_LENGTH=8192 \ inference-image:latest这里CONTEXT_LENGTH设成 8192 是个折中。开太大,KV Cache 占用飙升,并发能力下降;开太小,Agent 多轮工具调用时上下文容易截断,导致它"忘记"前面调过什么工具。我实测下来,Agent 场景下 8K 是起步,16K 更舒服,但要看显存够不够。
3.2 健康检查与就绪探针
推理服务启动后,模型加载需要时间,7B 模型在普通 SSD 上大概 30 秒到 1 分钟,32B 可能要好几分钟。如果 Agent 层在模型还没加载完就发请求,会直接报连接错误。所以必须配健康检查。
大多数推理镜像会暴露一个/health或者/v1/models端点。用 Docker 的HEALTHCHECK或者编排工具的就绪探针,轮询这个端点,返回 200 才认为服务可用。我一般会在 Agent 层加一个启动等待逻辑,轮询推理服务的健康端点,直到通了再开始接受请求。这个逻辑看起来简单,但能省掉大量"为什么第一次请求总是失败"的困惑。
注意:健康检查的频率别设太高,模型加载期间频繁请求可能拖慢加载速度。建议间隔 10 秒,超时 5 秒,重试 30 次。
3.3 量化精度的取舍
如果显存紧张,量化是必选项。INT8 量化对推理质量的影响通常很小,肉眼几乎看不出差别;INT4 量化在复杂推理任务上会有可感知的下降,尤其是需要多步逻辑链的 Agent 任务。我的建议是:Agent 场景优先保精度,宁可换小一号的模型,也别硬上 INT4。因为 Agent 的核心价值在于自主规划和工具调用,一旦模型"变笨",工具调用的准确率下降,整个平台就失去意义了。
如果实在要用 INT4,至少在 Agent 编排层加一层工具调用结果的校验,比如检查模型返回的 JSON 格式是否合法,不合法就重试或者降级到规则处理。这个兜底逻辑在实际运行中救过我好几次。
4. Agent 编排层的配置与工具接入
4.1 Harness 的核心配置文件长什么样
Agent 编排层的配置通常是一个 YAML 或者 JSON 文件,核心包含几块:模型端点、系统提示词、工具列表、记忆策略。模型端点指向推理服务的容器地址;系统提示词定义 Agent 的角色和行为边界;工具列表声明它能调用哪些外部能力;记忆策略决定对话历史怎么存、存多久。
系统提示词这块值得多花点心思。很多人随便写一句"你是一个有用的助手"就完事,结果 Agent 行为很不稳定。好的系统提示词应该明确:它的职责范围、遇到不确定时怎么办、工具调用的格式要求、以及禁止行为。比如明确告诉它"调用工具时必须输出合法的 JSON,不要附带解释文字",能大幅降低解析失败率。
工具列表的配置要包含每个工具的名称、描述、参数 schema。描述写得越清楚,模型越容易在正确的场景选中正确的工具。我见过因为工具描述太模糊,导致模型该查数据库的时候去调了计算器的情况。这不是模型笨,是描述没给够信息。
4.2 工具接入的三种典型方式
Agent 要真正有用,必须能碰外部世界。常见的工具接入方式有三种:
第一种是HTTP API 工具,把内部系统的 REST 接口包装成工具。比如查订单、查库存、发通知,都是这类。配置时把接口地址、认证方式、请求方法写进工具定义,Agent 调用时 Harness 负责发请求并把结果回传。
第二种是本地函数工具,直接在 Harness 进程里注册 Python 函数。适合做数据转换、格式校验、简单计算这类不需要外部依赖的操作。这种方式延迟最低,但要注意函数必须是纯函数或者幂等的,不然多轮调用可能出问题。
第三种是数据库查询工具,把 SQL 查询能力暴露给 Agent。这个要特别小心,必须做白名单和只读限制,绝对不能让 Agent 拿到写权限或者执行任意 SQL。我的做法是预先定义好若干条参数化查询模板,Agent 只能选模板填参数,不能自己拼 SQL。
| 工具类型 | 延迟 | 安全风险 | 适用场景 |
|---|---|---|---|
| HTTP API | 中 | 中 | 对接内部业务系统 |
| 本地函数 | 低 | 低 | 数据转换、计算 |
| 数据库查询 | 中 | 高 | 结构化数据检索 |
4.3 记忆管理:别让上下文无限膨胀
Agent 多轮对话最怕上下文爆炸。每轮工具调用都会往历史里塞请求和响应,几轮下来就撑满了。Harness 的记忆策略通常有几种:滑动窗口、摘要压缩、向量检索召回。
滑动窗口最简单,只保留最近 N 轮,超出的丢掉。缺点是早期的重要信息会丢失。摘要压缩是让模型定期把历史总结成一段话,省空间但会损失细节。向量检索召回是把历史存进向量库,每轮根据当前问题检索相关片段拼进上下文,这个最灵活但实现复杂。
我的实际选择是滑动窗口 + 关键信息固定的组合:保留最近 10 轮完整对话,同时把系统提示词和用户最初的任务描述固定放在上下文头部,不参与滑动。这样既控制了长度,又不会丢掉任务目标。实测在 8K 上下文下,这个策略能支撑 15 到 20 轮的工具调用对话。
5. 网关层与局域网访问打通
5.1 反向代理该配哪些项
网关层一般用 Nginx 或者 Caddy 做反向代理,把 Web UI 和 API 统一到一个端口。配置时有几个关键项:proxy_read_timeout要调大,因为 Agent 多轮推理可能耗时几十秒甚至几分钟,默认的 60 秒会直接断开;proxy_buffering建议关掉,流式输出才能实时显示;请求体大小限制要放开,长上下文请求的 body 可能很大。
流式输出这块特别值得说。Agent 平台如果等全部推理完再返回,用户会以为卡死了。开启 SSE 或者 WebSocket 流式传输,让 token 一个个吐出来,体验完全不一样。Nginx 配流式要注意关掉缓冲,并且设置X-Accel-Buffering: no响应头。
5.2 鉴权与访问控制
局域网不等于安全区。内部人员误操作、设备被借用、访客网络接入,都可能带来风险。网关层至少要做两件事:一是 API Key 鉴权,每个使用者或每个应用分配独立的 key,方便追溯;二是访问频率限制,防止某个脚本疯狂调用把 GPU 打满。
如果团队规模不大,用 Nginx 的auth_request模块配合一个简单的鉴权服务就够了。规模大一点,可以考虑接入内部统一认证。但别搞太复杂,局域网部署的初衷就是轻量,为了鉴权引入一堆中间件反而本末倒置。
5.3 让同事能访问到的完整链路
从同事的浏览器到 Agent 平台,链路是这样的:浏览器访问http://内网IP:端口,请求到网关层,网关校验 key 后转发给 Agent 编排层,编排层调用推理服务,推理服务返回结果,原路返回。任何一环不通,表现都是"页面打不开"或者"一直转圈"。
排查时按链路顺序来:先在服务器上curl网关端口,通了再curlAgent 层端口,再curl推理服务端口。这样能快速定位是哪一层的问题。我遇到过网关配好了但 Agent 层容器没加入同一网络,导致网关找不到上游的情况,就是靠这个顺序排查出来的。
6. 实测中那些文档不会写的坑
6.1 模型加载慢导致的启动顺序问题
前面提过健康检查,但实际部署时还有个更隐蔽的问题:如果三层服务用编排工具同时启动,Agent 层可能在推理服务还没就绪时就尝试建立连接,然后进入一个错误的重试循环,即使推理服务后来就绪了,Agent 层也可能因为连接池状态异常而一直失败。解决办法是给 Agent 层加depends_on配合健康检查条件,或者干脆在 Agent 启动脚本里写一个显式的等待循环。
6.2 中文编码与特殊字符
DeepSeek 中文能力强,但工具调用返回的结果里如果包含特殊字符,JSON 解析容易出问题。我踩过一次坑:某个工具返回的文本里有未转义的双引号,导致 Agent 层解析 JSON 失败,整个对话中断。后来在工具返回处理里加了一层转义和校验,才稳定下来。如果你的工具会返回用户输入的内容,这个坑几乎一定会遇到。
6.3 并发下的显存碎片
单用户测试一切正常,多用户同时用就开始报显存不足。这往往不是显存真的不够,而是碎片化。推理服务长时间运行后,显存分配会产生碎片,导致明明有空间却分配不出来。缓解办法是限制单次请求的最大 batch size,并且定期重启推理服务(比如每天凌晨低峰期)。听起来笨,但很有效。
6.4 日志把磁盘写满
Agent 平台的日志量比想象中大得多。每轮对话、每次工具调用、每个请求响应,如果都记全量,一天几个 GB 很正常。磁盘写满后,容器会各种异常。部署时一定要配日志轮转,Docker 的--log-opt max-size和max-file参数就能搞定,别等出事了再补。
7. 性能调优与日常维护的实操建议
7.1 推理服务的批处理调优
推理服务通常支持连续批处理,把多个并发请求合并成一个 batch 一起算,能显著提升吞吐。但 batch 越大,单请求延迟越高。这个平衡点要根据实际使用模式调。如果团队是交互式使用,延迟敏感,batch 设小一点;如果是批量任务,吞吐优先,可以设大。
调这个参数没有万能值,我的做法是先设一个保守值,然后用压测工具模拟真实请求模式,观察吞吐和延迟曲线,找到拐点。一般 7B 模型在 24GB 卡上,batch 设 8 到 16 是比较舒服的区间。
7.2 监控指标该看哪些
日常维护不需要大而全的监控,盯住几个关键指标就够:GPU 利用率和显存占用、推理服务的请求队列长度、Agent 层的工具调用成功率、网关层的响应时间 P95。这几个指标能覆盖绝大多数问题。GPU 利用率长期偏低说明有瓶颈在别处;队列长度持续增长说明推理能力不足;工具调用成功率下降说明模型或工具配置出了问题。
7.3 模型和配置的版本管理
局域网平台一旦跑起来,会不断有人提需求:换个模型、加个工具、改改提示词。如果没有版本管理,改乱了很难回滚。我的建议是把所有配置文件纳入 Git 管理,每次变更记录原因和效果。模型权重文件虽然大,但至少记录清楚当前用的是哪个版本、什么量化精度。这样出问题时能快速定位是哪次变更引入的。
7.4 定期做一次冷启动演练
平台跑久了,容易形成"只有某个人知道怎么重启"的局面。定期做一次完整的冷启动演练——从停掉所有容器开始,按文档一步步启动,验证全链路可用。这个过程能暴露很多隐藏问题,比如某个环境变量只在当前运行的容器里有、某个挂载目录的权限配置没写进文档。演练一次,比看十遍配置都管用。
8. 关于这套方案后续能怎么长
这套三层架构的好处是扩展路径清晰。想加知识库,在 Agent 层挂一个向量检索工具就行,推理层不用动。想支持多模型,推理层多起几个容器,Agent 层按任务类型路由。想对外开放,网关层加一层 API 网关做限流和计费。每一步都是增量,不用推倒重来。
我在实际维护中最大的体会是:局域网 AI Agent 平台的价值不在于模型多强,而在于它能不能稳定地融入团队的日常工作流。一个偶尔抽风、需要专人伺候的平台,哪怕模型再先进,大家也会慢慢弃用。反过来,一个能力中等但从不掉链子的平台,会成为团队离不开的基础设施。所以部署完之后,把精力花在稳定性、可观测性和文档上,比追新模型更划算。
最后分享一个小技巧:给平台加一个"反馈"按钮,让使用者能一键标记某次回答的好坏。这些反馈数据积累起来,是后续调优提示词和工具配置最真实的依据,比拍脑袋改配置靠谱得多。