Skyvern TypeScript SDK(@skyvern/client)使用指南:从快速上手到高级配置
【免费下载链接】skyvernAutomate browser based workflows with AI项目地址: https://gitcode.com/GitHub_Trending/sk/skyvern
导读
本文以开源仓库 Skyvern 中 TypeScript 官方 SDK(npm 包@skyvern/client)的 README 为主线,系统讲解如何在 Node.js 与各类 JavaScript 运行时中通过 TypeScript 调用 Skyvern API,驱动 AI 自动化浏览器工作流。你将掌握客户端实例化与runTask快速跑通、请求/响应类型体系、SkyvernError异常处理,以及附加请求头、查询参数、自动重试、超时控制、请求中止、原始响应访问、自定义 fetch 等全部高级配置,并深入 SDK 底层实现原理,理解每个配置项在源码中的真实作用。
一、SDK 概览与仓库定位
Skyvern 是一个"用 AI 自动化基于浏览器的工作流"的开源项目,后端通过 REST API 提供任务(Task)、工作流/Agent(Workflow/Agent)、调度(Schedule)、脚本(Script)、工件(Artifact)等能力。@skyvern/client正是面向 TypeScript/JavaScript 生态的官方客户端,它的设计目标是"为 TypeScript 提供对 Skyvern API 的便捷访问"。
该 SDK 位于仓库 skyvern-ts/client 目录,由 Fern 基于 OpenAPI 规范程序化生成。从 package.json 可以看到:
- 包名:
@skyvern/client,当前仓库版本为1.0.53; - 同时提供 CJS(
dist/cjs/index.js)与 ESM(dist/esm/index.mjs)双构建产物,exports字段完整声明了import/require两种消费方式; - 运行环境要求
node >= 18.0.0; - 唯一运行时依赖为
playwright(用于浏览器相关能力),其余测试工具(vitest、msw、biome 等)均为开发依赖; - 源码入口 src/index.ts 统一导出
SkyvernClient、SkyvernEnvironment、SkyvernError、SkyvernTimeoutError,以及Skyvern类型命名空间和浏览器自动化相关能力(SkyvernBrowser、SkyvernBrowserPageAgent、SkyvernBrowserPageAi)。
二、安装
在项目中通过 npm 安装即可:
npm i -s @skyvern/client安装后即可在 TypeScript 项目中直接import。若使用 pnpm/yarn,命令等价替换为pnpm add @skyvern/client或yarn add @skyvern/client。仓库内 skyvern-ts/client 目录本身使用 pnpm workspace 管理(见 pnpm-workspace.yaml 与packageManager: pnpm@10.14.0声明),也可通过pnpm build从源码构建出dist/cjs与dist/esm产物后本地使用。
三、快速上手:实例化客户端并运行第一个任务
SDK 的使用非常直接:创建SkyvernClient实例,传入 API Key,然后调用对应方法。
import { SkyvernClient } from "@skyvern/client"; const client = new SkyvernClient({ apiKey: "YOUR_API_KEY" }); await client.runTask({ "x-user-agent": "x-user-agent", prompt: "Find the top 3 posts on Hacker News." });apiKey会通过请求头x-api-key自动传递给服务端。从 src/Client.ts 的构造函数可以看到,客户端在初始化时还会自动附加一组 SDK 标识头:
X-Fern-Language: JavaScriptX-Fern-SDK-Name: @skyvern/clientX-Fern-SDK-Version: 1.0.47User-Agent: @skyvern/client/1.0.47X-Fern-Runtime与X-Fern-Runtime-Version(自动探测当前运行时类型与版本)
runTask对应的后端端点是POST /v1/run/tasks(见 Client.ts),请求体中的x-user-agent会被解构出来放到请求头,其余字段作为 JSON body 发送。
客户端提供的主要方法
从 Client.ts 的实现可以看出,SkyvernClient不仅封装了任务执行,还聚合了运行、工作流、文件夹与资源子客户端:
| 方法 | 后端端点 | 说明 |
|---|---|---|
runTask(request) | POST /v1/run/tasks | 运行一个 AI 任务(自然语言 prompt 驱动) |
runWorkflow(request) | POST /v1/run/agents | 运行一个工作流/Agent,支持template与x-max-steps-override参数 |
getRun(runId) | GET /v1/runs/{run_id} | 查询任务或工作流运行信息 |
cancelRun(runId) | POST /v1/runs/{run_id}/cancel | 取消单个运行 |
bulkCancelRuns(request) | POST /v1/runs/cancel | 批量取消运行 |
getWorkflows(request) | GET /v1/agents | 分页/搜索获取工作流列表(支持search_key、folder_id、status、tags等过滤) |
createWorkflow(request) | POST /v1/agents | 创建工作流 |
updateWorkflow(workflowId, request) | POST /v1/agents/{workflow_id} | 更新工作流 |
deleteWorkflow(workflowId) | POST /v1/agents/{workflow_id}/delete | 删除工作流 |
getFolders(request) | GET /v1/folders | 获取文件夹列表 |
createFolder(request) | POST /v1/folders | 创建文件夹 |
此外,客户端通过懒加载的 getter 暴露artifacts、scripts、schedules、agents四个子客户端(见 Client.ts),分别对应工件、脚本、调度和 Agent 资源的管理能力。每个方法都支持在方法级传入requestOptions覆盖全局配置。
四、请求与响应类型
SDK 将所有请求与响应类型导出为 TypeScript 接口(interface),统一放在Skyvern命名空间下,方便按需导入并获得完整的类型提示与编译期校验:
import { Skyvern } from "@skyvern/client"; const request: Skyvern.SchedulesListAllRequest = { ... };全部类型定义位于 src/api/types 目录,覆盖任务、运行、工作流、动作(Action)、Block(如ForLoopBlock、HttpRequestBlock、ExtractionBlock)、凭据(Bitwarden、1Password、Azure Vault 等)与各类枚举(ActionType、BlockType、FileStorageType等),数量超过 290 个类型文件,构成了完整的类型化 API 契约。仓库还提供了 reference.md 作为方法级 API 参考文档,每个方法都包含描述、用法示例与参数说明。
五、异常处理
当 API 返回非成功状态码(4xx 或 5xx)时,SDK 会抛出SkyvernError的子类。所有调用方都可以用统一的SkyvernError捕获:
import { SkyvernError } from "@skyvern/client"; try { await client.runTask(...); } catch (err) { if (err instanceof SkyvernError) { console.log(err.statusCode); console.log(err.message); console.log(err.body); console.log(err.rawResponse); } }从 src/errors/SkyvernError.ts 的实现可见,SkyvernError携带四个关键字段:
statusCode:HTTP 状态码;body:服务端返回的错误响应体;rawResponse:完整的原始响应(含 headers);message:自动拼接的摘要信息(包含状态码与格式化后的响应体)。
SDK 还针对常见状态码预置了具体错误子类(见 src/api/errors):BadRequestError(400)、ForbiddenError(403)、NotFoundError(404)、ConflictError(409)、RangeNotSatisfiableError(416)、UnprocessableEntityError(422)、InternalServerError(500)。以runTask为例,源码对 400 抛BadRequestError、对 422 抛UnprocessableEntityError,其余状态码回退为通用SkyvernError;当响应体非 JSON 或发生未知错误时也会包装为SkyvernError,而请求超时会抛出独立的SkyvernTimeoutError(见 Client.ts)。
六、高级配置详解
所有高级配置既可全局设置(构造SkyvernClient时传入),也可按请求覆盖(方法第二个参数传入)。这些选项在 src/BaseClient.ts 中有完整定义,下文逐一展开。
6.1 附加请求头(Additional Headers)
通过headers请求选项附加自定义请求头,适用于透传认证信息、跟踪 ID 等场景:
const response = await client.runTask(..., { headers: { 'X-Custom-Header': 'custom value' } });在源码中,自定义请求头会与 SDK 默认头、x-api-key按优先级合并(请求级最高),合并逻辑见 src/core/headers.ts 与 Client.ts。
6.2 附加查询字符串参数(Additional Query String Parameters)
通过queryParams请求选项附加自定义查询参数,会追加到请求 URL 上:
const response = await client.runTask(..., { queryParams: { 'customQueryParamKey': 'custom query param value' } });从实现看,queryParams会与各方法内部生成的参数(如getWorkflows的page、search_key等)合并后统一传给 fetcher(见 Client.ts),支持字符串、数组与对象值。
6.3 自动重试(Retries)
SDK 内置了带指数退避的自动重试机制。只要请求"可重试"且重试次数未超过上限(默认 2 次),就会自动重发。以下状态码会被判定为可重试:
- 408(Request Timeout)
- 429(Too Many Requests)
- 5XX(服务端内部错误,500 及以上)
使用maxRetries请求选项可调整重试策略:
const response = await client.runTask(..., { maxRetries: 0 // 请求级覆盖:完全关闭重试 });深入源码 src/core/fetcher/requestWithRetries.ts,可以看到重试实现的完整细节,值得在生产环境中理解:
- 初始退避延迟
INITIAL_RETRY_DELAY = 1000ms,最大退避延迟MAX_RETRY_DELAY = 60000ms,默认最大重试DEFAULT_MAX_RETRIES = 2; - 优先读取响应头
Retry-After(支持"秒数"和"HTTP 日期"两种格式,遵循 RFC 7231),其次读取X-RateLimit-Reset(Unix 秒级时间戳,带正向抖动),两者都没有时退化为2 ^ retryAttempt指数退避; - 所有退避延迟都会叠加 20% 的随机抖动(jitter),避免多个客户端同时重试造成"重试风暴"。
6.4 超时控制(Timeouts)
SDK 默认请求超时为 60 秒,通过timeoutInSeconds选项调整:
const response = await client.runTask(..., { timeoutInSeconds: 30 // 将超时覆盖为 30 秒 });从源码可见该默认值:timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000(见 Client.ts),即请求级选项优先于全局选项,最后回退到 60 秒。超时后会抛出SkyvernTimeoutError。
6.5 中止请求(Aborting Requests)
SDK 支持在任意时刻通过AbortSignal中止进行中的请求:
const controller = new AbortController(); const response = await client.runTask(..., { abortSignal: controller.signal }); controller.abort(); // 中止该请求abortSignal直接透传给底层 fetch 调用(见 Client.ts),配合AbortController可以优雅地实现"用户取消""超时兜底""任务切换"等交互场景。
6.6 访问原始响应数据(Access Raw Response Data)
当需要读取响应头等原始信息时,使用.withRawResponse()方法。它返回一个 Promise,resolve 为包含data与rawResponse两个属性的对象:
const { data, rawResponse } = await client.runTask(...).withRawResponse(); console.log(data); console.log(rawResponse.headers['X-My-Header']);其底层机制在 src/core/fetcher/HttpResponsePromise.ts 中:所有 API 方法实际返回的都是HttpResponsePromise<T>(一个内部持有"解析后数据 + 原始响应"的 Promise 子类)。普通await时只解包出data,而调用.withRawResponse()可同时拿到两者,无需额外请求。
6.7 运行时兼容性(Runtime Compatibility)
SDK 基于标准的 fetch API 实现,不依赖 Node.js 专属能力(browser字段中显式禁用了fs、os、path、stream等 Node 模块,见 package.json),因此支持以下运行时:
- Node.js 18+
- Vercel(Serverless 函数)
- Cloudflare Workers(Edge Runtime)
- Deno v1.25+
- Bun 1.0+
- React Native
6.8 自定义 fetch 客户端(Customizing Fetch Client)
如果在不受支持的运行环境中使用,SDK 提供了"打破玻璃"的逃生通道:通过fetcher选项注入自定义的 HTTP 客户端 / fetch 函数:
import { SkyvernClient } from "@skyvern/client"; const client = new SkyvernClient({ ... fetcher: // provide your implementation here });SDK 内部默认的 fetch 获取逻辑见 src/core/fetcher/getFetchFn.ts,直接返回全局fetch;替换后即可适配代理、签名、自定义传输层等特殊需求。
6.9 环境与端点配置
除了 README 主文档外,结合源码 src/environments.ts 可以补充一个实用的配置点——SDK 预置了三个环境常量:
| 环境常量 | 默认地址 | 适用场景 |
|---|---|---|
SkyvernEnvironment.Cloud | https://api.skyvern.com | 官方云服务(默认) |
SkyvernEnvironment.Staging | https://api-staging.skyvern.com | 预发布环境 |
SkyvernEnvironment.Local | http://localhost:8000 | 本地自托管后端 |
可在构造客户端时通过environment指定:
import { SkyvernClient, SkyvernEnvironment } from "@skyvern/client"; const client = new SkyvernClient({ apiKey: "YOUR_API_KEY", environment: SkyvernEnvironment.Local, // 连接本地 Skyvern 服务 });BaseClientOptions还支持baseUrl选项,优先级高于environment,用于对接任意自定义网关地址(见 BaseClient.ts)。在 Client.ts 的 URL 拼接逻辑中,优先级顺序为baseUrl→environment→ 默认云地址。这与仓库后端skyvern/forge提供的v1/run/tasks、v1/run/agents等路由(见 agent_protocol.py)一一对应。
七、SDK 内部实现原理
理解 SDK 的请求管道有助于排查问题。以runTask为例,一次调用的完整链路为:
- 合并请求头:SDK 默认头(含 API Key、SDK 标识)→ 方法级特有头(如
x-user-agent)→ 请求级自定义headers; - 组装请求:
core.fetcher接收 URL、HTTP 方法、headers、contentType、queryParameters、body 等参数(见 Client.ts); - 发起请求:通过
getFetchFn()获取 fetch 实现并执行; - 重试判断:
requestWithRetries依据 408/429/5XX 状态码与Retry-After、X-RateLimit-Reset头决定是否退避重试; - 响应处理:2xx 返回解析后的 body;非 2xx 依据状态码抛出对应的
SkyvernError子类。
SDK 的 fetcher 模块位于 src/core/fetcher,包含请求构造(makeRequest)、URL 创建(createRequestUrl)、错误响应解析(getErrorResponseBody)、二进制响应(BinaryResponse)等完整实现。仓库同时提供了一整套测试来验证这些行为:
- tests/wire:基于 mock 服务器的端到端(wire)测试,覆盖
agents、artifacts、schedules、scripts等资源; - tests/unit/fetcher:fetcher 单元测试;
- tests/custom.test.ts:自定义行为的集成测试;
- tests/mock-server:测试用的 mock 服务器基础设施(
MockServer、MockServerPool、mockEndpointBuilder等)。
八、参与贡献的注意事项
SDK 由代码生成器(Fern)程序化生成,这一点对贡献者有直接影响:直接修改本库的代码会在下一次生成发布时被覆盖。因此官方建议:
- 新增功能应先作为概念验证(Proof of Concept)提交 PR,但不会被原样合并;
- 更合适的路径是先开 issue 与维护者讨论,确认改动应落在生成代码侧;
- 对 README 文档的改进则始终欢迎直接提交 PR。
结语
@skyvern/client提供了从"一行代码跑通 AI 任务"到"精细控制重试、超时、中止与原始响应"的完整 TypeScript 访问层。结合本文介绍的源码实现(重试退避算法、HttpResponsePromise 机制、环境常量等),你可以在生产环境中自信地配置它,并在需要时通过自定义 fetcher 与 baseUrl 将其接入自托管的 Skyvern 后端。若想了解全部 API 方法签名,可直接查阅仓库内的 reference.md 与 src/api/types 类型定义。
【免费下载链接】skyvernAutomate browser based workflows with AI项目地址: https://gitcode.com/GitHub_Trending/sk/skyvern
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考