AIREITER

OpenRouter CLI:Ori、curl、llm 与 aichat

最后更新: 2026-09-01 01:55:29

搜索 OpenRouter CLI 时,通常会得到两种完全不同的答案。OpenRouter 官方的 ori 命令用于配置和启动现有的编程代理;社区客户端则侧重单次提问、REPL 聊天、JSON 输出或更广泛的 API 覆盖。如果你只是想在 Shell 管道中调用模型,OpenRouter API 加上 curl 就已经足够。

实际使用中,“OpenRouter CLI”到底指什么

“OpenRouter CLI”并不是某个统一的官方终端客户端名称。这个说法实际对应三类工作流:通过 OpenRouter 启动代理、直接在 Shell 中调用 API,或者使用 llm、aichat 这类第三方终端工作台。

你的终端任务从这里开始原因
运行 Claude Code、Codex、OpenCode 或其他受支持的代理官方 Ori Harness在现有代理外层应用 OAuth、模型选择和 OpenRouter 设置
发送单次提示词或处理标准输入curl 加 jq无需额外 CLI 依赖,并且可以完全控制请求内容
查看多个 OpenRouter 端点并返回 JSON@aaronjmars/openroutercli命令覆盖面广,支持 JSON 模式,并提供通用请求入口
使用带模型搜索的聊天 REPL@letuscode/openrouter-cli支持单次提问、REPL 聊天、模糊模型搜索和配置档案
运行多模型提示词、批处理或提示词链orc支持配置档案、模板、批处理、链式调用和代码分析
保留日志、Schema、附件和插件llm-openrouter将 OpenRouter 模型加入可扩展的 llm CLI
结合聊天、Shell 辅助、RAG、代理和本地提供商aichat这是一个更广泛的 Rust 终端工作台,并非只面向 OpenRouter 的客户端

关键区别在于归属和使用范围。OpenRouter 的 ori 集成以及 @openrouter/cli DevTools 包 都是官方项目,但它们都不是通用的 openrouter ask 客户端:DevTools 包主要用于 SDK 遥测查看器和 Claude Code 状态栏,而 Ori 的职责是启动现有的 Harness。

官方方案:安装并使用 Ori Harness

Ori 是 OpenRouter 官方推出的 CLI,用于配置受支持的编程代理 Harness。它负责通过 OpenRouter 完成身份验证,将选定的模型传递给底层代理,同时保留该代理原有的命令和参数;它不会取代 Claude Code、Codex、OpenCode 或其他 Harness。

按照 OpenRouter 公告和指南中的命令安装:

curl -fsSL https://openrouter.ai/labs/ori/install.sh | bash

然后完成身份验证并启动代理:

ori login
ori claude
ori codex
ori opencode
ori hermes

当前 Ori 文档还将 grok、pi、prime-agent 和 dsh 列为受支持的命令。ori dsh 只负责配置 DeepSeek Harness,不会启动它;之后还需要运行 dsh。你可以使用 ori update 更新 Ori。

OpenRouter Ori Harness page showing the official CLI entry point

不更换代理,也能切换模型

Ori 接受 OpenRouter 模型 ID,并会将无法识别的参数转发给底层 Harness:

ori claude --model anthropic/claude-sonnet-4.6
ori codex --model openai/gpt-5.2 --full-auto
ori opencode --model openrouter/auto
ori hermes --model openrouter/auto

不同代理的端点细节并不完全相同。例如,OpenRouter 关于 Claude Code 的指南使用兼容 Anthropic 的基础 URL https://openrouter.ai/api,而 Codex 这类兼容 OpenAI 的客户端使用 https://openrouter.ai/api/v1;Ori 的作用之一,就是屏蔽这些因 Harness 而异的配置差异。

Ori 使用基于浏览器的 OAuth PKCE,因此正常流程不需要把 OpenRouter API key 粘贴到每个代理中。OpenRouter 的 Ori Harness 文档表示,请求使用标准的 OpenRouter 计费和活动记录,不会产生单独的 Ori 账单;实际推理成本仍取决于所选模型和底层 Harness。

Ori 不是独立的聊天 REPL

如果你需要代理提供的工具、文件操作或审批机制,就使用 Ori。如果任务只是发送提示词、获取结构化响应,或运行一个不应启动编程代理的 Shell 管道,那么应使用 curl、直接客户端、llm 或 aichat。

这个边界很重要,因为官方发布材料将 Ori 定义为兼容性和配置层。官方的 @openrouter/cli 包也容易造成混淆:其当前文档中的命令是 openrouter devtools 和 openrouter statusline,而 1.0 版本线已经移除了此前的 start、stop、restart 和 code 等代理命令。

值得了解的社区 OpenRouter 客户端

社区客户端的差异,主要体现在它们为终端提供了什么样的操作界面。实际选择时,关键在于你需要交互式选择器、完整 API 覆盖、小型二进制文件、多模型自动化,还是稳定的机器可读输出。

客户端安装或启动方式最适合的场景需要确认的限制
@aaronjmars/openrouterclinpm install -g @aaronjmars/openroutercli广泛访问 OpenRouter API、OAuth PKCE、--json、用量数据、媒体任务,以及 request METHOD path非官方项目;需要 Node.js 20+;管理命令需要管理密钥
@letuscode/openrouter-clinpm i -g @letuscode/openrouter-cliopenrouter ask、repl、模糊模型搜索、配置档案、模板,以及 Markdown/纯文本输出README 说明项目仍处于 MVP 开发阶段;需要 Node.js 18.17+;采用 Polyform Noncommercial 1.0.0 许可证
orcnpm install -g openrouter-cli多模型提示词、配置档案、模板、批处理、提示词链和代码分析需要 Node.js 22+;使用 orc 命令;项目名和包名与上方的作用域客户端不同
ortcargo +nightly-2026-03-25 install --locked ort-openrouter-cliLinux 终端中的快速调用、提供商选择、标准输入、图片、感知 tmux 的连续执行,以及延迟/成本统计仅支持 Linux/x86_64;README 明确说明它不会验证 TLS 证书
llm-openrouterllm install llm-openrouter日志、别名、Schema、附件、工具,以及成熟的插件化工作流使用 OPENROUTER_KEY 这一环境变量约定;模型目录缓存一小时
aichat通过包管理器或二进制文件安装REPL、Shell 助手、RAG、代理、MCP、本地提供商,以及本地 HTTP 服务器抽象范围较广;README 没有提供按提供商逐项列出的功能或安全矩阵

以上是项目文档中列出的能力,并不是可直接比较的性能基准。

最小且可靠的工作流:curl 加 jq

如果系统中已经安装了 curl 和 jq,那么直接调用 OpenRouter API,是终端里最精简、也最透明的方式。OpenRouter Quickstart 文档介绍了 Bearer 身份验证、兼容 OpenAI 的 /api/v1/chat/completions 端点、model 字段、messages 数组,以及可选的流式输出。

先在当前 Shell 会话中设置密钥和模型:

export OPENROUTER_API_KEY='sk-or-v1-...'
export OR_MODEL='openai/gpt-4o'

然后发送一条提示词:

curl -sS https://openrouter.ai/api/v1/chat/completions \
  -H "Authorization: Bearer ${OPENROUTER_API_KEY}" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg model "$OR_MODEL" \
    --arg prompt "Explain Unix pipes in three sentences." \
    '{model: $model, messages: [{role: "user", content: $prompt}], stream: false}')" \
  | jq -r '.choices[0].message.content // .error.message'

建议将模型放进环境变量,而不是把模型 ID 复制到每个脚本中。官方 Models API 会返回 id、上下文长度、价格、支持的参数、提供商限制,以及可选的基准测试元数据。

把请求封装成可复用的 Shell 函数

下面的函数让 jq 负责编码提示词,从而确保请求体中的 JSON 安全。orask 接收命令行参数;orpipe 则将完整的标准输入作为一条提示词读取。

orask() {
  local prompt="$*"
  local model="${OR_MODEL:?Set OR_MODEL to an OpenRouter model ID}"

  jq -n \
    --arg model "$model" \
    --arg prompt "$prompt" \
    '{model: $model, messages: [{role: "user", content: $prompt}], stream: false}' \
  | curl -sS --fail-with-body \
      https://openrouter.ai/api/v1/chat/completions \
      -H "Authorization: Bearer ${OPENROUTER_API_KEY:?Set OPENROUTER_API_KEY}" \
      -H "Content-Type: application/json" \
      -d @- \
  | jq -r '.choices[0].message.content // .error.message // "Unknown OpenRouter error"'
}

orpipe() {
  orask "$(cat)"
}

示例:

orask "Turn this error message into a likely diagnosis: connection reset by peer"
cat README.md | orpipe

如果脚本还需要元数据,就保留完整 JSON,不要只提取文本:

orjson() {
  local prompt="$*"
  local model="${OR_MODEL:?Set OR_MODEL to an OpenRouter model ID}"

  jq -n \
    --arg model "$model" \
    --arg prompt "$prompt" \
    '{model: $model, messages: [{role: "user", content: $prompt}], stream: false}' \
  | curl -sS --fail-with-body \
      https://openrouter.ai/api/v1/chat/completions \
      -H "Authorization: Bearer ${OPENROUTER_API_KEY:?Set OPENROUTER_API_KEY}" \
      -H "Content-Type: application/json" \
      -d @-
}

这样可以保留响应中的 usage 对象,用于成本核算,同时也能将 API 错误与模型返回空响应区分开。

从命令行发现兼容模型

模型目录中的模型不一定支持所有请求参数。OpenRouter Models API 支持通过 supported_parameters 进行筛选,包括 tools,还可以按价格、上下文长度、吞吐量、延迟、热度或新近程度排序。

按照文档中的排序方式,从价格较低的一端列出支持工具的模型:

curl -sS -G https://openrouter.ai/api/v1/models \
  --data-urlencode 'supported_parameters=tools' \
  --data-urlencode 'sort=pricing-low-to-high' \
| jq -r '.data[] | [.id, .context_length, .pricing.prompt, .pricing.completion] | @tsv' \
| head -20

在将某个模型放进生产脚本前,先检查它的详细信息。OpenRouter 文档将单个模型的详情路由写作 /api/v1/model/{author}/{slug}:

curl -sS \
  "https://openrouter.ai/api/v1/model/${OR_MODEL}" \
| jq '.data | {id, context_length, architecture, pricing, supported_parameters, top_provider}'

pricing 中的数值按 token 或单位计价,因此不能不经换算就把原始小数理解为“每百万 token 的美元价格”。要查看一次请求实际消耗了多少输入和输出 token,响应中的 usage 字段更可靠。

在 Shell 管道中进行批处理

一种实用的批处理方式,是让文本文件每行包含一条提示词,并让每个结果对应一个 JSON 对象。下面的脚本会记录原始提示词、回答、用量和错误字段,不会把模型自然语言混入机器可读输出。

创建 prompts.txt:

Summarize the release notes in one paragraph.
List three security risks in this configuration.
Extract the names and versions from this sentence.

运行批处理:

#!/usr/bin/env bash
set -u

: "${OPENROUTER_API_KEY:?Set OPENROUTER_API_KEY}"
: "${OR_MODEL:?Set OR_MODEL}"

while IFS= read -r prompt || [[ -n "$prompt" ]]; do
  [[ -z "$prompt" ]] && continue

  request=$(jq -n \
    --arg model "$OR_MODEL" \
    --arg prompt "$prompt" \
    '{model: $model, messages: [{role: "user", content: $prompt}], stream: false}')

  response=$(curl -sS --fail-with-body \
    https://openrouter.ai/api/v1/chat/completions \
    -H "Authorization: Bearer ${OPENROUTER_API_KEY}" \
    -H "Content-Type: application/json" \
    -d "$request" || true)

  if jq -e '.choices[0].message.content' >/dev/null 2>&1 <<<"$response"; then
    jq -c --arg prompt "$prompt" \
      '{prompt: $prompt, answer: .choices[0].message.content, usage: (.usage // null)}' \
      <<<"$response"
  else
    jq -c --arg prompt "$prompt" \
      '{prompt: $prompt, answer: null, error: (.error.message // "Request failed"), usage: (.usage // null)}' \
      <<<"$response"
  fi
done < prompts.txt > results.jsonl

脚本会按顺序执行。只有在确认速率限制和预算后,才应加入并发,因为并行请求可能会迅速推高成本。OpenRouter 的价格页面列出免费计划每天 50 次请求,以及按量付费的 5.5% 平台费;因此,免费模型并不意味着可以无限批处理。

llm 和 aichat 适合什么场景

llm 和 aichat 都是支持 OpenRouter 的通用终端工作台。当你需要可复用提示词、会话、附件、工具、本地模型或历史记录时,它们比简单封装脚本更合适。

llm-openrouter:带日志、可扩展的方案

先安装基础的 llm 命令,再加入 OpenRouter 插件:

llm install llm-openrouter
llm keys set openrouter

插件文档将 OPENROUTER_KEY 作为环境变量名称。它会以类似 openrouter/anthropic/claude-sonnet-5 的名称暴露 OpenRouter 模型,并将模型列表缓存一小时。刷新方式如下:

llm openrouter refresh
llm models list

普通提示词和 Shell 管道可以这样使用:

llm -m openrouter/anthropic/claude-sonnet-5 \
  "Give me five short names for a pet tarantula"

cat app.py | llm -m openrouter/anthropic/claude-sonnet-5 \
  -s "Review this code for a security bug"

插件文档还介绍了 Schema、附件、工具调用、推理选项、提供商路由 JSON、OpenRouter Web 工具和密钥检查。它介于原始 curl 与自主编程代理之间,但模型缓存可能会落后于实时目录。

aichat:功能更全面的终端工作台

aichat 是一个基于 Rust 的 CLI,除了 OpenRouter,还支持 20 多个具名提供商和兼容 OpenAI 的端点。其文档列出的功能包括 CMD 模式、Chat-REPL、Shell 辅助、会话、宏、RAG、函数调用、MCP 工具、代理,以及提供聊天、嵌入和重排序端点的本地服务器。

它将 OpenRouter 配置为一个兼容 OpenAI 的客户端,并指向 https://openrouter.ai/api/v1;项目示例使用 openrouter:<model> 形式的模型名称。如果终端正在逐渐成为你的应用界面,可以考虑使用它;如果你更看重精简、便于检查的请求路径,那么 curl 或 llm 更合适。

排查那些看起来像 CLI 问题的故障

OpenRouter CLI 的故障可能发生在 Shell、客户端、所选模型和账户之间的边界上。与其立即更换工具,不如先分别检查这些层次。

现象首先检查可能所在的层
401 或缺少密钥错误确认客户端要求的变量名;llm-openrouter 使用 OPENROUTER_KEY,而原始 API 示例使用 OPENROUTER_API_KEYShell 或客户端身份验证
Ori 能打开代理,但模型被拒绝确认模型 ID,以及底层 Harness 对 API 的要求Harness 与模型兼容性
选择器中缺少某个模型刷新 llm 的一小时缓存;对于其他 Harness,则与 /api/v1/models 的结果对照客户端模型目录
工具或 Schema 请求失败使用 supported_parameters=tools 筛选 /models,或检查模型元数据模型能力
免费请求意外停止检查当前免费计划的请求上限,以及该模型是否仍作为免费模型提供账户或平台政策
成本高于预期记录 .usage、所选提供商、路由选项和缓存行为请求与提供商路由

在一篇讨论 OpenCode 和 Kilo Code 的 Reddit 帖子中,用户 u/GrevireDev 写道:

“Both Kilo Code and OpenCode maintain a hard-coded/preloaded list of OpenRouter models instead of dynamically fetching the full catalog.” — r/openrouter

用户 u/DrunkenRobotBipBop 在另一篇 OpenRouter 讨论中提到了成本和缓存问题:

“Take care of how you handle caching in openrouter. Everytime the provider changes, the cache is gone and you are going to pay full price.” — r/openrouter

把这些内容当作排查线索,而不是计费规则;实际成本仍应通过请求用量、提供商数据和当前 OpenRouter 价格进行确认。

OpenRouter CLI 常见问题

下面这些问题,基本涵盖了 openrouter cli 查询背后的常见安装和选择需求。简短答案会将问题指向正确的层次:官方启动器、原始 API、社区客户端或模型目录。

OpenRouter 有官方 CLI 吗?

有。OpenRouter 官方文档介绍了 ori CLI,但 Ori 本质上是现有编程代理的启动器和配置层。OpenRouter 的 @openrouter/cli npm 包是独立的 DevTools 工具,而 @aaronjmars/openroutercli 这类直接调用聊天/API 的 CLI 则属于社区项目。

不安装 CLI,也能在终端中使用 OpenRouter 吗?

可以。向 https://openrouter.ai/api/v1/chat/completions 发送带 Bearer 身份验证的 curl 请求,就足以完成一次性提示词调用;再配合 jq,既可以提取文本,也可以为管道保留完整 JSON。

哪个 OpenRouter CLI 最适合 JSON 管道?

对于小型脚本,直接使用 curl 的隐藏行为最少。若需要更广泛的命令功能,可以选择明确记录 JSON 模式的客户端,例如 @aaronjmars/openroutercli;也可以使用 llm,并显式保留所需的响应数据。

为什么我的 CLI 显示的模型比 OpenRouter 网站少?

客户端可能会缓存模型目录,也可能使用预加载的模型列表。你可以将选择器中的内容与 curl https://openrouter.ai/api/v1/models 的结果对照,在支持的情况下刷新客户端缓存,并传入接口返回的准确模型 ID,而不是显示名称。

Ori 需要 OpenRouter API key 吗?

OpenRouter 的 Ori 文档表示,正常登录流程使用 OAuth PKCE,因此用户不需要创建并粘贴单独的 API key。不过,原始 curl、llm-openrouter 和大多数社区客户端仍然需要密钥或各自的身份验证配置。

自动化 OpenRouter CLI 工作流前需要确认的事项

在固定某个模型之前,先查询实时 Models API;同时记录模型 ID 和响应中的 usage,并设置账户或密钥预算。CLI 只是前端:真正决定工作流是否可靠、是否负担得起的,仍然是 OpenRouter 的模型、提供商路由、上下文大小和账户限制。