System One
System One
开发文档SDK 文档模型API 参考打开 System One文档目录

SDK 与 API

TypeScript SDK 快速开始

构建决策应用

选择模型决策原语智能体集成:类型化工具路由面向编程智能体的 System One

用量与数据

计费与积分隐私与零数据保留
连接托管 API

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_ID

API 使用主站域名,不是文档站域名。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 密钥,不是服务商密钥或浏览器会话。在控制台检查密钥状态,寻求支持时不要发送密钥值。
端点错误或返回 HTMLCore 适配器使用 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,不要提供密钥或登录验证码。

下一步

  • SDK 指南与旧包迁移。
  • 决策原语、API 参考与模型选择。
  • 智能体接入、版本说明与数据处理。

用 Clairic 抽取类型化字段

用 Clairic 调用 extract({ state, fields }):字段类型、图像说明与托管 HTTP 示例。

API 参考

System One API 的 HTTP 决策、鉴权、响应约定,以及 Choice / Score / 是否判断的 TypeScript 示例。

本页内容

常见问题SDK 配置与 API 计费是两回事1. 创建 API 密钥并选择模型2. 安装与配置3. 发送第一个决策4. 理解结果官方 TypeSafe 客户端与响应头恢复中断请求验证接入并排查配置问题可选:不写代码体验 Playground下一步