FreeBridge — DSH 插件
在 DSH 里装上一个插件,不用登录、不用注册、不用填 API Key,模型直接出现在选择器里。
装完就能用,不需要改 cordis.yml,重启不会被覆盖。
为什么之前那些方法都失败了
先把这个说清楚,能省掉很多人踩坑:
| 流传的方法 | 现在真实状态 |
|---|---|
LLM7.io 的 Bearer unused 万能 key |
返回 401 invalid,已强制真 key |
| Pollinations 老端点 | 返回 403 Missing Turnstile token,要过人机验证 |
| OpenCode 免费池(xxx-free 模型) | 全部 throttled / region-blocked,共享池已枯竭 |
| Kilo Gateway | 匿名直接 200,无需任何 key |
| OVHcloud AI 匿名端点 | 可用但限制 2 RPM,模型 ID 大小写敏感 |
本插件用的就是 Kilo Gateway —— 目前唯一干净的匿名通道。
安装
dsh plugin --profile desktop add dsh-freebridge
或者本地开发方式:
git clone https://github.com/shendao325/freebridge.git
cd freebridge
dsh plugin --profile desktop add .
装好后重启 DSH,模型选择器里会出现 FreeBridge 分组。
不需要手动往 cordis.yml 里写 provider —— 插件通过 ctx.llm.registerAdapter() 自己注册,所以重启不会丢。
怎么用
- 打开模型选择器
- 找到 FreeBridge 分组
- 挑一个模型,推荐
kilo-auto/free(自动路由,永远有兜底)
模型名形如 Kilo Gateway · kilo-auto/free,前缀标明实际走哪个上游。
实测选型表
用同一道陷阱题(17 只羊,除了 9 只以外都死了,剩几只?标准答案 9)压测:
| 模型 | 耗时 | 答对 | 建议 |
|---|---|---|---|
| cohere/north-mini-code:free | 2.7s | 是 | 写代码首选,出字干脆 |
| reflection/beam-free | 3.4s | 是 | 1M 上下文 |
| kilo-auto/free | 4.0s | 是 | 日常默认,自动路由 |
| nvidia/nemotron-3-ultra-550b-a55b:free | 6.3s | 是 | 质量最高,550B |
| dots-studio/dots-3-note-preview:free | 6.6s | 是 | 512K,支持视觉 |
| nvidia/nemotron-3.5-lightning:free | 5.4s | 空输出 | thinking 吃光 token,调大输出上限 |
| nvidia/nemotron-3.5-super-vl:free | 6.3s | 空输出 | 同上 |
| stealth/glyph-cluster | 5.3s | 空输出 | 同上 |
| inclusionai/ling-3.1-flash-1019-free | 1.4s | 空输出 | 最快,但思考吃光输出 |
| recursive/flint-v1.0:free | — | 503 | 上游故障 |
「空输出」不是模型坏,是模型开了 thinking、max_tokens 太小被思考吃光了。真实对话给足 token 大多正常。
插件做了什么
DSH 会话
| ctx.llm.generate() -> adapter.stream()
v
FreeBridgeAdapter
| 加权随机选上游 -> 冷却检测 -> 失败自动换下一个
+--> Kilo Gateway (匿名,主力)
+--> OVHcloud AI (匿名,备用)
四个关键设计,每个都对应一次真实的失败:
1. 模型自动映射
用户请求 gpt-6-sol 这类官方名,上游没有 → 静默降级到该上游首选的免费模型,整个 turn 不会因为 model_not_found 直接失败。
2. 差异化冷却 429/5xx 按 Retry-After 冷却整个上游;400/404 只跳过不冷却 —— 模型不认不等于上游挂了。这一处最容易写错,写成统一冷却会让一个坏模型名拖垮整条通道。
3. 提交裁决(commit 规则) 在拿到第一个正文 delta 之前,所有 chunk 都先扣在缓冲里;一旦正文出现,才把缓冲倒出去并标记 committed。这样「想了一分钟然后撞上配额墙」这种最值得换上游的情况能被正确处理,且不会把两个模型的文本拼在一起。
4. 事件顺序保证 committed 翻转的瞬间,必须先把扣下的 reasoning chunk 倒空再发正文,否则调用方会先收到 text-delta、后收到 reasoning,前端渲染顺序整个错乱。
事件协议
插件按 harness 的 chunk 协议产出:
| 事件 | 说明 |
|---|---|
| block-start | blockType: text / reasoning |
| text-delta | 正文增量 |
| reasoning-delta | 思考链增量 |
| block-end | 完整块,含拼接好的文本 |
| usage | token 用量 |
| finish | reason.kind: stop / length / error / aborted |
已用真实 Kilo 流做过端到端验证,事件顺序为: block-start(reasoning) → reasoning-delta×N → block-start(text) → text-delta×N → block-end ×2 → usage → finish
配置
插件设置面板可配,也可以在 cordis.patch.yml 里改:
- id: freebridge
name: dsh-freebridge
config:
enabled: true
kilo:
enabled: true
weight: 20 # 权重越大越常被选中
ovh:
enabled: true
weight: 6
exposeHealth: true
| 字段 | 说明 |
|---|---|
| enabled | 总开关 |
| kilo.enabled / kilo.weight | Kilo 通道开关与权重 |
| ovh.enabled / ovh.weight | OVH 通道开关与权重 |
| exposeHealth | 是否暴露 /freebridge/health 状态接口 |
文件结构
freebridge/
├── index.js # 插件入口:name / inject / apply / Config
├── src/
│ ├── adapter.js # provider 适配器(harness 契约)
│ ├── upstream.js # 上游调用、模型目录缓存、冷却
│ └── parse.js # SSE 解析 -> chunk 事件
├── cordis.patch.yml # 插件注册补丁
├── package.json
└── README.md
依赖:
- @deepseek-ai/cordis ^4.0.2
- @deepseek-ai/dsh-llm
- Node ^22.19.0 || >=24.0.0
排查
装上了但选择器里没有 FreeBridge → 确认重启了 DSH;确认 cordis.yml 里有 - id: freebridge / name: dsh-freebridge(由 patch 自动写入)。插件没加载时看启动日志里的 [freebridge] ready。
对话报「额度已用尽」 → 你在用 OpenCode 免费池那批 -free 模型。切到 FreeBridge 分组的 Kilo 模型,那是独立额度。
回复是空的 → 模型开了 thinking,把输出上限调大。
OVH 报 404 但模型确实存在 → OVH 模型 ID 大小写敏感,必须 Meta-Llama-3_3-70B-Instruct,不能写小写。
注意
- 免费上游随时可能变(收紧鉴权、下架模型、限流)。这份实测表会过期,发现失效欢迎 PR 更新。
- 免费池通常会记录 prompt 用于改进服务,不要发送敏感内容。
- 插件只做协议转换与转发,不绕过任何鉴权。
- 仅供个人学习与测试,请遵守各上游的服务条款。
License
MIT
No comments yet. Be the first to write one.