沙盒功能目前处于私密预览阶段。随着我们的迭代,API 和功能可能会发生变化。注册等待列表以获取访问权限。
服务 URL 让你无需隧道、端口转发或 CLI 工具,即可访问在沙箱内运行的 HTTP 服务(REST API、Streamlit 应用、Jupyter notebook、API 文档)。每个沙箱 + 端口组合都有其自己的 URL,你可以在浏览器中打开、从代码中调用或与团队成员共享。
快速开始
在沙箱内启动一个 HTTP 服务器,然后获取一个 URL 来访问它:
from langsmith.sandbox import SandboxClient
client = SandboxClient()
with client.sandbox(snapshot_id=SNAPSHOT_ID) as sb:
handle = sb.run("python -m http.server 8000", timeout=0, wait=False)
svc = sb.service(port=8000)
# 在浏览器中打开
print(svc.browser_url)
# 或以编程方式发起请求
resp = svc.get("/")
print(resp.status_code)
handle.kill()
| 场景 | 如何操作 |
|---|
| 预览 Web 应用(Streamlit、Jupyter 等) | sb.service(port=<PORT>) 然后打开 browser_url |
| 从代码或 CI 调用 API | svc.get(...) / svc.post(...) 或使用服务令牌的 curl |
| 与团队成员共享实时演示 | 在 UI 中点击 Share Link 并发送 URL |
从 UI 打开服务
- 打开沙箱详情页。
- 找到 Open service 小部件。
- 输入端口号(例如
3000)。
- 点击 Open 在新标签页中启动,或点击 Share Link 复制一个可以发送给团队成员的 URL。
任何拥有此链接的人都可以访问该服务,即使没有 LangSmith 帐户。令牌过期后,请从 UI 生成新链接。
从 SDK 打开服务
获取服务 URL
在沙箱实例或客户端上调用 service():
svc = sb.service(port=3000)
# 或从客户端,通过沙箱名称
svc = client.service("my-sandbox", port=3000)
# 自定义令牌有效期(默认:10 分钟,最大:24 小时)
svc = sb.service(port=3000, expires_in_seconds=3600)
在请求服务 URL 之前,服务必须正在运行并监听指定端口。URL 仅路由流量,不会为你启动服务。
发起请求
返回的 ServiceURL 对象具有内置的 HTTP 辅助方法,可自动处理身份验证。令牌在过期前会透明刷新,因此无需手动管理。
svc = sb.service(port=8000)
resp = svc.get("/api/items")
resp = svc.post("/api/items", json={"name": "widget"})
resp = svc.put("/api/items/1", json={"name": "updated"})
resp = svc.patch("/api/items/1", json={"status": "active"})
resp = svc.delete("/api/items/1")
使用你自己的 HTTP 客户端
如果你更喜欢使用不同的 HTTP 客户端,请使用原始 URL 和令牌:
import httpx
svc = sb.service(port=8000)
resp = httpx.get(
svc.service_url + "api/items",
headers={"X-Langsmith-Sandbox-Service-Token": svc.token},
)
在浏览器中打开
使用 browser_url 在浏览器中打开服务。它会自动设置身份验证 cookie,因此所有后续的页面加载、图像和 API 调用都经过身份验证,无需在 URL 中包含令牌。
svc = sb.service(port=8000)
print(svc.browser_url)
你可以将此 URL 与团队成员共享。访问它无需 LangSmith 登录。
通过 REST API 生成 URL
curl -X POST \
"$LANGSMITH_ENDPOINT/api/v2/sandboxes/boxes/{sandbox_name}/service-url" \
-H "x-api-key: $LANGSMITH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"port": 3000, "expires_in_seconds": 3600}'
响应:
{
"browser_url": "https://{sandbox-id}--3000.smithbox.dev/_svc/auth?token=ey...",
"service_url": "https://{sandbox-id}--3000.smithbox.dev/",
"token": "ey...",
"expires_at": "2026-04-08T15:30:00Z"
}
示例:提供 FastAPI 应用服务
from langsmith.sandbox import SandboxClient
client = SandboxClient()
with client.sandbox(snapshot_id=SNAPSHOT_ID) as sb:
sb.write("/app/main.py", """
from fastapi import FastAPI
app = FastAPI()
items = []
@app.get("/items")
def list_items():
return items
@app.post("/items")
def create_item(item: dict):
items.append(item)
return item
""")
sb.run("pip install fastapi uvicorn", timeout=120)
handle = sb.run(
"uvicorn main:app --host 0.0.0.0 --port 8000",
timeout=0,
wait=False,
env={"PYTHONPATH": "/app"},
)
import time
time.sleep(3)
svc = sb.service(port=8000)
svc.post("/items", json={"name": "widget", "price": 9.99})
svc.post("/items", json={"name": "gadget", "price": 24.99})
resp = svc.get("/items")
print(resp.json())
# [{"name": "widget", "price": 9.99}, {"name": "gadget", "price": 24.99}]
# 在浏览器中打开自动生成的 API 文档
print(svc.browser_url)
handle.kill()
服务 URL 与 TCP 隧道对比
| 服务 URL | TCP 隧道 |
|---|
| 协议 | HTTP | 任意 TCP(数据库、Redis、SSH、HTTP) |
| 设置 | 零配置——只需一个 URL | 需要 SDK 或 CLI |
| 访问来源 | 浏览器、脚本、CI、任何地方 | 仅限本地机器 |
| 共享 | 复制 URL 并发送 | 不可共享 |
| 多页面 Web 应用 | 完全支持(子域路由) | 完全支持(本地端口) |
| 非 HTTP 服务 | 不支持 | 完全支持 |
对于你想从浏览器访问或与他人共享的 HTTP 服务,请使用服务 URL。对于非 HTTP 协议(如 psql 或 redis-cli)或当你需要仅限本地访问时,请使用 TCP 隧道。
故障排除
| 错误 | 原因 | 修复方法 |
|---|
| ”Service link has expired” | 令牌有效期已过 | 从 LangSmith 重新打开服务,或调用 sb.service() 获取新 URL |
| ”Service is not reachable” | 该端口上没有服务监听 | 验证服务器是否在沙箱内运行 |
| ”Authentication required” | 请求头或 cookie 中没有令牌 | 使用 browser_url 进行浏览器访问,或设置 X-Langsmith-Sandbox-Service-Token 请求头 |
将这些文档通过 MCP 连接到 Claude、VSCode 等,以获取实时答案。