☰
本地优先+云端兜底:Dify+Ollama+DeepSeek混合架构实战
2026/10/6 11:07:19 网站建设 项目流程

1. 为什么我要从“API 打工人”变成“本地优先玩家”

1.1 一个让我彻底醒悟的账单瞬间

去年年底,我负责的一个内部知识助手项目跑得正顺,日活不高但稳定。直到某天早上打开后台,发现当月 API 消耗已经超了预算的三倍。排查下来原因很朴素:一个批量文档摘要任务被误触发,几千份 PDF 在半小时内把上下文窗口塞满,token 像流水一样往外淌。那一刻我意识到,把核心能力完全押在按量计费的云端 API 上,本质上是在给 API 打工——你写的每一行代码、跑的每一次推理,都在为别人的计费器添砖加瓦。

这不是说云端 API 不好。它的模型能力强、维护成本低、上手快,对于验证阶段的项目几乎是唯一理性选择。但一旦进入稳定运行期,尤其是涉及内部文档、客户资料、代码仓库这类敏感数据时,“本地优先、云端兜底”就从一个技术选项变成了架构刚需。本地跑得动的任务本地跑,本地搞不定的难题再交给云端,既控成本又保隐私,还能在断网时保持基本可用。

这套思路落地下来,我最终选定的组合是Dify + Ollama + DeepSeek。Dify 负责编排和工作流,Ollama 负责本地模型托管,DeepSeek 作为云端兜底和高质量推理的补充。整套平台跑在 Docker 里,迁移和备份都方便。下面我把这套东西从选型到落地、从踩坑到调优的完整过程拆开讲,适合已经用过一两次大模型 API、想进一步掌控自己技术栈的开发者,也适合团队里负责基础设施的同学参考。

1.2 这套组合到底解决了什么问题

先把价值说清楚,免得读者跟着搭完发现不是自己想要的。

第一,成本可控。本地 Ollama 跑推理不产生按量费用,只有电费和硬件折旧。日常的问答、摘要、分类、信息抽取这类任务,7B 到 14B 级别的模型完全够用,没必要每次都调用云端大模型。

第二,数据不出内网。Dify 的知识库、工作流、对话记录全部落在自己的服务器上,Ollama 的推理也在本地完成。只有明确需要云端兜底的那部分请求,才会把脱敏后的内容发出去。

第三,断网可用。本地模型一旦拉取完成,整个问答链路不依赖外网。对于内网环境或者网络不稳定的场景,这一点比什么都重要。

第四,可替换性强。Dify 支持多种模型供应商接入,Ollama 支持任意 GGUF 格式模型,DeepSeek 的 API 也是标准 OpenAI 兼容格式。任何一环想换,改动量都不大,不会被某一家锁死。

注意:这套方案不是要完全取代云端 API,而是把“什么时候用本地、什么时候用云端”这个决策权拿回自己手里。全本地化在效果上一定有妥协,全云端化在成本和隐私上一定有风险,混合才是稳态。

2. 选型背后的逻辑:为什么是 Dify、Ollama 和 DeepSeek

2.1 Dify 的角色:不只是聊天界面

很多人第一次接触 Dify 以为它就是个开源的聊天前端,其实它的核心价值在工作流编排和知识库流水线。你可以把 Dify 理解成一个可视化的 LLM 应用开发平台:拖拽节点就能搭出一条“接收问题 → 检索知识库 → 组装上下文 → 调用模型 → 格式化输出”的完整链路,不需要自己写胶水代码。

我选 Dify 而不是自己用 FastAPI 手搓,主要看中三点。一是知识库流水线开箱即用,文档上传、分段、向量化、检索这一套它都封装好了,省掉大量调试时间。二是变量聚合器和条件分支这类节点,让复杂逻辑不用写代码就能表达,团队里非技术同学也能看懂流程。三是模型供应商抽象层做得好,同一个工作流里可以同时挂本地 Ollama 模型和云端 DeepSeek 模型,按节点切换,这正是“本地优先、云端兜底”需要的底层能力。

Dify 的部署方式有几种,社区版用 Docker Compose 拉起是最省事的。它自带 PostgreSQL、Redis、Weaviate 这些依赖,一条docker compose up -d就能跑起来。这里有个细节:Dify 的镜像体积不小,第一次拉取会比较慢,建议提前配好镜像加速,或者在有网络的环境下拉好镜像再导出到目标机器。

2.2 Ollama 的角色:本地模型的“应用商店”

Ollama 最大的贡献是把本地大模型的部署门槛降到了几乎为零。以前跑一个开源模型,要处理 CUDA 版本、量化格式、推理框架、显存分配一堆事,现在ollama run deepseek-r1:7b一条命令就完事。它内置了模型下载、量化、推理服务、API 暴露这一整套,对开发者极其友好。

我选 Ollama 而不是 vLLM 或者 llama.cpp 直接上手,理由是维护成本。vLLM 吞吐高,但配置复杂,对显存要求也高;llama.cpp 灵活,但需要自己编译和调参。Ollama 在易用性和性能之间取了个很好的平衡点,对于个人和小团队场景,它是性价比最高的选择。而且 Ollama 默认就在11434端口暴露 OpenAI 兼容接口,Dify 接入时几乎不用改配置。

Ollama 的模型存储路径默认在用户目录下,Linux 是/usr/share/ollama/.ollama或~/.ollama,Windows 是C:\Users\用户名\.ollama。模型文件动辄几个 G,C 盘很容易被撑爆。修改模型存储路径是部署后第一件要做的事,具体方法后面实操部分会讲。

2.3 DeepSeek 的角色:云端兜底与质量天花板

本地模型再强,遇到复杂推理、长上下文、多步规划这类任务,和云端旗舰模型还是有差距。DeepSeek 在这里扮演两个角色:一是质量兜底,当本地模型置信度低或者任务复杂度高时,把请求转给云端;二是能力补充,比如需要处理超长文档、需要更强的代码生成能力时,直接走云端。

DeepSeek 的 API 是 OpenAI 兼容格式,接入 Dify 时选“OpenAI 兼容”供应商,填上 base URL 和 API Key 就行。它的定价在同类模型里算很有竞争力的,配合本地兜底策略,整体成本能压到纯云端方案的零头。

这里要提醒一点:不要把敏感数据直接发给云端。我的做法是在 Dify 工作流里加一个脱敏节点,把姓名、手机号、身份证号、内部项目代号这类信息替换成占位符,再决定是否走云端。这个节点用 Dify 的代码节点几行 Python 就能实现,后面会给出示例。

2.4 三者组合的架构全景

把这三个东西串起来,整体架构是这样的:

  • 接入层:Dify 提供 Web 界面和 API,用户通过浏览器或外部系统调用。
  • 编排层:Dify 工作流决定每个请求走本地还是云端,负责知识库检索、上下文组装、结果格式化。
  • 推理层:Ollama 跑本地模型,DeepSeek 提供云端推理。
  • 存储层:PostgreSQL 存业务数据,向量库存知识库索引,Ollama 存模型文件。
  • 运行层:全部跑在 Docker 里,用 Docker Compose 编排。

这个架构的好处是每一层都可以独立替换和扩展。想换向量库,改 Dify 配置;想加本地模型,Ollama 拉一个就行;想换云端供应商,Dify 里加一个供应商配置即可。

3. 从零搭建:Docker 环境与依赖准备

3.1 Docker 安装的坑与正确姿势

整套平台跑在 Docker 上,所以第一步是把 Docker 装好。这一步看似简单,但我在不同系统上踩过的坑足够写一篇长文。

Windows 用户装Docker Desktop是最省事的,但要注意几个点。一是需要开启 WSL2 后端,否则性能会差很多。二是在安装过程中如果遇到 “Docker Desktop installation failed” 或者启动后一直转圈,大概率是 WSL2 内核没更新,去微软官网下载最新的 WSL2 内核更新包装上就好。三是 Docker Desktop 默认把镜像和容器数据存在 C 盘,如果 C 盘空间紧张,要在设置里把磁盘镜像位置改到其他盘。

Linux 用户直接用包管理器装 Docker Engine 就行,Ubuntu 下大概是:

sudo apt update sudo apt install -y docker.io docker-compose-plugin sudo systemctl enable --now docker sudo usermod -aG docker $USER

最后一行是把当前用户加入 docker 组,避免每次敲命令都要 sudo。执行完要重新登录一次才生效。

注意:国内网络环境下拉取 Docker 镜像可能会很慢甚至超时。建议在 Docker 配置里加上镜像加速地址,具体地址各云厂商都有提供,配置在/etc/docker/daemon.json的registry-mirrors字段里,改完重启 Docker 服务。

3.2 Dify 的 Docker Compose 部署

Dify 官方提供了 docker-compose.yaml,直接拉下来改改就能用。我的做法是先建一个目录,把 compose 文件和.env文件放进去:

git clone https://github.com/langgenius/dify.git cd dify/docker cp .env.example .env

然后编辑.env,重点改这几个地方。EXPOSE_NGINX_PORT是 Web 访问端口,默认 80,如果 80 被占用就改成别的。数据库密码、Redis 密码这些默认值建议改掉,尤其是部署在公网可访问的机器上时。SECRET_KEY一定要换成随机字符串,这个用于加密敏感信息。

改完执行:

docker compose up -d

第一次启动会拉取一堆镜像,包括 PostgreSQL、Redis、Weaviate、Nginx、API、Worker、Web 等,耐心等几分钟。启动完成后访问http://你的IP:端口,应该能看到 Dify 的初始化页面,设置管理员账号密码就能进去了。

这里有个常见问题:Dify SSL 错误。如果你在 Dify 里配置了 HTTPS 访问,或者通过反向代理转发,可能会遇到证书验证失败。排查思路是先确认证书链完整,再确认 Nginx 配置里的proxy_set_header有没有把 Host 和协议头正确传递。如果是自签证书,Dify 内部调用时可能不信任,需要在容器里把证书加到信任列表,或者干脆在内网环境用 HTTP。

3.3 Ollama 的安装与模型存储路径迁移

Ollama 的安装更简单。Linux 下一条命令:

curl -fsSL https://ollama.com/install.sh | sh

Windows 和 macOS 直接下载安装包。安装完ollama serve会作为服务自动启动,监听11434端口。

模型存储路径迁移是我强烈建议做的第一件事。默认路径在系统盘,模型一多就爆。Linux 下修改 systemd 服务配置:

sudo systemctl edit ollama.service

在打开的编辑器里加上:

[Service] Environment="OLLAMA_MODELS=/data/ollama/models"

然后sudo systemctl daemon-reload && sudo systemctl restart ollama。Windows 下则是设置系统环境变量OLLAMA_MODELS,指向新的目录,重启 Ollama 服务。

迁移完把旧目录里的模型文件挪过去,或者干脆重新拉。这里提醒一句:ollama 下载太慢是高频问题,尤其是拉大模型的时候。可以在拉取前先确认网络,或者用ollama pull的断点续传特性,中断了重新执行会接着下。如果实在慢,找一台网络好的机器拉好模型,把整个 models 目录打包拷过来,放到对应路径下 Ollama 就能识别。

3.4 拉取适合本地跑的 DeepSeek 模型

Ollama 上的 DeepSeek 系列有多个尺寸,选哪个取决于你的硬件。我的经验是:

模型规格显存需求适用场景推荐硬件
deepseek-r1:1.5b2GB 左右简单分类、抽取笔记本核显
deepseek-r1:7b6GB 左右日常问答、摘要入门独显
deepseek-r1:14b12GB 左右复杂推理、代码中端独显
deepseek-r1:32b24GB 左右高质量推理高端独显
deepseek-r1:70b48GB 以上接近云端质量多卡或大内存

拉取命令就是ollama pull deepseek-r1:7b,把 7b 换成你要的规格。拉完用ollama run deepseek-r1:7b测试一下,能正常对话就说明本地推理链路通了。

提示:如果显存不够,Ollama 会自动把部分层放到内存里跑,速度会慢但能跑起来。不过内存占用会飙升,8GB 内存的机器跑 7b 模型会比较吃力,建议至少 16GB。

4. Dify 接入 Ollama 与 DeepSeek 的完整配置

4.1 在 Dify 里配置 Ollama 供应商

Dify 默认的模型供应商列表里就有 Ollama。进入“设置 → 模型供应商”,找到 Ollama,点配置。关键是Base URL这一项。如果 Dify 和 Ollama 跑在同一台机器上,但 Dify 在 Docker 里,Ollama 在宿主机上,那么 Dify 容器里访问宿主机要用host.docker.internal(Windows/macOS)或者宿主机的内网 IP(Linux)。填http://host.docker.internal:11434或者http://192.168.x.x:11434。

填完点保存,如果配置正确,Dify 会自动拉取 Ollama 里已有的模型列表。如果报错 “an error occurred during credentials validation”,八成是网络不通。排查步骤:先在 Dify 的 API 容器里curl一下 Ollama 的地址,确认能通;再确认 Ollama 的OLLAMA_HOST环境变量是不是绑定了0.0.0.0,默认只绑127.0.0.1的话容器访问不到。

配置成功后,在 Dify 的模型列表里就能看到deepseek-r1:7b这类模型,可以设为默认对话模型或者在工作流里按节点选用。

4.2 配置 DeepSeek 云端供应商

DeepSeek 的接入走“OpenAI 兼容”这条路。在模型供应商里选 OpenAI,但把 Base URL 改成 DeepSeek 的 API 地址,API Key 填你在 DeepSeek 平台申请的密钥。模型名称填deepseek-chat或deepseek-reasoner,具体看你要用哪个。

这里有个容易踩的坑:模型名称必须和供应商那边完全一致,多一个空格都会报 “no api key for provider route” 这类错误。另外,如果你在 Dify 里同时配了多个 OpenAI 兼容供应商,要注意区分,别把请求发错地方。

配置完建议在 Dify 的“模型测试”里发一条消息验证,确认能正常返回再往下走。

4.3 工作流里实现“本地优先、云端兜底”

这是整套方案的核心逻辑。在 Dify 的工作流里,我一般这样设计:

第一步,问题分类节点。用一个轻量本地模型判断用户问题的类型和复杂度,输出一个标签,比如“简单”“中等”“复杂”。

第二步,条件分支。根据标签决定走哪条路。“简单”和“中等”走本地 Ollama 模型,“复杂”走 DeepSeek 云端。

第三步,本地推理节点。调用 Ollama 的 deepseek-r1:7b,设置合理的上下文长度和温度参数。

第四步,质量校验节点。用一个代码节点检查本地模型的输出,比如长度是否过短、是否包含“我不知道”这类兜底话术、是否触发了敏感词。如果校验不通过,走云端重试。

第五步,云端兜底节点。调用 DeepSeek,把原始问题和本地模型的输出一起发过去,让云端模型做修正或补充。

第六步,结果聚合。把最终答案返回给用户,同时记录这次请求走了哪条路,方便后续统计本地命中率。

这个设计的关键在于分类节点的准确性。分类错了,要么该本地的走了云端浪费钱,要么该云端的走了本地效果差。我的经验是分类节点用规则加小模型结合的方式,规则处理明显简单的(比如短问题、常见 FAQ),小模型处理模糊地带。

4.4 知识库流水线的搭建要点

Dify 的知识库是它的一大卖点。上传文档后,它会自动分段、向量化、建索引。但默认配置不一定适合所有场景,有几个参数值得调。

分段长度默认是 500 字符左右,对于技术文档可能偏短,导致上下文碎片化。我一般调到 800 到 1000,重叠 100 到 200。分段方式有自动和自定义两种,自动模式对格式规整的文档效果好,格式乱的建议自定义按标题或段落分。

检索方式有向量检索、全文检索、混合检索。混合检索效果最稳,但配置稍复杂。我的做法是先用混合检索,如果召回质量不理想再调权重。

注意:知识库的向量化也要消耗模型调用。如果用的是云端 embedding 模型,大批量文档上传时会产生费用。建议用本地 embedding 模型,Ollama 上拉一个nomic-embed-text或者bge-m3就能用,Dify 里配置成 embedding 供应商即可。

5. 实操中踩过的坑与排查技巧

5.1 容器网络不通的排查套路

Dify 和 Ollama 分处不同容器或宿主机时,网络问题是最常见的。我的排查顺序是:先在 Dify 的 API 容器里docker exec -it dify-api bash,然后curl http://目标地址:端口。如果 curl 不通,问题在网络层;如果 curl 通但 Dify 里配置报错,问题在配置层。

网络层的问题通常是三种:一是目标服务只绑了127.0.0.1,容器访问不到,要改成0.0.0.0;二是防火墙没放行端口;三是 Docker 网络模式不对,容器之间要用同一个自定义网络才能通过服务名互访。

配置层的问题多半是 URL 写错,比如该用host.docker.internal的地方写了localhost。记住一个原则:容器里的 localhost 是容器自己,不是宿主机。

5.2 上下文超长的处理策略

“dify 工作流 上下文超长”是高频报错。本地模型上下文窗口通常比云端小,7b 模型一般 8k 到 32k,云端动辄 128k。当知识库检索回来的内容加上对话历史超过窗口限制时,就会报错。

处理策略有几个层次。最直接的是限制检索条数,把 top-k 从默认的 5 调到 3 甚至 2。其次是压缩上下文,用一个本地小模型把检索回来的内容做摘要,只保留关键信息。再就是分段处理,把长文档拆成多轮对话逐步处理。

如果报错信息里出现 “maximum context length is 1048576 tokens” 这类,说明你调用的模型上下文窗口很大,但实际传入的内容还是超了,这时候要检查是不是有节点把整个知识库都塞进去了。

5.3 模型输出质量不稳定的调优

本地小模型输出质量波动大是常态。我的调优经验是:温度调低,日常问答设 0.3 到 0.5,需要创意的场景再调高。系统提示词写清楚,明确告诉模型它的角色、输出格式、禁止事项。加 few-shot 示例,在提示词里给一两个输入输出样例,效果提升明显。

还有一个技巧是后处理。本地模型输出经常带一堆废话或者格式不对,用一个代码节点做正则清洗和格式校验,能显著提升最终呈现质量。

5.4 常见问题速查表

问题现象可能原因排查方向
Dify 配置 Ollama 报凭证错误网络不通或地址写错容器内 curl 测试
Ollama 拉模型极慢网络或镜像源问题换网络或离线拷贝
工作流报上下文超长检索内容过多调小 top-k 或加摘要节点
本地模型输出乱码编码或量化问题换模型版本或调温度
Docker 启动失败端口占用或权限不足查日志和端口
知识库检索不准分段或检索方式不当调分段长度和检索模式
云端 API 报 400模型名或参数错误核对模型名和请求格式
容器间无法互访网络模式不一致统一到同一自定义网络

5.5 离线安装与迁移的实操

有些环境不能联网,这时候离线安装就派上用场。Docker 镜像可以在一台联网机器上docker pull后docker save成 tar 包,拷到目标机器docker load。Ollama 的模型文件直接拷贝 models 目录即可。Dify 的插件如果也要离线装,在联网环境装好后把插件目录打包迁移。

迁移 Dify 整体环境时,要迁移的东西包括:PostgreSQL 数据、Redis 数据(可选)、向量库数据、上传的文件、.env配置。最稳的方式是用docker compose down停掉服务,把整个数据卷目录打包,在新机器上恢复后docker compose up -d。

6. 性能与成本的平衡:我的实际运行数据

6.1 本地命中率与成本对比

跑了一个月后我统计了一下数据。在约 12000 次请求里,本地模型处理了大约 78%,云端处理了 22%。本地处理的平均响应时间 2 到 4 秒,云端 1 到 2 秒但受网络影响波动大。成本方面,相比纯云端方案,整体 API 费用下降了约 70%。

这个命中率不是固定的,取决于你的任务分布。如果业务里复杂推理占比高,本地命中率会下降,成本优势缩小。但即便如此,把简单任务分流到本地仍然划算。

6.2 硬件投入的回收周期

我用的是一台带 12GB 显存的机器,跑 14b 模型。硬件成本按市场价算,如果纯用云端 API,这笔钱大概能在 8 到 12 个月的 API 费用里省回来。之后就是净赚。当然这是按我的用量算的,用量小的团队回收周期会更长,但隐私和可控性的价值没法用钱衡量。

6.3 后续可以扩展的方向

这套平台搭好后,扩展空间很大。可以接入更多本地模型做 A/B 测试,可以加缓存层减少重复推理,可以把工作流暴露成标准 API 供其他系统调用,还可以加监控和告警,统计本地命中率和响应质量。

我最近在试的是把 Dify 的工作流和内部工单系统打通,让工单自动分类和摘要,进一步减少人工。这个方向跑通后再来分享。

最后分享一个我踩过好几次坑才记住的小技巧:改任何配置前先备份.env和数据卷。Dify 的配置项多,改错一个可能导致服务起不来,有备份能省下大量重装时间。另外,Ollama 的模型文件很大,迁移前先确认目标盘空间够,别拷到一半发现满了。

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

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

立即咨询