本番の設置

モデル接続とプロファイルの設定

セッションが使う接続とプロファイルを設定します

作業内容

ワークスペースのモデル接続とプロファイルを構成し、セッションの一つの turn で実際の呼び出しを確認します。モデル資格情報は利用者の API key とは異なります。

準備

owner ログイン、使うモデルの key またはプライベートなモデル endpoint、セッションからアクセスするリポジトリが必要です。費用上限と設定契約を確認します。

手順

1. コンソールの接続とプロファイル

セッションからモデルを呼ぶには、モデル key とその key を使うプロファイルが必要です。どちらも Web コンソールで作成します。owner でログインし、次の順で操作します。

  1. 設定 > エージェント接続 > モデル接続で接続を追加を押します。種類は anthropic、アドレスは既定値(https://api.anthropic.com)にし、Anthropic key を貼り付けて保存します。key は DB に封印して保存され、画面には末尾の四文字だけが表示されます。
  2. プロファイル > プロファイルを作成で先ほどの接続を選び、モデル・ツール・実行方式を設定して保存します。エージェントの作成時にこのプロファイルを選びます。

エージェントが使うリポジトリはプロファイル作成時には選ばず、そのエージェントの GitHub タブでワークスペースが許可した範囲内から選びます。

key を入れる前にこのプロファイルでセッションを開始すると、「モデル接続に使える key がない」という趣旨のエラーが出て、エラーに 1 の画面への経路が示されます。key の変更にも同じ画面の値を変えるを使います。

2. 環境変数を使う方法

key を DB ではなくサーバーの env ファイルに置く場合、/etc/werft/test-ops.env の ANTHROPIC_API_KEY を設定し、単一サーバーの手順 2 の設定文書に、環境変数名を使って接続とプロファイルを記入します。文書には値ではなく名前だけを書くため、秘密情報を含みません。connections と profiles を次のように設定し、リポジトリ項目に "profiles": ["claude-coding"] を追加してから、単一サーバーの手順 3で settings digest と release 入力を再生成します。設置済みの場合は Compose アップグレードで適用します。

{
  "connections": {
    "anthropic": {
      "kind": "anthropic",
      "endpoint": "https://api.anthropic.com",
      "auth": { "kind": "api_key", "value_env": "ANTHROPIC_API_KEY" }
    }
  },
  "profiles": {
    "claude-coding": {
      "runtime_kind": "claude_agent_sdk",
      "runtime_version": "0.3.319",
      "model": "claude-sonnet-5",
      "tools": ["Read", "Edit", "Write", "Glob", "Grep", "Bash"],
      "permission_mode": "default",
      "provider": {
        "kind": "anthropic",
        "endpoint": "https://api.anthropic.com",
        "auth": { "kind": "api_key", "value_env": "ANTHROPIC_API_KEY" }
      },
      "project_settings": { "claude_md": true }
    }
  }
}

この接続は後から画面での管理に移せます。モデル接続の該当行で画面でキーを入れるを押して key を再度貼り付けると、同じ接続とその上のプロファイルが、保存した key をそのまま使います。サーバーが env の値を読み取って移すわけではなく、人が再入力します。移行後も設定文書に同じ接続が残っていてかまいません。import は DB の行をそのまま維持します。

Kubernetes で Secret のモデル key を使わない場合は、secrets.catalogEnv からその名前を外します。固定 bootstrap トークンなど必要な名前は残します。一覧全体を置き換えるため、Secret の key と一致させる必要があります。

3. 設定文書の import・export

API_CONTAINER='<api-container-id-from-this-installation>'
docker exec "$API_CONTAINER" bun run apps/control-host/src/api/settings.ts export > settings.json
docker exec -i "$API_CONTAINER" bun run apps/control-host/src/api/settings.ts import --document - --dry-run < settings.json

API_CONTAINER はこの環境の status と project label で確認します。Kubernetes で次の package script を使うには、設置バージョンのリポジトリ checkout とホストの Bun・kubectl が必要です。bun run settings:k8s export と bun run settings:k8s import --document - --dry-run に置き換えます。dry-run の追加項目とエラーを確認してから、同じコマンドの --dry-run を外して import します。既存の DB 行をファイル内容で無条件に上書きするツールではありません。資格情報は文書に値ではなく環境変数名を書きます。

4. 課金のないプライベートモデル

課金のない profile(billing: none)

セルフホストしたモデル(Ollama、プライベートネットワークの LiteLLM など)にはトークンごとの請求がありません。価格表にもないため、そのままでは fallback の最高単価で計算され、SESSION_COST_LIMIT_USD と SDK の maxBudgetUsd により turn が中断されます。このような profile は provider.billing: none と宣言します。

provider:
  kind: litellm
  endpoint: http://litellm:4000
  billing: none
  auth:
    kind: bearer
    value_env: LITELLM_MASTER_KEY
  • 省略時は per_token です。省略した profile と per_token を明記した profile は fingerprint が同じで、どちらも価格表・fallback で計算します。
  • none profile で作成したセッションの provider 呼び出しは、応答の model 名によらず費用 0、ledger の priced_by=unmetered として記録します。トークンは従来どおり記録します。セッション費用が増えないため、四箇所の費用上限判定(egress 認可、nextInput、メッセージ受付、エンジン)には達しません。
  • claim の remaining_budget_usd は null で、worker は SDK に maxBudgetUsd を渡しません。SDK が未知の model を独自の推定単価で計算し、予算によって turn を中断するためです。制限する予算がないため、/clear などで SDK の費用集計が再開されても worker は drain しません。
  • GET /v1/sessions/{id}/usage は cost.kind: "unmetered" と応答します。amount_usd は "0.000000" です。このセッションには費用上限が適用されないため、cost_limit_usd は null です。上限到達の案内(attention.reason)にもドル上限は表示されません。budget_exceeded はトークン上限に達した場合だけ true になります。
  • 課金の有無はセッション作成時にセッション行(sessions.unmetered)へ固定します。価格、claim 予算、usage 表示はこの値を読み取り、報告を受けた API の catalog は参照しません。そのため rolling update 中にその profile を知らない replica が報告を受けても費用は加算されません。billing を変えると fingerprint が変わるため、新しい id で追加します(同じ id を変更すると既存セッションは CATALOG_MISMATCH になります)。
  • none profile のセッション作成は、すべての API replica とすべての scheduler の WORKER_IMAGE をこのバージョンへ更新してから行います。以前の API は unmetered セッションの報告も価格表で計算し、以前の worker は claim の remaining_budget_usd: null を契約違反として拒否し、エンジンを起動できません。同じ理由から、unmetered セッションが残る間は API・worker を以前のバージョンに戻しません。
  • トークン上限(SESSION_TOKEN_LIMIT)、時間・同時実行数の上限(MAX_TURN_SECONDS、EXECUTION_SLOT_LIMIT、QUEUED_INPUT_LIMIT_PER_SESSION)は引き続き適用されます。unmetered 行のトークンも sessions.provider_tokens に加算します。
  • API が none を受け付けるのは、endpoint host がプライベートアドレス(10/8、172.16/12、192.168/16、100.64/10、127/8、169.254/16、::1、fc00::/7、fe80::/10)、または公開 DNS にない名前(ドットのない compose サービス名、localhost、.internal・.local・.localhost・.lan・.home.arpa)の場合だけです。それ以外では起動しません。egress proxy 側では、その host を EGRESS_CREDENTIAL_PRIVATE_ALLOWLIST に入れます。
  • プライベートアドレスは必要条件にすぎません。プライベートネットワークの LiteLLM も有料 upstream を代理できます。none 宣言が正しいかは運用者の責任です。誤って宣言すると有料呼び出しが費用上限なしで実行されます。SESSION_TOKEN_LIMIT を設定していれば、その場合もセッションごとのトークンは制限されます。Datadog の werft.provider.unmetered_tokens_1h(直近 1 時間の unmetered 行のトークン合計)と provider コンソールの使用量を併せて確認します。

有効化前にアップグレードゲートを満たす必要があります。

確認

プロファイルを使うエージェントでセッションを作成し、turn が completed になることを確認します。ready 200 はモデル key や呼び出しの成功を検査しません。環境変数による管理からコンソールへ移した後は、新しい呼び出しと key 変更の動作を確認します。

よくある問題

モデル key がないというエラーでは、接続画面への経路を確認します。プライベート endpoint というだけで billing:none が安全になるわけではありません。有料 upstream を代理するモデルを none と宣言すると、費用上限なしで呼び出します。

元に戻す

使用中のプロファイル id を直接編集して fingerprint を変えないでください。新しい接続・プロファイルのバージョンを作成し、新しいセッションへ移行します。コンソールに保存した key を廃止する場合、provider 側の権限も併せて整理します。

次に読む

容量と費用の計画、バックアップと復元。

このページ