caveman-setup について
リポジトリ内の実稼働 LLM 呼び出しを、記録モードで Caveman ゲートウェイに接続するスキルです。最小限の変更、プロバイダーキーの保護、実リクエスト1回による検証を案内します。
主な機能
- 01実稼働 LLM 呼び出し箇所の特定
- 02対応クライアントのゲートウェイ経由化
- 03シークレットの環境変数管理
- 04保存済みキーと BYOK に対応
- 05実リクエスト1回で検証
活用シーン
- 01LLM を使うリポジトリへのゲートウェイ計測の追加
- 02既存 SDK 呼び出しのゲートウェイルーティング設定
- 03リポジトリとゲートウェイの接続確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ juliusbrussee/ caveman --skill caveman-setupインストール後、Claude Code で/caveman-setupを入力して読み込まれたか確認します。
詳細
このリポジトリを Caveman ゲートウェイ経由で接続します。Caveman はバイトを保持する LLM プロキシです。記録モードでは、アプリが送信する内容とそのコストを測定し、それ以外は何も変更しません。必要なのは、最小限の検証済みの統合です。リファクタリングではありません。
ここに至ったプロンプトには、4 つの値が記載されています。次の名前で参照してください。
GATEWAY— ゲートウェイのベース URL(例:https://gateway.caveman.soまたはhttp://127.0.0.1:8787)CAVE_API_KEY— ゲートウェイの認証シークレット(API キーと同様に扱います。環境変数のみに保存し、コミットせず、全文を表示しないでください)PROVIDER_KEYS—stored(プロバイダーキーは Caveman Cloud に暗号化して保存されます)またはbyok(このアプリがリクエストごとに独自のプロバイダーキーを送信します)DASHBOARD— ダッシュボードのベース URL(例:https://app.caveman.so)
値が 1 つでも不足している場合は、作業を中止して確認してください。URL を推測したり、キーを生成したりしないでください。
ルール(厳守)
- 一貫性のある統合。 既存の構成と適切な責任分界を通じて、すべての稼働中の LLM 呼び出し箇所を接続してください。正確性のために必要な各レイヤーに変更を加えてください。場当たり的なリファクタリングや一括フォーマット変更は行わず、責任の所在を明確にするか、ライフサイクルコストを下げる場合に限り、抽象化を追加してください。
- シークレットは環境変数に保存。
CAVE_API_KEYは、リポジトリですでに使われている環境ファイル(.env、.env.localなど)に設定してください。そのファイルが Git の追跡対象外でない場合は、.gitignoreに追加し、その旨を伝えてください。ソースコードにキーをハードコードしないでください。 - 観測した内容のみ報告。 最終報告には、実際の検証レスポンスに含まれる HTTP ステータスと使用量の数値を記載してください。成功を推測してはいけません。検証に失敗した場合は、代わりに失敗時のテンプレートを報告してください。
- 記録モードのみ。 追加するのは測定機能です。最適化を有効にせず、コスト削減を主張しないでください。オプティマイザーが明示的に有効化され、評価ゲートを通過するまでは、検証済みの削減額は $0 です。
- プロバイダーキーには関与しない。
PROVIDER_KEYS: storedの場合、キーを見ることはありません。byokの場合、アプリが既存のプロバイダーキーを保存している場所は一切変更しません。
手順 1 — 稼働中の LLM 呼び出し箇所をすべて見つける
依存関係ファイル(package.json、requirements.txt、pyproject.toml、
go.mod、ロックファイル)を読み、ソース内で LLM クライアントを検索してください。
- SDK のインポート:
openai、@anthropic-ai/sdk、anthropic、ai+@ai-sdk/*(Vercel)、langchain*、litellm、google-genai/@google/genai、crewai、pydantic_ai、openai-agents/agents api.openai.com、api.anthropic.com、generativelanguage.googleapis.comへの生の HTTP リクエスト- 既存のベース URL 環境変数:
OPENAI_BASE_URL、OPENAI_API_BASE、ANTHROPIC_BASE_URL、GEMINI_BASE_URL、GOOGLE_GEMINI_BASE_URL
変更を加える前に、見つかった箇所(呼び出し箇所ごとのファイルと行番号)を一覧にしてください。LLM 呼び出し箇所が見つからない場合は、作業を中止し、このファイル末尾にある「接続対象なし」のテンプレートを報告してください。統合を作り上げてはいけません。
手順 2 — アプリのスラッグを決める
ゲートウェイパス GATEWAY/w/<app> では、1 つのスラッグでこのアプリを識別します。パッケージ名またはモジュール名をもとに決めてください(例:support-bot、acme-api)。形式は、小文字の [a-z0-9] で始まり、その後に [a-z0-9._-] を使用できます。最大 64 文字です。このスラッグの配下にあるアプリグループ全体の費用は、ダッシュボードで確認できます。
ステップ 3 — 各呼び出し箇所を接続する
パターンは常に同じです:ベース URL → /w/<app>を付けたゲートウェイ、
さらに 1 つの認証ヘッダー。 ゲートウェイ認証にはx-cave-api-key: CAVE_API_KEY
を使用します(ヘッダーを指定しにくい場合はAuthorization: Bearer CAVE_API_KEYも使用できます)。
PROVIDER_KEYS: byokの場合は、x-cave-upstream-key: <アプリがすでに使用しているプロバイダーキー>
も送信します。
安全に接続できる理由は 2 つあります(どちらも期待ではなく、ゲートウェイによって強制されます)。
ゲートウェイはアップストリームの認証ヘッダーを一から再構築するため、クライアントの
Authorization/x-api-keyの値がプロバイダーに転送されることはありません。また、storedの場合、
アップストリーム認証にはサーバー側の暗号化された接続が使用されます。そのため、
storedモードで SDK が api-key パラメーターを必須とする場合は、Cave キーを設定してください。
ゲートウェイの認証に使われ、それ以上先に送られることはありません。
正確な形式(各呼び出し箇所に合うものを使ってください。これらは製品が公開している レシピであり、提案ではありません):
OpenAI SDK(TS) — Chat Completions と Responses はどちらも次の経路を通ります:
const client = new OpenAI({
baseURL: `${process.env.CAVE_GATEWAY_URL}/w/<app>/openai/v1`,
apiKey: process.env.OPENAI_API_KEY, // byok: unchanged · stored: use CAVE_API_KEY
defaultHeaders: {
"x-cave-api-key": process.env.CAVE_API_KEY!,
// byok only:
"x-cave-upstream-key": process.env.OPENAI_API_KEY!,
},
});
OpenAI SDK(Python) — 同じ形式です:base_url=f"{gw}/w/<app>/openai/v1"、
default_headers={"x-cave-api-key": ..., "x-cave-upstream-key": ...}。
Anthropic SDK(TS/Python) — SDK が/v1/messagesを自動的に追加します。
どちらのモードでも、ここではx-cave-api-keyヘッダーが必要です(この SDK 独自のキー
パラメーターはx-api-keyを使用しますが、これはゲートウェイ認証ヘッダーではありません):
client = anthropic.Anthropic(
base_url=f"{os.environ['CAVE_GATEWAY_URL']}/w/<app>",
api_key=os.environ["ANTHROPIC_API_KEY"], # byok: unchanged · stored: use CAVE_API_KEY
default_headers={
"x-cave-api-key": os.environ["CAVE_API_KEY"],
# byok only:
"x-cave-upstream-key": os.environ["ANTHROPIC_API_KEY"],
},
)
Vercel AI SDK — createOpenAICompatible({ baseURL: ${gw}/w//openai/v1, headers: { "x-cave-api-key": ... } });Anthropic モデルの場合は
createAnthropic({ baseURL: ${gw}/w//v1, headers: { ... } })。
LangChain/LangGraph — ChatOpenAI(base_url=f"{gw}/w/<app>/openai/v1", default_headers={...});ChatAnthropic(base_url=f"{gw}/w/<app>", default_headers={...})。LangGraph は、渡したモデルの設定を引き継ぎます。
LiteLLM — 呼び出しごとにapi_base=f"{gw}/w/<app>/openai/v1"と
extra_headers={...}を指定するか、LiteLLM プロキシのconfig.yamlで全体に設定します。
Raw HTTP/その他 — ホストを置き換え、プロバイダーのネイティブパスはそのままにします:
GATEWAY/w/<app>/v1/chat/completions(OpenAI プロトコル)または
GATEWAY/w/<app>/v1/messages(Anthropic プロトコル)に、ヘッダーを追加します。
具体例として、slug がsupport-botでホスト型ゲートウェイを使用する場合、OpenAI SDK のベース
URL はhttps://gateway.caveman.so/w/support-bot/openai/v1です。また、stored
モードでは、x-cave-upstream-keyの行はすべて完全に削除してください。これは byok 専用です。
記載のないフレームワーク(google-genai、crewai、pydantic-ai、openai-agents)については、
<docs origin>/docs/integrations/にある該当ページを参照してください。これは、このスキルの取得元と
同じオリジンです。その手順に従ってください。
リポジトリの env ファイルに追加し、コードから参照してください(リテラル値は使わないでください):
CAVE_GATEWAY_URL=<GATEWAY>
CAVE_API_KEY=<CAVE_API_KEY>
ステップ 4 — 実際のリクエストを 1 回送信して検証する
ユーザーがセットアッププロンプトを貼り付けたのは、まさにこの 1 回の小さな検証リクエストを 許可するためです。今すぐ送信してください。許可を求めて一時停止してはいけません。 ためらって検証されないまま終わる連携よりも、わずかなリクエストを 1 回送るほうが望ましい結果です。 検証と報告を自律的に完了することが、このスキルの目的です。
今構築した接続を通じて、最小限のリクエストを 1 回送信してください。アプリに専用スクリプトが
ある場合は、アプリ独自の最も低コストな経路を使います。ない場合は、今接続したプロトコルに
合った経路で、アプリ独自のモデルと小さな上限(max_tokens ≤ 32)を指定して curl を実行します:
# OpenAI-protocol wiring:
curl -sS "$CAVE_GATEWAY_URL/w/<app>/v1/chat/completions" \
-H "x-cave-api-key: $CAVE_API_KEY" \
-H "content-type: application/json" \
-d '{"model":"<model the repo already uses>","max_tokens":16,"messages":[{"role":"user","content":"ping"}]}'
# Anthropic-protocol wiring:
curl -sS "$CAVE_GATEWAY_URL/w/<app>/v1/messages" \
-H "x-cave-api-key: $CAVE_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"<model the repo already uses>","max_tokens":16,"messages":[{"role":"user","content":"ping"}]}'
(byok の場合:-H "x-cave-upstream-key: $PROVIDER_KEY"を追加します。)これは実際に課金される
プロバイダーリクエストです。それが目的です。実際のトラフィックを発生させ、実際に測定します。
レスポンスを確認してください。成功とは、usageブロックを含む HTTP 200 です。それ以外の場合は、
以下の該当する失敗テンプレートを使用します。
ステップ 5 — 報告する
最後は、実際に行ったことと確認できた内容を反映して、次の形式で正確に終えてください:
## Caveman is live in this repo
Wired: <n> callsite(s) in <n> file(s)
- <file> — <one-line what changed>
App slug: <app> — spend for this app groups under it
Verified: HTTP 200 · model <model> · <in> in / <out> out tokens (one real request)
Mode: record — measured only. No model-visible bytes changed, no optimization
enabled. Verified savings are $0 until you turn an optimizer on and it passes
its eval gate. That honesty is the product.
See the dollars: <DASHBOARD>/traces — your request is the top row, priced from
the public catalog. <DASHBOARD>/getting-started flips to "First request received."
Want spend split by workflow (e.g. support-reply vs nightly-digest), not just
by app? Say "discover workflows" — I'll fetch <docs origin>/docs/discover-workflows.md
and label every callsite by the job it does.
失敗時のテンプレート(記載どおりに使用し、決して表現を和らげないでください)
- 接続対象なし: "このリポジトリに LLM の呼び出し箇所は見つかりませんでした(SDK、プロバイダーへの直接 HTTP 通信、ベース URL の環境変数を検索しました)。このリポジトリが LLM コードを提供するのではなく、コーディングエージェントを実行するものである場合は、代わりに
caveman wrap <agent>を使用してください。詳しくは /getting-started をご覧ください。" - ゲートウェイに到達できない: "検証リクエストは GATEWAY に到達できませんでした()。接続設定は完了していますが、未検証です。ゲートウェイに到達できるようになるまで、計測は行われません。URL とネットワークを確認してから、上記の検証用 curl を再実行してください。"
- 401 cave_invalid_api_key: "ゲートウェイが CAVE_API_KEY を拒否しました。/getting-started で新しいキーを発行して環境ファイルを更新してください。接続設定自体に変更はありません。"
- 404 cave_route_not_found: "ゲートウェイに一致するルートがありません。通常は、形式が正しくない /w/ スラッグ(先頭は小文字の [a-z0-9]、続きは [a-z0-9._-]、最大 64 文字)か、SDK のプロトコルに一致しないパスが原因です。URL を修正して再検証してください。"
- プロバイダーエラー(ゲートウェイ経由の 4xx/5xx): ステータスと本文を記載どおりに報告してください。ゲートウェイには到達できており、認証も成功していますが、上流への呼び出しが失敗しました。通常は、アプリ自体のプロバイダーキーまたはモデル名に問題があります。
これらのいずれの場合も、成功したと報告してはいけません。未検証の連携は未検証として報告してください。