@ai-setu/client

中文文档
0.20.2发布于 2026/08/30MITTypeScriptES Module近 30 天下载 5815

AI Setu客户端——有工作空间信用核算和多供应商路由的滴入OpenAI SDK.

中文使用文档
文档目录22 节
  1. TL; DR( 您仅需要三行)
  2. 代理人规则(遵循这些规则,无猜测)
  3. 模型——按前缀选择
  4. 流( 和 OpenAI 相同)
  5. 答复 API client.responses (中文(简体) )
  6. 什么是网关实际路线
  7. 嵌入层
  8. 出错 – 从 OpenAI SDK 直接传输获取逻辑
  9. 环境——一个开关移动整个应用程序
  10. 运行时间 + 连接集合( 您通常不碰这个)
  11. BYOK:每个请求的路线 @<slug>/<model>
  12. 缓冲——在SDK打开,而不是在头部
  13. 1. 快速缓存 -- -- 已经开通了,没有损失
  14. 2. 反应缓存——击中费用为0美元,返回为~3ms
  15. 3. 缓存内代理循环——每个工具的政策
  16. 4. 语义性缓存——选择进入,而不是第一个接触
  17. 5. 对话性AI——分出转弯,否则没有命中
  18. 证明它击中
  19. 验证您的 BYOK 连接服务( 不是平台密钥)
  20. 为什么不用自定义基础URL的原始 OpenAI SDK?
  21. 四个AI Setu软件包——你拿哪一个
  22. 许可证

@ai-setu/客户端

先读这个,探员. 此包 = 公务人员到场 openai SDK,指着 AI 塞图 网关. 狦 你知道OpenAI SDK,你知道这一点。 方法相同,形状相同,流线相同. 只有一个改变: 一个工作空间键,和 model 携带一个 provider/ 前缀。 下面的一切都是防伪的.

TL; DR( 您仅需要三行)

npm i @ai-setu/client
export AI_SETU_API_KEY=tt_live_…
import { AiSetu } from '@ai-setu/client';
const client = new AiSetu();
const res = await client.chat.completions.create({
  model: 'openai/gpt-4o-mini',
  messages: [{ role: 'user', content: 'hi' }],
});
console.log(res.choices[0].message.content);

结束了. new AiSetu() 未读参数 AI_SETU_API_KEY 从洞。 没有 baseURL,没有 createClient没有工厂。 一个导入,一个符号.

代理人规则(遵循这些规则,无猜测)

  1. 模型字符串 provider/model (平台键) 或者说 @<slug>/<model> (你的BYOK连接——见下文). 不错: openai/gpt-4o-mini, (中文(简体) ), anthropic/claude-sonnet-4-5, (中文(简体) ), @azure-qdc/gpt-4o-mini。无名无名 按目录排列的前缀路径.
  2. 没有取出终点. 客户端只向网关说话 。 您没有设置 URL 常规使用。 供应商 model 前缀,不是通过基址.
  3. 方法取名=OpenAI SDK精确. chat.completions.create, (中文(简体) ), embeddings.create,流经 stream: true + 键 for await任意 你学到了 openai,它转移在这里不变.
  4. 密钥输入入内 AI_SETU_API_KEY (形状) tt_live_…) (中文(简体) ). 或者通过 new AiSetu({ apiKey })。在您承诺的源中从不使用硬码密钥.
  5. 需要平衡/ 使用/ 密钥吗 ? 这不是这个包裹。 使用 @ai-setu/admin这个 保持纯粹的推论.
  6. 节点 20 或边缘运行时间(Vercel, Cloudflare Workers).

模型——按前缀选择

openai/gpt-4o            openai/gpt-4o-mini       openai/text-embedding-3-small
anthropic/claude-sonnet-4-5                       anthropic/claude-haiku-4-5
bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0   (BYOK — your AWS account)

流( 和 OpenAI 相同)

const stream = await client.chat.completions.create({
  model: 'anthropic/claude-sonnet-4-5',
  messages: [{ role: 'user', content: 'Write me a haiku.' }],
  stream: true,
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}

答复 APIclient.responses(中文(简体) )

和您已经知道的一样的 SDK 方法 —— 它现在到达了网关 /v1/responses。 。 。 .

const r = await client.responses.create({
  model: 'openai/gpt-4o-mini',
  instructions: 'You are a concise support assistant.',
  input: [{ role: 'user', content: 'do you have anything in a darker fabric' }],
  max_output_tokens: 400,
});

两个规则,都很容易绊倒:

  1. 只有OpenAI家庭模式. openai, (中文(简体) ), bedrock-mantle, (中文(简体) ), groq, (中文(简体) ), xai, (中文(简体) ), deepseek, (中文(简体) ), mistral. Anthropic、双子座、Bedrock和Vertex没有反应 表面——它们以明显的出错被关闭,没有无声回落.
  2. 解释咒语每个表面不同. 给 reasoning: { effort: 'none' }。 。 。 . 打开 chat.completions 这个 reasoning_effort: 'none'每个人拒绝对方.

用法又以反应的形式出现—— usage.input_tokens 编号 : output_tokens,缓存计数器 usage.input_tokens_details - 不是说 聊天形状. promptCacheStats 读两个,所以不需要分行.

语义学潜入 不适用这条路线. 它和每个工具缓存策略读取 messages反应机构无法携带 精确的缓冲,快速缓冲, 预算,利率限制所有正常工作。 需要语义学吗? 使用 chat.completions。 。 。 .

什么是网关实际路线

AiSetu 扩展 openai SDK,所以你的编辑器 显示OpenAI的方法. 继承与路由不同:

方法状态
chat.completions已服务
responses(开放AI-家庭)
embeddings已服务
files, (中文(简体) ), batches404 (韩语) 无路线

嵌入层

const e = await client.embeddings.create({
  model: 'openai/text-embedding-3-small',
  input: 'hello world',
});

出错 – 从 OpenAI SDK 直接传输获取逻辑

使用类型守护, 不 instanceof 在子类。 理由: openai SDK 制作 APIError 从它的管子内, 所以亚类漂移每一个释放. 警卫将类型缩小到 APIError - 你还在得到 err.code, (中文(简体) ), err.status, (中文(简体) ), err.requestID。 。 。 .

import {
  AuthenticationError,
  RateLimitError,
  isInsufficientCreditsError,
  getInsufficientCreditsDetails,
  isProviderError,
} from '@ai-setu/client';

try {
  await client.chat.completions.create({
    /* … */
  });
} catch (err) {
  if (err instanceof AuthenticationError) {
    /* bad key */
  } else if (err instanceof RateLimitError) {
    /* slow down */
  } else if (isInsufficientCreditsError(err)) {
    const { balanceMicros, topupUrl } = getInsufficientCreditsDetails(err);
    console.error(`Out of credits (balance ${balanceMicros} micros). Top up: ${topupUrl}`);
  } else if (isProviderError(err)) {
    /* upstream provider broke */
  }
}

环境——一个开关移动整个应用程序

默认=生产(gateway.aisetu.ai) (中文(简体) ). 指向另一个网关(例如a) 由 URL 完全覆盖 :

export AI_SETU_BASE_URL=https://gateway.your-deployment.example.com

优先( 第一局胜出):

  1. new AiSetu({ baseUrl }) ——明细分明
  2. AI_SETU_BASE_URL ——完整 URL 覆盖(自主机 / 在-prem)
  3. 生产默认

(Base 总是正常化以结束于 /v1. ) (中文(简体) )

运行时间 + 连接集合( 您通常不碰这个)

  • 节点 20 ——全流程保持活性 undici.Agent 返回每个 AiSetu. 序列调用再利用 TCP 连接(~5ms p50 vs ~30ms sold).
  • 边缘( Cloudflare 工人/ Vercel) ——倒回站台取回,其中 已经游泳了. undici 是可选的dep,边缘捆绑者跳过它.

池默认值 : connections 32, (中文(简体) ), allowH2 true, (中文(简体) ), keepAliveTimeout 30s, (中文(简体) ), keepAliveMaxTimeout 90s (匹配网关闲置), bodyTimeout 0 (无盖-) 长思维模式流可以运行几分钟; 取消 AbortSignal) (中文(简体) ).

只有在必须时才能覆盖游泳池:

import { Agent, ProxyAgent } from 'undici';
import { AiSetu } from '@ai-setu/client';

// Corporate proxy:
const proxied = new AiSetu({ dispatcher: new ProxyAgent({ uri: 'http://proxy:8080' }) });

// Self-signed CA (baseUrl normalise to …/v1):
const onPrem = new AiSetu({
  baseUrl: 'https://gateway.internal.example',
  dispatcher: new Agent({ connect: { ca: fs.readFileSync('ca.pem') } }),
});

// No pooling at all (platform fetch on Node):
const unpooled = new AiSetu({ dispatcher: null });

全过程互换( 在任何 AiSetu ),或与 兄长SDKs:

import { setSharedDispatcher, getSharedDispatcher } from '@ai-setu/client';
import { Agent } from 'undici';
import { AiSetuAdmin } from '@ai-setu/admin';

setSharedDispatcher(new Agent({ connections: 64, allowH2: true }));
const admin = new AiSetuAdmin({ dispatcher: getSharedDispatcher() });

BYOK:每个请求的路线 @<slug>/<model>

您的提供者密钥居住于 连接 (每个都有一个 slug) (中文(简体) ). 挑一个 百分比 请求 在模型字符串中—— @<slug>/<model> ——和出入口路线 通过连接的钥匙。 一个客户端, 混合连接自由, 没有再动. 领先 @ 标记一发子弹(因此一发子弹可以等于提供者名称); 未知或 超范围子弹 未关闭 (4xx),从未出现无声平台键倒置.

const c = new AiSetu();

await c.chat.completions.create({
  model: '@azure-qdc/gpt-5.4-mini', // route via the Connection slug "azure-qdc"
  messages: [{ role: 'user', content: 'hi' }],
});

await c.chat.completions.create({
  model: 'openai/gpt-4o-mini', // platform key (no @slug)
  messages: [{ role: 'user', content: 'hi' }],
});

Pin 1 连接整个客户端 connection 选项 @ 可选 :

const c = new AiSetu({ connection: '@azure-qdc' });

缓冲——在SDK打开,而不是在头部

最便宜的储蓄 首先,顺序值得收养.

1. 快速缓存 -- -- 已经开通了,没有损失

提供者跳过重新预填您的提示( 系统) 前缀 即时,工具定义,定点对话),并打折扣这些符号. 模型 仍在运行,输出为 还是新鲜的 ——无停滞风险 都说吧 没有东西可以打开。 大部分代理工作量都占一半 忽略了这种方式而不注意:

import { promptCacheStats } from '@ai-setu/client';

const res = await c.chat.completions.create({ model, messages });
promptCacheStats(res);
// { inputTokens: 1000, cachedTokens: 3000, writeTokens: 0, ratio: 0.75 }

ratio 是避免了全价预填的提示份额。 读取 无论是OpenAI和Anthropic的用法形状, 所以你不分支提供商. 保持您的稳定部分迅速 首发且不变 - 时间戳或 系统顶部的会话 id 提示销毁每个呼叫的前缀 .

2. 反应缓存——击中费用为0美元,返回为~3ms

默认: 网关缓存当 temperature 未设定或 0键入 确切请求体,600秒。 设置全客户端默认值, 然后覆盖 按请求:

const c = new AiSetu({
  cache: {
    policy: 'support-faq', // TTL + stale window live in the console, not in code
    namespace: 'tenant-42', // keep one end-user's entries off another's
  },
});

await c.chat.completions.create(
  { model: '@mantle/zai.glm-4.7-flash', messages },
  c.withCache({ ttl: '2h', tags: ['sku:123'] }),
);
选项它能解决什么
policy暴发流量在暴发之间终止——为每个呼叫站点设定TTL + stale-while-validate一次
ttl一次性期限: 3600, (中文(简体) ), '30s', (中文(简体) ), '10m', (中文(简体) ), '2h', (中文(简体) ), '1d'政策上限
namespace每个终端用户/每个环境分区
tags['sku:123'] ——当数据变化而不是等待 TTL 时重新验证
force缓存 a temperature > 0 调用无论如何( 分类、 提取、 路由)
modeoff (通过) no-store (阅读,从不写) force-refresh {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢 semantic

A 类 政策加标签 击败长空 TTL : 标记让你持有一个答案 数小时后 数据发生变化时仍会下降.

坏值 掷出 - 否则,将删除打字的政策名称 关上门 把你藏起来 默默无动于衷.

3. 缓存内代理循环——每个工具的政策

代理转弯是最昂贵的交通 和最少的可缓存,因为 工具结果嵌入活数据。 你不能决定每个请求 —— 收到的文本 是任意的。 不过你 对 每一个工具在添加时都会做什么 所以 政策与工具:

import { withToolCache } from '@ai-setu/client';

const tools = [
  withToolCache(getCatalog, { policy: 'catalog', tags: ['catalog', 'sku:{sku}'] }),
  withToolCache(getBrandStory, { policy: 'brand-voice' }),
  withToolCache(addToCart, { cache: false }),
  withToolCache(checkout, { cache: false }),
];
声明含义
{ cache: false }从不缓存引用此工具的转折
{ policy: 'catalog' }工作空间政策的数字—— 首选
{ ttl: '60s', swr: '10m' }内入, 如果尚未配置策略
{ tags: ['sku:{sku}'] }从该呼吁中推断出来 – sku:9f2

转弯可缓存性来源于它实际所引用的工具. 任何工具 说 cache: false 绕过整个转弯; TTL 和 SWR 取下 最低 因此,一个转动 触及目录(60年代)和品牌 故事(24h)只和目录一样新鲜. 未经宣布的工具 阻挡什么.

旁道是可见的而不是沉默的:

client.lastCache;
// { status: 'bypass', hit: false, semantic: false, bypassedByTool: 'addToCart' }

4. 语义性缓存——选择进入,而不是第一个接触

mode: 'semantic' 匹配参数,而不仅仅是字节相同的体。 真实 fAQ 形状流量的值——但它是 没有 这是免费的 没有 页:1 低命中率默认修正 :

  • 所有准确的..错过 支付嵌入回程( 今天~ 342ms) 提供商甚至被调用。 对于一个已经需要~600毫米的工作量 在共同的道路上,这是一个很大的延迟.
  • 匹配质量为英通. 印地语和阿拉伯语家庭语句匹配 目前还很薄弱, Hinglish midle —— 代码切换流量可能会错过真实 语句和意向一致.

在回答短,重复,英语和耐耐性的地方使用. 提升 threshold (单位:千美元)0– 说吧 –1默认值 0.8如果近乎失踪的人正在得到服务. 急急急急急急急急急急急.

5. 对话性AI——分出转弯,否则没有命中

如果你建立语音或聊天代理,这是决定你点击率的部分.

一个用户的言语通常会传到几个供应商的电话中,而不是 同样可缓存。 答复是针对个人的,每个客户每个回合都有独特的答复。 这个 背后的意图分类 完全取决于客户说的话. 要求一个提示同时完成,整个转弯继承了回复的缓存性———— 这是零。 这句话是调和的门槛;这是分解.

将可分享的部分作为自己的呼号:

import { AiSetu, normalizeUtterance, sharedCacheOptions } from '@ai-setu/client';

// Intent classification — shared by every customer who ever says it.
const classifier = new AiSetu().withCache(sharedCacheOptions({ policy: 'intent' }));
await classifier.chat.completions.create({
  model,
  temperature: 0,
  messages: [
    { role: 'system', content: INTENT_LABELS }, // frozen — interpolate nothing
    { role: 'user', content: normalizeUtterance(transcript) },
  ],
});

// FAQ answer — paraphrase-matched, dropped when the article changes.
const faq = new AiSetu().withCache(
  sharedCacheOptions({ mode: 'semantic', policy: 'faq', tags: ['kb:returns-policy'] }),
);

normalizeUtterance 比看起来更重要的事情: 确切的缓存 Cononicalises JSON 但绝不重写信件文本,所以 "Cancel my order" 财务报告和审定财务报表 "cancel my order" 为: 两个条目.

sharedCacheOptions 套装 force (分类器通常运行于 temperature > 0和 如果你通过一个 namespace这是故意的——一个命名空间分隔 键盘空间,所以每个客户一个在可分享的呼叫中,给您一个零命中率,没有 任何地方都出错。 这是这一表面上最昂贵的错误.

最高杠杆的把戏根本不需要SDK 缓存非人性的身体,相接 名字写在后面. 如果模型不需要解释 结束 个人 字段,请不要在提示中出现.

完整的图案,包括能保持快速缓存的快速形状 转弯 : docs.aisetu.ai/概念/谈判-隐藏。 。 。 .

证明它击中

const c = new AiSetu({
  onCache: (info) => metrics.increment(info.hit ? 'cache.hit' : 'cache.miss'),
});

await c.chat.completions.create({ model, messages });
c.lastCache;
// { status: 'hit', hit: true, semantic: false, ageSeconds: 42 }

CacheInfo数字 :

字段含义
statushit | semantic-hit | stale | miss | refresh
hittrue 当没有供应商呼叫时(hit, (中文(简体) ), semantic-hit, (中文(简体) ), stale(中文(简体) )
semantic一个相似的匹配服务它
ageSeconds服务年龄
similarity余弦相似度, 仅按语义
bypassedByTool其声明阻碍开关的工具 bypass 仅限

lastCache 留下来 undefined 当请求完全不能缓存时—— a temperature > 0 调用无 force,或 mode: 'off'这是信号 没有任何东西被抬起头来 从一个 miss。 。 。 .

SDK无法解决的杀手: 用同样的方式拼写模型 每次都这样. zai.glm-4.7-flash 财务报告和审定财务报表 @mantle/zai.glm-4.7-flash 不一样 缓存分区 .

验证您的 BYOK 连接服务( 不是平台密钥)

每个响应的网关邮票属性信头; SDK 解析它们 因此,你可以确认——根据请求——你自己的钥匙已经送达:

const c = new AiSetu({
  onRouting: (r) => {
    if (!r.byok) throw new Error('expected BYOK, got platform key — bad slug?');
  },
});

await c.chat.completions.create({
  model: '@azure-qdc/gpt-5.4-mini',
  messages: [{ role: 'user', content: 'hi' }],
});

// Or read synchronously after any call:
c.lastRouting;
// { provider: 'openai', byok: true,
//   credentialId: '…uuid…', connectionSlug: 'azure-qdc' }

RoutingInfo数字 :

字段含义
provider服务供应商(openai, (中文(简体) ), anthropic, (...) (中文(简体) )
byoktrue = 钥匙已送达; false = 平台密钥(或未知弹出)
credentialId服务证书(仅BYOK)
connectionSlug服务过的连接语句( 只有 BYOK)
credentialLabel已贬值 的别名 connectionSlug (相同价值)

回调是最佳效果——内部的一个例外 onRouting 被吞下这样 错听者能断取相. 信头缺失( 门口长于此) - 没有回话, lastRouting 留下来 undefined证书编号/子弹 并不是秘密 —— 您拥有连接 .

遗产 : 页:1 workspaceCredential 选项+ label/model 模式字符串 已贬值. workspaceCredential 仍在工作(别名: connection; 计 数 赤线 label/model 窗体显示 没有 ——使用 @<slug>/<model>。 。 。 .

为什么不用自定义基础URL的原始 OpenAI SDK?

你当然可以. AiSetu 只为你做,并添加: env-var-第一构造 (单位:千美元)new AiSetu() 没有参数,保持静电池 调节到网关,和每个请求 BYOK 路线@<slug>/<model> / 该 connection 选项)。 不关心这些? 点 openai 在网关你自己.

四个AI Setu软件包——你拿哪一个

软件包用它当
@ai-setu/client运行时代理 / app 调用推论。 滴入为 openai。 。 。 .
@ai-setu/admin脚本 / CI / 构建器代理 在 TypeScript 中运行控制平面操作.
@ai-setu/cli同样的控制飞机行动 外壳。 。 。 .
@ai-setu/mcp构建器代理 (Claude Code, Cursor) 开机 + ops 对话.

全员运行本 = 页:1。 。 。 .

许可证

麻省理工学院.

版本与发布记录

@ai-setu/client 共发布 11 个版本,首次发布于 2026/06/18;过去 12 个月发布了 11 个版本。

版本发布日期距今
0.20.2latest2026/08/302 个月前
0.20.12026/08/292 个月前
0.20.02026/08/282 个月前
0.19.02026/08/232 个月前
0.17.02026/08/112 个月前
0.16.12026/06/254 个月前

关于 @ai-setu/client 的常见问题

@ai-setu/client 是什么?

AI Setu客户端——有工作空间信用核算和多供应商路由的滴入OpenAI SDK.

如何安装 @ai-setu/client?

在项目目录运行 npm install @ai-setu/client,或使用 pnpm add / yarn add / bun add。

@ai-setu/client 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@ai-setu/client 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@ai-setu/client 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@ai-setu/client 可以商用吗?

@ai-setu/client 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@ai-setu/client 的下载量有多少?

根据 npm 官方下载统计,@ai-setu/client 在 2026/10/05 – 2026/11/03 这 30 天内被下载 5,815 次,日均约 194 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@ai-setu/client 还在维护吗?

最新版本 0.20.2 发布于 2026/08/30(2 个月前);至今共发布 11 个版本,其中过去 12 个月发布了 11 个;首次发布于 2026/06/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。