TypeScript SDK 快速开始
安装 System One TypeScript SDK,连接托管 API,选择模型并读取类型化决策。
本文介绍如何将服务端 TypeScript 应用连接到 System One 托管决策 API。你将安装 SDK,配置平台 API 密钥与目录中的模型,并把一条客服消息评估为负责团队、紧急程度分数和重复扣款概率。API 只返回决策,不会分派工单、发起退款或执行工具。
常见问题
Q: 如何开始使用 System One TypeScript SDK?
A: 安装 SDK,设置 API 密钥,选择如 Clef Flash 或 Jev 的模型,调用 Choice、Score 或 Noul,从托管 System One API 获取类型化决策。
Q: 新账号有免费积分吗?
A: 有。新账号注册即送 100 积分,积分永不过期。
SDK 配置与 API 计费是两回事
开源 TypeScript SDK 提供客户端、适配器和类型化结果。安装 SDK 不会创建托管账户,也不等于购买推理服务。调用托管决策 API 会按所选模型的当前价格使用 System One 账户积分。发送决策请求前,请查看价格与请求大小;SDK 安装方式不是计费套餐。
本文使用 System One 平台 API 密钥,而不是服务商密钥。如果要用 SDK 直连其他服务,请阅读 SDK 安装与服务商直连适配器:这些集成使用各自的凭据与计费。不要把服务商密钥填入 SYSTEM_ONE_API_KEY。
1. 创建 API 密钥并选择模型
登录 System One,完成邮箱验证,在控制台打开 API 密钥。创建命名密钥,并在显示完整密钥时复制保存。列表只显示前缀,之后无法取回完整密钥。将其保存在服务端,不要放入提示词、浏览器代码、日志或版本控制。
新账号注册即送 100 积分。请在控制台查看余额。创建更多密钥不会重复获得欢迎积分。
通过当前模型目录或 Playground 选择器选择模型。点击下拉框旁的 模型信息 按钮查看所选模型的价格与限制,复制准确的 name 并确认支持 Choice、Score 和 Noul。也可通过公开的 GET /v1/models 或 /zh-CN/models 获取目录。下方 YOUR_MODEL_ID 是占位符,不是受支持的别名。不要用 SDK 默认值或其他服务的模型 ID 代替选择。
2. 安装与配置
SDK 支持 Node.js 20+。以下命令使用 Node.js 22.18+,可以直接执行这些 .mts TypeScript 文件。
npm install @system-one-ai/core@0.8.0 @system-one-ai/adapter-system-one@0.7.0 @system-one-ai/transport-fetch@0.8.0本快速开始使用当前托管三个包:core 0.8.0、adapter-system-one 0.7.0、transport-fetch 0.8.0。各包独立发布,且都解析到 core@^0.8.0。systemOneAdapter 会编码 Clairic 的 extract()(含图片),仍不会编码 evaluate() 的图片。托管 Clef/Clef Flash/Clef Omni 的决策图片请使用标准 Fetch 示例。Clairic 抽取见 Clairic 抽取。
创建已排除在版本控制之外的本地 .env 文件:
SYSTEM_ONE_API_KEY=replace-with-your-platform-key
SYSTEM_ONE_BASE_URL=https://system-one.dev/v1
SYSTEM_ONE_MODEL=YOUR_MODEL_IDAPI 使用主站域名,不是文档站域名。API 密钥是你的 System One 平台凭据。操作键与 API 密钥不同:每次新的逻辑评估生成一个新的随机 UUID,不要把它作为共享环境配置。重试同一操作时保留相同的键和完整请求。
继续操作前,将 .env 中的 YOUR_MODEL_ID 替换为所选目录条目的准确 name。运行下方命令时,.env 和 decision.mts 应位于同一工作目录。System One 适配器以 https://system-one.dev/v1 为 base URL,将决策请求发送到 /v1/systemone;https://docs.system-one.dev 只提供文档,不接收 API 请求。配置其他 HTTP 客户端时,可查阅 HTTP API 认证与端点参考。
3. 发送第一个决策
示例将一条客服消息作为共享 state,并定义三个具名问题。choice() 声明可选团队,score() 声明有序的紧急程度标准,booleanQuestion() 询问概率,而不是下达一个真/假操作指令。问题设计方法见 Choice、Score 与 Noul 决策原语。
保存为 decision.mts:
import { createSystemOne, choice, score, booleanQuestion } from '@system-one-ai/core';
import { systemOneAdapter } from '@system-one-ai/adapter-system-one';
import { createFetchTransport } from '@system-one-ai/transport-fetch';
const apiKey = process.env.SYSTEM_ONE_API_KEY;
const baseURL = process.env.SYSTEM_ONE_BASE_URL;
const model = process.env.SYSTEM_ONE_MODEL;
if (!apiKey || !baseURL || !model || model === 'YOUR_MODEL_ID') {
throw new Error('Set the API key, base URL, and catalog model.');
}
const client = createSystemOne({
apiKey,
baseURL,
model,
adapter: systemOneAdapter,
transport: createFetchTransport(),
timeoutMs: 30_000,
maxRetries: 0,
});
const operation = {
idempotencyKey: crypto.randomUUID(),
request: {
model,
state: { message: '同一笔订单被扣款两次。' },
questions: {
team: choice('选择负责审核这条请求的团队。', {
billing: '付款、发票与退款',
support: '技术故障排查',
review: '需要更多上下文',
}),
urgency: score('按以下有序标准评估紧急程度。', [
'可以等待常规审核',
'需要及时回复',
'需要立即由人工处理',
]),
duplicate: booleanQuestion('消息是否反映了重复扣款?', {
true: '同一订单被扣款多次',
false: '没有反映重复扣款',
}),
},
},
};
const result = await client.evaluate(operation.request, {
headers: { 'Idempotency-Key': operation.idempotencyKey },
});
console.log({
team: result.answers.team.choice,
distribution: result.answers.team.probabilities,
urgency: result.answers.urgency.score,
duplicateProbability: result.answers.duplicate.probability,
inputTokens: result.usage.inputTokens,
model: result.model,
requestId: result.response.requestId,
});node --env-file=.env decision.mts每次运行脚本都会开始新的计费操作,即使输入完全相同。操作只保存在内存中;重新运行脚本不是对超时或崩溃的恢复。三个问题与完整请求大小会按照所选模型的当前单价影响费用。请先检查估算和余额;不承诺固定答案、费用或延迟。示例使用非 null state、显式 instructions、普通问题 ID、非 null criteria、三个 Choice 选项与三个 Score 档位。仍需检查所选模型的当前能力,不要假设未来所有模型都接受同一请求。
4. 理解结果
team.choice是已声明的选项名之一,保留字面量类型。- 三档标准下,
urgency.score可以是0到2之间的小数。 duplicate.probability是0到1的P(true),不是 JavaScript 布尔值。- 可选统计和 token 计数缺失时表示未知,不要替换为零。
Core 会对不同适配器的结果进行规范化。在线上协议中,booleanQuestion() 转为 type: 'noul',答案字段为 noul;core 则提供 type: 'boolean' 与 probability。类型化结果不是精确 HTTP 正文,也不提供全部响应头。连接本托管 API 时使用显式 HTTP adapter 与 Fetch transport;SDK 文档中的其他服务适配器属于独立集成。
读取类型化答案时,同时查看 result.model 以识别返回的模型,并保留请求 ID 供排查使用,不要记录凭据或敏感 state。类型正确不代表判断一定正确。是否分派工单、是否需要人工审核,仍由应用决定;将答案连接到实际操作前,请阅读智能体接入与执行边界。
第一个示例打印的是 SDK 元数据,不是扣费凭证。如果集成需要平台记账 ID、扣费积分或重放状态,请采用下方读取响应头的示例,不要为了检查第一次请求而再发起一次请求。每个示例都会创建自己的操作。
官方 TypeSafe 客户端与响应头
官方 @typesafe-ai/sdk 是另一种受支持的 HTTP 客户端,其构造参数、类型和结果封装不同。它的 base URL 是不带 /v1 的 API 根地址,因为它会自行追加 /v1/systemone。
npm install @typesafe-ai/sdk@0.6.0保存为 official-decision.mts,使用上方相同的 API 密钥、base URL 和所选模型。这个独立示例创建自己的新操作,提出一个非 null Noul 问题,不依赖 nullable 输入支持。
import { TypeSafeClient } from '@typesafe-ai/sdk';
const apiKey = process.env.SYSTEM_ONE_API_KEY;
const baseURL = process.env.SYSTEM_ONE_BASE_URL;
const model = process.env.SYSTEM_ONE_MODEL;
if (!apiKey || !baseURL || !model || model === 'YOUR_MODEL_ID') {
throw new Error('Set the API key, base URL, and catalog model.');
}
const client = new TypeSafeClient({
apiKey,
baseURL: baseURL.replace(/\/v1\/?$/, ''),
defaultModel: model,
timeout: 30_000,
retry: { maxRetries: 0 },
logLevel: 'off',
});
const operation = {
idempotencyKey: crypto.randomUUID(),
request: {
model,
state: { message: '同一笔订单被扣款两次。' },
questions: {
duplicate: {
type: 'noul' as const,
instructions: '消息是否反映了重复扣款?',
criteria: {
true: '同一订单被扣款多次',
false: '没有反映重复扣款',
},
},
},
},
};
const { data, response, requestId: typeSafeRequestId } = await client.systemOne(
operation.request,
{ headers: { 'Idempotency-Key': operation.idempotencyKey } },
).withResponse();
const reportedCredits = response.headers.get('X-System-One-Credits');
const credits = reportedCredits !== null && /^\d+$/.test(reportedCredits)
&& Number.isSafeInteger(Number(reportedCredits)) ? Number(reportedCredits) : undefined;
console.log({
duplicateProbability: data.answers.duplicate.noul,
model: data.model,
inputTokens: data.usage?.input_tokens,
platformRequestId: response.headers.get('X-Request-Id'),
upstreamRequestId: response.headers.get('X-Upstream-Request-Id'),
typeSafeRequestId,
credits,
replayed: response.headers.get('X-Idempotency-Replayed') === 'true',
});node --env-file=.env official-decision.mts每次运行都会开始另一次计费评估,包括输入完全相同的重复运行。它不是第一个请求的离线替代方式,也不能安全地跨重启恢复:这个操作同样只保存在内存中。
withResponse() 返回解析后的 data,以及正文已被读取的 Response。其中 requestId 来自 X-TypeSafe-Request-Id,平台记账使用 X-Request-Id。从 X-System-One-Credits 和 X-Idempotency-Replayed 读取扣费与重放信息。缺失的费用表示未知,不是零。正文中 billing 或 request_id 等字段不能覆盖这些响应头。成功重放在响应头中报告零扣费。
需要精确响应文本时,保留上方相同的 client 和 operation,用以下替代代码替换从 withResponse() 调用到其 console.log() 的整段代码;不要把它追加为第二次评估:
const response = await client.systemOne(operation.request, {
headers: { 'Idempotency-Key': operation.idempotencyKey },
}).asResponse();
const text = await response.text();
console.log(text);asResponse() 由你负责读取正文,不要再对同一个 promise 等待解析后的结果。两种方法遇到非 2xx 都会拒绝。 官方 APIError 提供 status、headers 和 body;应读取响应头进行稳定错误分类,而不是匹配任意错误文字。官方 models.list() 返回解包后的数组,原始 GET /v1/models 返回 { models }。
官方 0.6.0 的 TypeScript 契约允许 null state、省略或为 null 的 instructions,以及 null Noul criteria。Core 0.8.0 要求非 null state、显式 instructions,以及提供时不能为 null 的布尔 criteria。两种客户端的类型都不能覆盖所选模型的能力限制。官方 timeout 是每次尝试的时限,core timeoutMs 是整次评估的总预算。两个示例都关闭重试。保持浏览器密钥暴露选项关闭,避免开启会记录提交内容的调试日志。参阅官方 SDK 源码。
恢复中断请求
这些快速开始示例在发送前只创建一次操作,并且只保存在内存中。进程内重试时,复用同一 operation.idempotencyKey 和 operation.request,不要重新执行创建操作的代码。要在应用崩溃或重启后恢复,真实应用必须在第一次发送前,将完整操作持久保存到任务记录中,再加载该记录,而不是创建新 UUID 或重新构造请求。这些快速开始示例没有实现持久恢复。
结果未知时,在恢复窗口内保持相同的实际模型、state、questions、扩展、数字值和键。超时或取消不能证明没有扣费。不要静默更换模型,也不要直接用新 UUID 重新开始。有意对相同输入重新评估属于新操作,需要新键。所有 API 密钥共享账户范围的操作键命名空间;更换 API 凭据不会得到新的操作命名空间。
409 request_in_progress 表示应按 Retry-After 等待,并恢复同一请求。409 idempotency_failed 表示前次失败且已退款;明确决定再次尝试时,需要新键。保留时间、过期、冲突和扣费未确定时的规则见幂等与重试。
验证接入并排查配置问题
按以下清单检查,不要反复发送决策请求。安装依赖和检查配置不需要推理;经过认证的模型目录请求 可以检查访问权限与可用模型,不消耗决策积分。但它不能证明评估一定成功,也不能证明余额充足。
| 检查项 | 应查看或修正的内容 |
|---|---|
| 运行环境与依赖 | 文中的 .mts 命令使用 Node.js 22.18+,core 0.8.0/adapter-system-one 0.7.0/transport-fetch 0.8.0 保持配套。 |
| 缺少环境配置 | 在包含 .env 和脚本的目录中运行命令,并替换密钥与模型占位符。密钥只保留在服务端,不要写入日志。 |
| 认证失败 | 使用有效的 System One API 密钥,不是服务商密钥或浏览器会话。在控制台检查密钥状态,寻求支持时不要发送密钥值。 |
| 端点错误或返回 HTML | Core 适配器使用 https://system-one.dev/v1,不是文档站地址。TypeSafe 官方客户端使用不带 /v1 的根地址,如上方示例所示。 |
| 模型或请求被拒绝 | 复制当前目录中的准确 name,检查支持的问题类型和请求限制。保留三个问题示例的纯文本形式。 |
| 已收到类型化结果 | 检查具名答案、返回的模型和可用的用量元数据。缺失的可选值仍表示未知;概率不等于执行操作的指令。 |
| 需要核对扣费 | 从可读取响应头的集成中获取 X-Request-Id、X-System-One-Credits 和 X-Idempotency-Replayed,再与控制台活动核对。Token 计数和 X-TypeSafe-Request-Id 不能替代平台记账元数据。 |
| 超时、请求中断或 API 错误 | 不要重新运行快速开始脚本来恢复。保留原操作,遵循幂等与重试规则,并根据稳定 API 错误参考处理,不要根据错误文字猜测。 |
查看当前价格与余额后,再决定是否发送第一次真实决策请求。完成配置不代表已经完成计费评估;选择发送后,应检查实际响应和账户活动。
可选:不写代码体验 Playground
登录后打开 Playground。它使用浏览器会话,不需要 API 密钥或 SDK。选择模型,点击下拉框旁的 模型信息 按钮查看价格与限制,然后加载客户支持示例。State 是上下文;Questions 说明要判断什么及可选结果。检查预计积分费用后,可以保持示例原样运行。
这仍是真实评估。查看答案、可选分布、扣费、实际耗时和请求 ID,再到控制台检查近期活动。缺失统计保持未知。如果连接失败,不要反复点击运行,因为另一次运行可能独立计费。先检查用量;需要帮助时,将请求 ID 发给 support@system-one.dev,不要提供密钥或登录验证码。