---
title: "Studio とは"
description: "arkor dev で得られるローカル Web UI: 学習を開始し、ストリームを眺め、最終アダプターとチャットし、*.arkor.app URL で公開する。"
---

Studio は [`arkor dev`](/ja/docs/framework/cli/dev) を実行したときに起動するローカル Web UI です。ローカルで動き、同じ CLI プロセスとループバック越しに通信し、dev サーバーを止めれば消えます。サインアップも公開 URL もありません。

`http://localhost:4000`（`arkor dev --port` で変更可）で開いてください。

## レイアウト

ヘッダーには現在の ID が `<mode> · <org>[ / <project>][ · <baseUrl-host>]` の形で表示されます。`mode` は `anonymous` か `oauth`。クラウド API ホスト suffix は CLI が本番エンドポイントを指しているときは隠され、それ以外で表示されます。

4 ページ、アプリ内ナビ（Overview / Jobs / Playground / Endpoints）で切り替えます:

| ルート | ページ | やること |
| --- | --- | --- |
| `#/` | Overview（このページ） | プロジェクトのランディング。ここから学習をトリガーする。 |
| `#/jobs` | [Jobs](/ja/docs/framework/studio/jobs) | 自動更新されるジョブ一覧。 |
| `#/playground` | [Playground](/ja/docs/framework/studio/playground) | 最終アダプターやベースモデルとチャット。 |
| `#/endpoints` | [Endpoints](/ja/docs/framework/studio/endpoints) | アダプター／ベースモデルを `*.arkor.app` URL として公開し API キーを管理。 |

Jobs ページは `#/jobs/:id` でジョブ単位の詳細（ライブステータス、Loss チャート、イベントログ）も開けます。ナビタブではなく Jobs のサブルートとして提供しています。

## アーキテクチャ

```
Studio（ブラウザータブ、http://localhost:4000）
   │  ループバック上の /api/*、CSRF トークン必須
   ▼
arkor CLI（ローカル）
   │  認証付き HTTPS
   ▼
Arkor マネージドバックエンド
```

`/api/*` リクエストごとに 3 つのチェックが走ります:

1. **Host ヘッダーのガード。** `127.0.0.1` と `localhost` のみ受理。`127.0.0.1` に DNS リバインディングされる悪意あるサイトに誘導された被害者でも、送信されるのは `Host: evil.com` で、ミドルウェアは HTTP 403 で拒否します。
2. **起動ごとの CSRF トークン。** `arkor dev` は起動ごとに 32 バイトのトークン（base64url）を生成し、`<meta name="arkor-studio-token">` として `index.html` にインジェクトし、すべての `/api/*` 呼び出しに必須化します（ヘッダー `X-Arkor-Studio-Token`、または `EventSource` リクエスト用に `?studioToken=`）。クロスオリジンタブは meta を読めないので、preflight をスキップする「simple」なクロスオリジン POST も拒否されます。比較には `timingSafeEqual` を使用しているため、タイミング攻撃に対して安全です。
3. **CORS なし。** SPA は同一オリジンなので CORS には意味がありません。`*` を反射すると「simple」なクロスオリジン POST（`text/plain`、`urlencoded`）を素通りさせてしまうので、トークンチェックがそれを拒否します。

トークンは `arkor dev` 起動のたびにローテートされるので、前回起動時の古いタブはリロードするまで HTTP 403 で失敗します。

## 現在できること

| 機能 | 補足 |
| --- | --- |
| **Run training** | Overview ページ (`#/`) のボタン。`POST /api/train` を呼ぶと `arkor start` がサブプロセスとして起動し、stdout/stderr が生のテキストとしてページにストリーミングされます。 |
| **Jobs リスト** | `#/jobs`。5 秒間隔の自動ポーリングに加えて手動 Refresh ボタン、名前 / ID での検索、status フィルター（`All` / `Running` / `Completed` / `Queued` / `Failed` / `Cancelled`）を備えます。列: Status、Name（詳細へリンク）、Created、ID。 |
| **Job 詳細** | `#/jobs/:id`。ライブステータスバッジ、SVG の Loss チャート、生イベントログ（直近 50 行）。Server-Sent Events 経由で `/api/jobs/:id/events` からストリーム。 |
| **Playground** | `#/playground` のチャット UI。2 モード: 1 つの対応ベースモデル、または任意の完了済みジョブの最終アダプター。 |
| **Endpoints** | `#/endpoints` の `*.arkor.app` URL 管理。Deployment の作成、enabled / auth mode の切替、API キーの発行と revoke。SDK の [`CloudApiClient`](/ja/docs/framework/sdk/deployments) と等価で、UI で行えるすべての操作にプログラマティックな呼び出しが対応。 |

## まだないもの

これらは SDK や HTTP API レベルでは存在しますが、Studio UI としては今のところありません:

| 不足 UI | 回避策 |
| --- | --- |
| 動作中ジョブのキャンセル / 一時停止 | 自前コードから [`trainer.cancel()`](/ja/docs/framework/sdk/trainer-control#cancel) を呼ぶ。 |
| Playground での中間チェックポイントアダプター選択 | トレーナー内で [`onCheckpoint({ infer })`](/ja/docs/framework/sdk/callbacks) を使う。SDK の `infer` は直前に保存されたチェックポイントに紐づく。 |
| Jobs リストのページング | 現状のポーリング一覧ビューでは対象外。サーバーが完全な一覧を返す前提。 |
| プロジェクトごとの複数トレーナー | `/api/manifest` が単一の `trainer` を返す。SDK の [`createArkor`](/ja/docs/framework/sdk/create-arkor) も 1 つしか受け付けない。 |
| Playground から `temperature` / `topP` / `maxTokens` を調整 | HTTP API（[`InferArgs`](/ja/docs/framework/sdk/infer)）はこれらを受け付ける。SDK から `infer` を呼ぶ際に渡してください。 |
| Loss チャートのズーム、エクスポート、ツールチップ | チャートは静的な SVG パス。 |
| Deployment 作成後のターゲット編集 | cloud API は `PATCH /v1/endpoints/:id` で `target` を受け付けますが、[Endpoints](/ja/docs/framework/studio/endpoints) UI では auth mode と enabled トグルしか公開していません。SDK の [`updateDeployment`](/ja/docs/framework/sdk/deployments) を使ってください。 |

## Studio を使うべきでない場面

Studio は開発ツールです。ループバックでのみ、`arkor dev` が立ち上がっている間だけリッスンし、起動ごとに CSRF トークンをローテートします。プロダクション利用では Studio にユーザーを向けるのではなく、学習済みモデルを[デプロイメント](/ja/docs/framework/sdk/deployments)として公開し、その OpenAI 互換エンドポイントをアプリケーションから呼んでください。[`infer`](/ja/docs/framework/sdk/infer) は学習中の `onCheckpoint` コールバック内でだけ使える関数です。
