Simon Willison 在 8 月 21 日更新了一款不起眼的 CLI 插件——llm-openrouter,版本号跳到 0.7。changelog 本身很平淡:适配 LLM 0.32,模型调用改走 OpenRouter 的 Responses API,新增三个服务端工具。

但把插件代码和 OpenRouter 官方文档摆在一起对一遍,会发现一件官方自己没写进文档的事:三个新工具里的 Shell,能在云端容器里直接执行命令,而 OpenRouter 公开的服务端工具清单里,压根没有这一项。

这次更新改了什么

0.7 要求 llm>=0.32openai>=2.32.0python>=3.10。插件底层通过子类化 LLM 0.32 的 Responses/AsyncResponses 实现,api_base 指向 OpenRouter 的 Responses 接口。

保留了 -o chat_completions 1 这个回退开关,可以退回旧接口——但退回旧接口后,服务端工具会被直接拒绝,等于鱼与熊掌不可兼得。

三个新工具里,WebSearch 支持 auto、native、exa、firecrawl、parallel、perplexity 六种引擎,对结果数量、搜索深度都做了参数校验;WebFetch 用来抓页面内容。这两个工具在 OpenRouter 官方文档里都能查到对应条目,行为基本对得上。

Shell 工具:文档里查不到的那一个

Shell 不一样。它的命令在 OpenRouter 托管的隔离容器里执行,不是本机 shell——这个设计思路没问题,云端沙箱本来就该和本地环境隔开。

问题是,OpenRouter 官方文档列出的服务端工具清单只有 web_search、web_fetch、datetime、apply_patch、fusion、advisor、subagent 七项,没有 shell。文档甚至明确建议:需要执行命令类需求,应该由开发者自建沙箱、用 function tool 实现,而不是指望官方的 server tool。

也就是说,插件在调用一个官方文档说"不存在"的能力。这大概率是尚未公开写入文档的 beta 内测接口,也可能是插件作者拿到了非公开访问权限——哪种情况都值得开发者多一分警惕,而不是照单升级。

  • 风险.一个"文档没写、代码却在调"的服务端工具,意味着行为边界、安全隔离、计费规则都无人可查,出了问题连报错依据都找不到。

被忽略的账单变量

原文的 changelog 只字未提成本,但服务端工具是要单独计费的,而且账单结构比想象中复杂。

WebSearch 按引擎收费:Exa、Parallel 每次请求 0.005 美元(含 10 条结果,超出部分每条加 0.001 美元),Perplexity 同样每次 0.005 美元,Firecrawl 走用户自己的额度。WebFetch 相对便宜:OpenRouter 原生抓取免费,Exa、Parallel 每千次抓取收 1 美元。

单看这几个数字不吓人。但 Responses API 支持 max_tool_calls 这种多轮工具循环——一个 agent 任务可能连续触发几十次工具调用,token 费用之外再叠加这些按次收费,实际账单和开发者本地跑一个脚本时的心理预期完全不是一个量级。

权限外包容易,账单外包才是真麻烦。

版本号罗生门与真正的坐标

有意思的是,另一独立信息源查到的 llm-openrouter 最新发布版本只有 0.6,没找到 0.7 的公开记录。这不一定是谁错了,更可能是发布信息在不同渠道之间存在时间差——但这提醒一件事:越是"今天刚发生"的新闻,越该多留一道核实的手续,而不是看到一个 changelog 就当成定论。

把这件事放回行业坐标里看会更清楚。OpenRouter、LiteLLM、Vercel AI Gateway、Bifrost这几家网关,都在从"转发 Chat Completions"升级到托管服务端工具,本质是把 agent 执行工具的信任边界,从客户端搬到云端。这个方向没错,本地沙箱确实比每个开发者各自造轮子更安全。

但 llm-openrouter 说到底还是 Simon Willison 一个人维护的 CLI 插件,不是生产级网关。它跑得比官方文档还快,恰恰说明这轮"服务端工具化"竞赛里,能力先上线、文档后补齐、计费说不清楚,是普遍状态,不是个例。

  • 结论.升级前先确认自己用没用到 Shell 或多轮 WebSearch,再决定要不要给 agent 任务设一个调用次数上限——这比读 changelog 更重要。