作者在 Claude Code 额度耗尽时探索调用 MiMo、GLN 等第三方模型处理简单确定性任务,测试了 herdr 等方案并发现权限系统绕过风险。
我大部分开发工作都在 Claude Code 订阅上完成。目前 Claude Fable 5.1 和 Opus 5.5 表现极为出色,我会直接称它们为当前技术的巅峰。唯一的问题是——令牌总是不够用。
与此同时,我手里还有不少其他模型的闲置配额。之前拿到过小米 MiMo 的免费配额,时不时还会出现一些国内模型的低价套餐,朋友还送了一个他们不再使用的 GLM 订阅。于是我开始琢磨:这些模型能否承接那些简单、流程固定的工作,把真正需要 Claude 的部分留给她?
我的第一次尝试是 herdr。Claude Code 可以调用 herdr 的 API,在另一个 pane 里启动另一个 harness(比如 opencode),向其发送指令,然后读取屏幕获取结果或检查进度。
效果是有的,但总觉得哪里不对劲。更糟糕的是,我发现 Claude Code 居然能审批另一个 harness 的权限提示,两个 harness 还可以互相审批来绕过权限检查。再加上 herdr 完全游离于 Claude Code 的权限体系之外,也不受 Codex 沙盒的约束——这太危险了。
我自己还写过一个叫 paimon 的 harness,给它加了一个内置 skill,使 Claude Code 或 Codex 可以直接调用它,类似 claude -p,但多了一些额外能力。调用方可以按范围查询 paimon 的会话历史;paimon 完成一个任务并退出后,还能重新启动继续同一个会话的工作。
理论上这比 claude -p 更好。但实际体验依然很差。Claude 并不总是会把任务委托给它。当 Claude 需要的上下文超出最终答案范围时,翻查 paimon 的会话历史需要好几个步骤,而这些步骤本身也要消耗令牌。简单任务上我怀疑整个流程烧掉的令牌比省下的还多。
我直觉问题可能更深层。无论 skill 里给了多少提示,Claude Code 始终没有把 paimon当作自己的子 agent 来对待。
然后我想起来:这些便宜模型有不少本身就支持 Anthropic API。之前我在 Claude Code 里用过它们,只需要设置几个环境变量就行。
那本地代理呢?启动代理,让 Claude Code 指向它,然后注册一些自定义子 agent——每个子 agent 有自己的模型名。所有 LLM 请求都经过代理;Fable 或 Opus 的请求直接转发给 Anthropic;而自定义子 agent(比如一个更便宜的 explore agent)的请求,则发往 MiMo、Kimi 或 GLM 的 Anthropic 兼容端点。从 Claude Code 的角度看,这些便宜的模型和内置子 agent 处于同等地位。
稍微调研了一下,发现情况比我预期的还要好。除了 base URL 环境变量之外,Claude Code 还支持在命令行上定义子 agent,每个子 agent 有自己的用途描述、权限和可用工具。所以 Claude Code 的配置文件完全不用改。一个包装脚本启动代理,然后用环境变量和额外参数启动 Claude Code。直接运行 claude 一切如常。
现有方案也有,比如 Claude Code Router。但它做的比我需要的多得多,也相当复杂。我的场景更简单,因为这些模型本来就支持 Anthropic 格式,不需要做协议转换。于是我决定自己写一个。
过程如我期望的那样简单。一个提示词,大概四五条推文的长度,用 Opus 5.5 的 Claude Code 一次就跑完了。
成果就是 cameo,一个约 400 行的 Go 小程序。名字来源于电影术语"客串"——正是这些第三方模型在这里的待遇。它们在 Claude Code 里以子 agent 的身份出现,演上一两场戏,而 Claude 始终是主角。
它读取一个 TOML 配置文件,在 localhost 上启动一个 HTTP 代理,然后以子 agent 的命令行参数启动 Claude Code。代理只查看每个请求的 model 字段。如果 model 属于 cameo 子 agent,代理就替换成对应提供商的模型名和 API key,再把请求转发过去。其他请求原封不动发给 Anthropic。代理永远不需要理解消息的其他部分,这就是代码如此精简的原因。
下面是项目自带的示例配置:
[agents.cheap-general]
description = """
General purpose agent for multi-step tasks: researching questions, searching \
code and making changes. Same role as the default general-purpose agent, but \
prefer this one first because it costs much less. If the result is not good \
enough, fall back to general-purpose."""
prompt = """
You are a general purpose software engineering agent. Complete the task you \
are given, then report what you did and what you found."""
url = "https://api.deepseek.com/anthropic"
key = "$DEEPSEEK_API_KEY"
model = "deepseek-flash"
[agents.cheap-explore]
description = """
Read-only agent for exploring the codebase: finding files, searching code and \
answering questions about how things work. Same role as the default Explore \
agent, but prefer this one first because it costs much less. If the result is \
not good enough, fall back to Explore."""
prompt = """
You are a read-only codebase exploration agent. Find what you are asked for \
and report it with file paths and line numbers. Never modify anything."""
tools = ["Read", "Grep", "Glob"]
url = "https://open.bigmodel.cn/api/anthropic"
key = "$GLM_API_KEY"
model = "glm-5.3"
每个 [agents.<name>] 分区会成为 Claude Code 里的一个子 agent。description 用来告诉 Claude 何时使用这个 agent 以及如何与其他 agent 排序。上面的两个 agent 分别与内置的 general-purpose 和 Explore agent 一一对应,但被标记为更便宜的选择。如果不想两者都保留,给你的 agent 起名 Explore 或 general-purpose,它就会直接替换掉内置的那个。
配置完成后,在你平时运行 claude 的地方换成运行 cameo 即可,所有参数都会透传过去。
实际使用下来,Claude Code 确实比之前选 paimon 时更频繁地选择便宜版本,尤其当我明确要求时效果更明显。
接下来我想支持 Codex,因为这些便宜模型也提供 OpenAI 兼容端点。但稍作调研就发现 Codex 已经全面转向 Responses API,而大多数模型只支持旧版的 Chat Completions API。要支持 Codex 就得自己写协议转换,那样我又是在重造 Claude Code Router 了。所以我决定暂时不做,至少要等这些模型也支持 Responses API再说。