Ollama、LM Studio 与任意 OpenAI 兼容端点
让 SideBoo 谷歌浏览器插件接上 Ollama、LM Studio、vLLM 或公司内网网关 —— 包括那条能消掉 403 的 OLLAMA_ORIGINS 设置。
9 分钟阅读 · 最后更新 2026-08-27
修掉 Ollama 的 403 / OLLAMA_ORIGINS 报错
Ollama 对浏览器扩展回 403,是因为它会校验 Origin 请求头,而默认只信任本机的网页来源。浏览器扩展没有这种来源:它的请求带的是 Origin: chrome-extension://<扩展 ID>,不在那份名单里。把 OLLAMA_ORIGINS 这个环境变量设成允许扩展来源,再重启 Ollama,403 就没了。
SideBoo 需要的值是 chrome-extension://*。具体怎么设取决于 Ollama 是怎么启动的,而且环境变量必须在 Ollama 启动之前就位——这正是很多人设了变量、再看还是 403、于是断定「没用」的原因。
# macOS —— 菜单栏应用的环境变量来自 launchd
launchctl setenv OLLAMA_ORIGINS "chrome-extension://*"
# 然后从菜单栏退出 Ollama,再重新打开
# Linux —— Ollama 跑在 systemd 单元里
sudo systemctl edit ollama.service
# [Service]
# Environment="OLLAMA_ORIGINS=chrome-extension://*"
sudo systemctl daemon-reload
sudo systemctl restart ollama
# Linux / macOS —— 或者干脆前台跑一次
OLLAMA_ORIGINS="chrome-extension://*" ollama serve
Windows 上,Ollama 读的是你账号的环境变量,而不是你当前那个终端里的。先从系统托盘退出 Ollama,在开始菜单里搜「编辑账户的环境变量」,新建一个名为 OLLAMA_ORIGINS、值为 chrome-extension://* 的用户变量,再重新启动 Ollama。在 shell 里用 set 或 $env: 设的变量只对那个 shell 拉起的进程有效,对托盘里的应用毫无作用。
LM Studio 有同一道关卡,只是换了个名字:它的本地服务在你打开 CORS 之前,一样拒绝跨源请求。开关和服务器的其它控制项放在一起——较新的版本里在 Developer 标签页,挨着端口输入框和启动/停止按钮。打开它,重启服务,再点一次「测试服务」。
什么时候需要自定义端点
只要你的模型服务实现了 OpenAI 的 /v1/chat/completions 协议,就能接进 SideBoo。在设置页打开「AI 助手」,点「添加提供商」,选弹窗底部那张虚线卡片「自定义 OpenAI 兼容服务」。自定义服务要你填三样:名称、API 地址、API Key。
常见的几类场景:
- 本地模型:Ollama、LM Studio、llama.cpp 的 server 模式;
- 自建推理服务:vLLM、SGLang、TGI;
- 聚合路由:OpenRouter 等把多家模型收敛到一个地址的服务;
- 公司内网网关:统一鉴权、审计和限流的企业代理。
本机服务通常不校验凭据,所以 API Key 那一栏可以留空:只要 SideBoo 看到地址指向 localhost 或 127.0.0.1,就不再要求填 Key。这两个主机名也是仅有的两个允许走明文 http 的地址——远程服务必须是 https,而 IPv6 字面量(例如 http://[::1]:11434/v1)会被直接拒绝。
接口地址怎么填
地址填到 /v1 为止,不要带 /chat/completions——SideBoo 会自己拼后面的路径。多填一层会得到 404,而不是更明确的报错。
# 本地 Ollama
http://localhost:11434/v1
# 本地 LM Studio
http://localhost:1234/v1
# OpenRouter
https://openrouter.ai/api/v1
# 自建 vLLM
https://llm.internal.example.com/v1
先用 curl 验证一次
在填进 SideBoo 之前,先确认这个地址和 Key 本身是通的。这一步能把「服务端问题」和「扩展问题」彻底分开:
curl https://your-endpoint.example.com/v1/chat/completions \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "your-model-name",
"messages": [{ "role": "user", "content": "ping" }],
"max_tokens": 8
}'
期望看到 200,响应体里有 choices[0].message.content。如果这一步就失败,问题在服务商或你的网络,改扩展设置没有意义。
跨源请求与 CORS
这是自建端点最容易踩的坑:curl 完全正常,扩展里却一直失败。curl 根本不发 Origin 请求头,所以它永远不会触发浏览器那道校验。浏览器扩展发出的是跨源请求,来源为 chrome-extension://<扩展 ID>,服务端必须显式允许它。
服务端至少要在预检(OPTIONS)和实际响应里带上:
- Access-Control-Allow-Origin:回显请求的 Origin,或者设为 *;
- Access-Control-Allow-Headers:至少包含 authorization 和 content-type;
- Access-Control-Allow-Methods:包含 POST 和 OPTIONS。
location /v1/ {
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin $http_origin always;
add_header Access-Control-Allow-Headers "authorization, content-type" always;
add_header Access-Control-Allow-Methods "POST, OPTIONS" always;
add_header Access-Control-Max-Age 86400 always;
return 204;
}
add_header Access-Control-Allow-Origin $http_origin always;
proxy_pass http://127.0.0.1:8000;
}
本地模型的额外注意事项
本地模型便宜又私密,同时也是最容易让人失望的那种配置。它有三个失败方式和网络毫无关系——问题出在模型本身撑不起 SideBoo 要它做的事:
- 「问 AI」整理标签页时,需要模型稳定地吐出合法 JSON。参数量太小的模型经常给出无法解析的结果;7B 往下,做摘要还行,分组就别指望了。
- 上下文长度至少留到 8K,60 个标签页的标题加提示词很容易超过 4K 的窗口。
- 冷模型是在第一次请求时才加载的,所以第一次「测试服务」可能超时、第二次却成功。下结论之前先跑两遍。
模型名怎么填
模型名要和服务端的标识符完全一致,包括大小写、日期后缀和厂商前缀。聚合路由几乎总是需要前缀:
| 服务 | 模型名示例 |
|---|---|
| Ollama | llama3.1:8b |
| vLLM | 启动时 --served-model-name 指定的那个名字 |
| OpenRouter | anthropic/claude-sonnet-5 |
| 内网网关 | 由网关自己定义,通常列在它的 /v1/models 里 |
拿不准时,直接请求端点的 /v1/models,返回列表里的 id 就是可以填的值。如果这个端点压根没有 /v1/models,「测试服务」会报「发现 0 个模型」;点「手动添加模型 ID」自己把名字打进去即可,对话不受影响。
怎么看到真正的错误
设置页里的提示是概括过的。要看服务端返回的原文,打开扩展的后台控制台:
- 打开 chrome://extensions 右上角把「开发者模式」打开。
- 点开 SideBoo 卡片上的 service worker 会弹出一个只属于扩展后台的 DevTools 窗口。
- 切到 Network 标签再触发一次 AI 操作 找到发往你端点的那条请求,Response 里就是服务端返回的完整错误体。
出问题时对照这张表
下面每一行都是一个真实的状态码或报错,对上的是真正造成它的那一件事。照现象找,别照猜想找——这一页上最常见的一个下午,就浪费在为一个根本与 Key 无关的问题反复重新生成 API Key。
| 现象 | 怎么处理 |
|---|---|
| 测试服务提示 401 | Key 复制时多了空格或被截断,或者 Key 已在控制台里撤销。重新生成一个再粘贴。 |
| 本机 Ollama 测试服务提示 403 | 来源校验。按本页开头设置 OLLAMA_ORIGINS 并重启 Ollama。 |
| 测试服务提示 429 | 账户没有余额或触发了速率限制。先去服务商控制台确认额度,再等一分钟重试。 |
| 测试服务提示 404 | 接口地址多带了 /chat/completions,或者少了 /v1。按上面「接口地址怎么填」重填一次。 |
| 连接正常但发现 0 个模型 | 该服务没实现 /models。手动把模型 ID 填进去,对话照常可用。 |
| 提示模型不存在 | 模型名要和服务端标识符完全一致。请求 /v1/models 查一下真实的 id。 |
| curl 正常但扩展里失败 | 几乎一定是 CORS 或来源校验。看后台控制台里的网络错误,按上面配置服务端。 |
| 整理结果分组很奇怪 | 标签页标题信息太少时模型只能猜。换成能力更强的模型,或者先手动关掉一批空白页再问。 |
| 整理标签页时报解析失败 | 模型没有返回合法 JSON,常见于小参数量的本地模型。换更大的模型,或改用云端服务商。 |
| 「问 AI」显示「未配置模型」 | 没有一家服务到达「已就绪」。回设置页点「测试服务」,并至少勾选一个模型。 |
常见问题
为什么 Ollama 对浏览器扩展回 403?
因为 Ollama 会校验 Origin 请求头,默认只接受 http://localhost 这类本机网页来源。Chrome 扩展发出的是 Origin: chrome-extension://<扩展 ID>,不在那份名单里,所以请求在到达模型之前就被拒了。同一个请求用 curl 发就成功,是因为 curl 压根不带 Origin。把扩展来源加进 OLLAMA_ORIGINS 再重启 Ollama,就是全部的修法。
OLLAMA_ORIGINS 应该设成什么?
chrome-extension://* 是放行任意 Chrome 扩展的写法,也是 SideBoo 需要的值。如果你只想放行一个扩展,就用它的完整 ID —— chrome-extension://<扩展 ID>,在 chrome://extensions 上它自己的卡片里能看到。OLLAMA_ORIGINS 也接受逗号分隔的多个值,所以你可以保留原有的值往后追加,而不是整个替换掉。无论用哪种写法,Ollama 只在启动时读一次这个变量,改完记得重启。