这阵子总有朋友问我同一个问题团队想用AI Agent提效但数据不能出内网、账号没法统一管、公网接口还时不时卡一下怎么办。老实说去年我自己也被这事折腾得不轻一直想找个能在局域网里自托管的方案。直到我把Docker部署DeepSeek Harness整套跑通才发现这事儿比想象中简单得多。DeepSeek Harness是一个把DeepSeek模型和Agent运行时环境打包好的容器化部署方案不需要公网不依赖外部API一张docker-compose文件就能拉起一整套能对话、能调用工具、能规划任务的AI Agent平台。这篇文章就把我的完整搭建过程、架构思路、参数调优和踩坑记录都摊开来讲适合团队内部想做私有化Agent服务的运维、后端也适合想在本地捣鼓一个可用的AI助手平台的开发者参考。1. 整体设计与部署思路拆解1.1 这个平台到底解决了什么问题在没有自建平台之前团队项目里想用大模型能力通常只有两条路一条是直接调云端API把业务数据发出去很多内部系统根本不允许另一条是在本地装一套完整的推理框架再加一套Agent编排系统光是环境依赖就能折腾好几个通宵。DeepSeek Harness的存在就是要把这条路走通它把模型推理服务、Agent运行环境、工具调用能力全部塞进容器镜像里你只需要准备一台有足够显存或内存的机器装好Docker就能得到一个局域网内可访问的AI Agent服务。它的价值不在于单一功能多强而在于把模型私有化部署和Agent能力落地两件事合并成了一件。部署完之后团队里的成员可以直接通过Web界面聊天也可以通过API把Agent能力接入已有系统比如让Agent去查数据库、读内部文档、调用定时任务。整个过程数据不出内网响应速度比走公网快得多而且离线也能用。1.2 核心组件与架构思路搞清楚架构再动手比直接敲命令重要得多。DeepSeek Harness从逻辑上分成三层模型服务层负责加载DeepSeek模型权重提供标准的API接口。这一层解决的是模型能不能跑起来的问题需要关注显存占用、并发能力、上下文长度这些参数。Agent编排层接收用户请求和大模型交互通过Function Calling机制决定要不要调用工具、调用哪个工具、如何根据工具返回结果继续生成回答。这一层决定的是模型好不好用的问题。工具与接入层把业务能力注册成Agent可以调用的工具比如搜索、计算、数据库查询、文档检索同时提供Web界面和API让团队接入。分层带来的好处非常直接模型可以单独换Agent逻辑可以单独改工具可以单独加。最开始我只在机器上跑了7B参数量的量化模型后来换了更大的模型只是改了一个环境变量Agent编排层和工具层完全不用动。这一点在容器化场景下尤其舒服因为每一层的依赖都被隔离在自己的容器里不会互相污染。1.3 为什么是Docker加大模型这套组合我自己最初也纠结过为什么不直接在裸机装一套算了。实际对比之后发现Docker带来的好处是碾压性的。模型的运行环境非常挑剔依赖的Python版本、推理框架、CUDA版本稍微对不上就起不来。用Docker等于把整套环境快照固化下来拿到任何一台装了Docker的机器上跑起来的结果完全一致。团队里换人接手、从测试机迁移到正式服务器都只是一条命令的事情。另一个关键原因是回滚方便。大模型推理上游依赖经常有更新有些更新看起来小但会让Agent行为产生很大变化。用Docker镜像打版本标签比如每次升级前把当前镜像打个快照出问题直接回退到上一个镜像5秒钟搞定。这种安全网在裸机部署时代是想都不敢想的。2. 部署前的资源评估与环境准备2.1 硬件需求选型指南部署之前先要对显存、内存有一个基本判断否则镜像一启动就被系统杀掉排查起来很崩溃。以DeepSeek系列模型为例量化后的模型权重大小大约为参数量乘以每参数字节数INT4量化大约每参数0.5字节加上KV Cache、激活值、推理框架开销实际占用大概是模型权重的1.3到1.5倍。模型规模量化精度推荐显存推荐内存适合场景7B级INT48GB16GB轻量对话、并发不高的内部工具14B级INT412GB24GB日常Agent任务、简单工具调用32B级INT424GB48GB复杂推理、多工具协同、长上下文如果机器没有独立显卡纯CPU跑也不是不行但推理速度会慢很多。我实测过一次7B量化模型在纯CPU环境下单次短回答大概要十几秒到半分钟做个演示或者内部低频率使用可以接受想当正经服务用建议还是准备一张显存够用的显卡。选型的原则很简单先想清楚并发量再反推硬件。内部团队几个人用7B或14B完全够不需要盲目上大模型。2.2 Docker环境与GPU支持配置接下来是Docker环境的准备。Linux服务器上安装Docker后别急着拉镜像先确认两件事一是docker compose插件是否可用二是GPU透传是否配置好。检查Docker Composedocker compose version如果提示没有这个命令需要单独安装docker-compose-plugin。DeepSeek Harness的编排文件用到了compose规范的常用语法没有插件就跑不起来。再检查GPU支持。要让容器里的大模型用到显卡必须装NVIDIA Container Toolkit。装完之后用一条命令验证docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi能正常输出显卡信息说明容器里已经可以访问GPU。这一步踩坑的人很多最典型的现象是镜像启动时报CUDA不可用或者driver not found但宿主机上nvidia-smi明明正常。根本原因大多是宿主机显卡驱动版本和容器内的CUDA镜像不匹配或者缺失了Container Toolkit这个桥接层。通用做法是保持宿主机驱动处于较新版本这样对新镜像的兼容性最好然后再用--gpus all做一次冒烟测试。2.3 镜像与版本选择的策略镜像选择上DeepSeek Harness的编排文件通常会指定一个组合模型服务镜像加Agent编排镜像。我的建议是优先选带明确版本标签的镜像不要追latest。追latest的代价是某天docker compose down docker compose pull之后整个平台莫名其妙出问题但镜像没变看日志也看不出所以然实际上就是你悄悄升了一个大版本。拉取镜像时如果比较慢可以给Docker配置镜像加速器。具体地址根据所在网络环境选一个支持的即可配置后重启Docker daemon生效。另外建议把镜像固定采用平台镜像加版本号的写法比如harness-api:0.3.4。这样既保证可复现也便于以后统一升级。3. 局域网AI Agent平台的完整部署实操3.1 目录编排与配置文件骨架动手之前先规划一个干净的目录结构。我习惯把配置和数据分开这样升级容器不会误伤数据/opt/harness/ ├── docker-compose.yml ├── config/ │ ├── models.json │ └── agents/ │ ├── console-agent.yaml │ └── researcher-agent.yaml ├── data/ │ ├── key-store/ │ └── logs/模型密钥、工具令牌这类敏感信息我倾向于放在独立的key-store目录中通过环境变量引用不直接写进docker-compose文件。这样即使把compose文件发给同事参考也不会泄露任何凭据。日志单独挂出来也很值得排查问题的时候不用进容器翻文件直接在宿主机用tail就能看。3.2 docker-compose配置逐行拆解下面这份是我现在还在用的精简版compose配置可以直接当作起点services: api-server: image: harness-api:0.3.4 ports: - 8000:8000 volumes: - ./config/agents:/app/agents:ro - ./data/logs:/app/logs environment: MODEL_ID: deepseek-r1:7b-q4 CONTEXT_WINDOW: 8192 MAX_CONCURRENT_REQUESTS: 2 TOOL_WHITELIST: web_search,calculator,db_query deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] healthcheck: test: [CMD, curl, -f, http://localhost:8000/health] interval: 30s timeout: 10s retries: 3 web-ui: image: harness-web:0.2.1 ports: - 8080:80 environment: API_BASE_URL: http://api-server:8000 depends_on: - api-server逐个说明几个关键配置的思路。MODEL_ID决定加载哪个模型。这个变量看上去简单其实暗藏一个原则模型服务镜像通常会去固定的模型仓库目录拉取权重文件不同ID对应不同权重。第一次启动时容器会自动下载权重这个步骤很耗时7B量化模型大概要下载4GB到6GB。建议在网络条件好的时段做这个初始化或者提前把权重文件手动放到挂载出来的模型目录里。CONTEXT_WINDOW是上下文长度直接影响显存占用。每增加一倍上下文长度KV Cache的显存占用大致也翻倍。我平时内部用8K就够写长文档场景会开到16K但显存小的机器不建议盲目加大。MAX_CONCURRENT_REQUESTS控制并发请求数默认给2就比较保守。显存足够的情况下可以调到4但超过6以后收益不大反而会明显拉长每个请求的排队时间。TOOL_WHITELIST是Agent能使用的工具白名单。这一步是安全关键点。开局先把范围收紧只开放你明确需要的工具比如web_search、calculator、db_query后续再加。很多人刚开始图省事把全部工具都放进来结果Agent在某些场景下出乎意料地调用了不合适的工具排查起来很被动。deploy.resources.reservations.devices是GPU透传声明注意这段只有在安装了NVIDIA Container Toolkit的机器上才能生效。没有GPU的机器把整段删掉模型服务会退回CPU推理模式但速度要做好心理准备。healthcheck是我特别强调加上的一块。很多容器启动了很久表面看起来正常实际模型还没加载完这时候外部请求进来会一直超时。健康检查让容器在真正就绪之前不接收流量配合编排系统的重启策略基本不会出现挂在半启动状态的情况。3.3 启动、验证与Agent配置配置文件准备好后依次执行docker compose up -d docker compose logs -f api-server第一次启动的日志里你应该能看到权重加载进度。等日志里出现model loaded successfully之类的字样再验证一下接口curl -X POST http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: deepseek-r1:7b-q4, messages: [ {role: user, content: 用一句话介绍你自己} ] }能返回正常的JSON应答说明模型服务通了。下一步就是配置Agent。Agent配置本质上是定义一个人设加一组工具加一套执行策略。比如我在console-agent.yaml里定义了一个负责IT运维咨询的Agentname: console-agent system_prompt: | 你是内部运维助手。当用户询问日志、服务状态或命令操作时 你必须显式调用日志搜索工具或命令执行工具获取信息 不要凭记忆编造结论。信息不足时直接说明。 tools: - web_search - calculator - db_query max_iterations: 5系统提示词这段值得多写字。大模型的推理能力再强如果提示词没有把工具的调用规则说清楚它就会倾向于凭记忆回答。比如你问服务为什么挂了它可能直接列一堆泛泛的排查步骤而不去调用工具查真实日志。加上你必须显式调用工具获取信息这句话之后行为立刻变得可靠很多。max_iterations限制Agent最多执行多少轮思考-调用工具-观察结果的循环避免它在复杂任务里无限自旋白白烧显存和电费。配置好后进入Web界面新建会话并选择console-agent简单问一句查一下最近一小时的错误日志如果Agent正确调用了日志工具并给出真实数据就说明Agent链路完整跑通了。4. AI Agent平台的核心机制与理解要点4.1 从模型到AgentFunction Calling与规划循环搭建过程中如果你只停留在能跑通的层面后面调参会很难受。稍微理解一下Agent的运行机制很多问题自己就能判断原因。Agent和普通模型ChatBot最本质的区别在于它多了一个规划循环。当用户抛出一个复杂问题Agent不会直接一次性回答而是先经过一轮又一轮的思考、行动、观察。这个过程用大白话说就是模型先想一句嗯这个问题我需要查一下内部知识库然后生成一个结构化的工具调用请求系统执行工具拿到结果把结果反馈给模型模型再决定是继续查下一个信息还是给最终回答。Function Calling是实现这个循环的底层机制。模型在训练时学会了输出格式化的JSON片段表示我要调用某个函数。DeepSeek Harness把模型输出的这段JSON解析出来匹配到对应的工具实现执行后在下一轮输入时把结果拼回去。整个过程看起来像模型自己在找资料实际上是我们给它装了一套眼和手。4.2 工具注册与提示词设计的实战心法工具在Harness里本质上是一个带描述的函数。每个工具需要提供清晰的名称、一句话描述、参数列表。这个描述比函数实现本身更影响Agent的调用准确性。模型是靠描述来决定选哪个工具的描述写得太笼统比如只写日志查询它可能不知道该不该用、什么时候用。我给工具加描述的惯用格式是在什么情况下用这个工具做什么能获得什么信息。比如当用户询问系统服务状态、错误日志、进程列表时使用日志查询工具获取目标服务的实时日志信息。这样的描述在意图识别阶段能显著提高命中率。我自己实际对比过同样的平台工具描述优化前后Agent正确调用工具的比例可以差出两成以上。提示词设计的另一个重点是约束工具的兜底策略。在系统提示词里明确写上信息不足时直接说明或者如果查找不到不要凭空猜测。这句话能拦下一大批模型幻觉。尤其在内部工具场景数据库里没有的数据模型经常试图编一个合理答案这对业务来说非常危险。4.3 局域网共享与访问控制平台跑起来之后局域网内的其他设备访问只需把API地址从localhost换成服务器的内网IP。这里有个安全细节容易被忽略默认情况下8000端口是暴露在宿主机所有网卡上的如果你的服务器有公网IP这个端口就等于对公网敞开。一定要注意用防火墙限制来源只允许内网网段访问sudo ufw allow from 192.168.1.0/24 to any port 8000 proto tcp sudo ufw allow from 192.168.1.0/24 to any port 8080 proto tcp另外Harness自带一个简单的API密钥机制建议立刻改掉默认密钥。内部系统之间调用Agent接口时在请求头带上令牌不要裸奔。用容器跑服务时宿主机防火墙规则是最后一道防线配置好后用另一台设备实测一下能不能通过外网地址访问确认被拦截。5. 常见问题与排查技巧实录5.1 容器起不来、接口无响应现象一容器反复重启。先用docker logs看退出原因八成是显存不够或配置了不存在的设备。显存不足时检查是不是同时开了太多模型容器或者CONTEXT_WINDOW开得太大。解决方案是把并发调到1、上下文调到4096先让容器跑起来再逐步往上调。现象二容器显示运行中但请求一直超时。这通常是模型还在加载中或者加载失败后在无限重试。用healthcheck可以规避服务发现层面的问题但日志里的模型加载进度才是判断关键。如果是卡在权重下载阶段确认网络能正常访问模型仓库或者改为手动下载权重后挂载进容器。现象三首次启动时端口被占用。服务器上常有其他web服务占着8000或8080。改compose里的ports映射比如9000:8000宿主机端口冲突就解决了不用动容器内部端口。5.2 Agent不调用工具或乱调工具排在第一位的问题是Agent完全不理工具把它当普通聊天模型用。原因往往是系统提示词里没有强调工具使用规则或者工具白名单里没有目标工具。排查顺序是先在配置的TOOL_WHITELIST里确认工具已经放行再检查工具的name和description是否清晰最后看会话级提示词是否覆盖了工具约束。有一种很容易忽略的情况是上下文长度不够Agent在长对话中丢掉了工具描述信息这时候把CONTEXT_WINDOW调大一点试试。另一个典型问题是Agent频繁调用同一个工具以至于停不下来。比如一个查日志的Agent明明已经拿到需要的日志片段了还在反复查。这通常出在max_iterations设置过大和提示词缺少终止条件上。给Agent定义的任务目标里加上当你已经获得足够信息回答用户时立即输出最终回答能有效减少无效循环。5.3 性能调优与稳定性经验性能瓶颈大多数时候不在推理层而在资源分配的长尾上。我自己的调优顺序是先压并发看显存余量再压上下文看响应延迟最后才考虑换更大的模型。一个常见误区是硬件明明够却把所有请求都塞给一个模型进程排队排到天荒地老。合理做法是把不同任务拆到不同的Agent和后端模型实例上比如普通问答用一个轻量模型实例复杂分析用一个高量化模型实例中间通过API网关路由。这样既稳定又不会让一个长任务把整个平台拖慢。稳定性方面我强烈建议加上容器自动重启策略api-server: restart: unless-stopped大模型服务偶发OOM或者卡死并不罕见重启策略能让你不在现场的时候服务也能自己恢复。数据挂载这一块也强调一下key-store和logs一定要用volume挂到宿主机上不然容器升级一次你辛辛苦苦积累的工具令牌和排障日志全没了。6. 经验扩展与后续演进6.1 从单机到多服务的演进路径当Agent平台稳定跑通一段时间后自然而然会发现一些进阶需求。我自己按优先级排序觉得最值得先做的是接入内部知识库。把团队内部的文档、FAQ、工单记录做一个本地向量检索服务注册成Agent的一个检索工具效果立刻上一个台阶。很多用户问的问题都是重复的有了知识库Agent就能给出一致且准确的答案不再每次都靠模型现场推理。再往下走可以做API网关统一入口。平台里有多个模型实例、多个Agent服务后前端直接各自连接会非常混乱。用网关做路由、限流、API密钥管理客户端只认一个入口。这个阶段基本就是从实验室项目走向内部基础服务的分水岭了。6.2 成本与运维心得最后聊一点运维成本上的体会。自托管大模型最容易被低估的不是硬件成本而是运行和维护的时间成本。模型镜像更新、权重升级、日志清理、密钥轮换这些事不起眼但都需要人持续投入。我的做法是每周固定留一小段时间处理平台事务检查日志里的报错数、模型响应延迟有没有恶化、显存余量是否健康。把这些事当作日常巡检对待而不是等项目出问题再救火平台的稳定性会好非常多。还有一条小经验善用日志的采样和轮转。Harness的日志在调试Agent行为时非常有价值可以看到每一轮模型思考内容和工具返回结果。但日志膨胀也很快配合/app/logs挂载目录做一个crontab清理或者保留最近7天的策略是必要的。我见过有人因为日志塞满磁盘导致整个Docker daemon异常那感觉实在不好受。回过头看整个部署过程最让我感慨的反而是编排文件定乾坤这一点。统筹好模型、提示词、工具、访问控制这几件关键事平台的可用性就有了八成保障。剩下的就是在实际使用中慢慢磨合让Agent越来越贴合团队的做事方式。