orcareplay について
OrcaReplay は、コーディングエージェントの実行を記録し、オフラインでリプレイおよびフォークするコマンドラインツールです。ローカルプロキシで通信を捕捉するためエージェント本体の変更は不要で、エージェントの失敗原因を調べる開発者に向いています。
主な機能
- 01コーディングエージェントの実行を完全に記録
- 02モデル呼び出しやトークン消費なしのオフラインリプレイ
- 03任意のステップから別のモデルへ分岐して実行
- 04同一チェックポイントでのモデル比較
- 05タイムラインと因果関係グラフの生成
活用シーン
- 01エージェントがファイルを削除した原因の調査
- 02同一コンテキストで複数モデルの結果とコストを比較
- 03問題報告用に実行過程の図を書き出す
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
6掲載時のツール一覧 · 2 週間前に更新
このツールにパラメーターはありません。
詳細
OrcaReplay
英語 · 简体中文 · 日本語 · 한국어 · Deutsch · Français · Español · العربية
エージェントが午前2時に何かを壊しました。午前9時に、正確に、オフラインで、何度でも再生しましょう。
どんなコーディングエージェントでも記録できます。モデルを一切呼び出さずに、実行をバイト単位で再現できます。任意のステップから別のモデルに分岐させ、どちらが正しく解決するかを確かめましょう。
OrcaRouterを手がけるチームが開発 — Claude、GPT、Gemini、Grok、DeepSeek、Qwen などを利用するための、1つの API キーと1つのエンドポイント。これは、デフォルトでorca setupが接続する先であり、orca compareをプロバイダーのアカウント4つではなく、1つのコマンドで実行できるようにするものです。
詳しくはこちら:OrcaRouter の全モデル API
GitHub リポジトリ:OrcaCode Review · OrcaRouter Lite
つながりましょう:X · Discord · Hugging Face · Ollama

1つのセッションから得られた実際の出力です — Claude Code の実行を記録し、その記録に対して再生した後、チェックポイント4で2つのモデルに分岐させ、npx tsc --noEmitで採点しています。ここにあるものは、何も作り物ではありません。
3つのコマンドで試す
orcareplayという名前の npm パッケージをインストールすると、orcaというコマンドが PATH に追加されます。「orca」という別のツールはなく、エージェントへのインストールもありません。
npm i -g orcareplay # the package is orcareplay; the command it installs is orca
orca record claude # your agent, unmodified, doing whatever it does
orca replay last # the same run again — no network, no tokens, no charge
orca replay last --from 4 --model claude-haiku-4-5 --ui
一番下の3つ目のコマンドが、このツールを使い続ける理由です。同じファイル、同じ会話のプレフィックスを使い、ステップ4以降は別のモデルで実行します。変数はモデルだけなので、結果に意味が生まれます。
最初の3つのコマンドには、エージェント、キー、ネットワーク、実際のトークンが必要です。まだ何も用意できていない場合は、必要なものがすべて含まれたコマンドを1つ実行するだけです。
orca quickstart
小さなプロジェクトと、その中にある本物のバグを修正するエージェントの記録を生成します。その後、モデルを呼び出さずに、プロジェクトに対して記録を再生します。最初はテストが2つ失敗し、再生後は4つ成功。3ターン分がトレースから提供され、費用はかかりません。--fullを指定すると、タイムライン全体と再生の様子をそのまま表示します。
エージェント自身のシステムプロンプトを読む
ループ全体を確認できるプロキシは、ハーネスが何かを送信する前に組み立てたプロンプトも確認できます。コマンドを1つ実行すると、プロンプトを取得し、マシン固有の情報を取り除いて、モデルごとに保存します。
node capture/capture.mjs claude --model claude-opus-5
対話型のプロンプトと-pのプロンプトは同じではなく、モデルによっても異なります。測定された違い、注意点、サニタイズのルールについては、capture/README.mdを参照してください。
これが存在する理由
現在、エージェントのデバッグは考古学のようなものです。ターミナルをスクロールし、再実行しては別のエラーに遭遇し、他人のハーネスに print 文を追加します。既存のツールは可観測性ツールです。実行に $4.12 かかり、61k トークンを使ったことは教えてくれますが、知りたいのはそれではありません。知りたいのは、なぜマイグレーションファイルを削除したのかです。
OrcaReplay は、実行をそのまま取り戻せるようにすることで、その問いに答えます。
| 可観測性ツール | OrcaReplay | |
|---|---|---|
| 実行にかかった費用がわかる | ✅ | ✅ |
| どのツール呼び出しがファイルを削除したかわかる | 場合による | ✅ |
| エージェントを再実行して同じ回答を得られる | ❌ | ✅ 記録からバイト単位で完全に同じ |
| モデルを変更してステップ 4 から再実行できる | ❌ | ✅ |
| エージェントの変更が必要 | 通常は SDK ラッパーが必要 | ❌ 環境変数 2 つ |
| ターミナルを閉じた後も使える | ❌ | ✅ ファイルだからです |
| モデル API の先にあるもの、たとえばシェルの終了コードやファイルへの書き込みを確認できる | ❌ | ✅ すべてのターン |
| リダイレクト先の API エンドポイントがないエージェントを記録できる | ❌ | ✅ オプトインの --tls-intercept |
最後の 2 行は、SDK ラッパーでは構造上対応できません。キャプチャはエージェントの下層、プロセスとソケットの境界で行われるため、エージェントが自分のものか、編集できるか、API キーを持っているかどうかは関係ありません。ChatGPT サブスクリプションでサインインした Codex CLI は、バックエンドだけが受け付ける認証情報を使って TLS 経由で独自のバックエンドと通信するため、接続先を変更すると同じセッションを維持できません。それでも orca は記録できます。詳しくは ハーネスの接続先を変更できない場合を参照してください。
仕組み
モデル API はステートレスなため、エージェントはターンごとに会話全体を再送信します。前のターンのツール結果も含まれます。そのため、モデルの前に置かれたプロキシはループ全体を確認できます。各リクエスト、ストリーミングされた各レスポンス、モデルが出力したすべてのツール呼び出し、ハーネスが生成したすべてのツール結果です。この特性を基盤として構築されているため、OrcaReplay はエージェントにパッチを適用しません。ローカルプロキシを起動し、環境変数を 2 つ設定して、あとは介入しません。
「egress blocked」が正確に意味すること。 リプレイ時、プロキシはトレースから提供できないものの転送を拒否するため、モデルは呼び出されず、トークンも消費されません。この実行では egress=blocked と表示されます。意図的に解除するには --loose を指定します。一致しないリクエストはプロバイダーが応答し、重大な差異として記録されます。同じ行には egress=live-on-unmatched と表示されます。リプレイでも、記録されたツール呼び出しは実際に実行されます。また、独自のソケットを開くツール(curl を実行するシェルコマンドや、何かを取得する MCP サーバーなど)は、どちらの場合も保証の対象外です。デフォルトではプロキシに到達せず、通常どおりネットワークに接続します。--tls-intercept を指定すると、子プロセス全体に HTTPS_PROXY が設定されるため、プロキシに到達します。傍受リストにないホストは変更されずにトンネル経由で転送されますが、そのホスト名、ポート、バイト数はトレースに記録されます。リストにあるホストへの呼び出しは、他の一致しない呼び出しと同様に、そこで拒否されます。リプレイはサンドボックスではありません。サンドボックスが必要な場合は、その中で実行してください。
プロトコルでは確認できない情報(終了コード、実際の所要時間、各バイトがどのストリームから出たか、誰にも知らせずに書き込まれたファイルなど)を、さらに 3 つのレイヤーで捕捉します。ベース URL の変数をまったく読み取らないエージェント向けに、5 つ目のレイヤーもあります。詳しくは対象となるエージェントを参照してください。6 つ目のレイヤーは、ハーネスに独自の構造情報がある場合に、それを読み取ります。どのサブエージェントが実行され、どのサブエージェントからどれに引き継がれたか、ガードレールが作動したか、どのグラフノードが何を生成し、そのうちどれがモデルをまったく呼び出さなかったか。これらはいずれも通信上には現れません。
%%{init: {'theme':'neutral'}}%%
flowchart LR
A["<b>your agent</b><br/><i>unmodified</i>"]
subgraph orca["orca · six capture layers"]
direction TB
P["<b>proxy</b><br/>base-URL env var"]
SH["<b>PATH shim</b><br/>exit code · timing · streams"]
MC["<b>JSON-RPC tee</b><br/>MCP config rewrite"]
FS["<b>shadow git index</b><br/>workspace per turn"]
FH["<b>fetch hook</b><br/>for a hardcoded origin"]
end
A --> P & SH & MC & FS & FH
P -->|"forwarded, auth intact"| U["<b>the model API</b><br/><i>or OrcaRouter · any gateway</i>"]
orca ==> T[("<b>one trace</b><br/>.orca/runs/run_a1b2c3")]
すべてが同じタイムラインに記録されます。orca が読み取った時刻ではなく、実際に発生した時刻順に並びます。
完全再現、フォーク、比較は同じものです
これらは3つのサブシステムではありません。カーソルを備えた同じプロキシです。カーソルとは、記録されたストリームのうち、ディスクからの応答を停止してネットワークからの応答を開始する位置です。
%%{init: {'theme':'neutral'}}%%
flowchart LR
subgraph disk["from disk · byte-for-byte · network blocked"]
direction LR
T1["turn 1"] --> T2["turn 2"] --> T3["turn 3"] --> T4["turn 4"]
end
T4 ==> CUR{{"<b>cursor</b>"}}
CUR ==> T5
subgraph net["from the network · any model you name"]
direction LR
T5["turn 5"] --> T6["turn 6"] --> T7["…"]
end
| コマンド | カーソルの位置 | 得られる結果 |
|---|---|---|
orca replay last | 末尾 | 実行全体をもう一度再生します。ネットワークはブロックされるため、トークンの消費も料金もばらつきもありません |
orca replay last --from 4 --model X | チェックポイント4 | 4までのターンは同一で、その後は別のモデルに引き継がれます |
orca compare last --from 4 --models a,b | チェックポイント4に複数回 | 1つの表に1つの変数、つまりモデルだけが表示されます |
チェックポイントは記録されるものではなく、導出されるものです。会話のプレフィックスが完成し、ワークスペースのスナップショットが作成された任意の時点を指します。したがって、すべてのフォークは、実際に存在したことが証明できる状態から開始されます。
バグ調査の実際の様子
エージェントには、失敗している認証テストを修正するよう指示したはずです。終了コードは 0 でしたが、テストはまだ失敗しています。まず、実際に何をしたのかを確認しましょう。
$ orca show last
run_6473f858b59e [email protected] 14 events exit 0
SEQ KIND WHAT DETAIL
0 RUN run started generic-openai
1 SNAP tree 919d32ba037537b43814c83779963b2cc3023db7 0 changed
2 MODEL claude-opus-5 1 messages
3 MODEL claude-opus-5 stop: tool_use · 100 in · 20 out
4 TOOL edit_file {"path":"auth.ts",…}
5 SNAP tree c6af62b75c0c8b8938bd6087328b5148f3dcd534 1 changed
6 FILE auth.ts modified +1 −3
7 TOOL edit_file ok
8 MODEL claude-opus-5 3 messages
9 MODEL claude-opus-5 stop: end_turn · 101 in · 5 out
10 SNAP tree c6af62b75c0c8b8938bd6087328b5148f3dcd534 0 changed
11 SHELL ["sh","-c","node --check nonexistent-file.ts"] /tmp/hunt
12 SHELL shell result exit 1 · 43ms
13 RUN run ended exit 0
info usage input=201 output=25 cost=$0.004890
モデル自身のトランスクリプトからは分からず、実行の終了コードにも隠れていた事実が 3 つあります。ファイルは実際に変更され(seq 6、+1 −3)、エージェントが実行したチェックは失敗し(seq 12、exit 1)、それでも処理を終えています。実行の終了コードが 0 だったのは、エージェントが 0 で終了したからです。
最後の事実こそ、専用のコマンドで確認する価値があります。orca show は何がどの順番で起きたかを示し、orca graph は何が何を生み出したかを示します。
$ orca graph last
FROM TO KIND WHY
3 model.response 4 tool.call recorded tool_use block in the response
4 tool.call 6 fs.change inferred changed path appears in tool input, same or previous turn
4 tool.call 7 tool.result recorded tool result answers its call
7 tool.result 8 model.request recorded tool_result block in the request
11 shell.exec 12 shell.result recorded shell result answers its exec
1 inferred — derived from this trace, not recorded in it
エッジには 2 種類あり、その違いは重要です。記録済みエッジは、実行時に書き込まれます。tool_use ブロックは、それを出力したレスポンスの中に実際に含まれているためです。推定エッジは、名前が示すルールに基づいて今まさに割り出されたものです。ファイルシステムのスナップショットはツール呼び出しごとではなく、ターンごとに 1 回取得されるため、ファイル変更を特定の呼び出しに結び付けるのは妥当な推測ではありますが、事実ではありません。推定エッジがトレースに書き戻されることはありません。チェックポイントが導出されるだけで記録されないのと同じです。そのため、サードパーティの読み取り側が信頼するフィールドに、orca が作り出した情報が入ることはありません。
--graph-card は、実行全体をその形式で描画します。時間は左から右へ、種類は上から下へ並び、失敗を生み出したチェーンがほかのすべてに対して強調表示されます。

重要なのは、この形です。実行は「リクエスト、レスポンス、呼び出し、効果、結果」というモチーフが繰り返されるもので、そこから外れるものはすべて注目に値します。また、出ていくエッジがないイベントは、リストではまったく見えない欠落です。
orca export last --card bug.svg は、そのチェーンだけを描画します。課題やメッセージに添えるのに適した形式です。

対象を手動で選んだわけではありません。--to は渡されていません。破線がトレースから切り離されて推測を事実に見せかけてしまわないよう、カードには凡例が含まれ、再現に使うコマンドも表示されます。
SVG が表示できるのは GitHub の課題など、ごく一部の場所だけです。X にはアップロードできず、Slack や Discord でもプレビューされません。そのため、ファイル名を .png にすれば PNG が作成され、.gif にすればチェーンが経路ごとに順次描画されます。この方法にはブラウザーが必要ですが、orca はブラウザーに依存しません。docs/media/README.md では描画ツールチェーンを package.json の外に置いているため、npm ci を実行する人が Chromium のダウンロードに費用をかけずに済みます。図を作成するコマンドのために、この方針を覆す必要はありません。ラスター画像を求めたときに環境が整っていなければ、orca はそれを解決する 1 行を表示します。orca doctor でも同じ状態を確認できます。また、.svg には何も必要ありません。
orca export last --card bug.png # the chain, ready to post
orca export last --card bug.gif # the same chain, one hop per frame
npm i --no-save playwright-core pngjs gifenc # only needed for the two above
これで、好きなだけ何度でも無料で再現できます。
$ orca replay last
info replay.done reused=2/2 exact=2 divergences=0 unmatched=0 exit=0
ネットワーク不要、トークン不要、ばらつきもありません。次に、本当に知りたいことを尋ねましょう。別のモデルなら正しくできたでしょうか?
$ orca compare last --from 5 --models claude-opus-5,claude-haiku-4-5 --verify "npm test"
MODEL VERDICT TOKENS COST WALL RUN
claude-opus-5 pass 201/25 $0.004890 0.3s run_1457b35062ba
claude-haiku-4-5 pass 201/25 $0.000326 0.3s run_b8ee08479fb6
どちらも合格です。一方は15 分の 1 のコストで済みます。ファイルも会話のプレフィックスもチェックポイントも同じで、変わったのはモデルだけです。だからこそ、この数値に意味があります。
タイムライン
orca replay last --ui(または orca ui)を実行すると、実行記録が自己完結型の HTML ファイルとして開きます。サーバーを起動し続ける必要も、ネットワークも、インストールも不要です。フィルターを適用したり、ステップごとに進めたり、スペースキーを押して実際に起きたペースで実行記録を再生したりできます。

すべてのレイヤーが同じタイムラインに表示されるため、4 つの別々の情報ではなく、ひとつの流れとして実行内容を確認できます。モデルのターンとトークン数、引数と結果を含む各ツール呼び出し、終了コードと実行時間を含むシェルコマンド、そして変更によって生成されたツリーを含むファイルシステムの変更が表示されます。
orca export last -o bug.html を実行すると、問題報告に添付できる単一ファイルに、このページをそのまま出力します。外部参照は一切含まれず、CI でも検証されています。そのため、ダウンロードフォルダーでも、飛行機の中でも、5 年後でも表示できます。
同じタスク、異なるモデル
orca compare は、記録した実行を同じチェックポイントから複数のモデルに分岐させ、同じファイルと同じ会話のプレフィックスを使って、選択したコマンドでそれぞれを評価します。変数はモデルだけなので、比較結果に意味が生まれます。

orca compare last --from 4 \
--models claude-sonnet-5,claude-haiku-4-5 \
--verify "npm test" \
--share verdict.svg # the card above, ready to paste into an issue
複数のモデルを指定する
モデルを比較するには複数のプロバイダーに接続する必要があります。手動で行う場合は、--upstream-anthropic と --upstream-openai があること、ひとつのゲートウェイで両方のワイヤ形式を扱えること、そしてキーの設定場所を把握しなければなりません。どれも実際の仕様ですが、見つけにくいため、代わりに質問できるコマンドを用意しています。
$ orca setup
Gateway URL (serves the model APIs) [https://api.orcarouter.ai]:
get a key at https://www.orcarouter.ai/console/token — OrcaRouter keys start sk-orca-
API key (stored 0600; leave blank for none):
info config.saved path=~/.config/orca/config.json mode=0600 gateway=https://api.orcarouter.ai auth=stored
6 models available:
anthropic/claude-opus-5
anthropic/claude-haiku-4-5
openai/gpt-5.2
...
$ orca models
MODEL $/MTOK IN $/MTOK OUT
anthropic/claude-opus-5 15 75
anthropic/claude-haiku-4-5 1 5
openai/gpt-5.2 1.25 10
some-local-model — —
orca setup は、単にファイルを書き込むのではなく、ゲートウェイが実際に提供しているモデルを確認します。そのため、URL の誤りや無効なキーは、比較の途中で 401 エラーになるのではなく、その場で分かります。また、選択したモデルも保存するため、その後はモデルリストや upstream フラグを指定せずに orca compare last --verify "npm test" を実行できます。orca models は認識できるモデルの料金を表示し、認識できないモデルにはダッシュを表示します。未知のモデルに架空の数値を当てはめると、比較テーブルに実在しないコストが載ってしまうためです。
OrcaRouter は、最初の質問に対する既定の選択肢です。Enter キーを押せば、Claude、GPT、Gemini、Grok、DeepSeek、Qwen などをひとつのオリジンとひとつのキーで利用できます。これは orca compare が想定する構成そのものです。モデル ID はプロバイダー名空間(anthropic/claude-sonnet-4.6、openai/gpt-4o-mini)を使用しており、orca が処理します。名前空間からワイヤ形式を選び、料金計算の前に取り除きます。
これはあくまで既定の選択肢であり、接続先が固定されるわけではありません。値を上書きするか、--gateway <url> を渡せば、OpenAI 互換の /v1/models およびチャットエンドポイントに対応するものなら、ホスト型ゲートウェイでも、自分で実行するものでも、同じように利用できます。
また、これはユーザー自身が送信を指定した通信に対してのみ、既定の選択肢になります。ゲートウェイが設定されていない場合、orca record はエージェント独自の呼び出しを、エージェント自身のキーを使って、すでに通信していたプロバイダーへそのままプロキシします。orca が、設定していない記録の送信先を変更することはありません。記録を開始しただけで、ソースコードが第三者に送信されることになるためです。
非対話型で使う場合は、orca setup --key <k> で既定の接続先を使用し、orca setup --gateway <url> --key <k> で別の接続先を指定できます。また、--key-env <VAR> を使うと、認証情報をディスクに保存せずに環境変数からキーを読み込みます。
キーがトレースに含まれることはありません。キーは送信リクエストにのみ付与され、記録される内容は認証情報を取り除いた受信リクエストから作られます。そのため、誰かが忘れないようにルールを設けるのではなく、仕組み上、記録から見えないようになっています。フラグによってゲートウェイの発行元以外に通信が送られる場合は、キーは一切付与されません。
実行のもう半分:orca push と orca pull
ローカルで記録したものとゲートウェイで記録したものでは、見えるものが異なり、どちらも全体像ではありません。
orca record はあなたのマシン上で動作するため、シェル、ファイルシステム、MCP、つまり副作用を記録します。
OrcaRouter ゲートウェイは通信経路上にあるため、どのノート PC にも見えないものをすべて記録します。すべてのキー、すべての同僚、すべての CI ジョブ、そして各呼び出しの背後にあるルーティング判断です。どちらも同じ orca-trace v0 を書き出すため、興味深いのはどちらか一方ではありませんでした。実行を両者の間で移動させることでした。
これまでは、その往復はブラウザーでのダウンロードとフォームへのアップロードでした。3 つのコマンドです:
$ orca list --remote # what the gateway is holding
$ orca push [run] # this machine -> the gateway
$ orca pull <run> # the gateway -> this machine

実際の出力です。このカードは、実際の往復を記録した docs/media/sync-transcript.txt から scripts/render-sync-card.mjs によって生成されます。orca record、続いて push、次に別のワークスペースへの pull、そして取得したコピーを読み取る orca show という流れです。手書きの行はありません。ここでのゲートウェイは、同じ 2 つのエンドポイントを話すローカルスタブなので、アドレスはループバックアドレスになっています。
push は、ほかの実行を受け取るコマンドと同じく、デフォルトで最後の実行を使います。pull はそうではありません。まだ実行を見たことのないマシンでは「最後」が何も意味しないため、ID を指定する必要があります。
そこで使うのが orca list --remote です。手元にない ID はデフォルト値として指定できませんし、以前はブラウザーのコンソール以外で ID を確認する方法がありませんでした。そのため、ID が必要なコマンドが、ターミナルから開けないタブにありました。--remote はゲートウェイに、orca list がこのディレクトリに尋ねるのと同じ質問をします。push がすでに POST しているパスに対して GET を行います:
$ orca list --remote --limit 3
RUN STARTED SOURCE APP TURNS TOOLS LAYERS MODELS OUTCOME
run_3d9e61a07b52 2026-09-21 09:36 upload generic-openai 1 0 model,fs m exit 0
run_8c14f2e9a07d3b6150e2c49a 2026-09-20 04:21 gateway Unknown 1 0 model,route deepseek/deepseek-v4-flash-free end_turn
run_f07a5c2e91d4468bb3e0a17c 2026-09-20 02:02 gateway curl 1 0 model,route deepseek/deepseek-v4.1-flash error
orca pull <run> # fetch one into this machine’s store
読み取るべき列は LAYERS です。 このページの両半分が扱うのはこの列です。model と route はゲートウェイに由来し、ノート PC には見えないルーティング判断を記録します。fs、shell、mcp、net はここで記録された実行に由来します。ダウンロードする前に、その実行に何が含まれているかがわかります。SOURCE も隣に表示されます。実行の出所と、実行に含まれるものは別の問いだからです。
STARTED は実行の最初のイベントであり、ゲートウェイがそれを保存した時刻ではありません。push された実行では、push するまでに待った時間だけ両者に差があります。OUTCOME は、ゲートウェイが記録した実行に付ける値(end_turn、error)であり、ここから push した実行の場合は終了コードです。ゲートウェイから報告されない値は空欄ではなく — と表示されます。古いデプロイではタイムスタンプがまったく送られないため、STARTED は 1970 年の日付ではなく未設定になります。--source gateway を指定するとゲートウェイが記録したものに絞り込み、--source upload を指定するとゲートウェイに push されたものに絞り込みます。この 2 つ以外の値は、空のリストを返すのではなくエラーになります。フラグを指定しない場合は両方が表示されます。--limit は件数を指定します(デフォルトは 20 件です)。--gateway は push と pull の場合と同じく、どのホストを使うかを上書きするオプションです。切り替え用のフラグを兼ねるわけではないため、すでに指定した宛先に URL を再度入力する必要はありません。この 3 つはすべて --remote と組み合わせて使います。--remote なしで指定すると、無視されずエラーになります。そうしないと、orca list --gateway <url> がこのディレクトリの実行を返したとき、そのホストからの応答と誤解されるためです。
--json を指定しても、同じ質問をします。orca list --remote --json はゲートウェイの実行を 1 つのドキュメントとして stdout に出力します。表を読む人がいない場合、orca pull <run> に渡す ID はここから取得できます。
必要なもの
replay スコープを持つキー。Console → API Keys → replay から取得できます。このスコープではセッションの実行を読み取ってプッシュできますが、リレーはできません。そのため、別の用途に見せかけたモデル通信の認証情報ではありません。リプレイキーはリレールートでは明示的に拒否されます。また、アップロードはワークスペースごとにデフォルトで無効になっており、Settings → request logs で有効にします。ゲートウェイが記録のみを行い、受け付けない状態が通常です。
$ export ORCA_GATEWAY_URL=https://api.orcarouter.ai # or your own gateway
$ read -rs ORCA_GATEWAY_KEY && export ORCA_GATEWAY_KEY # not typed on the command line
$ orca push last
どちらのエクスポートもシェルセッション中は保持されます。これが上記のルールの要点です。同じシェルで後から orca push --gateway <somewhere-else> を実行すると、エクスポートしたキーを別のゲートウェイに黙って渡すのではなく、拒否されます。
できないこと
- デフォルトの送信先にはなりません。
orca setupでは、モデルのゲートウェイをデフォルトで OrcaRouter にできます。エージェントがすでに実行していた呼び出しをプロキシすることは、情報の開示にはあたらないためです。一方、実行データは別です。実行データにはソース、シェル出力、ワークスペースのスナップショットが含まれ、コンテンツアドレス付きの BLOB として転送されます。そのため、プッシュ先のホストにデフォルトはありません。ゲートウェイが送信先となるのは、--gateway、ORCA_GATEWAY_URL、またはorca setupで入力した URL によって明示的に指定した場合だけです。orca setupで Enter キーを押したときに自動入力されるゲートウェイは、どれだけモデル通信に適していても送信先とは見なされません。通常のorca setupの後にorca push lastを実行すると、拒否され、その理由が表示されます。また、push.packedは、リクエストを送信した後ではなく送信する前に、ファイル数とバイトサイズを報告します。 - 求められない限り、ワークスペースのスナップショットは送信しません。
orca scrubはevents.jsonlと BLOB を書き換えますが、fs/配下のシャドウ Git ストアは書き換えられません。オブジェクトは展開可能な圧縮形式で保存され、内容のハッシュでアドレス指定されるためです。そのため、orca scrubはそれらを検索し、まだ何が含まれているかを知らせ、--drop-fsを提案します。したがって、デフォルトではプッシュ時にfs/はローカルに残ります。「オブジェクトにまだ素材が含まれています」と報告されたスクラブの後に、それでもプッシュで送信することがあってはなりません。必要なケース、つまりツリーを使ってチームメイトが再現する場合は、--fsで送信できます。送信時にはそのことが通知されます。ペイロードのうち、送信元と送信先のどちらでもスキャンできないのはここだけだからです(オブジェクトは圧縮されているため、平文のスキャンでは何も見つかりません)。 - セットアップされていないホストにキーを渡しません。 すべての認証情報には使用先があります。保存されたキーの使用先は
orca setupのゲートウェイ、エクスポートされたキーの使用先はORCA_GATEWAY_URLです。URL を指定せずにエクスポートされたキーには、使用先がありません。そして、認証情報は送信先がその使用先と一致する場合にのみ付与されます。--gatewayは実行データの送信先を変更しますが、キーの発行先は変更しません。そのため、別のホストを指定すると、他者の認証情報で認証するのではなく、プッシュが拒否されます。唯一許可されるのは、その呼び出しで指定された送信先だけを持つキーです。それ以前にホストと関連付けられていないため、これは CI での使用形態です。 - 匿名では実行しません。 キーなしで 3 つのいずれも試みることはありません。未認証リクエストは、設定ミスのある公開エンドポイントが応答するリクエストそのものです。また、実行データの所有者がいない宛先に送られたことや、一覧に表示された内容が自分に限定されていなかったことを知る手段として、
200を返されるのは望ましくありません。 - 部分的な置き換えは行いません。
pull --forceは古いコピーの隣に新しいコピーを書き込み、リネームで切り替えるため、クラッシュしてもどちらの場合でも実行データ全体が残ります。また、次のプルで前回の処理の残りを完了するか、ロールバックします。--forceは記録の置き換えを求めるものであり、記録を破棄してから失敗してよいという許可ではありません。
到着時にゲートウェイが行うこと
events.jsonl のインテグリティルートを再計算し、その値がマニフェストと一致しないプッシュを拒否します。そのため、プッシュではディスク上にあるバイト列をそのまま送信し、変換は行いません。また、アーカイブをスキャンして平文のシークレットを検出し、見つかった場合は拒否します。この拒否を回避するためのオプションが --force であり、--force がオプトインになっているのは、デフォルトの動作によって共有サーバーにキーが送られるのを防ぐためです。
ここで墨消し処理を再実行することはありません。TraceWriter は、呼び出し元が処理を迂回できないよう、ディスクに書き込むまでにすべてのイベントを スピル、墨消し、検証、追記 の順に処理します。そのため、プッシュで読み取るバイト列はすでに墨消し済みです。再度スキャンして墨消しすると、インテグリティルートの対象となるバイト列を書き換えてしまいます。これはアーカイブをプッシュできなくなる唯一の原因です。ゲートウェイのスキャンは、最初の処理を繰り返すのではなく、独立した二つ目の防御線です。
対応するエージェント
ハーネスを記録できるかどうかは、プロキシを指定できるか、そして到着後に orca がそのハーネスの使用するワイヤ形式を理解できるか、という2つの点で決まります。
| エージェント | キャプチャ方法 | 状態 |
|---|---|---|
| Claude Code | ANTHROPIC_BASE_URL | 動作します — 実際のバグ修正で検証済みです。詳細はこちら |
| Codex CLI(API key) | OPENAI_BASE_URL → Responses API | 動作します |
| Codex CLI(ChatGPT login) | --tls-intercept → Responses API | 動作します。判断が必要です |
| OpenAI Agents SDK | OPENAI_BASE_URL → Responses API | 動作します — SDK 自体が、デフォルトの Responses API で exact=1 の記録と再生を行います。CI で確認済み。SDK 独自のトレースは 2 つ目の送信先です |
| Vercel AI SDK | @ai-sdk/openai 経由の OPENAI_BASE_URL(2.0.41 以降)— orca record generic-openai --。オリジンがコンパイル時に組み込まれている場合は fetch フック(orca record node --) | 動作します — 環境変数に対応した SDK クライアントは generic-openai 経由で exact=1 の記録と再生を行います。CI で確認済み。ソースにコンパイルされたオリジンへ送信するエージェントも exact=1 の記録と再生を行います |
| grok-cli(およびその Telegram ボット) | orca record grok — GROK_BASE_URL と、サブエージェント用のフック | 動作します |
| OpenClaw | orca record openclaw — ゲートウェイ用のフックと、起動するエージェントへの環境変数の継承 | 動作します |
| opencode | orca record opencode | アダプターを提供済みです。両方のオリジンがリダイレクトされます |
| goose(Block) | orca record goose — OPENAI_HOST および OPENAI_BASE_URL、ANTHROPIC_HOST → Responses API | 動作します — goose 1.49.0 でエンドツーエンドの動作を確認済みです。何が異なるのか |
| LangGraph / LangChain | OPENAI_BASE_URL、ANTHROPIC_BASE_URL | 動作します — 2 ノードのグラフで、ストリーミングとツールを使った記録と再生が exact=2 で行われ、ライブでフォークできます。CI で確認済み。pip install orcareplay-langgraph を実行するとグラフも記録されます — どのノードがどのスーパーステップで実行されたか(モデルを呼び出さないノードも含む)を記録します |
| Haystack | orca record generic-openai -- python your_pipeline.py — OpenAIChatGenerator は base_url を OpenAI SDK に任せ、SDK が OPENAI_BASE_URL を読み取ります | 動作します — ChatPromptBuilder と OpenAIChatGenerator を含む Pipeline が exact=1 の記録と再生を行います。CI で確認済み |
| OpenHands | orca record generic-openai -- python your_agent.py — SDK は LiteLLM をラップし、OPENAI_API_BASE を読み取ります | 動作します — SDK 独自の LLM レイヤーが exact=1 の記録と再生を行います。CI で確認済み |
| CrewAI | orca record generic-openai -- python your_crew.py — 1.x 以降は独自のプロバイダーを使用し、OPENAI_API_BASE と OPENAI_BASE_URL を読み取ります | 動作します — 実際の Agent、Task、Crew が exact=1 の記録と再生を行います。CI で確認済み。1.x での変更点 |
| Aider | orca record generic-openai -- python your_agent.py — LiteLLM 経由でルーティングし、LiteLLM が OPENAI_API_BASE を読み取ります | 動作します — LiteLLM レイヤーが exact=1 の記録と再生を行います。CI で確認済み |
| browser-use | orca record generic-openai -- python your_task.py — ChatOpenAI は未設定の base_url をそのまま渡します | 動作します — exact=1 の記録と再生を行います。CI で確認済み。LLM レイヤーのみが対象です。ブラウザーは操作されません |
| Hermes(Nous Research) | ORCA_BASE_URL_VARS=… orca record generic-openai -- hermes … | 動作するはずです — プロバイダーごとに上書きします。変数を指定してください |
| IndexRAG | orca record indexrag -- --data-dir dataset/<name>/documents — パイプライン全体を 1 回の実行として扱います。チャットには OPENAI_BASE_URL、2 つ目のオリジンには INDEXRAG_EMBEDDING_BASE_URL を使います | 動作します — 実際のパイプラインでエンドツーエンドの動作を確認済みです。インデックス作成、埋め込み、回答のオフライン再生は exact=11/11 retrieval=3/3 で成功し、フォークしても記録済みのインデックスが保持されます。パイプラインで何が異なるのか |
| RAG パイプライン(LlamaIndex、GraphRAG、LightRAG) | orca record generic-openai -- <cmd> — 埋め込みとリランキングは特定の API 形式に依存せず再生されます | 動作します — 同時実行のインデックス構築と埋め込みバッチが exact=5 retrieval=2 の記録と再生を行います。CI で確認済み |
| IDE 内の Codex | orca record exec --tls-intercept -- code . | 動作します — 拡張機能がエージェントを起動し、エージェントはキャプチャ設定を継承します |
| オリジンがハードコードされたボット | orca record exec --tls-intercept -- <cmd> | 動作します — ソース内の URL に送信する Grok ボットです。詳細はこちら |
| サンドボックス内または別のマシン上のエージェント | orca attach | 動作します — orca に接続でき、エクスポートする内容が表示されます。詳細はこちら |
| その他すべて | orca record generic-openai -- <cmd> | ベース URL 変数を読み取る場合は動作します。読み取らない場合は orca record node -- <cmd> を使用してください |
| Claude Code、Hermes、goose を実際のハーネスに対してエンドツーエンドで実行したところ、それぞれが何かを壊しました。Claude Code は4つの問題を起こし、Hermes はプロキシが完全に破棄していたストリーミングのやり取りを見つけました。goose はさらに2つの問題を起こしましたが、どちらもアダプターの問題ではありませんでした。1つはリプレイマッチャー、もう1つはエラーだけのトレースを成功として報告する実行でした。それ以外のクライアントは、アダプターの契約と、それぞれが設定する変数を正確に記録したフィクスチャによって検証されます。そのため、ハーネスが読み取る変数名を変更すると、空のトレースが生成されるのではなく、チェックが失敗します。 |
異なる変数を読み取るハーネス
この表にあるほかのOpenAI互換クライアントはすべて OPENAI_BASE_URL を読み取ります。goose も読み取りますが、まず OPENAI_HOST を読み取ります。Anthropicの場合は ANTHROPIC_HOST だけを読み取ります。
この組み合わせは、両方の変数が気づかれないまま失敗するため、見た目以上に厄介です。
OPENAI_BASE_URLだけを設定すると、ユーザーがすでに別の用途でOPENAI_HOSTをエクスポートしている場合までは問題なく動作します。その場合はユーザーの値が優先され、実行はその接続先に送られ、orca は空のトレースに対して正常な記録を出力します。ANTHROPIC_BASE_URLは、generic-openaiが設定する変数であり、エコシステムのほかの部分が読み取る変数ですが、ここではまったく機能しません。この変数だけを指定したシンクには、リクエストが届きません。
そのため、アダプターは OPENAI_HOST、OPENAI_BASE_URL、ANTHROPIC_HOST の3つすべてを同じプロキシに設定し、フィクスチャも3つすべてを固定します。届くトラフィックは Responses API です。起動時の POST /v1/responses と GET /v1/models であり、プロキシがすでに対応を表明している openai-responses ダイアレクトで処理されます。
GOOSE_PROVIDER=openai GOOSE_MODEL=<model> orca record goose -- run -t "fix the failing test"
GOOSE_PROVIDER と GOOSE_MODEL は引き継いで渡し、新たに設定することはありません。goose にはカスタムエンドポイントのデフォルトがなく、こちらで選ぶと goose が起動するものとは別のエージェントを起動することになるためです。
利用する前に知っておくべき制限が2つあります。goose は orca の PATH シムを経由せずにシェルを実行するため、shell ツールの呼び出しは出力とともにトレースに記録されますが、実際の終了コード、所要時間、stdout と stderr の区別は記録されません。その情報があるかのように主張するくらいなら、--no-shell を指定して、何も記録しないようにしてください。また、goose は会話がすでに進行している最中に、セッションタイトル用として2つ目のモデルに問い合わせます。そのため、その呼び出しと最初の実際のターンは競合します。リプレイマッチャーは、どちらの順序で届いても処理できるようになっています。goose がこの動作をする最初のハーネスになるまでは、そうではありませんでした。
コーディングエージェントを起動するゲートウェイ
OpenClaw 自体はコーディングを行いません。Claude Code、Codex、opencode を子プロセスとして実行し、チャットアプリから操作するため、1回の実行で2種類のモデル通信が発生します。ゲートウェイ自身の呼び出しは fetch フックで捕捉されます。コーディングエージェントの呼び出しは通常の変数で捕捉されます。OpenClaw がそれらを読み取るからではなく、子プロセスは親プロセスの環境を引き継ぐため、OpenClaw が起動した Claude Code は、自分で実行した場合と同じように ANTHROPIC_BASE_URL を認識します。
orca record openclaw
この引き継ぎはオペレーティングシステムの機能であり、orca の機能ではありません。だからこそ、途中のどこかのレイヤーが環境変数をサニタイズするまでは、確実に機能しているように見えるのです。そのため、これを検証するテストがあります。モデル呼び出しを一切行わないゲートウェイのフィクスチャが、モデル呼び出しを行うエージェントを起動し、その孫プロセスのトラフィックを使ってオフラインで記録とリプレイを行います。
何も読み取らないエージェント
ソースに https://api.x.ai/v1 が直接記述されたボットは、変数を読み取らないため、リダイレクトできません。また、かなり一般的なエージェントの形でもあります。エージェントの下ではなく、ソケットで通信を捕捉します。
orca record exec --tls-intercept -- python bot.py
orca record exec --tls-intercept -- ./my-agent --task "fix the test"
exec(または any)はコマンドを起動しますが、オリジンも認証情報も設定しません。そのため、ボットはこれまでどおりの相手と通信し、orca はその途中で会話を読み取ります。api.x.ai はデフォルトの復号リストに含まれているため、Grok ボットではホスト名を指定する必要はありません。
orca が起動していないエージェントにも、orca が起動した何かを祖先に持つ限り、同じコマンドを使えます。これが IDE 内の Codex の構成です。拡張機能がエージェントを子プロセスとして起動するため、エディターを記録すれば、その配下にあるエージェントも記録されます。
orca record exec --tls-intercept -- code .
orca record exec --tls-intercept -- cursor .
再生時にフラグを繰り返し指定する必要はありません。インターセプト経由で記録した実行では、復号したホストが記録されます。orca replay はその情報を読み戻し、同じポリシーを再設定します。無効にしたい場合は --no-tls-intercept を指定してください。
デフォルトのリストに含まれないエンドポイントを復号するには、リストを置き換えるのではなく、追加します。
orca record exec --tls-intercept --tls-hosts '+my-gateway.internal' -- ./my-agent
通常の --tls-hosts a,b は、これまでどおり「指定したホストだけを復号する」という意味です。2 つの形式を併用した場合は、推測で処理せず、エラーになります。
このマシン上にないエージェント
開発コンテナー、VPS、または誰かの CI 上にあるエージェントは orca から起動できないため、環境を構築できません。そこで orca attach を使います。orca がプロキシを起動したままにし、接続先で貼り付けるブロックを表示して、停止するまで届いたものをすべて記録します。
orca attach --for claude
orca attach --for claude --bind 0.0.0.0 --advertise host.docker.internal
orca attach --tls-intercept # for an agent over there that reads no variable either
info attached run=run_e3d64e15ee8f proxy=http://127.0.0.1:33437 for=claude-code
# in the sandbox, before starting your agent:
export ANTHROPIC_BASE_URL='http://127.0.0.1:33437'
Recording. Press ctrl-C when the agent is done.
変数には orca record と同じアダプターを使うため、サンドボックスでの記録がローカルでの記録と食い違うことはありません。ワイルドカードにバインドする場合は --advertise が必須です。0.0.0.0 は待ち受けるアドレスを示すもので、接続に使えるアドレスではありません。orca は機能しない URL を表示しません。
このような実行を再生する場合は、逆の問題が発生します。エージェントがこのマシン上に存在しない可能性があるため、再生時もアタッチします。
orca attach --replay <run>
外部への通信をブロックした状態で記録を提供し、記録自体からハーネスを取得します。同じリモートエージェントを接続すれば、モデルを呼び出すことなく、オフラインでもう一度実行できます。
orca が認識していないベース URL 変数
すべてを列挙するのは無理があります。Hermes はプロバイダーごとに上書き設定を行い、独自の .env.example には NOVITA_BASE_URL、GLM_BASE_URL、KIMI_BASE_URL、MINIMAX_BASE_URL、HF_BASE_URL、NEBIUS_BASE_URL など、さらに十数個の変数があります。orca にリストを組み込んでも、書いた翌週には古くなってしまいます。そこで変数名を指定します。
ORCA_BASE_URL_VARS='OPENROUTER_BASE_URL' orca record generic-openai -- hermes
ORCA_BASE_URL_VARS='GLM_BASE_URL,KIMI_BASE_URL' orca record generic-openai -- my-agent
ORCA_BASE_URL_VARS='SOMETHING_BASE_URL=/' orca record node -- node agent.mjs
各変数は、末尾に /v1 を付けてプロキシを指すように設定されます。これは OpenAI 互換の上書き設定で必要な形式です。=<path> を付けるとその値を上書きし、=/ を指定するとオリジンのみを使います。
この方法でエージェントを記録して正常に動作した場合、アダプターは約 20 行で作成できます。docs/plugins.md を参照してください。うまくいかなかった場合は、トレースを送るのが最も役立ちます。orca export last -o run.html。
ハーネスの転送先を変更できない場合
ベース URL の変数を読み取るすべてのハーネスはベース URL の注入で捕捉でき、これに該当しない Node のハーネスは fetch フックで捕捉できます。ChatGPT のサブスクリプションでサインインした Codex CLI はどちらにも該当しません。ただし、その理由はこのセクションで以前説明していたものとは異なります。
Codex はプロバイダーのベース URL を読み取り、明示的に指定した URL は ChatGPT バックエンドより優先されます。どちらの経路も同じワイヤープロトコルを使います。ところが、そのバックエンドにひも付いているのは認証情報です。サインイン済みのサブスクリプションには、ChatGPT バックエンドが受け入れるプラン用トークンが含まれていますが、api.openai.com は受け入れません。URL を別の場所に向けると、Codex は代わりに API キーを求めます。つまり、サブスクリプションのセッションを記録するのではなく、別のセッションを記録することになります。Codex は Rust で書かれているため、どちらに到達するにしても、こちらの fetch は使えません。
そのための機能が --tls-intercept です。認証局を発行する機能なので、意図的に独立した選択肢として用意しています。
orca record codex --tls-intercept
orca record codex --tls-intercept --tls-hosts 'api.openai.com,*.chatgpt.com'
認証局は実行ごとに固有のものが作成され、orca が起動するエージェントだけが信頼します。信頼の設定には子プロセス自身の環境変数を使い、システムやブラウザーの信頼ストアは使いません。また、実行が終わると削除されます。orca がどこかへのインストールを提案することはありません。許可リストにないホストは読み取りを行わずにトンネル経由で通信し、アドレスとバイト数のみが記録されます。orca が平文を保持しないため、パスも本文も記録されません。すべての通信を傍受するよう求められても、要求は拒否されます。
この機能を通過するデータは、ログ行として記録されるわけではありません。傍受されたリクエストは、ほかのリクエストと同じワイヤー形式で解析されるため、通常のやり取りとしてトレースに記録されます。オフラインで再生したり、別のモデルに分岐させたりできます。API キーを一度も使っていない実行でも同様です。
同じ理由でライブエージェントを起動する orca replay --model、orca fork、orca compare でも利用できます。
エージェント、スクリプト、CI 向け
トレースはファイルです。オブザーバビリティダッシュボードにはできないことです。そのため、失敗した実行について最も役立つ質問は、エージェントが尋ねられるものです。「最後の実行を再生して、何が食い違ったか教えて」。すべてのコマンドはデータとして応答し、orca は自身を MCP 経由で提供します。
$ orca replay last --json
{"runId":"run_a278eea7b535","mode":"exact","traceRunId":"run_687e3f84b208","matchedExact":2,"divergences":0,"unmatched":0,"liveCalls":0,"exitCode":0}
$ orca show last --json | jq '.events[] | select(.kind == "TOOL")'
$ orca checkpoints last --json | jq '.[-1].seq'
標準出力には 1 つの JSON ドキュメントを出力し、診断情報は標準エラー出力に出力します。記録されたエージェント自身の出力も診断情報に含まれるため、実行中もドキュメントの解析可能な状態が保たれます。失敗時も JSON で応答し、終了コードは 0 以外になります。--json は list、show、events、checkpoints、graph、record、replay、compare、doctor に対応しています。
ツールとして。 orca mcp は、標準入出力を通じてトレースストアをエージェントに提供します。
{ "mcpServers": { "orca": { "command": "orca", "args": ["mcp"] } } }
orca_list_runs、orca_show_run、orca_checkpoints、orca_graph、orca_replay、orca_compare を利用できます。再生は無料で、オフラインで行えます。一方、orca_compare は、実際のトークンを消費することを自身の説明に明記しています。モデルがツールを選ぶ際に読み取るのはその文字列だけで、ほかには何も読まないためです。同じ理由で、orca_graph は recorded と inferred の意味を説明するために自身の説明文を使っています。
コードから。 シェルを使いたくない場合は、次のように利用できます。
import { Orca } from 'orcareplay';
const orca = new Orca({ cwd: process.cwd() });
const { unmatched, divergences } = await orca.replay('last');
const timeline = await orca.show('last');
この機能が標準出力に書き込んだり、process.exit を呼び出したりすることはありません。どちらもテストで確認しています。どちらかを行うライブラリを基盤にすることはできないからです。
ステータス
開発初期の段階です。v0 は上記 3 つのコマンドの基本的な骨格です。以下のすべての機能は、Node 20 および 22 で、1,393 件のテスト、トレース形式の適合性チェック、プラグイン API の中立性チェックを通じて検証されています。
| 機能 | 状態 |
|---|---|
| トレース形式 v0 + JSON Schema | 動作します |
| Anthropic/OpenAI 互換モデルのキャプチャ | 動作します |
| OpenAI Responses API のキャプチャ | 動作します — OpenAI Agents SDK と Codex CLI がデフォルトで使用する形式です。記録、オフラインでの再生とフォークが可能です。フォーク後も、エージェントが使用するワイヤ形式が維持されます |
| ベース URL 変数を読み取らないエージェント | 動作します — orca record node -- <cmd> は実行ディレクトリにプリロードを配置し、許可リストにあるプロバイダーホストへの globalThis.fetch をリダイレクトします。Node と Bun の両方に対応しています。Bun は NODE_OPTIONS の --require を無視するためです。オリジンがソースにコンパイルされている場合に使用してください。OPENAI_BASE_URL を尊重する通常の @ai-sdk/openai クライアントには、代わりに generic-openai を使用します |
| orca が読み取れない呼び出し | 動作します — 拒否せずに転送し、net.request/net.response として記録します。これは証拠であり、再生可能なターンではありません。何もキャプチャできなかった記録では、正常終了する代わりに警告が表示されます |
機械可読な出力(--json) | 動作します — stdout には単一の JSON ドキュメント、stderr には診断情報を出力し、失敗も JSON で出力します |
因果グラフ(orca graph) | 動作します — 何が何を引き起こしたかを、テーブルまたは JSON で表示します。すべてのエッジに、トレースに記録されたものか orca が今導出したものかが示され、どちらの場合もそのルールが記載されます。--to N を指定すると、あるイベントを生み出したチェーンに絞り込めます |
| 共有可能なカード | 動作します — orca export --card は因果チェーンを 1 つ描画し、--graph-card はそのチェーンを強調表示した実行全体を描画し、compare --share は判定テーブルを描画します。.svg は常に利用できます。.png と .gif はオプションのレンダーツールチェーンがインストールされている場合に利用できます。利用可能かどうかは orca doctor で報告され、このツールチェーンが npm ci によってインストールされることはありません |
エージェントなしでの初回実行(orca quickstart) | 動作します — パッケージには実際の記録と、その記録の作成元となったプロジェクトが含まれており、オフラインで一方をもう一方に対して再生します。そのため、最初に試すときに API キー、ネットワーク、トークンは不要です |
MCP サーバー(orca mcp) | 動作します — stdio 経由で 6 つのツールを提供するため、エージェントは自身の実行を読み取り、説明し、再生できます |
プログラム用 API(Orca) | 動作します — コマンドは API が返す内容を表示するため、ターミナルは唯一の信頼できる情報源を表示します |
| 入力したセッションの再生 | 動作しますが、概算です — その意味 |
| 差分報告付きの正確な再生 | 動作します — 記録されたファイルシステムを作業ツリーに復元してから、元に戻します。作業用コピーには --worktree、復元しない場合は --in-place を指定します。再生によって発見された差分や未一致リクエストを記録する独自の実行を作成し、単に繰り返した内容については親を参照します。スキップするには --no-trace を指定します |
| チェックポイントからのフォーク再生 | 動作します — フォークは独自のファイルシステムスナップショットを記録するため、再度フォークできる実行になります |
| モデル間の比較 | 動作します — orca setup はゲートウェイ(デフォルトは OrcaRouter。それ以外は指定した任意の URL)、キー、モデルリストを保存するため、orca compare にフラグは不要です |
| ファイルシステムのスナップショットと差分 | 動作します |
| 単一ファイルの HTML エクスポート | 動作します |
| MCP 呼び出しの記録 | 動作します — --mcp-config <path> で有効にします。再生とフォークでは、記録に使用された設定から再度インストルメントするため、レイヤーはフォーク地点で終わりません |
事後のスクラブ(orca scrub) | 動作します |
シェルのキャプチャ(PATH shim) | 動作します — 終了コード、実行時間、stdout/stderr の分離に対応しています。スキップするには --no-shell を指定します |
| モデル以外のネットワークキャプチャ | 動作します — --tls-intercept で有効にします。起動したエージェントだけが信頼する実行ごとの CA を発行し、許可リストにあるホストを復号し、それ以外は内容を読み取らずにトンネル経由で転送します。実行終了時にキーを削除します |
| Codex サブスクリプションモデルのキャプチャ/再生 | 動作します — /backend-api/codex/responses HTTPS フォールバックを認識し、一致判定のために zstd リクエストボディをデコードします。再生時はオリジンへの接続を開かず、記録された SSE 応答を返します |
| 実際のエージェントでの検証 | Claude Code が、実際のバグに対する実際の修正を記録しました。最初から最後までオフラインで再生し、チェックポイントからフォークしてエクスポートしました。テスト用データでは再現できなかった 4 つの問題が発生しましたが、すべて修正済みです — 実際のエージェントが発見した問題 |
| サブスクリプション認証のテスト環境 | Claude Code で動作します。ChatGPT サブスクリプションでサインインした Codex CLI は、自身のバックエンドだけが受け付けるプラン認証情報を使用します。そのため、URL をリダイレクトすると別のセッションが記録されてしまい、同じセッションは記録できません。--tls-intercept が必要です。API キーを使用する場合、特別な設定は不要です |
入力したセッションを再生する
orca record claude で開始して手動で操作した実行では、プロンプトは通信上のどこにも記録されません。Orca はハーネス自体のトランスクリプトからプロンプトを復元し、ターミナルを介さずに返すことでセッションを再生します。これにより会話は再現されますが、実行がバイト単位で完全に再現されるわけではありません。欠陥ではなく本質的な違いが 2 つあり、orca はそれを覆い隠さず、両方とも明示します。
- ハーネス自身が呼び出しを行います。 最初のターン前のクォータ確認、セッション名の指定要求、サブエージェント用に新しく書かれた委任プロンプトなどです。再生ではこれらを繰り返しません。マッチャーはそれらをスキップして次の実際の一致へ進み、スキップした数を報告します。そのため、対話形式で記録した実行で
reused=3/5と表示されても、依頼した内容はすべて再生されており、部分的な再生ではありません。 - ターミナルセッションには、再生では利用できないツールが提示されます。
AskUserQuestion、EnterPlanMode、ExitPlanMode、EndConversationはすべて、目の前に人がいることを前提とするため、同じエージェントを人なしで動かす場合には使えません。これらのスキーマは大きいため、該当ツールを含むリクエストは記録内容と大きく異なることがあり、その差が大きい場合は停止します。停止時には、不足しているツールとその理由が示されます。
argv にプロンプトを指定して記録する場合(orca record claude -- -p "…")は、記録とまったく同じ方法で再生が開始されるため、どちらの問題もありません。正確に再生する予定の実行には、この方法を使用してください。実行内容の確認には、どちらの場合でも影響はありません。orca show とビューアーでは、どちらも完全に確認できます。
インストール
npm i -g orcareplay
orca doctor # checks node, git, and which agents it can find
Node 20 以降が必要です。ネイティブ依存関係はないため、コンパイルは不要で、インストール時に取得されるのは tarball のみです。
0.1.1 以降のすべてのリリースは、RELEASING.md に記載されたタグ付きワークフローで公開されており、ビルドに使用したコミットと実行を明記したプロベナンス証明が付属します。npm のパッケージページで確認でき、npm audit signatures で検証できます。
ソースからインストールして開発する場合、または未リリースのコミットを実行する場合:
git clone https://github.com/Continuum-AI-Corp/OrcaReplay && cd OrcaReplay
npm ci && npm run build
npm install -g ./packages/cli # puts `orca` (and `orcareplay`) on PATH
リポジトリのルートで npm install -g . を実行しても、何もインストールされません。ルートは独自のバイナリを持たないワークスペースであり、orca は packages/cli にあります。
実行には Node 20 以降が必要です(CLI 自体の engines は >=20.0.0 です)。コントリビュートには ^20.19.0 || >=22.12.0 が必要です。これはテストツールチェーンが必要とするためです。ルートの package.json で別途宣言されているため、npm ci を実行する前に要件がわかります。アカウント、登録、API キーの変更は不要です。
Windows では、シェルのキャプチャにより sh.exe と bash.exe の前に .cmd シムが配置されます(Git for Windows が両方を提供します)。また、Windows では .cmd はシェル経由でしか実行できません。そのため、cmd.exe または PowerShell 経由で起動したシェルはキャプチャできますが、エージェントが自ら起動するシェルはキャプチャできません。Node ハーネスの child_process.spawn('bash') は本物の bash.exe を直接起動し、Claude Code は PATH を参照せずにシェルを見つけます。orca doctor は、マシンでどちらに該当するかを示します。シムが確認できなかったコマンドをツール呼び出しが実行した実行では、orca record が shell.ineffective と警告します。そのような実行は --no-shell を指定して記録してください。PATH に POSIX シェルがない場合、doctor が警告します。その場合は --no-shell を指定して記録します。
実行の保存場所
すべてのデータは、記録したプロジェクト内の .orca/runs/ に保存されます。プロジェクトごとに保存され、グローバルなストアはありません。そのため、実行データは対象のチェックアウトと一緒に移動します。1 つの実行ディレクトリが、それだけで内容を説明できる単位です。
.orca/
.gitignore # just `*` — the store excludes itself, so a trace cannot be committed by accident
runs/run_d0a2ee7ce615/
manifest.json # who, when, which adapter, the git commit, counts, integrity digest
events.jsonl # the timeline, one JSON object per line, append-only
blobs/ # content-addressed payloads over 4 KB, deduplicated
fs/ # shadow git index: the workspace at every turn
shims/ # the PATH shims this run used; written by orca, read by nothing
py/ # bootstrap for the agent-structure layer, when the agent is Python
redactions.json # what was removed, by rule and count — never by value
以前のセッションを探すには:
orca list # every run here, newest first, with what it was forked from
orca list --remote # and what the gateway is holding, without opening a browser
orca show run_d0a2ee7ce615 # the timeline in the terminal
orca replay last # `last` = newest recording (it skips replay traces)
orca replay run_d0a2ee7ce615 # or name one outright
orca gc --older-than 7d --dry-run # what would be reclaimed, before anything is
orca list は実行ディレクトリを直接読み込むため、誰かから送られたトレースにも使えます。.orca/runs/ に入れれば、どのコマンドからも参照できます。インデックスは作成されず、破損するデータベースもありません。唯一の例外は --remote ですが、これもインデックスではありません。ゲートウェイに問い合わせて結果を表示するだけで、何も保持しません。
プライバシー
トレースはローカルに保存され、モードは 0600 です。また、レコーダー自体はネットワーク接続を行いません。書き込み時にシークレットを秘匿します。環境変数の取得はデフォルトで拒否され、認証ヘッダーは決して書き込まれず、既知のキー形式とエントロピーの高い文字列は安定したプレースホルダーに置き換えられます。
秘匿化はベストエフォートの軽減策であり、保証ではありません。トレースは機密情報として扱ってください。おおよそ、シェルの履歴やヒープダンプと同程度に機密性の高いものです。
orca export last -o bug.html # prints exactly what it is about to write
orca scrub last --match my-hostname # remove something after the fact
orca scrub は events.jsonl、マニフェスト、すべてのテキストブロブを書き換え、標準の検出器を再実行して整合性ダイジェストを更新します。バイナリブロブはバイト単位で変更されません。
ファイルシステムのスナップショットは書き換えられません。Git オブジェクトは内容のハッシュで識別されるため、編集すると ID が変わり、そのオブジェクトを参照するすべてのツリーと、それらのツリーを参照するすべてのイベントを書き換える必要があります。これは履歴の書き換えであり、失敗すると実行を復元できなくなります。そのため scrub はスナップショットストアを 検索 し、文字列がまだ残っていればそのことを知らせます。消去できなかったトレースを、きれいになったと報告することはありません。--drop-fs はストアを丸ごと削除しますが、実行をフォークできなくなります。
オープンなものと、そうでないもの
トレース形式、コア、CLI、ビューアー、アダプター、プロバイダーインターフェースは、すべて Apache-2.0 のもとで常にオープンです。
OrcaReplay は OrcaRouter を開発する人々が開発しており、そのことは、どちらもユーザーが求めた以下の 2 つの場面に現れます。ゲートウェイを指定しない場合、orca setup は OrcaRouter を候補として提示します。これは確認でき、上書きもできるデフォルトであり、ユーザーが答えると選んだ質問に対するもので、ルートが自動的に選択されることはありません。また、明示的に生成した成果物、たとえばエクスポートや --share カードには、グラフに出典が記されるのと同じように、「built by the OrcaRouter.ai team」と表示されます。
どのモデルへの接続も、どこにでも向けられる単なる URL です。その接続先を他と異なる扱いにするコードパスはなく、クレジット表記によってどこかへルーティングされることもありません。
ベンダーが得る 特権 はありません。OrcaRouter のものを含むプラグインが使用できるのは、@orcareplay/plugin-api の公開 Provider インターフェースだけであり、その背後に非公開 API はありません。ベンダープラグインはまだ存在しないため、これを適用する CI ジョブ(scripts/check-neutrality.mjs)はそのことを示し、何もせずに成功します。プラグインが追加された時点で、ワークスペースのソースではなく公開済みパッケージを使ってビルドするようになります。プラグインに機能が必要になった場合は、まずその機能を公開インターフェースに追加し、2 つ目の実装によって、特定のベンダー向けに設計されたものではないことを示します。
ドキュメント
今すぐ問題を解決したい場合は、ここから始めてください:
リファレンス:
spec/orca-trace-v0.md— 規範となるトレース形式docs/integrations.md— フレームワークの記録方法。各コマンドは 1 つで、すべての数値を CI で検証しますdocs/architecture.md— キャプチャ、リプレイ、フォークの実際の仕組みdocs/validation.md— 実際のエージェントで初めて検証した際に起きた問題docs/launch-path.md— 開発済みのもの、未開発のもの、今後の予定docs/plugins.md— アダプターまたはプロバイダーの作成方法CONTRIBUTING.md— 5 分で回せる開発ループ- 初心者向けの最初の課題 — 12 件の課題と、最初に取り組むファイル
ご協力ください
フォーマットは v0 で、ウォーキングスケルトンが動作しています。プロジェクトにとって興味深い段階です。 判断を変更するコストはまだ低く、すぐに着手できる明白な作業がすでに書き出されています。
- 最初に取り組むのに適した 12 件の課題。それぞれ対象ファイルとテストが記載されています。
- アダプターを書く。 ファイル 1 つ、フィクスチャ 1 つです。ハーネスがベース URL の変数を読み取るなら、20 行ほどで済みます — docs/plugins.md。そうでない場合は、すでに
nodeで対応できるかもしれません。上記に記載されていないハーネスで記録結果が空になる場合は、どちらにしても課題として報告する価値があります。 - 統合チェックにフレームワークを追加する。
test/integrations/では、実際のフレームワークをスタブのオリジンに接続し、オリジンを停止してから再生します。8 つに対応済みですが、AutoGen、LlamaIndex、Pydantic AI、smolagents にはまだ対応していません。追加にはスクリプト 1 つと行 1 つが必要です。 - リーダーを再実装する。 仕様が CC BY 4.0 なのは意図的です。Python のリーダーはすでにあり、Go と Rust での実装を歓迎します。
- 再生を壊してみる。 マッチングの段階的な仕組みがこのプロジェクトの要です。改善する最も手っ取り早い方法は、誤った結果になる実際の記録を提供することです。
orca export last -o bug.htmlの出力を添えて課題を報告してください — これは単体で完結するファイルです。必要なものを取り出すには、先にorca scrubを使ってください。
午後の作業時間を節約できたら、⭐ を付けていただけると、ほかの人にも見つけてもらいやすくなります。
ライセンス
コードは Apache-2.0 です。トレース仕様は CC BY 4.0 なので、誰でも再実装できます。
OrcaRouter チームが開発 ·
orcarouter.ai ·
すべてのモデル ·
OrcaCode Review ·
X ·
Hugging Face
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。