如果我比别人看得更远,那是因为我站在巨人的肩上。 – 艾萨克·牛顿

不知道您是否像我一样:希望自己能有一个完全本地部署的AI实验室,它有可视化界面,可以与大模型聊天,可以做智能体,还可以提供标准化的接口…

ChatboxDifyOllama 与 Qwen(通义千问)大模型完全可以整合在一起,且整合后能形成 “本地模型 + 可视化开发管理 + 多端交互” 的完整 AI 应用链路。四者的定位互补性强,整合核心逻辑是 Ollama 负责本地运行 Qwen 模型 → Dify 提供模型管理与应用开发能力 → Chatbox 作为轻量客户端实现多端交互

系统/模型 核心定位 关键角色
Ollama 轻量本地大模型运行框架 「模型载体」:简化本地模型部署,支持一键启动 Qwen、Llama 等开源模型,提供 API 接口供外部调用
Qwen(通义千问) 阿里开源大模型(如 Qwen-8B/14B) 「核心能力源」:提供对话、生成、推理等 AI 能力,需依赖 Ollama 或其他框架运行
Dify 开源 LLM 应用开发平台 「开发与管理中枢」:支持接入 Ollama 部署的 Qwen 模型,提供可视化 workflow、RAG 检索、Agent 工具链,可快速搭建 AI 应用(如问答系统、智能助手)
Chatbox 多端 AI 客户端 「交互入口」:支持接入 Dify 或 Ollama 的 API,提供桌面(Windows/Mac/Linux)、移动端(iOS/Android)的轻量交互界面,优化用户使用体验

下面我们就一步一步的把这个AI实验室搭建起来。

环境准备

  • CPU: 4核,内存: 32G,GPU: 可选

    如果没有GPU,大模型运行速度会慢很多

  • 操作系统:Ubuntu

    windows也可以,但是要麻烦很多,部署中间也容易出各种问题


安装 dockerdocker-compose

参见:在ubuntu中离线安装docker和docker-compose

部署 ollama 和大模型 qwen

参见:在ubuntu中离线部署ollama和大模型qwen

构建和部署 web 版本的 Chatbox docker镜像

点击这里下载已经构建好的docker镜像

Chatbox 默认是桌面端 Electron 应用,所以构建纯 web 的 docker 容器时,需要自定义构建过程。

由于这不是“正宗”的使用方式,所以官方文档中并没有明确的支持,我在构建的时候花了不少精力踩坑。

详细的构建过程请参见:构建chatbox的web版本的docker镜像

部署 chatbox-web (与 ollama 在同一台服务器)

如果将 chatbox-web 部署在 ollama 同一台服务器上,按照上述步骤启动 Chatbox-web 后,就可以配置模型提供方了,具体步骤如下:

点击左下角 设置 按钮 -> 在模型提供方中选择 Ollama 。下面的配置供参考:

Ollama的配置
Ollama大模型的配置

请注意,API主机只填写 IP 和 端口号 即可

配置完毕后,就可以和大模型聊天了。

部署 chatbox-web (与 ollama 不在同一台服务器)

如果硬件条件比较好,通常我们不会把 chatbox-webollama 部署在同一台服务器上,比如下面的情形:

  • ollama地址:http://10.10.145.101:11005
  • chatbox-web地址:http://10.10.145.102:8001/
  • 客户端IP:10.10.145.111

解决 CORS(Cross-origin resource sharing,跨域访问)错误

在此情境下,当我们在 客户端 上打开浏览器打开 chatbox-web 进行聊天时,会出现 CORS(Cross-origin resource sharing,跨域访问)错误,例如: ‘http://10.10.145.101:11005/v1/chat/completions’ from origin ‘http://10.10.145.102:8001’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

CORS 是 跨域资源共享(Cross-Origin Resource Sharing) 的缩写,它是一种浏览器安全机制,用于决定是否允许网页从不同域名(跨域)请求服务器资源。
在这个场景下,chatbox-web在访问ollama时,会在http头中携带 chatbox-web 的信息: Orign:http://10.10.145.102:8001/ ,而ollama发现这个ip地址不是本机的IP,就会拒绝访问。

为了解决上述问题,我使用 nginx 做代理转发 chatbox-webOllama 的请求,那么只要 nginx 允许跨域访问,问题也就解决了。

解决 403 (Forbidden) 错误

解决了 CORS 问题后,在 chatbox-web 中聊天时,还会出现 403 (Forbidden),例如:
POST http://10.10.145.101:11005/v1/chat/completions 403 (Forbidden)

出现此问题的原因是:Ollama 本身也会验证 http头,如果有 Origin 和相关的信息,必须是 localhost 或者 127.0.0.1 ,为此,我们必须在nginx转发时,修改相关的 http头。

使用 nginx 代理 Ollama 服务

可以自己通过 docker pull nginx:1.29.3 下载 nginx。

为了部署方便些,我把 nginx 和 Ollama 部署在同一台机器(10.10.145.101)上, nginx 和 Ollama 使用同一个docker网络 chatnet ,在已经安装好 ollama 和 nginx 的 docker镜像后,把 配置文件 nginx.confdocker-compose.yaml 放在同一个文件夹,例如 文件夹名称为 ollama_with_proxy

使用下面的命令启动 ollama 和它的 nginx 代理:

cd ollama_with_proxy
docker-compose up -d

其中,nginx.conf 内容如下:

user  nginx;
worker_processes  auto;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen 80;
        server_name _;

        # ===== Chatbox → Ollama CORS 设置,同时转发 /v1/* 和 /api/* 到 Ollama =====
        location ~ ^/(v1|api)/ {	# 正则匹配:以 /v1/ 或 /api/ 开头的所有请求
            if ($request_method = OPTIONS) {
                add_header Access-Control-Allow-Origin "*" always;
                add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE" always;
                add_header Access-Control-Allow-Headers "Authorization, Content-Type, Accept, Origin, User-Agent, DNT, Cache-Control, X-Mx-ReqToken, Keep-Alive, X-Requested-With, If-Modified-Since" always;
                add_header Access-Control-Allow-Credentials "true" always;
                add_header Access-Control-Max-Age 1728000;
                add_header Content-Type "text/plain; charset=utf-8";
                add_header Content-Length 0;
                return 204;
            }

            add_header Access-Control-Allow-Origin "*" always;
            add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE" always;
            add_header Access-Control-Allow-Headers "Authorization, Content-Type, Accept, Origin, User-Agent, DNT, Cache-Control, X-Mx-ReqToken, Keep-Alive, X-Requested-With, If-Modified-Since" always;
            add_header Access-Control-Allow-Credentials "true" always;

            proxy_pass http://ollama:11434;	# 末尾没有 /v1/ 或 /api/,保持根路径转发
	
            # === 关键伪装头 ===
            proxy_set_header Host "localhost";
            proxy_set_header Origin "http://localhost";
            proxy_set_header Referer "http://localhost";
            proxy_set_header X-Forwarded-For "127.0.0.1";
            proxy_set_header X-Real-IP "127.0.0.1";
			
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-Proto $scheme;
        }

        # ===== Ollama 主页(测试用) =====
        location / {
            add_header Access-Control-Allow-Origin "*" always;
            proxy_pass http://ollama:11434/;
        }
    }
}

在上面的配置中,nginx 在docker环境中监听默认端口 80,它增加了允许跨域访问的配置,并且在转发请求时,修改了 关键的http头,以绕过 Ollama 的安全限制。

docker-compose.yaml 的内容如下:

version: '3.8'

services:
  # === Ollama 服务 ===
  ollama:
    image: ollama/ollama
    container_name: ollama
    restart: always
    ports:
      - "11434:11434"
    volumes:
      - /home/ollama/models:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    networks:
      - chatnet

  # === Nginx 反向代理 ===
  nginx-proxy:
    image: nginx:1.29.3
    container_name: nginx-proxy
    restart: always
    depends_on:
      - ollama
    ports:
      - "11005:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    networks:
      - chatnet

networks:
  chatnet:
    driver: bridge

上面的配置中先启动 ollama ,再启动 nginx。 如果部署环境没有 GPU,删掉 deploy 就可以了。

通过上述配置启动后,当访问 11434 端口时,直接使用 Ollama 服务,当访问 11005 端口时,则由 nginx 转发,这种方式允许跨域访问。

如果用户在 客户端 的浏览器打开 chatbox-web(http://10.10.145.102:8001/) 并开始与大模型聊天,调用的过程为:

sequenceDiagram participant U as 客户端[10.10.145.111] participant A as chatbox-web[http://10.10.145.102:8001/] participant B as nginx代理[http://10.10.145.101:11005] participant C as ollama[http://10.10.145.101:11434] U ->> A: (1) 打开页面,开始聊天 U ->> B: (2) 发送 HTTP POST 请求,携带 HTTP Header:`Origin:http://10.10.145.102:8001/` B ->> C: (3) 修改 HTTP Header 后,转发请求 C ->> C: (4) 推理 C ->> B: (5) 响应 B ->> U: (6) 响应

部署 dify 并搭建智能体

参见:用dify搭建智能体Agent

chatbox 中调用 dify API

dify社区版 貌似不提供兼容 OpenAI API 的 API;而在 chatbox中默认只能使用兼容 OpenAI API 的 API。所以如果想在 chatbox 中使用 dify 的智能体Agent,可以尝试两中方法:

  1. 使用 dify企业版
  2. 增加一个 代理,将 OpenAI API 格式的请求转发给 dify

总结

用自建 LLM、Chatbox 和 Dify 搭建 AI 实验室,既能发挥三者协同优势,实现从模型调试到应用落地的全流程覆盖,又能在数据安全、成本控制等方面突破公有云服务的局限。

此方案的缺点是一次性投入成本高,优点有:

  1. 数据安全与合规性拉满:这一组合特别适配金融、医疗等行业,轻松满足 GDPR、《数据安全法》等对数据隐私和出境的严格要求。
  2. 成本可控且长期性价比高: 本地 LLM 和私有化 Dify 能省去持续的 token 消耗开支;另一方面,Chatbox 可监控 token 使用量并设置限额,Dify 还能实现模型按需降级切换,进一步优化成本。
  3. 高度自主可控且灵活适配: LLM 可根据需求微调参数、优化模型结构,适配垂类场景,比如训练法律领域模型处理判例文书;Dify 支持对接本地 Llama 3 等模型,还能通过拖拽可视化编排业务流程;Chatbox 可接入本地部署的模型端点,实现零延迟交互,三者组合能快速响应个性化需求,比如调整模型推理逻辑或定制应用交互流程。
  4. 响应稳定无外部依赖: 本地部署的 LLM 避免了云端调用的网络波动、限流等问题。

此方案应该适用于以下场景:

  1. 高效的多模型研发与测试平台: 这个组合能成为模型的 “试验场”。Chatbox 能一键切换接入这些模型,开发者可在其中快速调试提示词、测试模型的对话逻辑和响应效果。
  2. 快速落地各类 AI 垂类应用: 借助 Dify 的工作流编排能力,结合本地 LLM 的专业能力,能快速搭建实用应用,再通过 Chatbox 提供交互入口。例如搭建企业 IT 工单分类系统,用 Dify 拖拽节点设计流程,调用本地 LLM 提取工单问题类型和紧急程度,最后通过 Chatbox 接收员工提交的工单并反馈处理结果。
  3. 赋能团队高效协作与办公: Chatbox 的团队协作模块可支持成员共享对话模板、调试经验,其文档解析功能能快速提取 PDF、Excel 中的关键信息;Dify 能搭建自动化工作流,比如人力资源部门可通过它构建简历筛选系统,自动匹配简历与岗位需求;实验室成员还能借助自建 LLM 处理批量文案生成、数据分析等任务,比如生成营销邮件、输出业务数据报告,大幅提升团队办公效率。
  4. 适配教学与科研场景: 对高校或科研机构而言,该实验室是理想的教学工具。学生可通过 Chatbox 直观体验多模型交互,用 Dify 学习 AI 应用的流程搭建,借助自建 LLM 尝试模型微调、训练等基础科研实验;科研人员则能基于此开展 RAG 技术优化、多模型融合等前沿研究,比如测试不同 chunk 大小对知识库检索效果的影响,且所有实验数据可追溯,方便复盘总结。
  5. 传统系统 AI 能力快速集成:Dify 可将实验室的 AI 能力一键生成 RESTful API,轻松对接企业现有 CRM、工单系统等。

🪐祝好运🪐