
一开始我也觉得大模型当然直接调 API 最方便DeepSeek 便宜、效果好注册完拿个 key 就能跑。可真正把 AI 用进工作流之后才知道给 API 打工的日子有多难受每月的 token 账单像无底洞公司内网里那些不能外传的合同、代码和复盘文档偏偏是模型最该读的材料云端接口中午一卡我这边整个应用跟着瘫痪。后来我动手把架构换掉用 Dify 做编排层用 Ollama 把开源模型跑在本地让 DeepSeek 的云端接口只在关键时刻介入搭出了一套「本地优先、云端兜底」的私有 AI 平台。这篇文章就把这套方案的来龙去脉、部署细节、路由设计和踩坑记录写清楚给同样不想被 API 绑架的朋友做个参考。先说结论这方案不一定适合所有人但如果你也在做企业内部工具、带知识库的问答机器人或者对数据边界比较敏感的小团队项目它大概率能帮你把成本降到原来的十分之一同时把命脉握在自己手里。1. 纯 API 方案的隐形账单我为什么决定自建1.1 按 Token 付费的账越算越不对劲先算一笔账。你可能觉得 DeepSeek 这类 API 已经很便宜单次调用才几分钱但你做内部工具的时候消耗的不是你输入的那几十个字而是每一次请求都被重复计算的上下文。我举个例子20 人团队的知识库问答机器人每人每天查 25 次就是 500 次请求每次把问题、命中的知识片段、最近 5 轮对话历史一起拼给模型平均按 2500 token 算一天就是 125 万 token。按 22 个工作日算一个月接近 2750 万 token。单独看单价确实不贵但乘上业务量之后一个月三四百块只是起点一旦某些复杂问题还要调用推理更强的高阶模型价格直接翻好几倍。最坑的是知识库越来越大以后为了让模型“记住”更多背景每次请求塞进去的上下文体量还会继续上涨。你以为你在写提示词其实你是在用真金白银反复烧同一批资料。所以我的第一个建议是从现在开始凡是接 API 的场景都先把 token 消耗记录下来。Dify 自带日志能看每次请求的 token 数别等到月底看账单才发现超额。1.2 数据不出内网的价值钱还是次要的更要命的是数据边界。我接过一个内部项目员工手册、合同范本、历史项目复盘全部进了知识库这些东西只要通过云端 API 走一圈等于把公司底裤晾在别人服务器上。供应商嘴上说数据有保护承诺但客户审计、内部合规这一关根本过不去。后来我想明白一件事真正适合云端 API 的是公开数据或不敏感任务而企业内部工具尤其是带知识库、带业务上下文的场景必须把“数据不出内网”当成硬需求再倒推架构。本地部署之后核心资料全部落在自己磁盘上不存在“上传到云端”这一步客户问起来也能直接给结论。这个价值很难用钱衡量但对很多团队来说它是比成本更致命的决策点。1.3 限流、断连与供应商锁定再有一个实际问题稳定性。云 API 平时看着很稳但高峰期该 429 还是 429偶尔机房抖动我这边所有依赖它的工作流就全部停摆。更麻烦的是锁定效应——一旦工作流的提示词、工具函数、会话管理全部围绕某一家供应商写死后面想换模型约等于重写整条应用。Dify 这类编排平台能把“供应商”抽象成插件不让提示词跟具体模型绑定死但如果你根本不跑本地模型那你只能在“用哪家云”之间做选择没有“不依赖云”的选项。本地模型存在之后你才真正拥有“换谁都能跑”的底气。这也是我后来坚决要上 Ollama 的原因不是为了省那点 token 费是为了把控制权拿回来。2. 整体架构怎么搭一套「本地优先、云端兜底」的路由设计2.1 三个组件各干什么事这套架构里三个角色各有分工别混着理解组件角色定位部署形态成本Dify应用编排、知识库管理、工作流、用户权限Docker Compose 或本机开源免费Ollama本地模型推理运行时离线可用宿主机裸装或容器免费只耗电DeepSeek API云端兜底处理本地模型搞不定的任务远程接口按 token 计费用户请求先到 DifyDify 决定该走哪个模型后端。Ollama 和 DeepSeek API 在 Dify 里都只是“模型供应商”插件同一个工作流里可以同时挂多个。向量检索、知识库分段、会话历史这些脏活累活都在 Dify 内部消化掉模型层相对干净。这套结构的核心不是“本地替代云端”而是“分工”批量、固定模板、敏感数据的活儿留在本地少量真正需要强推理的请求再上云。2.2 谁来决定「本地还是云端」路由规则设计路由是关键设计得当才能同时保住质量和钱包。我总结出三种思路实际部署时可以组合用。规则路由按任务类型分。日常问答、信息抽取、文本摘要、格式改写走本地代码生成、数学推理、长文分析走云端。规则清晰最容易落地。质量路由用一个小的分类模型判断问题难度或业务领域也可以让本地模型输出置信度低于阈值就自动转云端。容错路由不管前面怎么分只要本地节点超时、报错、进程崩溃就拉一个兜底分支把请求交给云端。这个分支必须存在否则本地模型一崩整条应用就跟着挂。打个生活化的比方本地模型是门诊医生处理常见病云端模型是三甲专家只有拿不准的时候才挂号。这样既不会让常见病排长队也不会逼着门诊医生硬诊疑难杂症。2.3 部署形态Windows / Linux / 内网服务器的通用方案部署形态我实际试过两种给你参考。Windows 单机Ollama 直接装 Windows 版Dify 用 Docker Desktop 跑。启动 Dify 容器后Ollama 的地址要写成http://host.docker.internal:11434因为容器里的localhost指向容器自己不是宿主。Linux 服务器一台 64G 内存的机器就能同时跑 7B 模型和 Dify 全家桶。Ollama 装裸机Dify 用 docker compose 起模型文件放独立数据盘别跟系统盘混在一起。端口规划上常见的是 80/443 给 Dify Web11434 给 Ollama。还要考虑并发7B 模型在消费级显卡上单用户大概能跑到 20–40 token/s但多人同时用会明显变慢。Dify 应用层可以限制并发数或者做排队如果团队超过十几个人同时用建议上更好的显卡否则体验会变差。3. 本地模型选型与部署细节Ollama 不是装完就能跑3.1 模型挑选Qwen 系列作为起点本地模型不是越大越好要按显存、内存、任务复杂度一起看。我给一个经过实测的选型表模型参数量最低显存Q4 量化适合任务备注qwen2.5:3b3.2B3-4GB粗分类、简单改写能力较弱适合做路由判断qwen2.5:7b7.6B6-8GB中文问答、摘要、信息抽取最稳的起点llama3.1:8b8.0B8-10GB英文任务、轻度代码中文表现不如 Qwendeepseek-r1 蒸馏版1.5B-8B4-10GB逻辑推理尝试蒸馏模型能力有限别期待太多大多数人起步选qwen2.5:7b最合适中文能力强资源占用可控7B 的 Q4 量化在 8G 显存上能流畅跑。显存特别紧张的可以先用qwen2.5:3b顶一顶但效果差距很明显只适合做分类或路由不适合做正经问答。3.2 部署与模型拉取装好、拉不动、离线导入Ollama 的安装本身很简单。Linux 上可以一条命令装完curl -fsSL https://ollama.com/install.sh | shWindows 直接下载安装包装完在命令行里就能用。接着拉模型ollama pull qwen2.5:7b这里有一个大家几乎都会遇到的问题模型仓库在境外拉取速度很慢甚至断掉。我的处理方式是不要死等官方仓库直接从国内公开镜像站点下载 GGUF 格式的模型文件然后本地导入。步骤如下先下载qwen2.5-7b-instruct-q4_k_m.gguf放到某个目录比如/data/models/然后在同一目录写一个ModelfileFROM /data/models/qwen2.5-7b-instruct-q4_k_m.gguf接着运行ollama create qwen2.5-7b -f Modelfile这样模型就直接注册到 Ollama 里了再ollama run qwen2.5-7b就能用。这种方式绕开了慢速拉取而且 GGUF 文件从哪里下载都可以版本可控。另外提醒一句Ollama 的模型文件非常占磁盘。7B 模型大约 4-5GB14B 就奔着 9GB 去了。平时用ollama list看看本地都有什么用ollama rm 模型名清理不用的不然很快能把你的数据盘塞满。3.3 实测效果本地模型能干的和干不了的我跑了两个月之后对本地 7B 模型的能力边界有了比较明确的感觉。能干得很好的任务信息抽取从合同、邮件、日志里抽字段和关键日期文案润色与改写保留原意的前提下换语气、压字数简单分类工单打标签、问题归类、情绪判断格式化输出把一段自由文本转成固定的 JSON 模板。明显干不好的任务复杂数学推理和多步逻辑几十行代码的调试和重构超长文档的精确归因经常张冠李戴需要融合大量业务规则的客服问答规则一多就漏。这不是说本地模型没用而是说你要按能力分活。让 7B 模型去硬扛复杂推理结果一定很糟糕你以为是模型问题其实是用错了场景。这也是为什么架构里一定要留云端兜底——本地负责批量云端负责疑难各司其职。3.4 常见事故llama-server 500 与进程被杀Ollama 跑着跑着突然报错是新手最崩溃的时刻。最常见的报错长这样ollama run qwen2.5:7b Error: 500 internal server error: llama-server process terminated我第一次看到这报错以为是模型坏了重新拉了一遍还是不行。后来排查才发现问题大多出在资源上。排查链路我建议按下面这个顺序走先看 Ollama 当前加载了什么模型ollama ps看机器内存和显存是不是爆了free -h和nvidia-smi翻 Ollama 日志。Linux 下是journalctl -u ollama或~/.ollama/logs/server.log如果日志显示 out of memory / killed基本就是资源不足导致的进程被杀如果确认磁盘和内存都够再考虑模型文件损坏删掉重新拉一遍。大多数 500 都不是模型文件的问题而是并发请求一多、显存被占满系统直接 OOM。所以 Ollama 跑 7B 模型至少给它留 8GB 显存或 12GB 内存空间同时做并发限制别让 Dify 把所有请求一次性灌给本地模型。4. Dify 接入本地与云端模型从配置到工作流的那些坑4.1 Ollama 供应商配置base_url 和模型 tag 的细节Dify 接入 Ollama 的路径是Dify 控制台 → 设置 → 模型供应商 → Ollama。这里有两个特别容易踩坑的点。第一个是Base URL。如果 Dify 是用 Docker 跑的那容器里的localhost不等于宿主机。你必须写宿主机可达的地址Windows 下用http://host.docker.internal:11434Linux 下写http://192.168.x.x:11434总之不能用http://localhost:11434。第二个是模型名称必须带 tag。在 Dify 里填模型 ID 的时候要写qwen2.5:7b不能只写qwen2.5。很多教程里只写qwen2.5测试的时候就会提示模型不存在。之后再把上下文长度按你本地模型的支持度填上比如 4096。配置完一定要点一下后面的“测试”按钮。Dify 会调一次接口确认通不通如果提示失败优先检查 base_url 能不能从容器里访问而不是怀疑模型坏了。4.2 DeepSeek 供应商与凭据验证失败401 到底卡在哪云端兜底我用的是 DeepSeek API在 Dify 模型供应商里添加 DeepSeek填 API Key模型选deepseek-chat。这一步看起来简单但真实遇到过的报错有两个一个是配置保存时提示an error occurred during credentials validation另一个是调用时报unexpected status 401 unauthorized: incorrect api key provided: sk-svcac****凭据验证失败的排查顺序先确认 API Key 复制完整前后有没有多余空格确认选的是 DeepSeek 供应商不是 OpenAI 或其他兼容项确认 Dify 所在服务器能访问 DeepSeek 的接口域名公司内网经常有防火墙或网络策略拦截这种情况会显示同样的凭据错误如果最后一步是换过 key那 Dify 里可能存在旧 key 缓存删掉供应商重新添加一次。最直接的方法是用 curl 绕开 Dify直连 DeepSeek 接口验证 key 本身可用curl https://api.deepseek.com/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的key \ -d {model:deepseek-chat,messages:[{role:user,content:ping}],max_tokens:10}如果 curl 能正常返回内容说明 key 没问题问题出在 Dify 侧如果 curl 本身也报 401那就是 key 本身不对去控制台重新生成一个再填。4.3 SSL / HTTPS 报错排查从日志看起“Dify SSL 错误”这个名字看着吓人实际上大多数时候是配置不对称导致的。我把它拆成三类情况浏览器访问 Dify 控制台时提示证书无效多半是反代层或者入口用 HTTPS 但证书过期/自签。内网使用建议直接用 HTTP没必要套 HTTPS。Dify 后端调用 Ollama 时出现 SSL 相关报错Ollama 默认是 HTTP 服务如果你在 base_url 里写了https://当然会握手失败。公网部署时证书配置在 Nginx 或 Caddy 反代层终止 TLS让外部走 HTTPSDify 后端保持 HTTP。公网场景我建议用 Nginx 反代配置大致长这样server { listen 443 ssl; server_name your.domain.com; # 填你自己的证书路径 ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem; location / { proxy_pass http://127.0.0.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }如果你在内网环境最简单的方式就是全链路 HTTP不折腾证书。不要自己给 Dify 容器塞一堆 openssl 配置那是一条没有尽头的路。先分清是浏览器层、调用层还是反代层的问题再对症处理比瞎改配置高效得多。4.4 上下文超长百万 token 也塞不下整个知识库我在测试阶段遇到过一个很典型的报错api error: 400 this models maximum context length is 1048576 tokens. however...这个报错来自云端接口提示模型上下文窗口是 1048576 tokens但我传的内容超过了限制。问题在于我当时天真地把整个知识库的文档摘要拼进了系统提示词想着“百万 token 够大肯定装得下”。结果不仅没装下还差点把请求打爆。这里必须想清楚一件事模型窗口大不等于你应该塞满它。把大量无关上下文塞进去会让检索质量下降、响应变慢而且云端的 token 成本直接爆炸。正确做法是走 RAG而不是全文堆砌。Dify 知识库检索节点有几个关键参数直接给一组经验值分段长度500-800 字TopK6 左右相似度阈值从 0.3 起调命中少了就往下降对话历史只保留最近 4-6 轮再早的内容用摘要节点提前压缩不要无限带。这样既保证上下文可控又不会让模型在无关信息里找答案。4.5 文档解析失败与 Dify 迁移Unstructured 服务与数据备份做知识库的时候很多人喜欢直接传 PDF 和 Word然后看到报错unstructured api url is not configured for doc file processing.这个报错的来龙去脉是Dify 上传 PDF/Word 后需要调用独立的文档解析服务来抽取内容如果该服务没有启动或者 URL 没配置就会提示未配置。解决办法有两种。一种是正经解法在 Dify 的 docker-compose 配置文件里启用 unstructured 容器设置对应的 URL 环境变量让文档解析服务跑起来然后再上传 PDF。这样 Dify 就能自己抽取内容、做分块。另一种是省事解法小团队文件量不大就不要跟 PDF 较劲。先把 PDF 转成 Markdown 或纯文本再用 txt/md 建知识库。Dify 对纯文本和 Markdown 的解析非常稳定不依赖额外服务。复杂 PDF 可以用开源工具在本地转一下再传绕开这个坑。顺带说一个很多人问的迁移问题。Dify 的所有数据都在它自己的volumes目录里迁移到新机器时把整个 volumes 目录拷贝过去在新机器上重新docker compose up -d就行。唯一要留意的是模型供应商的 API Key 有时候需要重新填一次其他数据基本都在。5. 混合路由工作流实录一套对话应用的成本与效果复盘5.1 工作流设计意图分类 条件分支 兜底节点Dify 里搭混合路由我实际用起来最顺的结构是下面这样用文字描述不依赖复杂画图工具开始节点接收用户消息一个 LLM 分类节点判断用户问题属于“简单/常规任务”还是“复杂/推理任务”条件分支节点根据分类结果下发简单任务 → Ollama 本地节点 → 生成回复复杂任务 → DeepSeek 云端节点 → 生成回复额外挂一个兜底分支如果本地节点报错或超时自动走云端节点。分类节点本身用本地小模型就够比如qwen2.5:3b。因为分类任务很轻用本地跑不会产生云端费用。条件分支的判断词要写清楚“不确定就归为复杂”宁可多花一点云端费用也不要让简单模型去硬答复杂问题。这套结构最大的好处是它把成本控制前移了。绝大多数常规问题在本地就消化掉了云端只在真正需要的时候被调用同时兜底分支保证了本地模型崩溃时用户不会看到一个毫无回应的死应用。5.2 真实账单对比自建前后的成本变化以我自己的团队为例上线混合路由一个月之后的账单对比如下口径纯云端方案本地优先 云端兜底月请求量约 2.2 万次约 2.2 万次本地承担比例0%约 80%云端请求量2.2 万次约 4000 次云端 token 消耗约 3000 万约 350 万预估月成本400-600 元50-80 元说明一下具体数字会因业务不同而浮动但趋势非常明确把固定模板类、批量类、敏感类任务往本地压云端的钱只花在少量高难任务上成本自然降下来。代价是你要多维护一套本地模型环境但 Ollama 的维护成本其实不高只要别去追最新版本稳定跑几个月没问题。5.3 后续扩展多模型轮换、迁移备份与优化方向这套架构跑顺之后可扩展空间比我想象的大。第一多模型轮换很方便。Dify 的模型供应商是插件化的同一个工作流里可以随时挂新的供应商本地想换更强的模型只要更新 Ollama 里的模型文件Dify 填新模型名就行。第二Dify 迁移和备份很简单。前面提过整个 volumes 目录拷贝走新机器docker compose up -d数据就回来了。第三后续优化方向可以考虑把 Embedding 也换成本地模型。现在很多知识库应用还在用云端 Embedding每次入库、查询都在烧 token。如果本地模型能承担这部分成本能再压一截。前提是你本地机器吃得消毕竟 Embedding 和生成模型同时跑资源占用确实不小。最后给一个实在的建议不要一开始就追求完美的路由策略。先用最简单的规则把整个流程跑起来用 Dify 自带的日志统计一周看看真实请求都落在哪类任务上。然后再决定哪些任务留在本地、哪些上云那时候你的成本优化才是真正对症的而不是拍脑袋拍出来的。这套架构并没有把 AI 变得更聪明它只是把聪明用在了刀刃上。我几个月的体会有两个一是路由规则比本地模型大小更重要宁可让本地模型做简单事也别让它硬扛复杂推理二是先跑通再优化不要一上来就折腾复杂的混合策略。每次调整完模型或供应商之后先在 Dify 的调试预览里手动跑三种问题类型——简单的、复杂的、完全无关的——不然你连模型什么时候悄悄变了都不知道。这样搭出来的平台既保住了数据边界也让 API 账单回到了一个正常人能接受的数字。