mcpField
C
caveman-setup

caveman-setup

github.com/juliusbrussee云与 DevOps115.8k106.3k 次安装3 天前更新
代码仓库

关于 caveman-setup

用于将代码库中的实时 LLM 调用接入 Caveman 网关的技能,仅启用记录模式。它指导最小化集成、保护提供商密钥,并通过一次真实请求验证配置。

主要功能

  1. 01定位实时 LLM 调用点
  2. 02将受支持的客户端接入网关
  3. 03将密钥保存在环境变量中
  4. 04支持托管或 BYOK 提供商密钥
  5. 05通过一次真实请求验证

适用场景

  1. 01为使用 LLM 的代码库添加网关测量
  2. 02为现有 SDK 调用配置网关路由
  3. 03验证代码库与网关的连接

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/juliusbrussee/caveman --skill caveman-setup

安装后在 Claude Code 中输入/caveman-setup确认已加载。

详细介绍

你正在通过 Caveman 网关接入此代码库。Caveman 是一个保留字节的 LLM 代理:在记录模式下,它会测量应用发送的内容及其成本,不做其他任何改动。你的任务是完成最小化且经过验证的集成,而不是重构。

引导你到此处的提示词提供了四个值。请按以下名称引用它们:

  • 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)

如果缺少任何值,请停止并索要。不要猜测 URL,也不要创建密钥。

规则(不可妥协)

  1. 集成完整且一致。 通过现有配置和适当的接入点接入所有实际运行的 LLM 调用点。修正所需的每一层都要处理。不要顺手重构或全面格式化;只有在能明确归属或降低生命周期成本时才添加抽象。
  2. 密钥留在环境变量中。 将 CAVE_API_KEY 放入代码库已使用的环境文件(.env、.env.local 等)。如果该文件未被 git 忽略,请将其添加到 .gitignore 并说明。绝不要在源代码中硬编码密钥。
  3. 只报告实际观察到的内容。 最终报告必须说明真实验证响应中的 HTTP 状态和用量数据,绝不能假定成功。如果验证失败,请改用失败模板。
  4. 仅使用记录模式。 你添加的是测量功能。不要启用任何优化,也不要声称有任何节省——在明确启用优化器并通过其评估门槛之前,经验证的节省额为 $0。
  5. 提供商密钥不归你处理。 使用 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 步 — 选择应用 slug

一个 slug 用于在网关路径中标识此应用:GATEWAY/w/<app>。根据包或模块名称推导 slug(例如 support-bot、acme-api)。格式要求: 首字符为小写 [a-z0-9],其后为 [a-z0-9._-],最多 64 个字符。控制面板上此应用的所有使用量均归入该 slug。

第 3 步 — 接入每个调用点

模式始终相同:基础 URL → 网关(路径中带有 /w/<app>),再加一个身份验证请求头。 网关身份验证使用 x-cave-api-key: CAVE_API_KEY(在请求头不方便的情况下,也可以使用 Authorization: Bearer CAVE_API_KEY)。使用 PROVIDER_KEYS: byok 时,还要发送 x-cave-upstream-key: <the provider key the app already uses>。

有两个事实可以确保接入安全(这两点都由网关强制执行,并非只是期望如此): 网关会从头构建上游身份验证请求头,因此客户端的 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 自身的 key 参数会放在 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": ... } });通过 createAnthropic({ baseURL: ${gw}/w//v1, headers: { ... } }) 使用 Anthropic 模型。

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 中统一配置整个集群。

原始 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/ 下对应的页面——使用与本技能来源相同的 origin——并按其中说明操作。

将以下内容添加到仓库的环境变量文件中(并在代码中引用,不要使用字面量):

CAVE_GATEWAY_URL=<GATEWAY>
CAVE_API_KEY=<CAVE_API_KEY>

第 4 步 — 通过一次真实请求验证

用户粘贴设置提示词,授权的正是这一次小型验证请求。现在就发送——不要停下来征求许可。因为犹豫而导致集成未验证,比发送一次极小的请求更糟;自主完成验证并汇报,正是本技能的目标。

通过刚刚接入的路径发送一个最小请求——如果应用有相应脚本,就使用应用自身成本最低的路径;否则,使用与刚接入协议相匹配的路径执行 curl,并使用应用自身的模型以及较小的上限 (max_tokens ≤ 32):

# 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"。)这是一次真实的、会产生费用的提供商请求——目的就在于此:真实流量、真实测量。

读取响应。成功条件 = HTTP 200 且包含 usage 块。其他情况 = 使用下方匹配的失败模板。

第 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.

失败模板(逐字使用并填入内容——绝不可弱化措辞)

  • 没有可接入的内容:"我在此仓库中没有发现任何大模型调用点(已搜索 SDK、 原始提供商 HTTP 请求、基础 URL 环境变量)。如果此仓库运行的是编码 Agent, 而不是提供大模型代码,请改用 caveman wrap <agent>——参见 /getting-started。"
  • 网关无法访问:"验证请求无法访问 GATEWAY ()。接线已完成,但尚未验证——网关可访问之前,不会测量任何内容。 请检查 URL 和网络,然后重新运行上方的验证 curl 命令。"
  • 401 cave_invalid_api_key:"网关拒绝了 CAVE_API_KEY。请在 /getting-started 创建新密钥并更新 env 文件;接线本身没有变化。"
  • 404 cave_route_not_found:"网关未匹配到任何路由——通常是 /w/ slug 格式错误(首字符为小写 [a-z0-9], 后续字符为 [a-z0-9._-],最多 64 个字符),或路径与 SDK 的协议不匹配。请修正 URL 并重新验证。"
  • 提供商错误(经网关返回 4xx/5xx):逐字报告状态码和正文;网关可访问且身份验证已通过,但上游调用失败—— 通常是应用本身的提供商密钥或模型名称有问题。

遇到以上任何情况,绝不可报告成功。未验证的集成必须报告为未验证。

评论

支持 Markdown