资讯详情

资讯详情

Docker 部署本地 AI Agent 平台:局域网内数据不出内网的实践指南

1. 为什么要在局域网里自建 AI Agent 平台1.1 从“调用云端 API”到“把模型搬进机房”的转变过去一年我身边不少做企业内部工具的朋友都经历了同一个心路历程一开始图省事直接调云端大模型的 API几行代码就能跑通一个问答机器人演示效果也漂亮。但真到了要落地到业务场景里问题就一个接一个冒出来——数据不能出内网、调用量一大成本失控、网络抖动导致响应不稳定、敏感业务文档不敢往上传。尤其是做内部知识库、工单辅助、代码审查这类场景数据合规这条线一卡云端方案基本就废了。于是“把模型部署到自己的局域网里”成了很多团队的刚需。而 Docker 这套容器化方案恰好把部署这件事的门槛拉到了普通人也能上手的程度。你不需要懂 CUDA 编译、不需要手动配 Python 环境、不需要跟各种依赖冲突搏斗一条docker compose up -d就能把一个完整的 AI Agent 平台拉起来。这就是我今天想聊的核心用 Docker 部署一套本地化的 AI Agent 平台让局域网内的所有设备都能访问数据全程不出内网。这里说的“AI Agent 平台”不是单纯跑一个聊天模型而是包含模型推理服务、Agent 编排逻辑、工具调用能力、会话管理的一整套东西。你可以把它理解成一个“局域网版的小型 AI 中台”前端同事的网页、后端同事的服务、甚至运维的脚本都能通过一个统一的接口去调用它。1.2 这套方案到底解决了谁的痛点先明确一下适用人群免得你看到一半发现不是自己需要的中小企业内部工具开发者公司没有专门的 AI 基础设施团队但业务上确实需要 AI 能力希望用最低成本搭一套自己能维护的平台。对数据合规有硬要求的团队处理的是合同、病历、财务、内部代码这类不能外传的数据云端 API 直接排除。想学习和折腾 AI Agent 的技术爱好者想搞清楚 Agent 到底是怎么编排的、工具调用是怎么实现的自己搭一套比看文档理解得深十倍。有闲置 GPU 或高性能 CPU 机器的团队机器闲着也是闲着跑个本地模型服务内部随便用。反过来说如果你只是偶尔问几个通用问题、对数据合规没要求、也不想维护任何服务那直接用现成的云端产品更省事没必要折腾这套。自建的核心价值在于“数据主权”和“可控成本”而不是“效果一定比云端好”——这一点得先摆正预期。1.3 整体架构长什么样在动手之前先把整个平台的骨架讲清楚不然一会儿看到一堆容器名容易懵。我这套方案的核心思路是“分层解耦”每一层各司其职坏了一层不影响其他层层级作用典型组件模型推理层真正跑大模型、输出 token本地推理服务容器Agent 编排层处理对话逻辑、工具调用、上下文管理Agent 服务容器接入层统一 API 网关、鉴权、限流反向代理容器存储层会话历史、向量数据、配置持久化数据库容器 挂载卷管理界面网页端对话、调试、监控前端容器这么分层的好处是模型想换就换Agent 逻辑想改就改前端想重做就重做彼此之间通过标准 HTTP 接口通信。最忌讳的就是把所有东西塞进一个容器里那样一旦某个环节出问题排查起来就是一团乱麻而且没法单独升级。2. 部署前的环境准备与关键决策2.1 硬件选型别被“必须上 GPU”吓到很多人一听本地部署大模型第一反应是“我没显卡搞不了”。实际情况要分场景看纯 CPU 推理7B 到 14B 级别的量化模型在 16 核以上的服务器 CPU 上跑响应速度大概每秒几个到十几个 token做内部问答、文档摘要完全够用。缺点是并发一高就顶不住。单张消费级显卡24G 显存能比较舒服地跑 14B 到 32B 的量化模型响应速度能到每秒几十 token支持几个人同时用。多卡或专业卡适合 70B 以上模型或者高并发场景但成本和运维复杂度陡增一般团队用不上。我的建议是先用 CPU 或手头现有的卡把流程跑通确认业务真的需要再升级硬件。我见过太多团队一上来就买卡结果平台搭好了没人用纯属浪费。显存估算有个粗略公式模型参数量B× 量化位数 ÷ 8 ≈ 显存占用GB。比如 14B 模型用 4bit 量化大约需要 14×4÷8 7GB 显存再留 2-3GB 给上下文和框架开销10GB 显存就能跑起来。2.2 系统与 Docker 环境操作系统我推荐 Ubuntu 22.04 LTS 或者同级别的长期支持版本内核新、驱动兼容性好、社区资料多。Windows 上虽然也能用 Docker Desktop但涉及到 GPU 直通和网络配置时会多不少坑生产环境不建议。Docker 环境需要装三样东西# 安装 Docker Engine以 Ubuntu 为例 curl -fsSL https://get.docker.com | sh # 安装 Docker Compose 插件 sudo apt-get install docker-compose-plugin # 把当前用户加入 docker 组免 sudo sudo usermod -aG docker $USER # 执行完记得重新登录组权限才生效装完之后用docker run hello-world验证一下。如果要用 GPU还得装对应的容器运行时和驱动装完用docker run --rm --gpus all 基础镜像 nvidia-smi测试能否在容器里看到显卡。这一步千万别跳过我踩过的坑就是驱动版本和容器运行时版本对不上容器里死活看不到卡排查了大半天。2.3 网络规划局域网访问的核心既然是局域网平台网络规划必须提前想清楚。核心是三件事固定 IP跑服务的机器一定要设静态 IP或者在路由器里做 DHCP 绑定。不然机器一重启 IP 变了所有客户端的配置全得改。端口规划给每个服务分配固定端口避免冲突。我习惯用 8000 段给 API、3000 段给前端、5432 给数据库一目了然。防火墙放行只放行局域网网段访问别图省事直接开公网。用ufw的话规则写成ufw allow from 192.168.1.0/24 to any port 8000这种形式精确到网段。提示如果你的局域网里有多个网段比如办公网和研发网分开记得在网关设备上配好路由否则跨网段访问会失败。这个坑我在一个客户现场遇到过服务明明起来了另一个网段的同事就是连不上最后发现是路由没配。2.4 存储与数据持久化容器最大的特点是“用完即弃”所以所有需要保留的数据都必须挂载到宿主机上否则容器一重建数据全没。需要持久化的东西包括模型文件动辄几个 G 到几十个 G重新下载太痛苦会话历史数据库向量库数据配置文件日志我习惯在宿主机上建一个统一的数据目录比如/data/ai-platform/下面按服务分子目录。然后在 compose 文件里用volumes把容器内路径映射出来。这样即使把容器全删了数据还在重建容器后挂载回去就能恢复。3. 核心服务的容器化拆解3.1 模型推理服务平台的“发动机”模型推理服务是整个平台最吃资源的部分也是配置最讲究的部分。我把它单独拎出来讲因为它的参数直接决定了平台能不能用、好不好用。推理服务容器一般会暴露一个兼容 OpenAI 格式的 HTTP 接口这样上层的 Agent 服务就能用统一的 SDK 去调用换模型的时候上层代码几乎不用改。启动参数里几个关键项模型路径指向挂载进来的模型文件目录。上下文长度决定了单次对话能塞多少内容。设太大吃显存设太小长文档处理不了。一般 8K 到 32K 是常见区间。并发数同时能处理多少个请求。CPU 推理建议设 1-2GPU 推理可以设 4-8具体看显存。量化方式4bit 量化省显存但精度略降8bit 平衡不量化最准但最吃资源。# compose 片段示意 model-service: image: 本地推理服务镜像 ports: - 8000:8000 volumes: - /data/ai-platform/models:/models command: --model /models/你的模型目录 --context-length 16384 --max-concurrent 4 deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu]注意模型文件建议提前用下载工具拉到本地再挂载别在容器启动时现下。几十 G 的文件下载中断一次前面的全白费而且容器启动会卡住很久看起来像“启动失败”。3.2 Agent 编排服务平台的“大脑”Agent 服务和模型服务是两回事。模型服务只负责“根据输入生成输出”而 Agent 服务负责的是“决定该不该调用工具、调用哪个工具、怎么把多轮结果拼起来”。这是整个平台最有技术含量的部分。一个典型的 Agent 服务要处理这些逻辑会话管理每个用户的每轮对话都要有独立的上下文不能串。工具注册与调用把内部 API、数据库查询、文件检索这些能力包装成“工具”让模型在需要时调用。提示词模板不同场景用不同的系统提示词比如客服场景和代码审查场景的提示词完全不同。结果后处理模型输出的原始文本要经过清洗、格式化才能返回给前端。agent-service: image: 本地 Agent 服务镜像 ports: - 8001:8001 environment: - MODEL_ENDPOINThttp://model-service:8000/v1 - DB_HOSTdb-service - DB_NAMEagent_platform volumes: - /data/ai-platform/agent-config:/app/config depends_on: - model-service - db-service这里有个关键点Agent 服务和模型服务之间用容器名互相访问比如http://model-service:8000而不是用 IP。Docker Compose 会自动创建一个内部网络容器名就是域名这样即使 IP 变了也不影响。这是容器编排相比手动部署的一大优势。3.3 数据库与向量存储平台的“记忆”会话历史、用户配置这些结构化数据用关系型数据库存就行PostgreSQL 是稳妥选择。而如果你要做知识库检索RAG还需要一个向量数据库来存文档的向量表示。向量库的选择上轻量场景用内置的向量扩展就够了不用单独起一个服务数据量大、检索要求高的场景再考虑独立的向量数据库容器。新手建议先用最简单的方案跑通别一上来就上重型组件否则光是调通各个组件之间的连接就够你喝一壶的。数据库容器一定要配好持久化卷和初始化脚本。初始化脚本负责建表、建索引、插入默认配置放在/docker-entrypoint-initdb.d/目录下容器首次启动时会自动执行。这样重建数据库时不用手动敲 SQL。3.4 反向代理与统一入口局域网里访问最好有一个统一的入口而不是让用户记一堆 IP 加端口。用反向代理容器做这件事好处有三统一域名用户只记一个地址比如http://ai.内网域名。路径分流/api转发到 Agent 服务/转发到前端用户无感知。基础防护可以加简单的访问控制、请求大小限制、超时设置。# 反向代理配置示意 server { listen 80; server_name ai.内网域名; location /api/ { proxy_pass http://agent-service:8001/; proxy_read_timeout 300s; } location / { proxy_pass http://frontend-service:3000/; } }提示proxy_read_timeout一定要调大默认 60 秒对于大模型生成来说太短了长回答还没生成完连接就被掐断了。我一般设 300 秒起步。4. 完整部署流程与实操记录4.1 目录结构与 compose 文件组织先把整个项目的目录结构规划好这是后续维护的基础ai-platform/ ├── docker-compose.yml ├── .env ├── configs/ │ ├── agent/ │ ├── nginx/ │ └── db-init/ ├── data/ │ ├── models/ │ ├── postgres/ │ └── vectors/ └── logs/.env文件用来放环境变量比如数据库密码、端口号、模型路径。千万别把密码硬编码在 compose 文件里一是容易泄露二是换环境时改起来麻烦。用.env文件compose 会自动读取。# .env 示例 POSTGRES_PASSWORD换成你自己的强密码 MODEL_PORT8000 AGENT_PORT8001 WEB_PORT804.2 分步启动与验证我强烈建议不要一次性把所有服务全拉起来而是分层启动、逐层验证。这样出问题时能快速定位是哪一层的问题。第一步先起数据库docker compose up -d db-service docker compose logs -f db-service # 看到 database system is ready to accept connections 就说明好了第二步起模型服务这一步最慢因为要加载模型docker compose up -d model-service docker compose logs -f model-service # 等到出现监听端口的日志然后用 curl 测一下模型服务是否正常curl http://localhost:8000/v1/models # 应该返回模型列表的 JSON第三步起 Agent 服务验证它能不能连上模型服务和数据库docker compose up -d agent-service curl -X POST http://localhost:8001/api/chat \ -H Content-Type: application/json \ -d {message: 你好, session_id: test-001}第四步起前端和反向代理最后从局域网另一台机器访问验证。4.3 局域网访问验证与性能实测服务全起来之后从局域网内另一台电脑访问http://跑服务机器的IP看能不能正常打开界面、正常对话。这一步验证的是网络配置如果打不开按这个顺序排查宿主机本地curl localhost通不通不通是服务问题。宿主机curl 本机IP通不通不通是服务监听地址问题可能只监听了 127.0.0.1。局域网其他机器ping 宿主机IP通不通不通是网络或防火墙问题。ping 通但端口连不上是防火墙端口没放行。性能方面我在一台 16 核 CPU、64G 内存、无显卡的机器上实测7B 量化模型单用户对话首 token 延迟约 1-2 秒生成速度约每秒 8-12 个 token。这个速度做内部问答够用但做实时对话会有点卡顿感。换成单张 24G 显卡跑 14B 量化模型后首 token 延迟降到 0.5 秒以内生成速度每秒 30 token体验就顺畅多了。配置模型规模首 token 延迟生成速度适用场景16核 CPU7B 量化1-2 秒8-12 token/s内部问答、文档摘要单张 24G 卡14B 量化0.5 秒30 token/s多人并发对话双卡32B 量化1 秒20-30 token/s复杂推理、代码辅助4.4 让平台真正“好用”的几个配置平台能跑起来只是第一步要让它好用还得做几件事配置模型预热模型服务启动后第一次请求会特别慢因为要加载权重到显存。可以在服务启动脚本里加一个预热请求让它启动完就自动跑一次用户第一次访问时就不用等。设置合理的超时和重试Agent 服务调用模型服务时超时要设够同时要有重试机制。网络抖动或者模型服务短暂卡顿时重试能避免用户看到报错。日志分级与轮转容器日志默认会一直堆积把磁盘撑爆。在 compose 里配置日志轮转logging: driver: json-file options: max-size: 50m max-file: 5健康检查给每个服务配 healthcheck这样 compose 能知道服务是不是真的健康而不是“容器在跑但服务挂了”。healthcheck: test: [CMD, curl, -f, http://localhost:8000/v1/models] interval: 30s timeout: 10s retries: 3 start_period: 120sstart_period对模型服务特别重要因为加载模型可能要一两分钟这段时间内健康检查失败是正常的不能算服务挂了。5. 常见问题排查与避坑经验5.1 容器起不来先看这三处容器启动失败是最常见的问题排查顺序我总结成一张表现象可能原因排查方法容器秒退启动命令错误、配置语法错docker compose logs 服务名看报错一直重启依赖服务没起来、健康检查失败看依赖服务日志检查 healthcheck 配置端口占用宿主机端口被其他程序占了ss -tlnp | grep 端口号查占用权限拒绝挂载目录权限不对检查宿主机目录的属主和权限我踩过最坑的一次是挂载目录权限问题容器里的服务以非 root 用户运行但挂载出来的宿主机目录属主是 root导致服务没权限写日志容器起来就退。解决办法是提前把宿主机目录的属主改成容器内运行用户的 UID或者在 compose 里指定user参数。5.2 模型加载慢或加载失败模型加载失败通常有几个原因模型文件不完整下载中断、模型格式和推理框架不匹配、显存不够。显存不够是最隐蔽的因为容器不会直接报“显存不足”而是加载到一半崩掉日志里可能只有一句含糊的错误。排查方法先在宿主机上用nvidia-smi看显存占用确认没有其他程序占着然后看模型服务日志里加载到哪一步崩的。如果是显存问题换更小的量化版本或者减小上下文长度。5.3 局域网能 ping 通但访问不了这个问题我遇到过好几次基本都是防火墙或监听地址的问题。分两种情况服务只监听了 127.0.0.1容器内服务默认可能只监听本地回环需要在启动参数里指定监听0.0.0.0。这个在容器里尤其要注意因为容器有自己的网络命名空间。宿主机防火墙拦截ufw status看一下规则确认局域网网段被放行。还有一种情况是 Docker 的网络模式用了host之外的模式端口映射写错了。检查 compose 里的ports配置格式是宿主机端口:容器端口别写反了。5.4 对话响应慢或中途断开响应慢的原因可能是模型太大、并发太高、或者上下文太长。中途断开多半是超时设置太短。我的经验是反向代理的proxy_read_timeout设 300 秒以上。Agent 服务调用模型服务的客户端超时也设 300 秒。如果用了流式输出确认每一层都支持流式转发中间任何一层做了缓冲都会导致“看起来卡住”。提示流式输出SSE在反向代理层特别容易出问题因为默认会缓冲响应。Nginx 里要加proxy_buffering off;和proxy_cache off;否则用户会看到回答“憋”很久然后一次性蹦出来体验很差。5.5 数据丢失与备份容器化部署最大的风险就是数据丢失。我见过有人docker compose down -v一把梭把数据卷全删了几个月的会话记录瞬间蒸发。记住-v参数会删除数据卷除非你确定不要数据了否则永远别加这个参数。备份策略上数据库用定时pg_dump导出到宿主机另一个目录模型文件本身不用备份重新下载即可配置文件纳入版本管理。这样即使整台机器挂了换台机器把数据恢复回去半小时就能重新跑起来。6. 平台上线后的扩展方向6.1 接入内部知识库做 RAG平台跑通之后最有价值的扩展就是接入内部知识库。做法是把内部文档切块、向量化、存进向量库用户提问时先检索相关片段再把片段作为上下文喂给模型。这样模型就能回答“我们公司的报销流程是什么”这类只有内部资料才有的问题。关键点在于文档切块策略切太大检索不准切太小上下文不完整。一般按语义段落切每块 300-500 字块之间留一点重叠。这个参数没有标准答案得根据你的文档类型实测调整。6.2 多模型路由与降级平台稳定运行后可以接入多个模型按任务类型路由简单问答用小模型省资源复杂推理用大模型保质量。同时配置降级策略大模型服务挂了自动切到小模型保证平台始终可用。6.3 用量统计与成本核算虽然是本地部署没有 API 费用但电费、硬件折旧也是成本。可以在 Agent 服务里记录每次请求的 token 数、耗时、用户定期统计。这样能看清楚平台到底被谁在用、用在什么地方为后续扩容提供依据。我在实际维护这套平台的过程中最大的体会是部署只是开始运维才是长期工作。一开始追求“功能全”什么组件都想上结果维护成本高得吓人。后来做减法只保留真正被用到的功能平台反而更稳定。如果你也打算搭一套我的建议是先跑通最小可用版本让业务先用起来再根据真实反馈逐步加功能别一上来就追求大而全。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →