news 2026/10/12 20:16:14

数据不出内网:基于Ollama+OneAPI构建企业专属DeepSeek智能中台

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据不出内网:基于Ollama+OneAPI构建企业专属DeepSeek智能中台

1. 内网部署 DeepSeek 的真实困境与破局思路

很多企业想把大模型用起来,第一反应是调云端 API,但真到落地阶段,安全部门一句"数据不能出内网"就把方案打回去了。尤其是金融、医疗、制造业的研发团队,代码、工单、客户资料这些内容一旦离开内网,合规上根本过不去。我接触过几个团队,他们的诉求非常一致:模型要能跑在自己的服务器上,接口要统一,最好还能像调 OpenAI 那样一行代码切换模型。

这就是"企业专属 DeepSeek 智能中台"要解决的问题。核心思路其实不复杂:用 Ollama 在内网服务器上把 DeepSeek 跑起来,再用 OneAPI 做一层统一网关,把 Ollama 的本地模型、以及未来可能接入的其他模型,全部包装成标准的 OpenAI 兼容接口。这样上层业务系统只需要认一个 Base URL 和一个 Key,底层换模型、加模型都不用改业务代码。

为什么选 DeepSeek?因为它在中文推理、代码生成上的表现确实能打,而且开源权重可以本地部署,32B 量化版本在单张 24G 显存的卡上就能跑起来,对中小企业来说门槛可控。为什么选 Ollama?它把模型加载、显存管理、API 暴露这些脏活都封装好了,一条ollama serve就能对外提供 HTTP 接口。为什么还要 OneAPI?因为 Ollama 原生接口虽然能用,但格式和 OpenAI 不完全一致,而且多模型、多 Key、用量统计这些企业级需求它不管,OneAPI 正好补上这块。

整个链路是这样的:业务系统 → OneAPI(统一网关,端口 3000)→ Ollama(本地推理,端口 11434)→ DeepSeek 模型。数据全程在内网流转,不出网卡。下面我把这套中台的搭建过程拆成可复制的步骤,包括离线环境下的模型导入、OneAPI 的渠道配置、以及连通性验证。

2. 前置准备:Ollama 离线安装与 DeepSeek 模型导入

内网服务器最大的坑就是装不了东西。Ollama 官方的一键脚本curl -fsSL https://ollama.com/install.sh | sh在内网直接歇菜,因为脚本本身要联网下载二进制包。所以必须走离线路线:在有网的机器上下载好安装包和模型文件,再通过 U 盘或跳板机传进内网。

先说 Ollama 的离线安装。根据服务器架构(一般是 linux-amd64),在有网机器上执行:

curl -L https://ollama.com/download/ollama-linux-amd64.tgz -o ollama-linux-amd64.tgz

下载完通过 scp 或堡垒机传到内网服务器,比如放到/tmp目录。然后解压安装:

sudo tar -C /usr -xzf /tmp/ollama-linux-amd64.tgz

解压后/usr/bin/ollama就有了,直接执行ollama serve能跑起来。但为了让它开机自启、方便管理,建议注册成 systemd 服务。先创建专用用户:

sudo useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama sudo usermod -a -G ollama $(whoami)

然后在/etc/systemd/system/ollama.service写入:

[Unit] Description=Ollama Service After=network-online.target [Service] ExecStart=/usr/bin/ollama serve User=ollama Group=ollama Restart=always RestartSec=3 Environment="PATH=$PATH" Environment="OLLAMA_HOST=0.0.0.0:11434" [Install] WantedBy=default.target

注意这里加了OLLAMA_HOST=0.0.0.0:11434,否则 Ollama 默认只监听 127.0.0.1,OneAPI 容器访问不到。改完执行:

sudo systemctl daemon-reload sudo systemctl enable --now ollama

接下来是模型导入,这是内网部署最绕的一步。内网没法ollama pull,得先在本地机器上把模型拉下来,找到模型文件,再传进去。本地执行:

ollama pull deepseek-r1:32b ollama show deepseek-r1:32b --modelfile

输出里会有一行FROM C:\Users\xxx\.ollama\models\blobs\sha256-96c415...,这个路径就是模型权重文件。同时把 Modelfile 导出:

ollama show deepseek-r1:32b --modelfile > Modelfile

把权重文件和 Modelfile 一起传到内网服务器同一目录,比如/opt/models/deepseek。进去后重命名权重文件,方便识别:

mv sha256-96c415656d377afbff962f6cdb2394ab092ccbcbaab4b82525bc4ca800fe8a49 deepseek-r1_32b.gguf

然后编辑 Modelfile,把FROM那行改成相对路径:

FROM ./deepseek-r1_32b.gguf

最后导入:

ollama create deepseek-r1:32b -f Modelfile ollama list

看到deepseek-r1:32b出现在列表里,模型这步就成了。这里有个细节:Modelfile 里的 TEMPLATE 和 PARAMETER 不要动,那是 DeepSeek 的对话模板,改了会导致输出格式错乱。

3. OneAPI 网关部署与渠道配置可复制片段

模型跑起来只是第一步,要让业务系统方便调用,还得有 OneAPI 这层网关。OneAPI 是开源的 LLM API 管理与分发系统,能把 Ollama、OpenAI、Claude 等各种后端统一成 OpenAI 格式。内网部署同样用 Docker,先写docker-compose.yaml:

services: db: image: mysql:8.1.0 container_name: mysql restart: always environment: MYSQL_ROOT_PASSWORD: mysql-password volumes: - ./data:/var/lib/mysql one-api: image: justsong/one-api container_name: one-api restart: always ports: - "3000:3000" depends_on: - db environment: - SQL_DSN=root:mysql-password@tcp(db:3306)/one_api - TZ=Asia/Shanghai - TIKTOKEN_CACHE_DIR=/TIKTOKEN_CACHE_DIR volumes: - ./data:/data - ./TIKTOKEN_CACHE_DIR:/TIKTOKEN_CACHE_DIR networks: default: name: one-api

这里有个内网必踩的坑:OneAPI 依赖 tiktoken 做 token 计数,而 tiktoken 启动时会去openaipublic.blob.core.windows.net下载编码文件,内网直接超时。报错长这样:

[FATAL] failed to get gpt-3.5-turbo token encoder: dial tcp ... i/o timeout, if you are using in offline environment, please set TIKTOKEN_CACHE_DIR to use exsited files

解决办法是手动把编码文件放进去。tiktoken 认的是 URL 的 SHA-1 作为文件名,先算哈希:

echo -n "https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken" | sha1sum | head -c 40

输出是9b5ad71b2ce5302211f9c61530b329a4922fc6a4。在有网机器上下载cl100k_base.tiktoken,重命名为这个哈希值,放进./TIKTOKEN_CACHE_DIR目录。如果日志里还报别的 encoder 缺失,重复这个操作,直到启动不再报错。

启动服务:

docker compose up -d docker compose logs -f one-api

看到监听 3000 端口就 OK。浏览器访问http://内网IP:3000,默认账号root,密码123456,首次登录务必改掉。

接下来配置 Ollama 渠道。进后台「渠道」→「添加新的渠道」,关键字段这样填:

字段值说明
类型Ollama下拉选择
名称deepseek-local自定义
分组default默认分组
模型deepseek-r1:32b与 ollama list 一致
代理留空内网直连
密钥任意填Ollama 不校验

最容易卡住的是「代理」地址。OneAPI 跑在容器里,容器内的localhost指向容器自己,不是宿主机。所以不能填http://localhost:11434。两种解法:一是让 OneAPI 容器用 host 网络模式,network_mode: host,然后填http://127.0.0.1:11434;二是保持 bridge 网络,填http://host.docker.internal:11434,但 Linux 下需要在 compose 里加extra_hosts: - "host.docker.internal:host-gateway"。我一般用第一种,省事。

渠道建好后,去「令牌」页面新建一个令牌,这就是业务系统要用的统一 Key。到这里,网关层就通了。

4. 内网调用验证与连通性排查动作

配置完不验证等于没配。验证要分两层:先确认 Ollama 本身能出结果,再确认通过 OneAPI 能出结果。

第一层,直接在服务器上打 Ollama 原生接口:

curl http://127.0.0.1:11434/api/generate -d '{ "model": "deepseek-r1:32b", "prompt": "用一句话解释什么是向量数据库", "stream": false }'

如果返回 JSON 里有response字段且内容是中文,说明模型加载正常。如果卡住不动,多半是显存不够,去看nvidia-smi或者journalctl -u ollama -f的日志。

第二层,走 OneAPI 的 OpenAI 兼容接口。假设 OneAPI 在内网 IP192.168.1.100,令牌是sk-xxxxxxxx:

curl http://192.168.1.100:3000/v1/chat/completions \ -H "Authorization: Bearer sk-xxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-r1:32b", "messages": [{"role": "user", "content": "写一个 Python 快速排序"}], "stream": false }'

返回结构里choices[0].message.content就是模型输出。这一步通了,说明整条链路打通:请求进 OneAPI,OneAPI 转发给 Ollama,Ollama 推理后原路返回。

Python 业务侧调用更简单,用 openai 官方 SDK 改个 base_url 就行:

from openai import OpenAI client = OpenAI( base_url="http://192.168.1.100:3000/v1", api_key="sk-xxxxxxxx" ) resp = client.chat.completions.create( model="deepseek-r1:32b", messages=[{"role": "user", "content": "帮我审查这段 SQL 有没有注入风险"}] ) print(resp.choices[0].message.content)

这样业务代码完全不用感知底层是 Ollama 还是别的,未来要加模型,只在 OneAPI 后台加渠道,业务侧改个 model 名即可。

连通性排查我整理了一个顺序:先在服务器上curl 127.0.0.1:11434确认 Ollama 活着;再curl 127.0.0.1:3000确认 OneAPI 活着;然后从另一台内网机器curl 192.168.1.100:3000确认端口没被防火墙拦;最后带上 Key 打完整请求。哪一步断,问题就锁定在哪一层。

5. 常见报错排查:401、local proxy failed 与 reading choices

内网搭这套东西,报错基本集中在几个固定位置。我把踩过的坑按现象列出来,对照着查能省不少时间。

401 Unauthorized。这个最常见,八成是 Key 的问题。先确认请求头里Authorization: Bearer sk-xxx格式对不对,Bearer 后面有空格。再确认令牌在 OneAPI 后台是不是被禁用或额度耗尽。还有一种情况是令牌绑定的分组和渠道分组不匹配,比如令牌是 default 分组,渠道却建在 vip 分组,请求就会 401。去「令牌」页面看分组设置,和渠道保持一致。

local proxy failed / dial tcp 127.0.0.1:11434 connection refused。这是 OneAPI 连不上 Ollama 的典型报错。原因就一个:容器网络隔离。OneAPI 容器里的 127.0.0.1 不是宿主机。解决方式前面提过,要么把 OneAPI 改成 host 网络,要么用host.docker.internal并配extra_hosts。改完记得docker compose down && docker compose up -d重建容器,光 restart 不生效。

reading choices: unexpected end of JSON input。这个报错说明 OneAPI 收到了 Ollama 的响应,但解析失败。常见原因是 Ollama 返回了非标准格式,或者模型名对不上。先确认渠道里填的模型名和ollama list输出完全一致,大小写、冒号都不能差。再确认 Modelfile 导入时没改坏 TEMPLATE,模板错了会导致输出结构异常。如果还不行,去 OneAPI 日志里看原始响应:

docker compose logs -f one-api | grep -i "choices"

OAuth / 登录相关报错。如果你用的是 OneAPI 的 OAuth 登录(比如接企业 SSO),内网环境下回调地址配错会一直跳转失败。检查后台「系统设置」里的服务器地址,必须填内网可访问的地址,不能填 localhost。另外首次部署如果没改默认密码,有些版本会强制要求改密,按提示操作即可。

模型加载超时或 OOM。这不是 OneAPI 的问题,是 Ollama 侧显存不够。32B 模型量化后大概需要 20G 左右显存,如果卡是 16G 就会加载失败。换 14B 或 7B 版本,或者用ollama ps看当前加载状态。日志里出现CUDA out of memory就是显存爆了。

排查这类问题有个通用心法:先分层定位,再逐层缩小。Ollama 层、网络层、OneAPI 层、业务层,每层单独验证,不要一上来就怀疑最上层。

6. 从本地中台到统一接入:长期编码场景的延伸

内网中台搭好之后,日常的模型调用就统一走 OneAPI 这一个入口了。但实际用起来你会发现,团队里不同角色的需求差异挺大:有人只是偶尔问问问题,有人要长期跑 Agent 做代码审查,还有人需要把模型接进 IDE 做补全。这时候光有一个内网网关还不够,得考虑怎么把内网模型和外部能力做统一调度。

我的做法是保留内网 OneAPI 作为主入口,同时用 TaoToken 这类统一接入层来管理多来源的模型调用。它的价值在于把不同后端(本地 Ollama、云端模型)的 Key 和 Base URL 收敛成一套配置,业务侧不用为每个来源写一套适配代码。对于需要长期跑编码任务的场景,可以直接用 Coding Plan 把模型调用额度管起来,避免某个 Agent 把额度跑爆。

具体接入时,Base URL 填https://taotoken.net/api,Key 在控制台的 API Keys 页面生成,Model ID 按你实际要用的模型填。这三件套配好,无论是 Cline、Codex 还是自己写的脚本,都能用同一套凭证。如果你还在选模型阶段,可以先去模型对话页面实测一下不同模型在代码任务上的表现,再决定长期用哪个。

需要说明的是,内网中台和统一接入层不是替代关系。内网中台解决的是"数据不出内网"的合规底线,统一接入层解决的是"多模型调度和额度管理"的效率问题。两者配合,才能既守住安全,又不牺牲开发体验。对于刚开始搭中台的团队,建议先把 Ollama + OneAPI 这条链路跑通,验证模型效果和性能,再考虑接入层的扩展。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/12 20:15:58

云原生技术演进与避坑指南:从容器到编排的实战解析

简介:云原生技术的前世今生以PDF图解形式梳理技术脉络,定位为入门科普与架构演进参考,适合开发者、运维人员、架构师及云原生初学者。内容基于云原生计算基金会的定义,系统讲解容器、服务网格、微服务、不可变基础设施、声明式API…

作者头像 李华
网站建设 2026/10/12 20:14:01

Arch Linux 安装 Codex 桌面版:从 AUR 到 pacman 的完整配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/12 20:13:10

海康NCG V5.11.100 CentOS7部署避坑指南

简介:本资源是海康威视iSecure Center综合安防管理平台中视频联网网关(NCG)V5.11.100版本的官方安装部署手册,面向安防系统集成工程师、平台运维人员及二次开发技术人员,解决NCG组件在新软件体系架构下的标准化部署、集…

作者头像 李华
网站建设 2026/10/12 20:13:07

Open Code Review 实战:从流程设计到工具链的代码评审落地指南

1. 从"open-code-review"这个名字说起:它到底想解决什么问题第一次看到open-code-review这个标题,我脑子里蹦出来的第一个念头是:这大概率不是一个具体的工具名,而是一类工程实践的统称——把代码评审这件事从"关起…

作者头像 李华
网站建设 2026/10/12 20:07:45

PL0编译器设计与实现:从词法分析到中间代码生成的编译原理实验指南

简介:这是山东大学编译原理课程PL/0编译器实验的完整实现,面向计算机专业学生及编译原理学习者,覆盖词法分析、语法分析、语义分析与符号表建立等编译器前端核心环节。压缩包共94个文件、约513KB,以C/C源码、CMake构建脚本、可执行…

作者头像 李华
网站建设 2026/10/12 20:07:07

open-code-review:让代码评审有据可查、有果可闭环的工程实践

1. 项目概述:open-code-review 到底要解决什么代码评审这件事,但凡在团队里待过一两年的人,都经历过那种“评审2小时,改动3行”的尴尬局面。评审邮件发出去没人理,约了个会议大家对着屏幕沉默,等终于有人说…

作者头像 李华