你本地已经跑着 Ollama,手上还有一个 DeepSeek 的 API Key,想在一个脚本里既用本地模型又用远端接口——结果多半卡在「Ollama 的 OpenAI 兼容层到底能指到哪」「Key 该放哪一层」「同一个 SDK 能不能同时管两边」。这篇不讲协议原理,只给能照着做的工程做法:怎么选调用路径、参数怎么对齐、超时并发怎么设、连通怎么验、出问题按什么顺序查。
你本地已经跑着 Ollama,手上还有一个 DeepSeek 的 API Key,想在一个脚本里既用本地模型又用远端接口。真正卡人的地方往往不是代码写不出来,而是三件事没想清楚:Ollama 的兼容层到底能指到哪、Key 该放在哪一层、同一个 SDK 能不能同时管两边。
这篇不讲协议原理,只给能照着做的工程做法。先定调用路线,再把配置和密钥分开落位,然后处理超时与并发,最后按一个固定顺序验连通、查问题。末尾留一套日志和回归办法,保证你换完配置之后知道有没有把原来的东西弄坏。
先定路线:让 Ollama 转发,还是让代码分别直连
第一条路是把请求打到 Ollama 的本地端口,由它转发出去;第二条路是代码里维护两套 base_url,按任务自己切换。前者配置集中、改动小,但可控参数少;后者灵活,代价是 Key、超时、重试都得你自己管。选哪条,取决于你要不要统一入口做日志、要不要按模型做降级、以及是不是只在个人机器上跑。
- 转发路线
- 所有请求先到本机端口,好处是入口统一,坏处是远端鉴权和重试不一定透明
- 直连路线
- 代码里分别指向本地和远端两个地址,参数完全可控,但要自己维护两套配置
- 混合路线
- 本地模型走转发、远端接口直连,适合既要统一日志又要精细控制的场景
如果对「兼容层」「base_url」这些词的含义还没把握,先去 /ai-dict 把术语对齐,再回来看自己的调用链,能省掉很多来回试错的时间。
配置落位:环境变量、base_url 与模型名的对齐
Key 只放环境变量或本地未入库的配置文件。不要写进前端代码,不要提交到仓库,更不要和 Ollama 的本地配置塞进同一个文件——分开存放,轮换的时候才不会牵一发动全身。
- 分离两套地址变量本地那套用 localhost 写法,远端那套用服务商给的地址,变量名区分开。混写成同一个变量,切换时必然出错。
- 校验模型名本地拉取的模型名和远端接口接受的模型名不是一回事。发请求前先确认对方文档里写的标识,混用会直接报找不到模型。
- 精简请求体字段优先只保留两边都认的字段。多出来的字段在转发路径上容易被吞掉,也可能直接触发报错。
要挑远端平台,可以到 /ai-nav/category/ai-api 按自己的需求筛;接口字段的差异则对照 /openai-compatible-interface-spec 逐项核,尤其是那些名字一样但含义不同的参数,最容易埋坑。
超时、并发与降级:本地快远端慢,怎么不互相拖死
本地推理和远端接口的延迟特性完全不同:本地吃显存、首字可能慢但后段稳定;远端受网络和额度限制、抖动更大。把两者的超时和并发混在一起设,结果就是一边拖死另一边。
| 维度 | 本地链路 | 远端链路 |
|---|---|---|
| 连接超时 | 可以设得短一些 | 按网络情况适当放宽 |
| 读取超时 | 按模型推理速度定 | 通常要明显长于本地 |
| 并发上限 | 受显存约束 | 受额度与限流约束 |
| 失败处理 | 本地报错多为加载失败 | 远端多为超时或限流 |
- 连接超时和读取超时分开设,不要沿用同一份默认值
- 并发池不要共用:本地和远端各自排队,否则本地任务会被远端限流拖住
- 降级顺序写死在代码里,远端超时或限流时切本地继续跑,但要标记结果来源
- 重试只对幂等请求做,加退避;流式请求断流后要能接着拼,不要从头再来
- 降级输出一定要打标记,避免下游把它当成同质量结果使用
降级这件事有明确的适用边界:如果任务本身对输出质量有硬要求,那切到本地模型继续跑只是为了让流程不中断,结果必须人工复核。不确定的时候,宁可让请求失败,也不要静默降级。
连通验证与排错顺序:五步从近到远
最常见的错误是一上来就查整合代码,其实问题多数出在更近的地方。按从近到远的顺序查,能少走很多弯路。
- 验本机端口先确认本地端口活着、能返回模型列表。这一步不通,后面都不用看。
- 验远端接口单独用最简请求打远端,确认地址和鉴权没问题。两边分别验完再合起来测。
- 核对地址与路径检查有没有拼错端口、有没有多写一层路径。这是最常见的 404 来源。
- 查鉴权看 Key 是否带对前缀、是否被环境变量覆盖成空值。401 类问题可以到 /tools/verify 定位。
- 查模型名与字段确认模型名和请求字段被对方接受,最后再排查代理、证书这类网络层问题。
每次失败都把完整响应体记下来,只留一个状态码很难复盘。接口延迟基线可以用 /tools/speed-test 量一遍,之后判断「是不是变慢了」就有参照。
日志与回归:怎么知道换配置后没坏事
日志不是越多越好,关键字段记全就够。每次请求至少记四项:走的是本地还是远端、用的哪个模型名、耗时、失败原因分类。这样出问题能按链路统计,而不是一条条翻。
- 准备一份固定用例集,十几条就够,覆盖短问答、长输入和流式输出
- 改配置、换模型名、调超时之后跑一遍,看输出格式和成功率有没有明显变化
- 对比时只比同一批用例的相对变化,绝对数值受环境和时段影响,别拿不同时间的两次结果下结论
- 用量与成本的口径不要凭感觉,到 /tools/token-price-calculator 按自己的调用量折算
- 把每次配置变更和回归结果记在一起,下次改坏了能快速回滚
调用链能不能长期跑得住,靠的不是某次调通,而是每次改完配置都知道自己有没有弄坏别的部分。
常见问题
本地模型和远端接口的模型名能写成同一个吗?
不能。本地拉取的模型名由你本地决定,远端接口的模型名由对方平台规定,两边取值不同。写成同一个变量后,切链路时必然有一边报找不到模型。稳妥做法是两个独立配置项加一个「用哪边」的开关。
远端接口超时了,要不要直接把请求转本地?
要看场景。对格式要求高、结果要进下游的任务,静默降级会让输出质量不一致;更稳的是先重试一次,仍失败再切本地,并在日志和返回结构里标出来源,让调用方能判断要不要人工复核。