Launch HN: Coasty (YC S26) – 专为计算机操作智能体打造的 API
Launch HN: Coasty (YC S26) – An API for computer-use agents

原始链接: https://coasty.ai/docs

Coasty 现已提供“自带密钥”(BYOK)选项,允许用户完全使用自己的 Anthropic 或 OpenAI 账户来运行计算机操作框架。选择此项后,所有大模型调用(包括执行器、基础和代码智能体)都将使用您自己的服务商账户,而非平台默认设置。 **主要特性:** * **安全管理:** 密钥可通过请求头发送(单次使用),也可通过 `PUT /v1/llm/keys/{provider}` 安全存储。存储的密钥均采用 AES-256-GCM 加密;系统仅返回非敏感的指纹信息。 * **拒绝静默回退:** 一旦启用 BYOK,系统将严格使用您的凭据。如果密钥无效或缺失,程序会直接报错(例如 `LLM_KEY_INVALID`),而不会自动回退到平台默认密钥。 * **精细化控制:** 您可以按请求配置服务商和模型,包括按角色设置模型覆盖(例如,为压缩任务选择成本更低的模型)。 * **计费说明:** 在继续支付 Coasty 平台使用费的同时,您所消耗的 Token 将直接由您的 LLM 服务商向您收费。 该功能为您提供了对模型选择和数据使用权的完全掌控,同时确保了 API 凭据的安全性。

抱歉。
相关文章

原文

By default every LLM call in the computer-use harness runs on Coasty's managed models. BYOK (bring your own key) flips that: opt in and the entire harness (the worker, grounding, the code agent, and compaction; every LLM call) runs on your own Anthropic or OpenAI account instead. Opt-in is always explicit, per request or per stored key. provider: "managed" (or omitting llm entirely) keeps the platform default, unchanged.

There are two ways to hand over a key. Store it once with PUT /v1/llm/keys/{provider} (encrypted with AES-256-GCM at rest; only a sha256-prefix fingerprint is ever echoed back), or send it per request in headers. A header key takes precedence over the stored key. Sending a key without a provider returns 422.

X-LLM-Provider: anthropic
X-LLM-Api-Key: sk-ant-your_key_here
X-LLM-Model: claude-sonnet-4-6

The headers work on POST /v1/predict, POST /v1/runs, POST /v1/workflows/{id}/runs, POST /v1/sessions, and POST /v1/schedules. Stored keys are managed through three endpoints, gated by the llm_keys scope (granted to new live keys by default). These endpoints require a live key; sandbox keys cannot read, overwrite, or delete the production credential store:

import os, requests

BASE = "https://coasty.ai/v1"
HEADERS = {"X-API-Key": os.environ["COASTY_API_KEY"]}

# Store (upsert) your own Anthropic key. Encrypted at rest; never echoed back.
stored = requests.put(
    f"{BASE}/llm/keys/anthropic",
    headers=HEADERS,
    json={"api_key": os.environ["ANTHROPIC_API_KEY"]},
    timeout=30,
).json()
print(stored)   # {"provider": "anthropic", "key_fingerprint": "a1b2c3d4", "stored": true}

# List stored keys: provider, fingerprint, timestamps. Never the key itself.
keys = requests.get(f"{BASE}/llm/keys", headers=HEADERS, timeout=30).json()
for k in keys["keys"]:
    print(k["provider"], k["key_fingerprint"])

# Delete when you rotate away (404 LLM_KEY_NOT_FOUND when none is stored)
requests.delete(f"{BASE}/llm/keys/anthropic", headers=HEADERS, timeout=30)

On the request body, the same endpoints accept an llm object that selects the provider and, optionally, a model per harness role. It deliberately has no api_key field (a 422 if you attempt one): keys ride headers or the encrypted store only, so they can never be echoed in run objects, webhooks, or idempotency replays.

import os, requests

BASE = "https://coasty.ai/v1"
HEADERS = {"X-API-Key": os.environ["COASTY_API_KEY"]}

# Start a run on YOUR Anthropic key (stored earlier via PUT /llm/keys/anthropic).
# The llm block deliberately has NO api_key field (422 if you try): keys ride
# headers or the encrypted store only, never request bodies.
run = requests.post(
    f"{BASE}/runs",
    headers=HEADERS,
    json={
        "machine_id": "mch_test_0123456789abcdef",
        "task": "Open the billing page and download the latest invoice as PDF",
        "llm": {
            "provider": "anthropic",             # or "openai"; "managed" = platform default
            "model": "claude-sonnet-4-6",        # any model on your account (vision-capable)
            "compaction_model": "claude-haiku-4-5",  # optional per-role override
        },
    },
    timeout=30,
).json()

# Per-request variant: send the key in headers instead of storing it.
# A header key takes precedence over the stored key for this request only.
byok_headers = {
    **HEADERS,
    "X-LLM-Provider": "anthropic",
    "X-LLM-Api-Key": os.environ["ANTHROPIC_API_KEY"],
    "X-LLM-Model": "claude-sonnet-4-6",
}

# The run echoes a non-secret llm block; the key itself is never returned.
run = requests.get(f"{BASE}/runs/{run['id']}", headers=HEADERS, timeout=30).json()
print(run["llm"])   # {"provider": ..., "model": ..., "key_fingerprint": ..., "key_source": ..., "key_scrubbed": ...}

Per-role overrides exist for tuning cost against quality: run compaction on a cheaper model while the worker stays on the default, for example. For runs, workflows, and schedules the key is snapshotted encrypted into the run, so crash-recovery on another replica keeps using your key; it is scrubbed the moment the run reaches a terminal state. GET /v1/runs/{id} echoes a non-secret llm block: {provider, model, key_fingerprint, key_source, key_scrubbed}. Schedules store only the non-secret preference; at fire time the current stored key is used. Delete the stored key and future firings fail loudly with LLM_KEY_NOT_CONFIGURED; they never silently run on platform keys.

Grounding (pixel-coordinate resolution) quality is tuned on the platform model. When running grounding on your own model, expect the best results with the defaults, and use grounding_model to experiment before committing a cheaper or different model to that role.

No silent fallback, ever: once you ask for BYOK, no code path can use Coasty's platform LLM keys. Errors from your provider surface as your key's issue with stable codes: LLM_KEY_NOT_CONFIGURED, LLM_KEY_INVALID, LLM_PROVIDER_AUTH_FAILED, LLM_PROVIDER_RATE_LIMITED, LLM_PROVIDER_QUOTA_EXCEEDED, and LLM_PROVIDER_ERROR.

Billing: Coasty's per-call and per-step platform charges are unchanged with BYOK. The model tokens are billed by your provider account directly.

联系我们 contact @ memedata.com