Clawdbot整合Qwen3:32B部署教程:解决跨端口代理、CORS与API对接问题

1. 为什么需要这个整合方案

你是不是也遇到过这样的情况:本地跑着Qwen3:32B大模型,用Ollama启动后监听在11434端口,但想把它接入Clawdbot聊天平台时,浏览器直接报错“跨域被拒绝”?或者前端页面调用API时卡在预检请求(OPTIONS),控制台一堆红色错误?又或者好不容易配好反向代理,结果Clawdbot发来的请求被网关拦在8080端口外,根本连不到18789的内部服务?

这不是你的配置有问题,而是典型的前后端分离架构下的通信断点——模型服务、网关、前端三者不在同一网络域,端口不互通,策略不兼容。

这篇教程不讲抽象原理,只说你马上能用上的实操步骤。我们会从零开始,把Qwen3:32B通过Ollama部署好,再用轻量级代理打通Clawdbot前端到模型API的整条链路,重点解决三个卡点:

  • 跨端口转发(8080 → 18789)
  • 浏览器CORS拦截(让前端能安全调用)
  • Clawdbot API格式兼容(适配OpenAI-style接口)

整个过程不需要改一行模型代码,不依赖Kubernetes或Docker Compose复杂编排,纯命令行+配置文件,30分钟内可完成。

2. 环境准备与基础服务部署

2.1 确认系统与依赖

请确保你的服务器或本地机器满足以下最低要求:

  • 操作系统:Linux(Ubuntu 22.04 / CentOS 8+)或 macOS(Intel/Apple Silicon)
  • 内存:≥64GB(Qwen3:32B推理需较大显存/内存,无GPU时启用--num-gpu 0走CPU+RAM)
  • 磁盘空间:≥100GB(模型权重约35GB,缓存与日志预留空间)
  • 已安装:curlwgetjqgit(基础工具)、ollama(v0.3.0+)

小提醒:如果你还没装Ollama,执行这条命令一键安装(Linux/macOS通用):

curl -fsSL https://ollama.com/install.sh | sh

2.2 拉取并运行Qwen3:32B模型

Qwen3:32B目前未上架Ollama官方库,需手动加载GGUF量化版。我们使用社区验证稳定的qwen3:32b-f16镜像(基于Qwen3-32B-Instruct量化为FP16格式):

# 1. 创建模型定义文件 qwen3-32b.Modelfile
cat > qwen3-32b.Modelfile << 'EOF'
FROM https://huggingface.co/bartowski/qwen3-32B-GGUF/resolve/main/Qwen3-32B-Instruct-Q4_K_M.gguf
PARAMETER num_ctx 32768
PARAMETER stop "<|im_end|>"
PARAMETER stop "<|endoftext|>"
PARAMETER temperature 0.7
PARAMETER top_p 0.9
TEMPLATE """{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
{{ .Response }}<|im_end|>"""
EOF

# 2. 构建模型(耗时约3–5分钟)
ollama create qwen3:32b -f qwen3-32b.Modelfile

# 3. 启动服务,绑定到 127.0.0.1:11434(默认,不对外暴露)
ollama serve &

验证是否启动成功:

curl http://localhost:11434/api/tags | jq '.models[] | select(.name == "qwen3:32b")'

如果返回模型信息,说明Ollama已就绪。

2.3 启动Clawdbot Web网关(18789端口)

Clawdbot本身不内置模型服务,它是一个前端+网关组合体。你需要下载其预编译二进制(支持Linux/macOS):

# 下载最新版(以 v1.4.2 为例)
wget https://github.com/clawdbot/clawdbot/releases/download/v1.4.2/clawdbot-v1.4.2-linux-amd64.tar.gz
tar -xzf clawdbot-v1.4.2-linux-amd64.tar.gz
chmod +x clawdbot

# 启动网关,监听 18789 端口(注意:不加 --host=0.0.0.0,仅本机可访问)
./clawdbot serve --port 18789 --model qwen3:32b

此时,Clawdbot网关已在 http://127.0.0.1:18789 运行,但它还不能被浏览器直连——因为前端页面通常跑在 http://localhost:8080,而浏览器禁止跨端口请求。

3. 解决核心三连击:代理、CORS、API对齐

3.1 用Caddy搭建智能反向代理(替代Nginx)

我们不用Nginx——配置冗长、重启麻烦。改用Caddy,它自带HTTPS、自动CORS头、零配置反向代理,一条命令即可生效。

# 安装 Caddy(Linux)
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy

# 创建代理配置 /etc/caddy/Caddyfile
sudo tee /etc/caddy/Caddyfile > /dev/null << 'EOF'
:8080 {
    reverse_proxy 127.0.0.1:18789 {
        header_up Host {host}
        header_up X-Forwarded-For {remote}
        header_up X-Forwarded-Proto {scheme}
    }
    # 关键:全局开启 CORS,允许任意前端调用
    header Access-Control-Allow-Origin "*"
    header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE"
    header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
    header Access-Control-Allow-Credentials "true"
    header Access-Control-Max-Age "3600"
}
EOF

# 启动 Caddy(自动监听 8080)
sudo systemctl enable caddy
sudo systemctl start caddy

此时,访问 http://localhost:8080 就等同于访问 http://localhost:18789,且所有响应头已自动注入CORS许可。

为什么选Caddy?它比Nginx少写20行配置,且header指令天然支持动态注入,无需写if判断;更重要的是,它不会因Access-Control-Allow-Origin: *credentials: true冲突而报错——Caddy会自动忽略该组合的校验,真正“开箱即用”。

3.2 修复Clawdbot与Qwen3 API格式差异

Ollama原生API是 /api/chat,返回结构为:

{ "message": { "content": "回答内容" } }

但Clawdbot默认期望OpenAI-style格式(如/v1/chat/completions),字段名和嵌套不同。我们不改Clawdbot源码,而是用中间层适配器做轻量转换。

创建一个Python脚本 adapter.py

# adapter.py —— 运行在 18789 端口,作为Clawdbot与Ollama之间的翻译官
from flask import Flask, request, jsonify
import requests
import json

app = Flask(__name__)
OLLAMA_URL = "http://127.0.0.1:11434/api/chat"

@app.route('/v1/chat/completions', methods=['POST'])
def chat_completions():
    data = request.get_json()
    
    # 映射 OpenAI 字段 → Ollama 字段
    ollama_payload = {
        "model": "qwen3:32b",
        "messages": [
            {"role": "user", "content": data["messages"][0]["content"]}
        ],
        "stream": False,
        "options": {
            "temperature": data.get("temperature", 0.7),
            "top_p": data.get("top_p", 0.9),
            "num_ctx": 32768
        }
    }

    try:
        resp = requests.post(OLLAMA_URL, json=ollama_payload, timeout=300)
        resp.raise_for_status()
        ollama_res = resp.json()
        
        # 转换回 OpenAI 格式
        openai_res = {
            "id": "chat-" + ollama_res.get("created_at", "").replace("-", "").replace(":", "")[:12],
            "object": "chat.completion",
            "created": int(ollama_res.get("created_at", "0").split("T")[0].replace("-", "")),
            "model": "qwen3:32b",
            "choices": [{
                "index": 0,
                "message": {
                    "role": "assistant",
                    "content": ollama_res.get("message", {}).get("content", "")
                },
                "finish_reason": "stop"
            }],
            "usage": {
                "prompt_tokens": len(ollama_payload["messages"][0]["content"]),
                "completion_tokens": len(ollama_res.get("message", {}).get("content", "")),
                "total_tokens": 0
            }
        }
        return jsonify(openai_res)
    except Exception as e:
        return jsonify({"error": {"message": str(e), "type": "api_error"}}), 500

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=18789, debug=False)

安装依赖并运行:

pip install flask requests
nohup python adapter.py > adapter.log 2>&1 &

现在,Clawdbot发往 http://localhost:18789/v1/chat/completions 的请求,会被这个适配器接收、转成Ollama格式、调用本地11434端口,并原样返回标准OpenAI结构——Clawdbot完全无感,就像在调用ChatGPT。

3.3 验证全链路是否打通

打开终端,模拟Clawdbot前端的一次真实调用:

curl -X POST http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3:32b",
    "messages": [{"role": "user", "content": "用一句话介绍你自己"}],
    "temperature": 0.5
  }' | jq '.choices[0].message.content'

如果返回类似:
“我是通义千问Qwen3-32B,一个超大规模语言模型,擅长回答问题、创作文字、编程、逻辑推理等任务。”

恭喜!你已完整打通:
浏览器(8080)→ Caddy代理 → Clawdbot网关(18789)→ Python适配器 → Ollama(11434)→ Qwen3:32B

4. 常见问题与避坑指南

4.1 “OPTIONS预检失败”?检查这三点

这是CORS最常卡住的地方,90%源于以下配置遗漏:

  • ❌ 忘记在Caddy中添加 header Access-Control-Allow-Methods "OPTIONS"
  • Access-Control-Allow-Headers 没包含 Content-Type(Clawdbot必带)
  • ❌ 代理配置里漏了 header_up X-Forwarded-*,导致Ollama收到空Host头而拒绝

正确做法:直接复制前面3.1节的Caddyfile,不要自行删减header_up块。

4.2 “模型加载慢/显存爆掉”?试试这些参数

Qwen3:32B在无GPU环境运行吃内存。若出现OOM或启动超时:

  • 启动Ollama时加参数:
    OLLAMA_NUM_GPU=0 OLLAMA_MAX_LOADED_MODELS=1 ollama serve
    
  • 在Modelfile中降低上下文长度:
    PARAMETER num_ctx 8192(从32768降到8K,内存占用减少60%)
  • 使用更轻量GGUF量化:替换为Qwen3-32B-Instruct-Q3_K_M.gguf(精度略降,速度翻倍)

4.3 Clawdbot页面空白?检查前端地址

Clawdbot前端默认读取环境变量 VUE_APP_API_BASE_URL。如果你用的是预编译包,需修改其index.html中的JS配置:

<!-- 找到这一行 -->
<script>window.apiBase = "http://localhost:18789";</script>
<!-- 改为 -->
<script>window.apiBase = "http://localhost:8080";</script>

否则前端仍会直连18789,绕过Caddy代理,CORS再次触发。

4.4 如何让服务开机自启(生产环境)

避免每次重启都手动拉起四个进程(ollama、clawdbot、adapter、caddy),用systemd统一管理:

# 创建 /etc/systemd/system/qwen3-clawdbot.service
sudo tee /etc/systemd/system/qwen3-clawdbot.service > /dev/null << 'EOF'
[Unit]
Description=Qwen3:32B + Clawdbot Stack
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'ollama serve & sleep 5 && ./clawdbot serve --port 18789 --model qwen3:32b & sleep 3 && python3 /root/adapter.py &'
RemainAfterExit=yes
User=root

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable qwen3-clawdbot
sudo systemctl start qwen3-clawdbot

5. 总结:你已掌握一套可复用的AI网关模式

回顾整个流程,你实际构建的不是一个“Qwen3部署教程”,而是一套通用的大模型前端接入范式

  • 代理层(Caddy):解决跨域与端口隔离,是前后端通信的“翻译桥”
  • 协议层(Adapter):抹平不同模型API的语义差异,让Clawdbot、AnythingLLM、LobeChat等任意前端都能复用同一套后端
  • 模型层(Ollama):专注模型加载与推理,不耦合业务逻辑

这套结构的好处是:下次你想换成Qwen2.5-72B或DeepSeek-V3,只需改Modelfile和adapter.py里的model名,其余配置一动不动。

最后提醒一句:别把18789或11434端口直接暴露到公网。Caddy已为你守好8080这道门,所有外部流量必须经它过滤、加头、限速——这才是安全又省心的AI服务上线姿势。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐