モデル接続とプロファイルの設定
セッションが使う接続とプロファイルを設定します
作業内容
ワークスペースのモデル接続とプロファイルを構成し、セッションの一つの turn で実際の呼び出しを確認します。モデル資格情報は利用者の API key とは異なります。
準備
owner ログイン、使うモデルの key またはプライベートなモデル endpoint、セッションからアクセスするリポジトリが必要です。費用上限と設定契約を確認します。
手順
1. コンソールの接続とプロファイル
セッションからモデルを呼ぶには、モデル key とその key を使うプロファイルが必要です。どちらも Web コンソールで作成します。owner でログインし、次の順で操作します。
- 設定 > エージェント接続 > モデル接続で接続を追加を押します。種類は
anthropic、アドレスは既定値(https://api.anthropic.com)にし、Anthropic key を貼り付けて保存します。key は DB に封印して保存され、画面には末尾の四文字だけが表示されます。 - プロファイル > プロファイルを作成で先ほどの接続を選び、モデル・ツール・実行方式を設定して保存します。エージェントの作成時にこのプロファイルを選びます。
エージェントが使うリポジトリはプロファイル作成時には選ばず、そのエージェントの 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.jsonAPI_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 で計算します。 noneprofile で作成したセッションの 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になります)。 noneprofile のセッション作成は、すべての 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 側の権限も併せて整理します。