首页
/ LobeHub 官方 TypeScript SDK 全解析:@lobehub/sdk 的资源化 API 客户端架构与工程实践

LobeHub 官方 TypeScript SDK 全解析:@lobehub/sdk 的资源化 API 客户端架构与工程实践

2026-09-07 23:45:09作者:郦嵘贵Just

@lobehub/sdk 是 LobeHub 面向其 REST API 的官方 TypeScript SDK,它以 OpenAPI 规范为唯一事实来源,通过代码生成器产出"资源风格"(resource-style)的类型安全客户端。本篇文章将带你完整掌握它的安装方式、资源方法命名规则、自定义部署接入、SSE 流式响应的读取技巧,并结合仓库源码与测试用例,剖析其从规范到生成的工程链路、零依赖 HTTP 运行时设计以及自动化发布流程。读完你既能在自己项目中快速接入 LobeHub API,也能复用它"OpenAPI 驱动 SDK"的可维护工程范式。

本文基于仓库 packages/sdk/README.md 并结合 packages/sdk 下源码展开,仓库为只读,以下所有内容均为查看与使用方式。

一、SDK 概览:一份 OpenAPI 规范驱动的资源化客户端

@lobehub/sdk 的全部类型与接口并非手工维护,而是由位于 packages/openapi/openapi.yml 的 OpenAPI 3 规范经 @hey-api/openapi-ts 代码生成而来,配置见 packages/sdk/openapi-ts.config.ts。规范中的服务地址(servers)明确指向 https://app.lobehub.com(见 packages/openapi/openapi.yml),所有路径均以 /api/v1/... 为前缀。

SDK 的核心设计目标有两个:

  • 全类型化:每一个路径、参数、请求体与响应类型都直接来自 openapi.yml,编译期即可校验请求是否合法;
  • 零运行时依赖:HTTP 运行时被打包进 SDK 内部(inlined),不额外引入第三方请求库。

生成的代码被提交进仓库(packages/sdk/src/generated/),因此发布到 npm 的包不依赖"安装时再生成"这一步骤,用户拿到即可运行。

当前包版本为 1.0.0,标记为 private: true(见 packages/sdk/package.json),仅在自动化发布流程中由工作流临时改写为公开可发布形态,具体见后文"发布"章节。

二、安装

npm install @lobehub/sdk

如使用 pnpm 等包管理器,等价命令为 pnpm add @lobehub/sdk。该包导出 ESM 产物并携带完整声明文件,发布形态在 .github/workflows/release-sdk.yml 中被改写为 main: ./dist/index.mjstypes: ./dist/index.d.mts(详见仓库发布脚本处理逻辑)。

三、快速上手:创建客户端并调用首个接口

SDK 的入口是 createLobeHub() 工厂函数,它接收一个配置对象并返回根实例 LobeHub

import { createLobeHub } from '@lobehub/sdk';

const lobehub = createLobeHub({
  // LobeHub API Key(形如 `sk-lh-...`)或一个 OIDC JWT
  apiKey: process.env.LOBEHUB_API_KEY!,
});

const me = await lobehub.users.me();                                    // 当前登录用户
const { data, error } = await lobehub.agents.list();                    // 拉取 Agent 列表
const agent = await lobehub.agents.get({ path: { id: 'agt_...' } });    // 按 ID 获取 Agent

await lobehub.agentGroups.create({ body: { name: 'My group' } });       // 创建分组
await lobehub.files.uploadBatch({ body: { files: [/* … */] } });        // 批量上传文件

1. createLobeHub 的配置项与认证实现

工厂函数定义在 packages/sdk/src/index.ts,其签名如下:

配置项 类型 说明
apiKey string(必填) LobeHub API Key(sk-lh-... 前缀)或 OIDC JWT,用于 Bearer 认证
baseURL string(可选) API 服务地址,默认指向 DEFAULT_BASE_URL = 'https://app.lobehub.com'
其余配置 继承自 Config 任何底层 fetch 客户端支持的可选项,如自定义 fetchheaders

从源码实现看,apiKey 会被包装进认证回调 auth: () => apiKey,从而在每次请求中以 HTTP Authorization: Bearer <apiKey> 头发送。生成代码中每个接口都声明了 security: [{ scheme: 'bearer', type: 'http' }](例如 sdk.gen.tsHealth.check 的定义),与 createLobeHub 的默认 Bearer 行为一一对应。

2. 工厂函数做了什么

packages/sdk/src/index.ts 的核心逻辑很简洁:

export const createLobeHub = (options: LobeHubOptions): LobeHub => {
  const { apiKey, baseURL = DEFAULT_BASE_URL, ...clientConfig } = options;
  const config: Config = { ...clientConfig, auth: () => apiKey, baseUrl: baseURL };
  return new LobeHub({ client: createClient(createConfig(config)) });
};

即:合并配置 → 绑定认证回调与默认域名 → 通过 createClient(createConfig(...)) 构造底层 fetch 客户端 → 注入到 LobeHub 根实例。

LobeHub 根实例(packages/sdk/src/generated/sdk.gen.ts 起)内部以懒加载 getter 按需实例化每一个资源组(如 agentsfiles),并把同一个 client 注入所有子资源,保证它们共享同一套配置、认证与请求拦截链。由于每个 SDK 实例都持有独立客户端,多个 createLobeHub 实例之间互不串扰——这一点在 packages/sdk/src/index.test.tskeeps client instances isolated between SDK instances 用例中有直接验证。

四、资源与方法的命名规则

SDK 的"资源风格"体现在:每个 API 的顶级路径段(segment)对应根实例上的一个资源对象,方法名遵循一套机械的、可推导的规则。规则定义在 packages/sdk/openapi-ts.config.ts,其注释给出了完整的推导逻辑:

HTTP 方法 + 路径形态 生成的默认方法名
GET 资源集合 list
GET 单资源 .../{id} get
POST 资源集合 create
PATCH / PUT 单资源 update
DELETE .../{id} delete
附加静态子路径段 按 PascalCase 追加(如 GET .../{id}/chunkslistChunksGET .../{id}/urlgetUrl

此外,针对"按机械规则生成的名称不够达意"的少数接口,配置中维护了一张显式覆盖表 METHOD_NAME_OVERRIDES(见 packages/sdk/openapi-ts.config.ts),举例:

原始路径 覆盖后的方法名
GET /api/v1/health health.check
GET /api/v1/users/me users.me
POST /api/v1/files/batches files.uploadBatch
POST /api/v1/files/queries files.query
POST /api/v1/files/{id}/parses files.parse
POST /api/v1/knowledge-bases/{id}/files/batch knowledgeBases.addFiles
DELETE /api/v1/knowledge-bases/{id}/files/batch knowledgeBases.removeFiles
POST /api/v1/knowledge-bases/{id}/files/move knowledgeBases.moveFiles
POST /api/v1/messages/replies messages.createReply
DELETE /api/v1/messages messages.deleteMany(注释说明:这是按所选 id 批量删除,语义并非"删除全部")

openapi-ts.config.ts 中的 nesting 函数将每个 operation 归组到其资源对象下:取路径第三段(去掉 /api/v1/ 前缀后的资源根)并转为 camelCase 作为资源名。

当前版本全部资源组

从根实例的 getter 集合(packages/sdk/src/generated/sdk.gen.ts)与生成的资源类可以确认,当前 SDK 共暴露以下资源对象(README 列出的基础集合之外,还包含从规范同步生成的管理类资源):

  • 基础业务:healthagentsagentGroupsfilesknowledgeBasesmessagesmessageTranslationstopicsmodelsproviderspermissionsrolesusers
  • 交互与评估:responseschatevalusage
  • 接入与密钥:apiKeysmcpServers

各资源的实际方法可在 packages/sdk/src/generated/sdk.gen.ts 中逐一核对。以 Files 为例,其方法包括 list / create(表单上传)/ get / update / delete / getUrl / parse / listChunks / createChunks / uploadBatch / query;以 Roles 为例,还包括权限子资源方法 listPermissions / updatePermissions / deletePermissionsUsers 同样包含角色管理子方法 listRoles / updateRoles / deleteRoles。在生成资源类中,能直接看到每个方法对应的真实 HTTP 语义,例如 files.create 使用 formDataBodySerializer'Content-Type': null(交由浏览器自动填充 multipart/form-data 边界)。

五、接入自定义部署与底层客户端配置

默认客户端指向 LobeHub 云服务 https://app.lobehub.com。若你自托管 LobeHub 或在本地点服务上联调,可通过 baseURL 将请求指向其他部署实例:

const lobehub = createLobeHub({
  apiKey: 'sk-lh-...',
  baseURL: 'http://localhost:3010',
});

由于 createLobeHub 接受底层客户端的全部可选配置(Config 类型),你还可以透传:

  • fetch:自定义 fetch 实现(单元测试即通过注入的 mock fetch 捕获请求断言,见 packages/sdk/src/index.test.ts);
  • headers:客户端级默认请求头(支持普通对象、Headers 实例与 [key, value] 元组数组等合法 HeadersInit 形态);
  • 其他与请求序列化、响应解析相关的底层选项。

仓库在客户端构建上做了一层重要的健壮性兜底:针对 @hey-api/openapi-ts 0.99 生成的 headers 处理在 HeadersInit 某些合法形态下会出错的问题,packages/sdk/scripts/generate-sdk.ts 在生成后自动重写两处代码:

  1. 客户端合并 headers 时,将元组数组先经由 new Headers() 归一化,避免 Object.entries[['X-Trace','1']] 变成数字键;
  2. 写操作方法把对象展开合并改写为 mergeMethodHeaders(...) 辅助函数,将各种 HeadersInit 形态都归一为普通对象,从而保证表单上传方法上的 'Content-Type': null 删除哨兵能存活到客户端最终合并阶段,正确移除客户端默认的 Content-Type: application/json

上述行为均有测试锁定:preserves per-call Headers instances and tuple arrays on write methodsnormalizes tuple-array headers at client level and on read methodsdrops a client-default Content-Type on form-data uploads(见 packages/sdk/src/index.test.ts)。

关于类型与错误处理

  • 原始规范中的全部类型(path / body / response 等)可从 @lobehub/sdk/types 子路径导入,映射文件为 packages/sdk/src/generated/types.gen.ts
  • 每个方法都接受可选的 ThrowOnError 泛型开关:默认为 false,此时调用返回 { data, error, response } 风格的 RequestResult,需要自行判断 error;可显式指定 { throwOnError: true } 让请求失败时直接抛错。

六、流式响应(SSE)

调用大模型相关的 responses.create 接口时,若在请求体中设置 stream: true,服务端将以 Server-Sent Events(SSE)的方式推送结果。默认情况下客户端会按 JSON 解析响应,要读取原始事件流,需要配合 parseAs: 'stream' 选项:

const { response } = await lobehub.responses.create({
  body: { input: '…', model: '…', stream: true },
  parseAs: 'stream',
});
for await (const chunk of response.body!) {
  // 逐块解码 SSE 数据
}

这样可以直接消费 response.body 的可读流。仓库为后续"一等公民"的强类型 SSE 方法预留了基础设施:packages/sdk/src/generated/core/serverSentEvents.gen.ts 中已包含事件流客户端的类型定义(如 onSseEventonSseErrorsseMaxRetryAttemptssseMaxRetryDelaysseDefaultRetryDelay 等),README 也明确指出:"具备规范响应 schema 的一等类型化 SSE 方法将在后续提供",即当前属于底层手工解码阶段。

七、面向维护者的开发流程

作为包维护者或希望二次开发 SDK 的贡献者,packages/sdk/README.md 提供了三个核心命令:

命令 作用
bun generate 基于 ../openapi/openapi.yml 重新生成 src/generated/(规范变更后执行;命名规则集中在 openapi-ts.config.ts
bun run build 通过 tsdown 构建 ESM 与 d.ts 声明到 dist/
bun run test 运行单元测试 + 生成产物漂移检查(drift check)

在仓库中对应实现为 packages/sdk/scripts/generate-sdk.tspackages/sdk/scripts/generate-sdk.test.ts。生成脚本支持两种模式:

  • bun scripts/generate-sdk.ts:清空 src/generated/ 后按 openapi-ts.config.ts 重新生成,再执行上文提到的 headers 重写修补;
  • bun scripts/generate-sdk.ts --check:在临时目录中重新生成一份输出,与仓库已提交的 src/generated/ 做逐字节比对,不一致即退出并提示 "Run bun generate in packages/sdk and commit the result"。

测试脚本 generate-sdk.test.ts 以子进程方式执行 --check,确保 API 路由变更时提交的生成产物不会"静默漂移"。

需要特别说明 CI 边界:这个包的漂移检查没有接入常规 PR 流水线,只在本机执行 bun run test 与发布工作流内运行(README 与测试注释均明确说明"not wired into PR CI")。对这类强规范的仓库而言,这是一条值得借鉴的取舍——把成本较高的全量比对放在发布前把关,而不是每次 PR 都执行。

八、自动化发布:canary 驱动的 npm 发布流水线

@lobehub/sdk 的发布完全由 GitHub Actions 工作流 .github/workflows/release-sdk.yml 自动化完成,无需人工干预 npm 版本号。核心机制如下:

  • 触发条件:向 canary 分支推送且改动涉及 packages/sdk/** 时自动触发;也提供手动 workflow_dispatch 入口;
  • 版本策略:以包内 package.json 的基础版本(当前为 1.0)拼接 UTC 时间戳,生成 1.0.<UTC timestamp> 作为发布版本,保证每次发布版本单调递增;
  • 质量闸门:流水线依次执行 bun scripts/generate-sdk.ts --check(产物漂移检查)、pnpm --filter @lobehub/sdk test(单元测试)、pnpm --filter @lobehub/sdk build(构建),三道关卡全部通过才进入发布;
  • 发布前准备:脚本将 privatedevDependenciesscripts 等字段移除,把 exports 中指向 ./src/*.ts 的入口改写为 ./dist/*.mjs(并生成对应 .d.mts 声明),写入 repositoryfiles: ['dist'] 后执行 npm publish --provenance --access public
  • 供应链安全:发布步骤申请了 id-token: write 权限并携带 --provenance,即 npm 包会附带可验证的来源证明(SLSA provenance)。

因此,向 canary 分支合入一次 SDK 改动后,规范的发布路径是:bun generate 重新生成并提交生成产物,推送即触发发布——工作流内的 --check 漂移检查正是为了守护最终发布物的正确性。

九、实践要点小结

  1. 默认即云端:不传 baseURL 时全部请求发往 https://app.lobehub.com,本地自托管务必显式传 baseURL
  2. 认证无感知apiKeycreateLobeHub 内自动成为 Bearer 头,也可直接传入 OIDC JWT;
  3. 方法与资源名可推导:绝大多数方法是 list/get/create/update/delete + PascalCase 子段 的机械产物,个别语义不直观的接口(如 files.uploadBatchknowledgeBases.addFilesmessages.deleteMany)可在 packages/sdk/openapi-ts.config.ts 的覆盖表中查到真名;
  4. 流式响应需手工解码responses.create + stream: true 需配 parseAs: 'stream' 读取 response.body,强类型 SSE 支持仍在路线图中;
  5. 类型即文档:全部请求/响应类型可从 @lobehub/sdk/types 导入,需要深挖字段时直接阅读 packages/sdk/src/generated/types.gen.ts,它是 OpenAPI 规范的可读投影。

如需了解某个接口的完整字段与取值,最权威的参照永远是上游规范文件 packages/openapi/openapi.yml,SDK 与其保持一致是发布流水线的硬性约束。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.74 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.63 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
518
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389