资讯动态

Docker 部署 DeepSeek Harness:局域网 AI Agent 平台实战

发布时间:2026/10/13 7:32:55 来源:尧图企业网站定制
1. 为什么要在局域网里自建 AI Agent 平台1.1 从“调用云端 API”到“把模型搬进机房”的转变过去一年我身边不少做企业内部工具的朋友都遇到同一个尴尬业务部门想用大模型做知识问答、文档摘要、工单分类但数据不能出内网采购流程又走不通。于是“局域网里跑一个能对话、能调工具、能接内部系统的 AI Agent 平台”就成了刚需。DeepSeek 系列模型因为推理能力强、中文表现好、开源权重可本地部署成了很多团队的首选底座。而 Harness 这类 Agent 编排框架负责把模型、工具、记忆、工作流串起来让模型不只是“聊天”而是能真正执行任务。标题里的“Docker 部署 DeepSeek Harness”本质上就是解决三件事第一把模型推理服务容器化避免环境依赖地狱第二把 Agent 编排层也容器化让工具调用、会话管理、接口暴露都在同一套编排里第三让整个平台只监听局域网地址外部访问不了内部同事却能通过浏览器或内部系统直接调用。这套方案适合谁适合有基本 Linux 和 Docker 基础、手里有一台带显卡的服务器或工作站、想快速验证 AI Agent 落地场景的开发和运维同学。哪怕你之前只跑过单机版模型这篇文章里的步骤也能让你把整套平台搭起来。1.2 局域网部署的真实价值不只是“安全”很多人第一反应是“局域网等于安全”但实际用下来局域网部署的价值远不止于此。首先是延迟可控模型推理不走公网首 token 延迟能稳定在几百毫秒级别做实时交互式 Agent 时体验差别非常明显。其次是成本可预测不用按 token 计费一台机器跑满也就那点电费适合高频调用的内部场景。第三是可定制你可以把内部数据库、工单系统、代码仓库都封装成工具接进去模型能直接查数据、改状态这是云端 API 很难做到的。第四是数据闭环所有对话记录、工具调用日志都留在本地后续做微调或评测时这些就是最真实的语料。但局域网部署也有它的坑显卡驱动和 CUDA 版本不匹配、Docker 权限配置不当导致容器看不到 GPU、模型权重下载慢、Agent 框架的端口暴露太随意导致内部误访问。这些问题我在不同项目里都踩过后面会逐个拆解。先给一个整体判断如果你只是想让几个人试用单卡 24G 显存的机器跑 7B 或 14B 量化模型就够如果要多人并发或跑更大模型建议 48G 以上显存并且把推理服务和 Agent 编排分开部署避免互相抢资源。2. 整体架构设计与选型思路2.1 三层结构推理层、编排层、接入层这套平台我习惯拆成三层。最底下是推理层负责加载 DeepSeek 模型权重对外暴露一个兼容 OpenAI 接口规范的 HTTP 服务。中间是编排层也就是 Harness 所在的位置它负责管理会话、解析用户意图、决定调用哪个工具、把工具结果拼回上下文再交给模型。最上面是接入层可以是一个简单的 Web 聊天界面也可以是内部系统通过 REST 调用的入口。三层都用 Docker 管理但网络模式要仔细设计推理层和编排层放在同一个自定义 bridge 网络里互相用容器名通信接入层只暴露编排层的端口到局域网推理层端口不对外。为什么这么分因为推理层最重、最吃资源升级模型或换量化版本时不应该影响编排逻辑编排层变化最频繁改工具、改提示词、改工作流时不应该重启模型。分开之后你可以单独重启某一层调试效率高很多。另外推理层用 vLLM 或类似的高吞吐推理框架编排层用 Python 写的 Agent 框架两者通过 HTTP 通信解耦得很干净。2.2 为什么选 Docker 而不是裸机部署裸机部署不是不行但依赖冲突会让你怀疑人生。比如推理框架要求特定版本的 CUDA 运行时Agent 框架又依赖另一个版本的 Python 库系统里还跑着别的服务升级一个包可能把另一个搞崩。Docker 的价值在于把每个服务的依赖封在镜像里宿主机只需要装好显卡驱动和 Docker 引擎剩下的都在容器里解决。而且 Docker Compose 能把多个容器的启动顺序、网络、卷挂载写在一个文件里换机器时复制过去就能重建这对内部工具来说太重要了。还有一个容易被忽略的点资源限制。Docker 可以给每个容器限制 CPU、内存、甚至 GPU 数量。推理容器可以独占显卡编排容器只分几个 CPU 核这样即使编排层出问题也不会把推理服务拖垮。裸机部署时一个进程内存泄漏可能把整台机器搞挂容器化之后至少有个隔离边界。2.3 网络与端口规划只让该看见的人看见局域网部署最怕的就是“不小心暴露到公网”。我的做法是Docker Compose 里所有服务默认不映射端口到宿主机只在需要对外的那一个服务上写ports并且绑定到内网 IP比如192.168.1.50:8080:8080而不是0.0.0.0:8080:8080。这样即使宿主机有公网 IP外部也访问不到。推理层完全不映射端口只在内部网络里被编排层访问。如果内部还有防火墙或 VLAN 划分再把编排层的端口限制在特定网段。端口规划上我一般这样分配推理服务内部用 8000编排服务内部用 8080Web 界面用 3000。对外只暴露 8080 和 3000而且这两个端口都绑定内网 IP。数据库或向量库如果要用也放在内部网络不映射端口。这样一套下来从局域网外部看这台机器就像没开任何服务一样。3. 环境准备与基础依赖安装3.1 硬件与系统的最低要求先说实话这套平台对硬件有门槛。推理层如果跑 DeepSeek 7B 的 4-bit 量化版本显存至少 8G但实际用起来建议 12G 以上因为上下文长度和并发会吃额外显存。14B 量化版本建议 16G 到 24G。如果要用 32B 或更大48G 起步。CPU 方面编排层和工具调用不需要太多核8 核够用但内存建议 32G 以上因为模型加载和向量检索都吃内存。硬盘至少留 100G 给模型权重和日志SSD 最好机械盘加载模型会慢到让你以为卡死了。系统我推荐 Ubuntu 22.04 LTS 或 24.04 LTS内核版本新一点对显卡驱动支持更好。如果是 CentOS 系注意 Docker 和 NVIDIA 容器工具包的安装方式略有不同。Windows 不是不能做但 WSL2 的 GPU 直通偶尔有坑生产环境还是建议 Linux。3.2 显卡驱动与容器工具包这一步是很多新手翻车的地方。顺序很重要先装显卡驱动再装 Docker最后装 NVIDIA Container Toolkit。驱动版本要和你打算用的 CUDA 版本匹配比如推理框架要求 CUDA 12.1那驱动版本至少要 530 以上。装完驱动后用nvidia-smi确认能看到显卡和显存。然后装 Docker Engine注意不要用系统自带的旧版本按官方文档添加软件源安装。NVIDIA Container Toolkit 是让 Docker 容器能访问 GPU 的关键。装完之后要配置 Docker 的默认运行时或者至少在docker run时加--gpus all。我习惯在/etc/docker/daemon.json里加上default-runtime: nvidia这样所有容器默认都能看到 GPU省得每次写参数。改完重启 Docker 服务然后跑一个测试容器验证docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi如果能看到显卡信息说明容器 GPU 直通没问题。看不到就检查驱动版本、Docker 版本、Toolkit 版本三者是否兼容。3.3 目录规划与权限设置我习惯在宿主机上建一个统一目录比如/opt/ai-platform下面分models、data、logs、config四个子目录。models放模型权重data放向量库和会话数据logs放各容器日志config放 Compose 文件和配置文件。这样备份和迁移时直接打包整个目录就行。权限方面Docker 容器里跑的服务通常用非 root 用户但挂载的宿主机目录如果权限不对容器里写不进去。我的做法是创建一个专用用户组把宿主机目录的属组设成这个组容器里也用同一个 GID 的用户运行。或者简单点把目录权限设成 755容器里用 root 跑但这样安全性差一些。内部工具的话我倾向于前者多花十分钟配权限后面省很多事。4. 推理层部署让 DeepSeek 在容器里跑起来4.1 模型权重获取与量化版本选择DeepSeek 的模型权重可以从公开的模型仓库获取但局域网环境往往下载慢。我的做法是先在能访问外网的机器上下载好再用移动硬盘或内部文件服务传到目标机器。下载时注意选对版本如果显存紧张选 4-bit 或 8-bit 量化版本如果显存充足且追求效果选 FP16 或 BF16 原版。量化版本的文件通常小很多7B 的 4-bit 大概 4G 左右14B 的 4-bit 大概 8G 到 9G。选量化版本时有个经验不要只看显存占用还要看推理框架是否支持这种量化格式。比如有些框架对 GPTQ 支持好有些对 AWQ 支持好选错了可能加载失败或速度很慢。我一般优先选推理框架官方推荐的量化格式这样兼容性最有保障。另外模型目录里通常有config.json、tokenizer.json等文件要确保全部下载完整缺一个文件都可能导致加载报错。4.2 推理容器镜像与启动参数推理层我一般用现成的高吞吐推理镜像比如 vLLM 的官方镜像或者自己基于 CUDA 基础镜像构建。用现成镜像的好处是省去编译时间坏处是版本可能不是最新的。自己构建的话Dockerfile 里要写清楚基础镜像、Python 版本、推理框架版本、依赖库构建一次大概十几分钟。启动参数是重点。以 vLLM 为例关键参数包括--model指定模型路径--tensor-parallel-size指定用几张卡--gpu-memory-utilization指定显存占用比例--max-model-len指定最大上下文长度。显存占用比例我一般设 0.9留一点给系统。最大上下文长度要根据模型支持的范围和显存来定设太大容易 OOM设太小又不够用。7B 模型在 24G 显存上上下文设 8192 通常没问题设 16384 就要看并发量了。docker run -d --name deepseek-infer \ --gpus all \ --network ai-net \ -v /opt/ai-platform/models:/models \ -v /opt/ai-platform/logs:/logs \ vllm/vllm-openai:latest \ --model /models/deepseek-7b-awq \ --quantization awq \ --gpu-memory-utilization 0.9 \ --max-model-len 8192 \ --port 8000启动后看日志出现Uvicorn running on http://0.0.0.0:8000就说明服务起来了。然后用curl在内部网络里测试一下docker exec -it deepseek-infer curl http://localhost:8000/v1/models能返回模型列表就说明推理层正常。4.3 显存不足时的降级策略显存不足是常见问题。如果启动时报 OOM有几个降级方向第一换更小的量化版本比如从 8-bit 换到 4-bit第二降低--gpu-memory-utilization比如从 0.9 降到 0.8第三减小--max-model-len比如从 8192 降到 4096第四减少并发通过--max-num-seqs限制同时处理的请求数。这几个参数要配合调不能只改一个。我遇到过一种情况模型能加载但一有请求就 OOM。后来发现是--max-model-len设太大KV Cache 占满了显存。把上下文从 16384 降到 8192 后并发能力反而提升了因为每个请求占的显存少了。所以调参时要有取舍不是越大越好。5. 编排层部署Harness 与工具链集成5.1 Harness 框架的核心概念Harness 这类 Agent 编排框架核心概念通常包括 Agent、Tool、Memory、Workflow。Agent 是执行主体负责接收用户输入、决定下一步动作Tool 是 Agent 能调用的外部能力比如查数据库、发邮件、调内部 APIMemory 负责保存会话历史和长期记忆Workflow 把多个 Agent 或工具按顺序或条件串起来。理解这几个概念后配置起来就有章法了。部署 Harness 时最关键的是把推理层的地址配进去。因为推理层在同一个 Docker 网络里所以地址可以直接写容器名加端口比如http://deepseek-infer:8000/v1。这样即使推理容器重启换了 IP编排层也不用改配置Docker 的内部 DNS 会解析容器名。5.2 工具注册与权限控制工具是 Agent 平台的价值所在。我一般先接三类工具内部知识库检索、工单系统查询、代码仓库搜索。知识库检索用向量数据库把内部文档切片、向量化后存进去Agent 收到问题先检索再回答。工单系统查询通过内部 APIAgent 可以根据工单号拉取详情。代码仓库搜索通过 Git 服务的 APIAgent 可以查某个函数的实现。权限控制容易被忽略。不是所有 Agent 都能调用所有工具比如查询工单的工具应该只对客服类 Agent 开放代码搜索工具只对研发类 Agent 开放。Harness 通常支持按 Agent 配置工具白名单部署时要仔细设置。另外工具调用日志要单独记录方便审计和排查。5.3 会话管理与上下文长度控制会话管理直接影响用户体验。Harness 一般会把会话历史存在数据库或内存里每次请求时把最近几轮对话拼进上下文。但上下文长度有限不能无限拼。我的做法是设置一个阈值比如最近 10 轮对话或 4000 token超过就做摘要压缩把早期对话总结成一段简短描述再拼进去。上下文控制还有个技巧工具调用的结果往往很长比如检索到 5 篇文档每篇 1000 字全拼进去上下文就爆了。我一般只取最相关的 2 到 3 篇每篇截取关键段落或者让模型先对检索结果做一次摘要再把摘要拼进上下文。这样既保留了信息又控制了长度。6. 接入层与局域网访问配置6.1 Web 界面与 API 双通道接入层我通常提供两个通道一个是 Web 聊天界面方便非技术同事直接使用另一个是 REST API方便内部系统集成。Web 界面可以用现成的开源项目也可以用 Harness 自带的界面。关键是这个界面要能配置后端地址指向编排层的服务。API 通道要设计好鉴权。局域网虽然外部访问不了但内部也可能有误操作或恶意调用。我一般用简单的 API Key 机制每个内部系统分配一个 KeyHarness 里配置 Key 到权限的映射。这样即使 Key 泄露也能快速禁用。6.2 端口绑定与防火墙规则前面提过端口要绑定内网 IP。具体做法是在 Compose 文件里写ports: - 192.168.1.50:8080:8080而不是8080:8080。这样 Docker 只会监听 192.168.1.50 这个地址其他网卡上的请求不会响应。如果宿主机有多个网卡要确认绑的是正确的那个。防火墙方面如果宿主机开了 ufw 或 firewalld要放行内部网段到 8080 和 3000 的流量同时拒绝其他来源。比如 ufw 可以这样配ufw allow from 192.168.1.0/24 to any port 8080 ufw allow from 192.168.1.0/24 to any port 3000 ufw deny 8080 ufw deny 3000这样只有 192.168.1.0/24 网段能访问其他都拒绝。6.3 内部域名与反向代理如果内部有 DNS 服务可以给这台机器配一个内部域名比如ai-platform.internal这样同事不用记 IP。反向代理可以用 Nginx 或 Caddy把 80 端口的请求转发到 8080 和 3000。Caddy 配置更简单自动处理 HTTPS 证书如果内部有 CA 的话。反向代理还有个好处可以统一加访问日志和限流。比如限制每个 IP 每分钟最多 60 个请求防止有人写脚本刷接口。Nginx 的limit_req模块就能做配置几行就行。7. 常见问题与排查技巧实录7.1 容器启动失败与日志排查容器启动失败时第一步永远是看日志docker logs --tail 100 deepseek-infer常见错误包括模型路径写错、量化格式不支持、显存不足、端口被占用。模型路径错误会报FileNotFoundError量化格式不支持会报ValueError: Unknown quantization method显存不足会报CUDA out of memory端口占用会报Address already in use。根据错误信息对症下药。如果日志里没有明显错误但容器就是起不来检查docker ps -a看退出码。退出码 137 通常是 OOM 被系统杀掉退出码 1 是程序自身错误。还可以用docker inspect看容器的详细状态和挂载情况。7.2 GPU 不可见与驱动兼容问题容器里nvidia-smi报command not found或No devices found说明 GPU 直通没配好。检查顺序宿主机nvidia-smi是否正常Docker 是否装了 NVIDIA Container Toolkitdaemon.json里默认运行时是否配了 nvidia启动容器时是否加了--gpus all。这四个环节任何一个出问题都会导致 GPU 不可见。驱动兼容问题更隐蔽。有时候宿主机驱动版本和容器内 CUDA 版本不匹配容器能启动但一跑推理就报错。解决办法是查推理框架要求的 CUDA 版本然后确认宿主机驱动支持这个版本。NVIDIA 的兼容性表可以查到驱动版本和 CUDA 版本的对应关系。7.3 推理速度慢与并发瓶颈推理速度慢可能有好几个原因。第一模型量化格式不适合当前硬件比如在支持 FP8 的卡上跑了 GPTQ速度会打折。第二--max-num-seqs设太小请求排队。第三上下文太长KV Cache 占用大每次生成都要重新计算。第四CPU 到 GPU 的数据传输瓶颈比如输入文本特别长时tokenize 和传输时间占比高。排查时先用nvidia-smi看 GPU 利用率如果利用率低但请求排队说明是并发限制或 CPU 瓶颈如果利用率高但速度还是慢说明是模型本身或显存带宽限制。针对性地调参或换量化格式。7.4 常见问题速查表问题现象可能原因排查方法解决方向容器启动即退出模型路径错误看日志 FileNotFoundError检查挂载路径和模型文件名启动报 OOM显存不足看日志 CUDA out of memory换量化版本或降上下文长度GPU 不可见Toolkit 未配容器内 nvidia-smi检查 daemon.json 和启动参数推理速度慢并发限制看 GPU 利用率和队列调 max-num-seqs 或换量化端口访问不了绑定地址错误宿主机 netstat 看监听改 ports 绑定内网 IP工具调用失败网络不通容器内 curl 工具地址检查 Docker 网络和防火墙8. 实操心得与后续扩展方向8.1 我踩过的三个坑第一个坑是模型权重权限。下载的模型文件属主是 root容器里用非 root 用户跑读不了文件。后来把模型目录权限改成 755问题解决。第二个坑是 Docker 网络。一开始用默认 bridge 网络容器间只能用 IP 通信重启后 IP 变了配置就失效。后来建了自定义网络用容器名通信稳定多了。第三个坑是日志占满磁盘。推理容器日志默认写到文件跑几天就几十 G。后来配了日志轮转限制单个文件大小和保留数量。8.2 性能调优的几个实用参数除了前面提的显存和上下文参数还有几个值得调。--enable-prefix-caching可以缓存相同前缀的 KV多轮对话时提速明显。--swap-space设大一点可以在显存不足时用内存交换但速度会降。--disable-log-requests关掉请求日志减少 IO 开销。这些参数要根据实际负载试没有万能配置。8.3 后续可以接什么平台搭起来后可以逐步扩展。第一接更多工具比如日历、邮件、内部审批流。第二加评测模块定期用测试集跑一遍看模型回答质量有没有下降。第三做多模型路由简单问题用小模型复杂问题用大模型省资源。第四加用户反馈机制把点赞点踩的数据收集起来后续做微调。这些扩展都不需要改架构在编排层加模块就行。8.4 一个容易被忽略的细节时区与日志时间容器默认时区是 UTC日志时间比北京时间晚 8 小时排查问题时容易看错。启动容器时加-e TZAsia/Shanghai或者在 Compose 文件里配environment: TZ: Asia/Shanghai。这样日志时间和本地一致省得换算。这个细节很小但实际排查时能省不少事。8.5 备份与迁移的简单方案整套平台的数据主要在models、data、config三个目录。定期把这三个目录打包传到内部备份服务器就行。迁移时在新机器上装好驱动和 Docker把目录复制过去改一下 Compose 文件里的 IP 绑定重新docker compose up -d就能恢复。模型权重不用重复下载省时间。我一般每周备份一次模型更新后立即备份一次。8.6 安全加固的几点建议局域网不等于绝对安全内部也可能有误操作。建议做几件事第一API Key 定期轮换第二工具调用加审计日志记录谁在什么时候调了什么第三限制单用户请求频率防止刷接口第四定期更新推理框架和编排框架的镜像修补已知问题第五如果内部有安全扫描工具把平台加进去定期扫。这些措施不复杂但能挡住大部分内部风险。8.7 关于模型选择的个人体会我用下来7B 量化版本适合做知识问答和简单工具调用14B 在复杂推理和长文档处理上明显更好32B 以上适合对质量要求高的场景。但模型越大部署成本和延迟越高。我的建议是先用 7B 跑通流程验证场景有价值后再升级。不要一上来就追求最大模型容易在环境配置上耗太久失去耐心。先跑起来再优化这是内部工具落地最实际的路径。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑