沙盒功能目前处于私密预览阶段。随着我们的迭代,API 和功能可能会发生变化。注册等待列表以获取访问权限。
在创建引用这些密钥的沙箱之前,你必须在 LangSmith 工作区 设置中配置你的密钥(例如
OPENAI_API_KEY)。配置认证代理规则
在创建沙箱时添加proxy_config。每条规则指定:
| 字段 | 描述 |
|---|---|
match_hosts | 要拦截的主机(支持类似 *.github.com 的通配符) |
match_paths | 要匹配的路径(空值 = 所有路径) |
headers | 要注入的头部,每个头部包含 name、type 和 value |
no_proxy | 完全绕过代理的主机(例如 localhost) |
头部类型
每个头部都有一个type,控制其值的存储和显示方式:
| 类型 | 描述 |
|---|---|
workspace_secret | 使用 {KEY} 语法引用工作区密钥。在推送时解析。 |
plaintext | 值按原样存储和返回。用于非敏感头部。 |
opaque | 仅写入。值在静态存储时加密,且永远不会通过 API 返回。 |
单个 API 示例
创建一个沙箱,自动将 OpenAI API 密钥注入到出站请求中:curl -X POST "$LANGSMITH_ENDPOINT/api/v2/sandboxes/boxes" \
-H "x-api-key: $LANGSMITH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"snapshot_id": "<snapshot-uuid>",
"name": "openai-sandbox",
"wait_for_ready": true,
"proxy_config": {
"rules": [
{
"name": "openai-api",
"match_hosts": ["api.openai.com"],
"headers": [
{
"name": "Authorization",
"type": "workspace_secret",
"value": "Bearer {OPENAI_API_KEY}"
}
]
}
]
}
}'
多个 API 示例
添加多条规则以同时向多个服务进行身份验证:curl -X POST "$LANGSMITH_ENDPOINT/api/v2/sandboxes/boxes" \
-H "x-api-key: $LANGSMITH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"snapshot_id": "<snapshot-uuid>",
"name": "multi-api-sandbox",
"wait_for_ready": true,
"proxy_config": {
"rules": [
{
"name": "openai-api",
"match_hosts": ["api.openai.com"],
"headers": [
{
"name": "Authorization",
"type": "workspace_secret",
"value": "Bearer {OPENAI_API_KEY}"
}
]
},
{
"name": "anthropic-api",
"match_hosts": ["api.anthropic.com"],
"headers": [
{
"name": "x-api-key",
"type": "workspace_secret",
"value": "{ANTHROPIC_API_KEY}"
},
{
"name": "anthropic-version",
"type": "plaintext",
"value": "2023-06-01"
}
]
},
{
"name": "github-api",
"match_hosts": ["api.github.com"],
"match_paths": ["/repos/*", "/user"],
"headers": [
{
"name": "Authorization",
"type": "workspace_secret",
"value": "Bearer {GITHUB_TOKEN}"
}
]
}
],
"no_proxy": ["localhost", "127.0.0.1"]
}
}'
通过 SDK 配置
from langsmith.sandbox import SandboxClient
client = SandboxClient()
client.create_sandbox(
snapshot_id=SNAPSHOT_ID,
name="openai-sandbox",
proxy_config={
"rules": [
{
"name": "openai-api",
"match_hosts": ["api.openai.com"],
"headers": [
{
"name": "Authorization",
"type": "workspace_secret",
"value": "Bearer {OPENAI_API_KEY}",
}
],
}
]
},
)
import { SandboxClient } from "langsmith/experimental/sandbox";
const client = new SandboxClient();
await client.createSandbox(snapshotId, {
name: "openai-sandbox",
proxyConfig: {
rules: [
{
name: "openai-api",
matchHosts: ["api.openai.com"],
headers: [
{
name: "Authorization",
type: "workspace_secret",
value: "Bearer {OPENAI_API_KEY}",
},
],
},
],
},
});
使用回调的动态凭据
静态规则在沙箱创建时从你的工作区密钥中提取凭据。对于需要按请求解析的凭据——短期 OAuth 令牌、按用户范围限定的令牌、由你自己的认证服务颁发的令牌——请改用回调。代理会向你提供的 URL 发送 POST 请求,你的端点返回要注入的头部,代理会缓存结果。 回调与规则一起在proxy_config 下配置:
| 字段 | 描述 |
|---|---|
match_hosts | 要拦截的主机(语法与规则相同;支持类似 *.github.com 的通配符)。 |
url | 你的回调端点。必须是代理可访问的 http:// 或 https:// URL。 |
request_headers | 附加到代理 → 回调请求的头部,例如你的端点用于验证请求的 HMAC 或共享密钥。仅允许 plaintext 和 opaque 类型(不允许 workspace_secret)。 |
ttl_seconds | 解析后的头部在重新调用回调前缓存的时间。必须在 60 到 3600 之间。 |
rules 中的任何规则匹配主机,则跳过该主机的回调。在规则内,首次匹配优先;如果多个回调匹配,同样适用首次匹配优先。
回调契约
当代理需要为匹配的主机解析凭据且缓存未命中时,会发出以下请求:POST <callback.url>
Content-Type: application/json
<request_headers from your config, attached verbatim>
{"host": "api.example.com", "port": 443}
2xx 状态码和 JSON 主体响应:
{
"headers": {
"Authorization": "Bearer <token>",
"X-Org-Id": "..."
}
}
ttl_seconds。任何非 2xx 响应、传输错误或格式错误的 JSON 都会导致失败关闭:沙箱的请求将被拒绝,并返回 502 callback resolution failed(不注入头部,不缓存响应)。
示例
当你的 OAuth 令牌由你自己的服务按需颁发时,使用回调:curl -X POST "$LANGSMITH_ENDPOINT/api/v2/sandboxes/boxes" \
-H "x-api-key: $LANGSMITH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"snapshot_id": "<snapshot-uuid>",
"name": "callback-sandbox",
"wait_for_ready": true,
"proxy_config": {
"callbacks": [
{
"match_hosts": ["api.github.com", "*.githubusercontent.com"],
"url": "https://auth.your-app.example.com/sandbox-credentials",
"request_headers": [
{
"name": "X-Integrator-Secret",
"type": "opaque",
"value": "<shared-secret-your-endpoint-verifies>"
}
],
"ttl_seconds": 300
}
]
}
}'
通过 SDK 配置
from langsmith.sandbox import SandboxClient
client = SandboxClient()
client.create_sandbox(
snapshot_id=SNAPSHOT_ID,
name="callback-sandbox",
proxy_config={
"callbacks": [
{
"match_hosts": ["api.github.com", "*.githubusercontent.com"],
"url": "https://auth.your-app.example.com/sandbox-credentials",
"request_headers": [
{
"name": "X-Integrator-Secret",
"type": "opaque",
"value": "<shared-secret-your-endpoint-verifies>",
}
],
"ttl_seconds": 300,
}
]
},
)
import { SandboxClient } from "langsmith/experimental/sandbox";
const client = new SandboxClient();
await client.createSandbox(snapshotId, {
name: "callback-sandbox",
proxyConfig: {
callbacks: [
{
matchHosts: ["api.github.com", "*.githubusercontent.com"],
url: "https://auth.your-app.example.com/sandbox-credentials",
requestHeaders: [
{
name: "X-Integrator-Secret",
type: "opaque",
value: "<shared-secret-your-endpoint-verifies>",
},
],
ttlSeconds: 300,
},
],
},
});
通过 MCP 将这些文档连接到 Claude、VSCode 等,以获取实时答案。

