ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

本地优先云端兜底:Dify+Ollama+DeepSeek私有AI中台实战

本地优先云端兜底:Dify+Ollama+DeepSeek私有AI中台实战 1. 为什么我决定不再把核心业务逻辑交给云端 API1.1 从一次线上事故说起去年冬天的一个凌晨我负责的一个内部知识问答系统突然大面积超时。排查了半小时才发现是上游大模型 API 的调用配额在高峰期被限流了。那一刻我意识到一个问题当你的产品核心能力完全依赖第三方 API 时你其实是在给 API 打工。对方调整一次限流策略、改一次计费规则、甚至只是机房抖动一下你的业务就得跟着抖三抖。这不是个例。做 AI 应用开发的同行应该都有类似体会调用量小的时候一切安好一旦业务量上来成本曲线陡得吓人而且响应延迟完全不可控。更别提数据合规层面的顾虑——很多企业内部文档、客户资料从原则上就不应该离开自己的服务器。所以从去年下半年开始我陆续把几套系统的推理层做了重构核心思路就一句话本地优先云端兜底。日常请求走本地部署的模型遇到本地扛不住的高复杂度任务再自动降级到云端 API。这套架构跑了大半年稳定性和成本都达到了我的预期今天把完整的搭建思路和踩坑记录整理出来。1.2 这套平台到底解决了什么问题先把定位说清楚。我搭的这套东西本质是一个私有 AI 中台它要同时满足四个诉求数据不出内网敏感文档、内部知识库的检索增强生成RAG全流程在本地完成向量化、检索、生成都不经过外部网络。成本可控高频、低难度的请求比如意图分类、简单问答、文本格式化全部由本地小模型处理只有真正需要强推理的任务才走云端。可用性兜底本地服务挂了或者模型加载失败时能自动切换到云端业务不中断。可编排不是简单调个接口而是要有工作流编排能力能把知识库、变量处理、条件分支、多模型路由串起来。技术选型上我用Dify做编排层和应用层Ollama做本地模型运行时DeepSeek作为云端兜底的主力模型底层用Docker统一管理。这套组合的好处是每一层都可以独立替换——哪天想换本地推理引擎或者想加一个新的云端供应商改动都很小。1.3 适合谁来参考这套方案如果你符合下面任意一条这篇内容应该对你有用手里有内部文档、知识库想搭一个能问答的系统但不想把数据传出去已经在用云端 API但被成本和限流折腾得够呛想找个折中方案团队里有一台带独立显卡的机器甚至没有独显也行想把它利用起来对 Dify、Ollama 这些工具有耳闻但一直没跑通完整链路。需要说明的是这套方案不是零成本本地那台机器的电费和硬件折旧是实打实的。但相比按 token 计费的云端 API只要你的调用量到一定规模本地化的边际成本优势会非常明显。2. 三层架构的拆解编排、推理、兜底各司其职2.1 Dify 在架构里扮演的角色很多人第一次接触 Dify会以为它只是个聊天界面生成器这其实低估它了。在我的架构里Dify 承担的是大脑皮层的角色——它不负责具体的推理计算但负责决定谁来算、怎么算、算完怎么处理。具体来说Dify 提供了几个关键能力工作流编排可以把接收问题 → 检索知识库 → 判断复杂度 → 选择模型 → 生成回答 → 后处理这一整条链路可视化地串起来每个节点都能单独配置。模型供应商管理它支持同时接入多个模型供应商包括本地的 Ollama 和云端的 DeepSeek并且可以在工作流里按条件动态选择。知识库流水线文档上传、分段、向量化、检索这一套是内置的省去了自己写 RAG 管道的功夫。变量聚合与条件分支这是做本地优先、云端兜底逻辑的关键后面会详细讲。我选择 Dify 而不是自己从零写一套编排逻辑核心原因是它把 RAG 和模型路由这两件最繁琐的事做成了开箱即用。自己写当然更灵活但开发周期和后期维护成本会高出一个量级。2.2 Ollama 为什么适合做本地推理层本地推理引擎的选择其实不少我最终选 Ollama主要看中三点第一是部署简单。Ollama 基本是下载即用一条命令就能拉起一个模型服务对外暴露一个兼容 OpenAI 格式的接口。这意味着 Dify 接入它几乎零成本——直接当成一个 OpenAI 兼容的供应商填进去就行。第二是模型管理省心。它内置了模型拉取、版本管理、显存调度。你不需要自己去折腾模型格式转换、量化、加载脚本这些底层细节。对于我这种更关注应用层而不是推理内核的人来说这省了大量时间。第三是资源占用可控。Ollama 支持按需加载模型不用的模型会自动卸载释放显存。在一台显存有限的机器上这个特性很关键——你可以同时准备多个模型但同一时刻只加载正在用的那个。当然它也有短板比如并发能力不如专业推理框架高并发场景下需要额外做队列控制。但对中小规模的内部系统来说完全够用。2.3 DeepSeek 作为云端兜底的定位云端兜底我选 DeepSeek理由很直接在同等能力水平下它的调用成本相对友好而且接口兼容性好。它提供标准的 OpenAI 兼容接口接入 Dify 只需要填 API Key 和 Base URL。但要注意兜底不等于随便用。我在架构里给它设了明确的触发条件只有满足以下情况才会走云端本地模型判断该问题复杂度超过阈值比如需要长链条推理本地服务健康检查失败临时不可用用户显式选择了高质量模式。这样设计的好处是云端调用量被压到最低成本自然就下来了。我实测下来在合理配置触发条件后云端调用占比能控制在总请求量的 15% 以内。2.4 三层之间的数据流与健康检查把三层串起来看一次完整的请求是这样流动的用户请求进入 Dify 的应用入口Dify 先做意图识别和复杂度判断这一步用本地小模型根据判断结果路由到本地 Ollama 或云端 DeepSeek如果走本地先做知识库检索把检索结果拼进提示词模型生成回答Dify 做后处理和格式化返回给用户。健康检查这块我单独做了一个定时任务每隔一段时间 ping 一次 Ollama 的服务端口。如果连续失败就在 Dify 的工作流里把路由开关切到云端。这个逻辑用 Dify 的条件分支节点就能实现不需要额外写代码。层级组件核心职责故障时的表现编排层Dify工作流、路由、知识库整体不可用需优先保障本地推理层Ollama高频请求推理自动降级到云端云端兜底层DeepSeek复杂任务推理提示用户稍后重试3. 从零把环境跑起来Docker 编排的实操细节3.1 Docker 环境准备中最容易忽略的几件事Dify 官方推荐用 Docker Compose 部署这一步看起来简单但坑不少。我先把环境准备的关键点列出来第一Docker Desktop 的资源分配要提前调。默认配置下Docker Desktop 给容器的内存往往只有 2GB 左右而 Dify 加上它的依赖PostgreSQL、Redis、向量数据库跑起来2GB 根本不够会频繁出现容器被 OOM Kill 的情况。我的建议是至少给到 8GB如果本地还要跑 Ollama机器总内存最好 32GB 起步。第二端口冲突要提前排查。Dify 默认会占用 80、5432、6379 等端口。如果你机器上已经装了本地的 PostgreSQL 或 Redis启动时就会报端口占用。解决办法要么改 Dify 的端口映射要么先停掉本地服务。我个人的习惯是统一改映射端口避免影响本机已有环境。第三磁盘空间要留够。光 Dify 本身的镜像加数据就有几个 GB再加上 Ollama 拉的模型一个 7B 模型量化后大概 4-5GB建议至少预留 50GB 空间。3.2 Dify 的 Docker Compose 部署与常见报错部署流程本身不复杂拉取官方仓库、复制环境变量文件、启动 compose 就行。但实际跑的时候我遇到过几个典型报错这里逐个说。报错一credentials validation 失败。这个通常出现在首次启动时原因是数据库还没初始化完成Dify 的 API 服务就去连了。解决办法是等 PostgreSQL 容器完全健康后再启动 API 服务或者直接重启一次 API 容器。Docker Compose 里可以配置depends_on加健康检查来规避。报错二SSL 相关错误。如果你在容器里看到 SSL 握手失败的日志多半是容器内的时间不对或者证书链有问题。前者重启容器通常能解决后者需要检查你的网络环境是否有中间代理拦截。我遇到过一次是宿主机时间漂移导致的校准系统时间后就好了。报错三插件离线安装失败。Dify 的插件市场默认从线上拉取内网环境下会失败。解决办法是提前在有网环境把插件包下载下来通过本地上传的方式安装。这个后面会单独讲。启动命令大致是这样# 克隆 Dify 仓库 git clone https://github.com/langgenius/dify.git cd dify/docker # 复制环境变量模板 cp .env.example .env # 启动所有服务 docker compose up -d # 查看服务状态 docker compose ps启动后访问本机的 80 端口就能看到 Dify 的初始化界面第一次进去要设置管理员账号。3.3 Ollama 的安装与模型存储路径迁移Ollama 的安装相对独立可以装在宿主机上也可以装在 Docker 里。我推荐装在宿主机上原因是它能直接调用宿主机的 GPU性能损耗最小如果装在 Docker 里还要额外配置 GPU 透传麻烦且容易出问题。安装完成后第一个要处理的问题就是模型存储路径。默认情况下Ollama 会把模型存在系统盘的用户目录下一个模型几个 GB很快就把系统盘撑爆。所以第一件事就是改存储路径。在 Linux 上通过设置环境变量OLLAMA_MODELS指向一个大容量磁盘的目录即可。在 Windows 上则是设置系统环境变量后重启 Ollama 服务。改完之后之前下载的模型需要手动迁移过去或者重新拉取。# Linux 下临时设置当前会话有效 export OLLAMA_MODELS/data/ollama/models # 永久生效写入 shell 配置 echo export OLLAMA_MODELS/data/ollama/models ~/.bashrc source ~/.bashrc3.4 模型拉取慢的应对思路模型拉取慢是绕不开的问题尤其是动辄几个 GB 的大模型。我的应对策略有三条一是选对模型尺寸。不是越大越好。对于意图分类、简单问答这类任务3B 到 7B 的模型完全够用拉取快、推理也快。只有确实需要强推理的场景才考虑更大的模型。二是错峰拉取。网络高峰期拉取大模型速度可能只有几百 KB/s。我一般安排在夜间或者网络空闲时段拉取速度能提升好几倍。三是提前准备好离线包。如果目标机器完全没网可以在有网环境把模型文件导出拷贝过去再导入。Ollama 的模型文件结构是标准的直接复制模型目录也能生效。拉取命令很简单# 拉取一个 7B 级别的模型 ollama pull qwen2.5:7b # 查看已安装的模型 ollama list # 测试模型是否可用 ollama run qwen2.5:7b 你好请做个自我介绍4. 把 Dify 和 Ollama 接起来模型接入的完整链路4.1 在 Dify 里配置 Ollama 供应商Dify 接入 Ollama 的路径是进入设置 → 模型供应商 → 添加 Ollama。关键要填的是Base URL这里有个容易踩的坑。如果你的 Dify 是跑在 Docker 里的而 Ollama 跑在宿主机上那么填http://localhost:11434是连不通的——因为在容器里localhost 指的是容器自己。正确的做法是填宿主机的内网 IP或者用 Docker 的特殊域名host.docker.internalDocker Desktop 环境支持。# Docker 环境下的正确填法 http://host.docker.internal:11434 # 或者用宿主机内网 IP http://192.168.1.100:11434填完之后点测试如果显示连接成功就说明链路通了。这时候 Dify 会自动拉取 Ollama 里已安装的模型列表你勾选需要的模型即可。4.2 云端 DeepSeek 的接入与 Key 管理DeepSeek 的接入更简单在模型供应商里选 OpenAI 兼容类型填上 Base URL 和 API Key 就行。但这里我要强调一个安全实践API Key 绝对不要硬编码在工作流里也不要在多个应用间共用同一个 Key。我的做法是在 Dify 的供应商配置里统一管理 Key工作流只引用供应商不直接碰 Key给不同的应用分配不同的 Key方便按应用统计用量和排查问题定期轮换 Key尤其是团队协作场景。如果遇到no api key for provider route这类报错基本就是供应商配置和实际调用不匹配——比如工作流里选了某个供应商但那个供应商的 Key 没配或者配错了。排查时先确认供应商列表里对应项的状态是正常的。4.3 模型路由的触发条件设计这是整套架构的核心逻辑。我在 Dify 的工作流里设计了一个复杂度判断节点用一个本地小模型对用户问题做快速分类输出简单或复杂。判断的依据可以包括问题长度超过一定字符数倾向于复杂是否包含多步推理的关键词比如分析对比为什么是否命中知识库的高置信度匹配命中则本地处理。根据判断结果工作流走不同的分支简单问题走 Ollama复杂问题走 DeepSeek。这个逻辑用 Dify 的条件分支节点实现不需要写代码。提示复杂度判断本身也要消耗算力所以判断用的模型要足够小、足够快否则就本末倒置了。我一般用 1.5B 到 3B 级别的模型做这件事。4.4 变量聚合器在兜底逻辑里的妙用Dify 的变量聚合器Variable Aggregator是个容易被忽视但极其好用的节点。它的作用是把多个分支的输出汇聚成一个统一的变量。在兜底场景里它的价值就体现出来了本地分支和云端分支各自生成回答但下游节点比如格式化、返回只认一个变量。用变量聚合器把两个分支的输出合并下游就不用关心回答到底来自哪个模型。具体配置时把本地模型节点的输出和云端模型节点的输出都接到聚合器上聚合器会按执行顺序取第一个有值的输出。这样即使本地分支因为异常没产出云端分支的结果也能正常往下走。5. 知识库流水线的搭建与上下文超长的处理5.1 文档分段策略对检索质量的影响知识库的效果七分靠分段三分靠模型。分段策略没做好再强的模型也检索不出正确内容。我的经验是分段长度不要一刀切。技术文档适合 500-800 字符一段因为技术概念往往成段出现而 FAQ 类内容适合按问答对切分一段就是一个完整问题。重叠设置相邻分段之间保留 10%-20% 的重叠避免关键信息正好被切断在边界上。分隔符选择优先按语义分隔段落、标题其次才按固定长度硬切。Dify 的知识库配置里这些都支持关键是要根据你的文档类型去调而不是用默认值一把梭。5.2 检索增强生成链路的节点编排一个完整的 RAG 链路在 Dify 里大概是这样编排的知识库检索节点输入用户问题输出最相关的若干分段重排序节点可选对检索结果做二次排序提升相关性提示词组装节点把检索到的分段和用户问题拼成一个完整的提示词模型调用节点把组装好的提示词发给模型后处理节点格式化输出附上引用来源。这里有个细节检索返回的分段数量要控制。返回太多提示词会超长返回太少可能漏掉关键信息。我一般设 top-k 为 3 到 5再配合重排序效果比较平衡。5.3 上下文超长报错的根因与拆解maximum context length is xxx tokens这个报错做 RAG 的人几乎都遇到过。它的根因很简单你拼给模型的提示词加上模型要生成的回答总长度超过了模型的上下文窗口。但拆开看超长的来源可能有好几个检索回来的分段太多或太长历史对话没有做截断越聊越长系统提示词本身写得太啰嗦。对应的解决思路超长来源解决手段检索分段过多降低 top-k或对分段做摘要压缩历史对话过长只保留最近 N 轮或做对话摘要系统提示词冗长精简提示词去掉冗余描述模型窗口太小换用上下文窗口更大的模型我个人的习惯是在提示词组装节点之前加一个长度预估节点如果预估超过阈值就先对检索结果做压缩再拼提示词。这样能从源头避免超长报错。5.4 知识库迁移与备份的注意事项知识库搭好之后迁移和备份是要提前考虑的。Dify 的知识库数据存在它依赖的 PostgreSQL 和向量数据库里直接备份这两个数据库的卷就能完整迁移。但要注意两点一是向量维度和嵌入模型绑定如果你迁移后换了嵌入模型原来的向量就失效了必须重新向量化二是文档原始文件也要备份因为重新向量化时需要用到原始文档。我的做法是定期把知识库的数据库卷和原始文档目录一起打包备份迁移时整体恢复避免出现向量和文档对不上的情况。6. 那些让我熬夜的坑完整排查链路复盘6.1 Ollama 连不通的三层排查法Dify 报无法连接 Ollama时不要急着改配置按下面三层依次排查能快速定位问题第一层Ollama 服务本身是否在跑。在宿主机上执行ollama list如果能列出模型说明服务正常如果报连接错误说明服务没起来先解决服务问题。第二层网络是否可达。从 Dify 所在的容器里 ping 宿主机的 IP看能不能通。如果不通是网络配置问题如果通但端口连不上是防火墙或端口监听问题。第三层地址填得对不对。前面说过容器里的 localhost 不是宿主机。确认 Base URL 填的是宿主机 IP 或host.docker.internal。这三层排查下来90% 的连接问题都能定位。6.2 插件离线安装的完整流程内网环境装 Dify 插件是个高频需求。完整流程是在有网环境从 Dify 插件市场找到目标插件下载对应的插件包通常是.difypkg格式把插件包拷贝到内网机器在 Dify 的插件管理页面选择从本地安装上传插件包等待安装完成刷新页面确认插件已启用。要注意的是有些插件有依赖关系需要先装依赖插件。另外插件版本要和 Dify 主版本兼容版本不匹配会安装失败。6.3 工作流上下文超长的实战处理前面讲了超长的原理这里说一个我实际处理的案例。有个用户反馈问了一个长文档相关的问题后系统就报上下文超长。排查发现是因为这个应用开启了多轮对话记忆而用户之前已经聊了十几轮历史对话累积起来非常长再加上这次检索回来的分段直接爆了窗口。我的处理方式是在对话记忆节点上设置最大保留轮数我设的是 5 轮同时对更早的历史做摘要压缩。改完之后同样的对话场景再没出现过超长报错。这个案例的教训是多轮对话的记忆一定要设上限否则迟早会撞上上下文窗口。6.4 模型思考过程干扰输出的处理有些模型尤其是带推理能力的会在输出里带上大段的思考过程比如让我想想……首先……然后……。这些内容如果直接返回给用户体验很差。处理方式有两种一是在提示词里明确要求模型只输出最终答案不要输出思考过程二是在后处理节点里用规则或小模型把思考过程剥离掉。我一般两种结合用提示词先约束后处理再兜底。对于某些思考过程特别顽固的模型可以在 Dify 的模型参数里调整或者换用不带思考输出的模型版本。7. 稳定运行半年的几点个人体会7.1 成本与体验的平衡点在哪跑了半年我最大的体会是本地优先不等于本地万能。一开始我试图把所有请求都塞给本地模型结果发现复杂任务的质量确实不如云端用户体验下降明显。后来调整策略把云端调用占比控制在 15% 左右既保住了成本又保住了质量。这个平衡点因业务而异。如果你的场景以简单问答为主本地占比可以更高如果以复杂分析为主云端占比就得提上去。关键是要有数据支撑我专门做了个统计记录每天本地和云端的调用量、响应时间、用户满意度用数据来调参数。7.2 硬件配置的真实建议关于硬件我的真实建议是内存32GB 起步16GB 会很紧张尤其是同时跑 Dify 和 Ollama 时显存如果要用 7B 以上模型8GB 显存是底线12GB 以上更从容存储SSD 是必须的模型加载速度对体验影响很大机械硬盘会拖后腿。如果暂时没有独显用 CPU 跑小模型也能凑合但速度会慢很多只适合对延迟不敏感的场景。7.3 后续可以继续优化的方向这套架构还有不少可以打磨的地方。比如引入缓存层对高频重复问题做缓存进一步降低推理压力模型微调用业务数据对本地模型做轻量微调提升垂直领域表现多机部署把 Ollama 单独部署到一台带强显卡的机器上Dify 跑在另一台通过网络调用监控告警给本地服务加上健康监控异常时自动通知。最后分享一个小技巧把常用的提示词模板固化下来不要每次都在工作流里现写。我建了一个提示词库按场景分类用的时候直接引用既省时间又保证一致性。这套东西搭起来前期确实要花点功夫但一旦跑顺后面维护起来会轻松很多。
返回列表