☰
本地优先云端兜底:Dify+Ollama+DeepSeek+Docker私有AI平台搭建指南
2026/10/3 5:26:53 网站建设 项目流程

1. 从“给 API 打工”到“自己当调度”:这套私有 AI 平台到底在解决什么

如果你现在还在把每一次对话、每一份文档解析、每一个工作流节点都直接怼到云端 API 上,那你大概率已经体会过下面这几种滋味:账单像坐了火箭,月初刚充的额度月中就见底;某个深夜服务商抽风,整条业务线跟着一起躺平;想拿内部资料做知识库,又担心数据出了内网就再也说不清楚去了哪。说白了,这就是在给 API 打工——你出钱、出数据、出业务逻辑,最后命脉却攥在别人手里。

我搭这套「本地优先、云端兜底」的私有 AI 平台,核心动机就一句话:把高频、稳定、涉密的那部分负载留在本地,把低频、突发、需要顶级模型能力的那部分交给云端。本地这一层用 Ollama 跑开源模型,负责日常问答、文档预处理、简单分类和向量化;编排层用 Dify 做工作流、知识库和 Agent 调度;云端兜底接 DeepSeek 这类高性价比 API,只在本地模型搞不定或者需要更强推理时才出手。整套东西用 Docker 串起来,跑在一台带独显的机器或者一台配置还行的服务器上。

这套方案适合谁?我总结了三类人。第一类是中小团队的技术负责人,预算有限但又想给内部搭一个能用的 AI 助手,不想每个月被 API 账单追着跑。第二类是独立开发者或者技术博主,想在自己的项目里集成 AI 能力,又希望成本可控、数据可控。第三类是对数据敏感的场景,比如法务、医疗、企业内部知识管理,这些场景里数据不出内网是硬性要求,但偶尔又需要云端模型的强推理能力做补充。

关键词里的 Dify、Ollama、DeepSeek、Docker 这四个词,基本就是这套平台的四大支柱。Dify 负责“编排”,Ollama 负责“本地推理”,DeepSeek 负责“云端兜底”,Docker 负责“把这一切装进盒子里”。热词里出现的 dify ssl 错误、dify 安装 windows、ollama 下载慢、deepseek 401 unauthorized、docker desktop 安装教程这些,全都是我在搭建过程中真实踩过的坑,后面会一个个拆开讲。

先给一个整体架构的直觉:你可以把它想象成一家公司。Ollama 是坐班员工,随时在岗,处理日常事务,成本固定;DeepSeek API 是外部顾问,按次收费,只在遇到疑难杂症时请过来;Dify 是项目经理,决定哪个任务派给坐班员工、哪个任务请外部顾问;Docker 是办公楼,把所有人装进标准化的房间里,搬家、扩容、复制都方便。这个类比贯穿全文,后面讲每个组件时你都能对上号。

2. 四块积木怎么摆:Dify、Ollama、DeepSeek、Docker 的分工与选型逻辑

2.1 Ollama 为什么是本地推理的首选而不是自己撸 llama.cpp

很多人一提到本地跑模型,第一反应是去 GitHub 上 clone llama.cpp 自己编译。我早期也这么干过,结果是:编译环境折腾半天,量化格式搞不清楚,换个模型又要重新配参数。Ollama 的价值就在于它把模型下载、量化、加载、API 暴露这一整套流程标准化了。你只需要ollama run qwen3.5:2b这样一行命令,它自动帮你拉模型、起服务、开一个兼容 OpenAI 风格的接口。

选 Ollama 而不是 vLLM 或者 TGI,理由也很实际。vLLM 吞吐量确实高,但它对显存的要求和部署复杂度也高,适合有专门运维的团队。Ollama 在单机、少量并发、快速迭代的场景下,体验是最好的。我们这套平台定位就是“私有、轻量、够用”,不是要扛几千 QPS 的生产级推理,所以 Ollama 的取舍刚好匹配。

热词里有个ollama run qwen3.5:2b error: 500 internal server error: llama-server process,这个错误我遇到过。根因通常是模型文件下载不完整,或者显存不够导致 llama-server 进程起不来。解决办法是先ollama rm掉那个模型重新拉,再检查显存占用。如果是显存问题,换更小的量化版本,比如从 q4 换到 q4_0 或者 q3。

2.2 Dify 在编排层的不可替代性:为什么不用 LangChain 自己写

LangChain 灵活,但灵活意味着什么都要自己写。工作流可视化、知识库管理、Agent 工具调用、多模型切换、日志追踪,这些 Dify 开箱即用。对于中小团队来说,Dify 省下的开发时间是以周计的。而且 Dify 的模型供应商配置是抽象过的,你可以在界面上同时配 Ollama 和 DeepSeek,然后在工作流里按节点选择用哪个,这种“本地优先、云端兜底”的切换在 Dify 里就是下拉框选一下的事。

Dify 的另一个价值是知识库流水线。热词里出现的dify 知识库流水线、dify unstructured api、dify unstructured api url is not configured for doc file processing都跟这块有关。Dify 处理文档时,如果是简单文本它自己就能解析,但遇到 PDF、Word 里的复杂排版,它会调用 Unstructured API 来做结构化提取。如果你没配这个 API,上传 doc 文件就会报unstructured api url is not configured。这个后面在知识库章节会详细讲怎么处理。

2.3 DeepSeek 作为云端兜底的性价比账怎么算

DeepSeek 的 API 价格在同类里属于很能打的,尤其是它的推理能力在复杂任务上明显强于同尺寸的开源模型。我把它定位成“兜底”,意思是:本地 Ollama 能处理的,绝不走云端;本地处理不了的,或者用户明确要求高质量输出的,才路由到 DeepSeek。这样既控制了成本,又保证了体验上限。

热词里的deepseek api如何调用、codex接入deepseek、unexpected status 401 unauthorized: incorrect api key provided: sk-svcac这些,核心都是 API Key 的配置问题。401 这个错误基本就是 Key 错了、过期了、或者复制的时候带了空格。Dify 里配置 DeepSeek 供应商时,Key 要填在正确的位置,而且注意有些代理层会改写 Authorization 头,导致 Key 传不过去。

2.4 Docker 把三者装进一个可迁移的盒子

Docker 在这套架构里的角色是“环境标准化”。Ollama、Dify、数据库、向量库,每个组件都有自己的依赖和版本要求,裸机装很容易互相打架。用 Docker Compose 把它们编排起来,每个服务一个容器,网络互通,数据卷持久化,迁移的时候整个目录打包带走就行。热词里dify 迁移、docker安装mysql8.0并使用、docker安装redis主从这些,都是围绕容器化部署和迁移的实操需求。

组件角色部署方式成本模型适用负载
Ollama本地推理引擎Docker 容器或裸机固定硬件成本高频、涉密、简单任务
Dify编排与知识库Docker Compose开源免费工作流、Agent、知识库
DeepSeek云端兜底API 调用按 token 计费低频、复杂推理
Docker环境标准化宿主机安装免费所有组件的运行底座

这张表是我选型时的决策依据。你可以看到,本地和云端的成本模型完全不同,一个是固定投入,一个是边际成本。把两者组合起来,就是用固定成本覆盖大部分负载,用边际成本覆盖峰值和疑难,整体成本曲线会比纯云端平滑很多。

3. 从零把平台跑起来:Docker、Ollama、Dify 的安装顺序与关键配置

3.1 Docker 环境准备:Windows 和 Linux 的差异点

Docker 的安装本身不复杂,但 Windows 和 Linux 的坑点完全不同。Windows 上你要装 Docker Desktop,热词里docker desktop安装教程、dify 安装 windows都是这个场景。Windows 版 Docker Desktop 默认用 WSL2 作为后端,所以你得先确保 WSL2 装好、虚拟化在 BIOS 里开了。我见过有人装完 Docker Desktop 发现起不来,折腾半天结果是 BIOS 里 VT-x 没开。

Linux 上相对简单,curl -fsSL https://get.docker.com | sh一把梭,然后systemctl enable docker设成开机自启。但 Linux 上要注意用户权限,普通用户默认不在 docker 组里,每次都要 sudo。执行usermod -aG docker $USER然后重新登录,就能免 sudo 了。

提示:Windows 上 Docker Desktop 的资源限制默认比较保守,如果你要跑 Ollama 加载 7B 以上的模型,记得在 Settings 里把内存调到至少 8GB,CPU 核心数给到 4 个以上,否则模型加载会非常慢甚至 OOM。

安装完验证一下:docker --version和docker compose version都能正常输出,就说明基础环境 OK 了。热词里启动docker、docker下载这些基础操作就不展开了,重点讲后面的编排。

3.2 Ollama 部署:绕开下载慢和离线安装的坑

Ollama 的官方安装脚本在国内网络环境下拉模型会非常慢,热词里ollama下载慢、ollama下载太慢了、ollama国内镜像源、ollama离线安装包全是这个痛点。我的做法是两条路并行:一是配镜像源加速,二是准备离线安装包。

配镜像源的方式是在启动 Ollama 服务前设置环境变量。Linux 下可以写进 systemd 的 service 文件,Docker 下直接在 compose 里加 environment。具体地址这里不展开,你搜“ollama 镜像源”能找到当前可用的。设置完之后ollama pull的速度会有明显提升。

离线安装包适合完全断网或者网络极差的环境。思路是在一台网络好的机器上ollama pull好模型,然后把~/.ollama/models整个目录拷到目标机器。注意模型目录的权限和路径要一致,否则 Ollama 找不到。Docker 部署的话,把模型目录挂载成 volume 就行。

Ollama 默认监听 11434 端口,起好之后用curl http://localhost:11434/api/tags验证,能返回模型列表就说明服务正常。这一步很关键,因为后面 Dify 要连这个地址,如果 Ollama 本身没起好,Dify 里配了也是白配。

3.3 Dify 的 Docker Compose 部署与 SSL 错误的根因

Dify 官方提供了 docker-compose.yaml,clone 下来docker compose up -d就能起。但热词里dify ssl错误出现的频率很高,这个问题的根因通常是:Dify 的 Web 服务默认走 HTTPS,但自签证书或者证书链不完整,导致浏览器或者内部服务调用时报 SSL 错误。

我的处理方式是分场景。如果是本地开发,直接在 compose 里把CONSOLE_API_URL和APP_API_URL改成 http,省掉证书这层。如果是正式环境,用 Nginx 做反向代理,证书用 Let's Encrypt 签,Nginx 到 Dify 容器内部走 http,这样证书问题就隔离在 Nginx 这一层,Dify 本身不用管证书。

另一个常见错误是dify an error occurred during credentials validation,这个通常出现在配置模型供应商的时候。比如你配 Ollama,Base URL 填错了,或者填了localhost但 Dify 在容器里,容器内的 localhost 指向的是容器自己而不是宿主机。正确做法是填宿主机的内网 IP,或者用 Docker 的host.docker.internal(Windows/Mac)或宿主机的 bridge 网关 IP(Linux)。

3.4 模型供应商配置:Ollama 和 DeepSeek 在 Dify 里的正确填法

Dify 里配 Ollama 供应商,关键字段是 Base URL 和模型名称。Base URL 填http://宿主机IP:11434,模型名称填你在 Ollama 里 pull 下来的模型名,比如qwen3.5:2b。填完点测试,如果报连接错误,先确认 Ollama 服务在宿主机上能访问,再确认 Dify 容器能 ping 通宿主机 IP。

配 DeepSeek 供应商,关键字段是 API Key 和 Base URL。DeepSeek 的 API 兼容 OpenAI 格式,Base URL 填官方地址,Key 填你申请的那个。热词里unexpected status 401 unauthorized: incorrect api key provided: sk-svcac****这个错误,就是 Key 不对。注意几点:Key 前后不能有空格,不能有多余的引号,如果是从网页复制的,有时候会带上不可见字符,建议粘贴到纯文本编辑器里过一遍再填。

配好之后,在 Dify 的模型列表里应该能同时看到 Ollama 的本地模型和 DeepSeek 的云端模型。这时候你就可以在工作流里按节点选择用哪个了,这就是“本地优先、云端兜底”的落地方式。

4. 让本地模型和云端模型各司其职:工作流里的路由策略与上下文管理

4.1 什么任务留给 Ollama,什么任务甩给 DeepSeek

路由策略的核心判断维度有三个:任务复杂度、数据敏感度、响应时间要求。我画了一个简单的决策逻辑,你可以直接套用。

任务类型推荐模型理由
日常问答、闲聊Ollama 小模型高频、简单、本地够用
文档摘要、分类Ollama 中等模型数据可能敏感,本地处理
知识库检索问答Ollama + 向量库数据不出内网
复杂推理、代码生成DeepSeek本地模型能力不足
多轮深度分析DeepSeek需要强上下文理解
格式化输出、翻译Ollama 或 DeepSeek看质量要求

这个表不是死的,你可以根据自己机器的配置和预算调整。核心原则是:能用本地解决的绝不走云端,本地解决不好的果断走云端。不要为了省那点 API 费用,让用户体验大打折扣;也不要什么都往云端扔,那又回到了给 API 打工的老路。

4.2 Dify 工作流里的条件分支怎么配

Dify 的工作流支持条件分支节点,你可以根据输入内容的特征来决定走哪条路。比如我配了一个简单的规则:如果用户输入里包含“代码”“推理”“分析”这类关键词,或者输入长度超过某个阈值,就路由到 DeepSeek;否则走 Ollama。

更精细的做法是用一个轻量模型做意图分类。先用 Ollama 跑一个小模型,让它判断这个请求是简单还是复杂,然后根据判断结果路由。这个分类模型可以很小,比如 2B 级别的就够,因为它只做二分类,不需要多强的能力。

配置的时候注意,条件分支的判断条件要写得明确,避免模糊匹配导致路由错误。Dify 的条件分支支持变量比较、包含判断、正则匹配等,你可以组合使用。

4.3 上下文超长问题的处理:从 1048576 tokens 报错说起

热词里api error: 400 this model's maximum context length is 1048576 tokens. howeve和dify工作流 上下文超长是同一个问题:上下文塞太多了,超过了模型的上限。DeepSeek 的上下文窗口虽然大,但也不是无限的,而且上下文越长,费用越高、响应越慢。

我的处理策略是三层。第一层是输入截断,在进工作流之前就把超长的输入切掉或者摘要掉。第二层是知识库检索代替全文塞入,不要把所有文档都塞进上下文,而是用向量检索只取最相关的几段。第三层是对话历史压缩,多轮对话不要把全部历史都带上,只带最近几轮,或者用一个小模型把历史压缩成摘要。

Dify 的知识库功能天然就是干这个的。你把文档传进知识库,它做切分和向量化,问答的时候只检索相关片段,这样上下文长度就可控了。这也是为什么我强烈建议把知识库用起来,而不是直接把文档内容拼进 prompt。

4.4 本地模型和云端模型的输出一致性怎么保证

混用本地和云端模型,一个容易被忽略的问题是输出风格不一致。本地小模型可能回答得比较简短、口语化,DeepSeek 可能回答得比较正式、结构化。如果同一个应用里两个模型混着用,用户会觉得体验割裂。

我的做法是在 prompt 层面做统一。不管走哪个模型,系统 prompt 里都加上相同的输出格式要求,比如“用 Markdown 格式回答”“分点列出”“不超过 300 字”等。这样即使底层模型不同,输出格式也能保持一致。另外,可以在工作流最后加一个格式化节点,对输出做统一的后处理。

5. 知识库流水线:文档解析、向量化与 Unstructured API 的配置

5.1 Dify 知识库的文档处理流程拆解

Dify 的知识库处理文档分几步:上传、解析、切分、向量化、存储。解析这一步是关键,简单的 txt、md 它自己就能处理,但 PDF、Word、PPT 这些格式,Dify 会调用 Unstructured API 来做结构化提取。热词里dify unstructured api url is not configured for doc file processing就是这一步没配好。

Unstructured 是一个开源的文档解析工具,能把各种格式的文档转成结构化文本。你可以自己部署一个 Unstructured 服务,然后在 Dify 的环境变量里配UNSTRUCTURED_API_URL指向它。如果不想自己部署,也可以用 Dify 内置的解析能力,但复杂排版的文档解析效果会差一些。

我的建议是:如果你的知识库主要是纯文本或者简单 PDF,用 Dify 内置的就行;如果有大量复杂排版的文档,自己部署一个 Unstructured 服务,解析质量会好很多。

5.2 文档切分策略:chunk size 和 overlap 怎么定

文档切分是知识库效果的关键。切太大,检索出来的片段包含太多无关信息,浪费上下文;切太小,片段可能不完整,丢失关键信息。Dify 默认的切分参数是 chunk size 500、overlap 50,这个对大多数场景够用,但不是最优。

我的经验是:技术文档、法律条文这类结构清晰的,chunk size 可以小一点,300-400,overlap 50-80,保证每个片段聚焦一个点。叙述性的文章、报告,chunk size 可以大一点,600-800,overlap 100,保证上下文连贯。切分的时候尽量按语义边界切,比如按段落、按标题,而不是机械地按字数切。Dify 支持自定义分隔符,你可以把\n\n、\n#这些加进去,让切分更符合文档结构。

5.3 向量化模型的选择:本地还是云端

向量化模型决定了检索的质量。Dify 支持多种 embedding 模型,你可以用 Ollama 跑本地的 embedding 模型,也可以用云端 API。本地的优势是数据不出内网、没有调用费用,劣势是质量可能不如云端顶级模型。

我的选择是:如果知识库内容不敏感,用云端 embedding 模型,质量更好;如果敏感,用本地 embedding 模型,比如 Ollama 上的nomic-embed-text或者bge-m3。本地 embedding 模型对硬件要求不高,CPU 就能跑,速度也还可以。

注意一点:embedding 模型换了之后,之前向量化的数据要重新处理,因为不同模型的向量空间不兼容。所以选模型的时候要慎重,别频繁换。

5.4 知识库检索的调优:top-k、score threshold 怎么设

检索的时候,top-k 决定返回几个片段,score threshold 决定低于多少分的片段被过滤掉。top-k 设太大,会塞入无关信息;设太小,可能漏掉关键信息。我的经验值是 top-k 设 3-5,score threshold 设 0.5-0.7,具体看你的 embedding 模型和文档质量。

如果发现检索结果不理想,先检查切分是否合理,再检查 embedding 模型是否适合你的语言和领域,最后调 top-k 和 threshold。有时候问题不在检索参数,而在文档本身质量太差,比如扫描版 PDF 没有 OCR,解析出来全是乱码,那再怎么调也没用。

6. 踩坑实录:401、SSL、下载慢、上下文超长的排查链路

6.1 401 unauthorized 的完整排查过程

热词里unexpected status 401 unauthorized: incorrect api key provided: sk-svcac****这个错误,我完整踩过一遍。当时的排查链路是这样的:

第一步,确认 Key 本身是否有效。拿 Key 直接 curl DeepSeek 的 API,如果也报 401,说明 Key 有问题,去后台重新生成一个。第二步,确认 Key 有没有多余字符。从网页复制的时候经常带上换行或者空格,肉眼看不出来,粘贴到编辑器里看行尾。第三步,确认 Dify 里填的位置对不对。Dify 的模型供应商配置里,Key 要填在 API Key 字段,不要填到别的字段里。第四步,确认有没有代理层改写请求头。如果你在 Dify 前面挂了 Nginx 或者别的网关,检查它有没有把 Authorization 头丢掉或者改写。

这四步走完,401 基本都能解决。如果还不行,看 Dify 的容器日志,docker logs dify-api能看到具体的请求和响应,里面会有更详细的错误信息。

6.2 SSL 错误的三种场景和对应解法

SSL 错误我遇到过三种场景。第一种是 Dify 自签证书,浏览器不信任,解法是换正式证书或者本地开发用 http。第二种是 Dify 容器内部调用外部服务时证书验证失败,解法是在容器里装 ca-certificates 或者临时关闭验证(不推荐生产用)。第三种是 Nginx 反代配置里证书链不完整,解法是把中间证书也配上。

排查 SSL 问题的时候,curl -v是你的好朋友,它能显示完整的握手过程,哪一步失败一目了然。另外,openssl s_client -connect host:port也能帮你看证书链是否完整。

6.3 Ollama 下载慢的加速方案对比

下载慢这个问题,我试过三种方案。方案一是配镜像源,速度提升明显,但镜像源有时候会挂,需要备用。方案二是离线安装包,一劳永逸,但需要一台网络好的机器做中转。方案三是用代理,但这个涉及网络配置,这里不展开。

我的建议是:日常用镜像源,同时准备一份常用模型的离线包放在内网,镜像源挂了就切离线。常用模型就那么几个,qwen 系列、llama 系列、bge 系列,提前拉好放着,用的时候直接挂载。

6.4 上下文超长的预防比修复更重要

上下文超长这个问题,修复很简单,截断就行。但截断意味着信息丢失,效果会打折。所以我的策略是预防为主:知识库检索控制返回片段数,对话历史做压缩,输入做预处理。在工作流里加一个检查节点,如果上下文长度超过阈值,先触发摘要或者截断,再进模型。

Dify 的工作流里可以用代码节点做这个检查,写几行 Python 判断 token 数,超了就调摘要模型压缩。这个摘要模型可以用本地的小模型,成本低、速度快。

7. 迁移、备份与日常维护:让这套平台能长期跑下去

7.1 Dify 迁移的完整步骤

热词里dify 迁移是个高频需求。Dify 的迁移分两部分:配置和数据。配置在.env文件和docker-compose.yaml里,数据在 PostgreSQL 和向量库里。迁移的时候,先把这两个文件拷过去,然后把数据库和向量库的 volume 一起打包拷过去,在新机器上docker compose up -d就能恢复。

注意版本要一致,Dify 不同版本之间的数据库 schema 可能有变化,跨版本迁移要先看官方的升级说明。另外,迁移后要检查模型供应商配置,因为里面可能有 IP 地址或者 Key,换环境后可能需要调整。

7.2 数据备份策略:哪些要备、多久备一次

要备份的东西有三样:PostgreSQL 数据、向量库数据、Ollama 模型目录。PostgreSQL 存的是 Dify 的应用配置、对话历史、知识库元数据;向量库存的是文档向量;Ollama 模型目录存的是模型文件。

备份频率看你的使用强度。个人用,一周一次够了;团队用,建议每天增量备份、每周全量备份。备份方式可以用pg_dump导 PostgreSQL,向量库看具体用的什么(Milvus、Qdrant、Weaviate 各有各的备份方式),Ollama 模型目录直接 rsync 就行。

7.3 日常维护:日志、监控、资源占用

日常维护主要看三样:容器状态、资源占用、日志。docker stats能看每个容器的 CPU、内存、网络占用,Ollama 加载模型的时候内存会飙高,这是正常的,但如果持续不降,可能是模型没释放。docker logs看日志,重点看 error 和 warning。

资源占用方面,Ollama 是吃内存和显存的大户,Dify 的 API 和 Worker 吃 CPU 和内存,PostgreSQL 和向量库吃磁盘和内存。如果机器配置有限,优先保证 Ollama 的资源,其他组件可以适当限制。

7.4 扩展方向:从单机到多机、从单模型到模型池

这套平台跑通之后,扩展方向有几个。一是加更多本地模型,形成模型池,按任务类型路由到不同模型。二是把 Ollama 拆到单独的机器上,Dify 和数据库留在原机器,通过内网调用,这样推理和编排解耦,各自扩容。三是加缓存层,高频问题的答案缓存起来,减少模型调用。

我个人在实际操作中的体会是:这套平台最大的价值不是省了多少钱,而是把控制权拿回了自己手里。数据在哪、模型用哪个、成本怎么控,全都是你自己说了算。刚开始搭的时候会踩一些坑,但一旦跑通,后面就是滚雪球式的效率提升。最后再分享一个小技巧:把常用的工作流和 prompt 模板导出成 JSON 存起来,换环境或者重装的时候直接导入,能省掉大量重复配置的时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询