Jev /v1/systemone
POST /v1/systemone は cc-router の Jev(System One)意思決定モデル入口 です。Jev は構造化された意思決定モデルです。リクエストで状態 state と質問の集合 questions を渡すと、レスポンスの answers に質問ごとの構造化された回答が返り、会話テキストは生成しません。
cc-router は複数の上流の Key を独立した仮想モデル model-jev にまとめます。プロトコルは翻訳せずそのまま透過しますが、対話入口と同じく複数サブスクリプションのディスパッチ、失敗時の切替、クールダウン、利用上限、リクエストログを利用できます。
対応バージョン:cc-router v6.3.0 以上。4 つの入口の比較は エンドポイント概要 を参照してください。
Jev は Claude Code や Codex のような対話ツールでは使えません。対象は自作のコード、エージェントフレームワーク、または HTTP リクエストを送れる任意のプログラムです。
クイック接続
| 設定項目 | 入力内容 |
|---|---|
| エンドポイント URL | http://127.0.0.1:23456/v1/systemone(フルパスで指定) |
| 認証 | Authorization: Bearer <token>。x-api-key: <token> でも構いません |
| モデル名 | model-jev(anthropic/ / openai/ プレフィックス可)、または上流の実際のモデル名 |
コマンドラインで確認:
curl http://127.0.0.1:23456/v1/systemone \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <cc-router token>" \
-d '{
"model": "model-jev",
"state": "Hello World",
"questions": {
"says_hello": {
"type": "noul",
"instructions": "Does the state text contain a greeting?"
}
}
}'
cc-router の「仮想モデル」ページには model-jev のカードがあり、アドレスとトークンを入力済みの curl 例をそのままコピーできます。「セットアップガイド → 汎用接続方法」にも Jev の接続カードがあります。
Python(httpx):
import httpx
resp = httpx.post(
"http://127.0.0.1:23456/v1/systemone",
headers={"Authorization": "Bearer <cc-router token>"},
json={
"model": "model-jev",
"state": "ユーザー:先週買ったイヤホンが壊れたので返金してほしい。",
"questions": {
"refund": {"type": "noul", "instructions": "Is the user asking for a refund?"},
},
},
timeout=60,
)
print(resp.json()["answers"])
プロトコル位置付け
クライアント (System One) cc-router 上流
───────────────────────── ────────────────────────────────────────────────── ──────────────────────────
POST /v1/systemone ───────►│ 検証:JSON オブジェクト + model が文字列 │
│ ↓ │
│ model-jev のサブスクリプション間でディスパッチ │──► 選択 / model 書き換え
│ ↓ │◄── 上流レスポンス
│ そのまま返却(model フィールドのみ復元) │
◄────── HTTP レスポンス ───│ │
3 つの対話入口とは異なり、/v1/systemone は Anthropic Messages のディスパッチ pipeline を通らず、プロトコル翻訳も一切行いません。
- リクエストボディは
modelフィールドが書き換えられる場合を除き、バイト単位でそのまま上流へ転送されます。 - レスポンスボディは
modelフィールドが復元される場合を除き、そのままクライアントへ返されます。 - ルーティングはパスで決まります。この入口に入ったリクエストは、ボディにどのモデル名が書かれていても常に
model-jevを使います。
リクエスト
フィールド
cc-router は最小限の検証だけを行い、それ以外のフィールドの検証は上流に任せます(上流ごとに検証ルールがもともと異なるため)。
| フィールド | cc-router による検証 | 説明 |
|---|---|---|
| リクエストボディ全体 | あり | JSON オブジェクトである必要があり、そうでなければ 400 を返す |
model | あり | 文字列である必要があり、そうでなければ 400 缺少 model 字段(model フィールドがありません)を返す |
state | なし | 判定対象の状態。そのまま転送 |
questions | なし | 質問の集合。キーは質問 ID、値は type や instructions などを含む。そのまま転送 |
| その他のフィールド | なし | そのまま転送 |
非ストリーミングのみ対応です。
stream: trueの扱いは上流ごとにばらばら(400 を返すもの、無視するもの)なので、頼らないでください。
model の書き換えルール
System One サブスクリプションにはそれぞれ任意設定の Jev モデルスロットが 1 つあります。cc-router は選ばれたサブスクリプションに応じて、上流へ実際に送る model を決めます。
クライアントが指定した model | サブスクリプションに Jev モデルを設定済み | サブスクリプションに Jev モデルが未設定 |
|---|---|---|
model-jev(または anthropic/model-jev / openai/model-jev) | 設定したモデルに書き換え | そのエンドポイントの例示モデル(clef-flash、jev-latest など)に書き換え |
上流の実際のモデル名(jev-preview など) | 設定したモデルに書き換え | そのまま透過 |
model を書き換えた場合、レスポンスの model はクライアントが指定した名前に復元されます(たとえば model-jev のまま返る)。書き換えていない場合は、上流が返した具体的なバージョン名がそのまま透過されます(たとえば jev-latest は上流で jev-1.13.0 に解決されます)。
上流アドレスに
{model}プレースホルダを含むエンドポイント(Cloudflare の/run/@cf/.../{model}など)では、モデル名に使えるのは英数字と._:-だけで、先頭は英数字である必要があります。そうでなければ 400 を返します。モデル名が URL パスに埋め込まれたときに、上流の別のエンドポイントへアクセスされるのを防ぐためです。
レスポンス
成功時は上流の標準的な System One レスポンスボディを返します。形式は次のとおりです。
{
"model": "model-jev",
"answers": {
"says_hello": { "type": "noul", "noul": 0.98 }
},
"usage": { "input_tokens": 160, "output_tokens": 0 }
}
- 回答の具体的な構造は質問の
typeによって決まります。詳細は上流のドキュメントに従ってください。 - Cloudflare Clef の元のレスポンスは
{result, success, errors, messages}のエンベロープに包まれていますが、cc-router はエンベロープを外して上記の標準形式にそろえます。success: falseの場合は、2xx であっても失敗として扱います。 usageは「統計」と「利用レシート」に計上されます(使用量がある場合にのみ、レシートに model-jev が表示されます)。
エラー
cc-router 自身が生成するエラーは、TypeSafe 公式のエラーボディ形式を採用しています。
{ "detail": { "error_type": "invalid_request_error", "message": "缺少 model 字段" } }
| ステータスコード | error_type | 発生条件 |
|---|---|---|
400 | invalid_request_error | リクエストボディが JSON オブジェクトでない、model がない、モデル名に不正な文字が含まれる |
401 | — | cc-router のトークン認証に失敗(ほかの入口と同じく Anthropic 形式のエラーボディ) |
4xx | 上流のまま | 候補のサブスクリプションがすべて失敗し、最後の失敗が「リクエスト自体の誤り」だった場合。最後の上流のエラーをそのまま返す |
502 | api_error | Cloudflare が 2xx を返したが、エンベロープ内が success: false または result がない |
503 | overloaded_error | model-jev にサブスクリプションが 1 つもバインドされていない。または、すべての候補がネットワーク、5xx、認証、レート制限、利用上限のために利用できない(message に各サブスクリプションの状態の要約が付く) |
ディスパッチ
- System One サブスクリプションだけをディスパッチ:
model-jevにバインドできるのは、エンドポイントが System One のサブスクリプションだけです。対話系サブスクリプションは使われず、System One サブスクリプションがほかの仮想モデルに入ることもありません。 - ディスパッチモードは通常どおり有効:順次 / ラウンドロビン / セッション固定の 3 モードがすべて使え、クールダウンやトークン上限も対話入口と同じです。
- 4xx でも次の上流に切り替え:実測では、同じリクエストに対する受け入れ範囲が上流ごとに異なります(未知のモデルに 400 を返すものもあれば 404 を返すものもある)。そのため、ある上流が 4xx を返すと cc-router は次の上流を試し、そのサブスクリプションをクールダウンしません。
401/403/429はサブスクリプション自体の状態の問題とみなします。401/403ではサブスクリプションを認証失敗としてマークし、429ではレート制限のクールダウンに入ります。 - セッション固定は
x-session-idリクエストヘッダのみで識別:ヘッダがなければラウンドロビンで割り当てます。cc-router はリクエストボディからセッションを推定しません(同じstateでもそれぞれ独立した判定です)。
対話入口との分離
対話入口(/v1/messages など) | /v1/systemone | |
|---|---|---|
| 使える仮想モデル | model-fable / opus / sonnet / haiku / fallback | model-jev のみ |
| 相手側のモデル名を受け取った場合 | 対話入口が model-jev を受け取ると即座に 400 を返す | 何を指定しても常に model-jev を使う |
| バインドできるサブスクリプション | 対話系サブスクリプション | System One サブスクリプション |
| プロトコル翻訳 | あり(/v1/messages を除く) | なし |
GET /v1/models | 一覧に含まれる | model-jev は一覧に含まれない |
内蔵の上流
cc-router の「サブスクリプションを追加」で、次のいずれかのプロバイダの System One エンドポイントを選ぶだけです。プロバイダのドロップダウンで Jev タグが付いているのが、意思決定モデルに対応したプロバイダです。
| プロバイダ | 説明 |
|---|---|
| TypeSafe | Jev モデルの提供元。モデル名は手入力:jev-latest(安定版)または jev-preview(プレビュー版)。認証は Authorization: Bearer のみ対応 |
| Cloudflare Clef | Cloudflare の意思決定モデルで、例示モデルは clef-flash。直接接続と AI Gateway 経由のどちらも可能:サブスクリプション追加時にアカウント ID を入力し、AI Gateway 経由の場合はゲートウェイ ID も入力します。API Token には Workers AI の権限が必要です(AI Gateway 経由の場合は AI Gateway の権限も必要) |
| OpenRouter | System One エンドポイントを選択 |
| Ollama | ローカルの System One エンドポイント。Ollama 0.35 以上が必要 |
サブスクリプションのプロトコルは作成後に固定され、対話用エンドポイントと System One エンドポイントの間で切り替えることはできません。変更したい場合は新しいサブスクリプションを作成してください。
リクエストログとプライバシー
試行ごと(次の上流への切替によるリトライを含む)にリクエストログが 1 行記録され、「受信エンドポイント」には /v1/systemone と表示されます。ログには state、questions、answers、信頼度、料金は記録されません。上流の 422 エラーボディにエコーされたリクエスト全体も、保存前に取り除かれます。