OpenClaw Model Manager:让我不用再手改模型路由 JSON 的 GUI
- 分类
- 工具与下载
- 发布日期
- 2026年7月11日
- 作者
- Jacob Lloyd —— 项目完成后,在 AI 协助下撰写
- 阅读时长
- 约 9 分钟阅读
简单来说: 一个免费的桌面应用,给我家里的 AI 系统配上了一块像样的控制面板,取代了原来那种有风险的手改配置文件方式。它能显示每个助手正在用哪个 AI「大脑」,点一下就能切换,而且拒绝保存任何会把系统弄坏的内容。它的诞生原因很简单:曾经有一次打错一个字,就悄无声息地让一个助手掉线了。
我曾经在 JSON 文件里把一个模型 ID 打错了字,结果用这个模型的智能体就这么悄无声息地哑火了。没报错,没崩溃。它就那么坐在那儿,对着一个根本不存在的模型自说自话,而我却在别处满世界找一个"更有意思"的 bug。这个应用,就是我给自己定下的"绝不再犯"。
TL;DR
- 这是什么:一个 GTK4/libadwaita 桌面应用,用来编辑
openclaw.json——这份配置决定了我 OpenClaw 系统里每个智能体、子智能体和 cron 任务该和哪个 LLM 对话。 - 费用:免费,MIT 协议,源码在下面的 zip 里。
- 需要什么:装了 GTK4 + libadwaita + PyGObject 的 Linux(包管理器一行命令搞定)、Python 3.11 以上,还有一套 OpenClaw 安装——没有的话,用自带的示例配置从零开始也行。
- 最终得到什么:一屏看全所有智能体模型的仪表盘、既不会写坏文件也不会指派死模型的保存机制,以及一个点一下就能把 Claude Code CLI 路由到免费本地模型、便宜的 DeepSeek,或者真金白银计费的 Anthropic 的开关。
最终得到什么
先看截图。这些截图来自一个沙盒环境,跑的是用完即弃的 HOME 目录里的一份假配置。应用是真的,数据是假的,里面没有我的任何密钥。
主窗口回答的问题,以前得靠 grep JSON 才能搞清楚:哪个模型跑在哪里,又要花多少钱?每个智能体、整套系统的默认值、子智能体的覆盖设置、cron 任务,甚至连相邻的一个邮件智能体用的模型也在内。每一条都带一个颜色标签:Local(这台机器)、Remote(第二台机器),或者 Cloud(会出现在账单上的那种)。
为什么会做这个
OpenClaw 是我在家里跑的多智能体系统:好几个 AI 智能体,各自指向一个模型,有的本地免费,有的云端计费。所有路由都集中在一个文件里,~/.openclaw/openclaw.json:模型目录、每个智能体的主/备选分配、供应商配置,还有网关自己的鉴权令牌。手改这个文件,老是在两个地方栽跟头。
第一,写错的模型 ID 会悄无声息地失败。有一次某个陈旧的默认值就把一个智能体指向了 vllm/google/gemma-4-31b-qat——这个模型供应商压根没提供过。格式不对的保存更糟:一处改错,整个网关就崩溃循环。
第二,在不同后端之间切换 Claude Code CLI,靠的是看不见的环境变量手术。OpenClaw 会为编码任务拉起 Claude Code,而这些请求发去哪里、账单算在谁头上,是由网关 systemd unit 上的 ANTHROPIC_* 环境变量决定的。在免费本地、便宜的 DeepSeek 和真正的 Anthropic 之间来回切换,以前每次都得手写一个 systemd drop-in。这种事,正是我晚上 11 点最容易搞错的类型。
保存流程
我需要能信得过的,是点下 Save 之后到底发生了什么。按顺序如下:
有两个步骤扛着大梁。校验会拒绝任何供应商未公布过的模型 ID,这让开头那种打错字的 bug 从"要靠自己留神检查"变成"结构上根本不可能发生"。而原子写入的存在,是因为 openclaw.json 里存着网关的鉴权令牌,必须一直保持 chmod 600:临时文件在写入任何内容之前就先获得原文件的权限,然后 fsync,再重命名覆盖原文件。哪怕保存到一半崩溃,旧文件也丝毫无损。
一次糟糕的保存,离撤销只差一次 rename,而且你留着的是五代历史,不是一代。
Coding Helper 的 drop-in
切换 Claude Code CLI 的路由是单独一条流程,因为它完全不碰 openclaw.json。它写的是一个 systemd drop-in,在网关拉起 Claude Code 之前先覆盖它的环境变量。
四种模式,一个下拉菜单:LM Studio(免费、本地)、通过其 Anthropic 兼容端点接入的 DeepSeek(便宜)、Anthropic Cloud(默认选项:完全没有 drop-in,什么都不覆盖),或者 Disabled——这个选项会把 CLI 指向 http://127.0.0.1:9/blocked,让每一次调用都快速失败而不是干等着。还有一个一键实时测试,会向 LM Studio 或 DeepSeek 发一个真正符合 Anthropic 格式的 ping,并报告到底是哪个模型应答了。你信的不是一个配置界面,而是一次刚刚发生过的真实请求。
让 API 密钥远离 unit 文件
DeepSeek 模式需要一个 API 密钥,而 systemd 的 unit 文件是放密钥的糟糕地方:直接写进去的东西,在磁盘上和 systemctl show 的输出里都是明文。所以这个 drop-in 里从来不含密钥本身,写的是这个:
ExecStart=/usr/bin/bash -c 'export ANTHROPIC_API_KEY="$$DEEPSEEK_API_KEY"; exec <gateway cmd>'
诀窍在 $$。在 unit 文件里,$$ 会被转义成一个字面的 $。如果不这么写,systemd 会在拼装命令行的时候自己把变量展开,真正的密钥就会出现在进程的 argv 里,ps 一下就能看到。用两个美元符号,bash 收到的就是字面意义上的 $DEEPSEEK_API_KEY,并在运行时从网关的 EnvironmentFile(~/.openclaw/gateway.systemd.env,chmod 600)里展开它。这个密钥不会出现在 unit 文件里,不会出现在 systemctl show 里,也不会出现在进程列表里——只存在于那一个进程自己的 bash 环境中。zip 包里的 examples/ 文件夹用 CHANGE_ME 占位符记录了这套写法。
安装设置
摘自 zip 里附带的 README:
# 1. Install GTK4 + libadwaita + PyGObject from your distro's packages
# (one dnf/apt line — see README-SETUP.md for the exact package names)
# 2. Install the app and its launcher
install -Dm755 openclaw-model-manager ~/.local/bin/openclaw-model-manager
# .desktop file goes to ~/.local/share/applications/
# 3. If you don't already have an OpenClaw config:
cp examples/openclaw.json.example ~/.openclaw/openclaw.json
chmod 600 ~/.openclaw/openclaw.json
# then replace every CHANGE_ME placeholder inside it
# 4. Optional — API keys, both chmod 600, examples provided:
# ~/.openclaw/.env
# ~/.openclaw/gateway.systemd.env
除了 PyGObject,不需要额外的 pip 安装;其余全是 Python 3.11+ 的标准库,包括 tomllib。整个应用就是一个可执行脚本(164KB,3,570 行)、一个 .desktop 启动器、一份 README、一份 MIT 许可证,加上四份示例配置。压缩成 zip 只有 49KB。
踩过的坑
- Cloud 模式的意思是"没有 drop-in",不代表"一定用的是我自己的 Anthropic 账户"。它什么都不覆盖,所以 unit 里原本配置好的东西会照常运行。选中的模式没有可用密钥时应用会警告,但还是要自己确认一下。
- 这个 drop-in 会屏蔽你真正的 Anthropic 密钥,这是故意的设计。Local 模式会给网关拉起的所有东西都设上
ANTHROPIC_API_KEY=lm-studio。在我这台机器上,这曾经悄悄把我交互式的claudeCLI 别名也重新路由到了 LM Studio——Claude Code 看起来"照常在工作",答案却是本地模型给的。如果 Claude 的回答开始不对劲,先运行systemctl --user cat openclaw-gateway.service找找有没有 drop-in,再去怀疑模型本身。 openclaw update改动了网关的 ExecStart 之后,重新选一次 DeepSeek 模式,好把新命令重新包一层。应用会从 unit 片段里读取权威的 ExecStart,并识别出自己的包装痕迹(靠的是index.js加上没有$$DEEPSEEK_API_KEY来判断),所以不会出现二次包装——但它也不会主动去修一条没被要求重新检查的命令。- 本地模型的安全默认值是
reasoning: true。一个会输出reasoning_content却被配置成reasoning: false的模型,在网关看来就是卡住了:大约 390 秒的沉默,然后被 kill。对不做推理的模型来说,这个开关开着也无害,所以新增模型对话框默认就是开的。这个坑真的让我调试掉了不少时间。 - 非空的
plugins.allow是一份严格的白名单。某个插件条目上的enabled: true不起任何作用,除非它的 id 也在allow里。应用能正确读出这一点,但它刻意从不写入任何plugins.*,所以插件行为异常时,这不是能告诉你原因的工具。 - 网关自己也会改写
openclaw.json(身份校准、openclaw update)。应用会追踪文件的 mtime,在覆盖一次外部编辑之前发出警告,保存前的备份保留的是磁盘上实际存在过的内容。 - 模型 ID 的格式是
provider/raw-id。没有斜杠的裸 ID,会通过本地的 LM Studio 端点来解析。这不是错误,只是一个值得了解的约定——省得你去找一个根本不存在的 provider 字段。
下载
仅限个人使用免费。如果它替你省下了一下午的时间,欢迎点旁边的咖啡按钮支持一下。