用 Clairic 抽取类型化字段
用 Clairic 调用 extract({ state, fields }):字段类型、图像说明与托管 HTTP 示例。
Clairic 是 System One 的抽取模型。它读取共享 state(要抽取的文本或结构化上下文)和一组类型化字段,为每个字段返回一个类型化的值。它不生成自由文本,也不回答 Choice、Score 或 Noul 问题。
extract({ state, fields }) 和 evaluate() 用的是同一个 SystemOne 客户端。不要把 fields 传给 evaluate(),也不要把 questions 传给 extract()。
公开模型名是 clairic,写法与 jev、clef 相同。请使用这个名称,或在目录列出时从 GET /v1/models 复制准确的 name。不要自己给模型名加前缀。
同一张发票任务可在登录后的发票抽取演示中试用。模型说明与积分费率见 Clairic 模型页。
常见问题
Q: How do I use the Clairic SDK?
A: 调用 extract({ state, fields }),用 Clairic 从智能体状态抽取类型化字段。可用 System One TypeScript SDK 或托管 HTTP API。
Q: Is Clairic the same as Choice?
A: No. Choice picks among options; Clairic extract returns structured fields you define. Both are part of System One.
安装
抽取需要 core 0.8.0、托管适配器 0.7.0 和 Fetch transport 0.8.0。这三个包都依赖 @system-one-ai/core@^0.8.0。
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.0systemOneAdapter 将抽取请求 POST 到 {baseURL}/systemone。适配器默认地址是 https://system-one.dev/v1,因此托管路径为 POST https://system-one.dev/v1/systemone,请求体带 fields。默认抽取模型是 clairic。
抽取一张发票
保存为 extract-invoice.mts,将 SYSTEM_ONE_API_KEY 设为 System One 平台密钥。每次运行都会创建一次新的计费操作。
import {
createSystemOne, defineFields, textField, numberField, dateField, listField, estimateField,
} 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;
if (!apiKey) throw new Error('Set SYSTEM_ONE_API_KEY.');
const client = createSystemOne({
adapter: systemOneAdapter,
transport: createFetchTransport(),
apiKey,
timeoutMs: 30_000,
maxRetries: 0,
});
const fields = defineFields({
invoice_number: textField({ instructions: '单据上印刷的发票号码。' }),
due_date: dateField({ instructions: '开票日期加上账期天数。' }),
total: numberField({ decimals: 2, instructions: '应付合计。' }),
contacts: listField({ items: 'text' }),
days_to_pay: estimateField({ min: 0, max: 120, step: 1 }),
});
const result = await client.extract({
model: 'clairic',
state: [
'发票 INV-2291',
'销方:北风供应',
'购方:Contoso 有限公司',
'开票日期:2026-09-02,账期 30 天',
'应付合计:1080.00,含运费',
'联系人:Dana Ruiz、Priya Shah',
].join('\n'),
fields,
referenceDate: '2026-10-19',
options: { includeQuantiles: false },
});
const invoice: string | null = result.answers.invoice_number.value;
console.log({
model: result.model,
invoice,
dueDate: result.answers.due_date.value,
total: result.answers.total.value,
contacts: result.answers.contacts.value,
daysToPay: result.answers.days_to_pay.median,
truncated: result.truncated,
usage: result.usage,
});node --env-file=.env extract-invoice.mtscreateSystemOne() 返回 SystemOne 实例,new SystemOne({ ... }) 是同一个构造函数。defineFields() 会保留字段 ID 的字面量类型,供 ExtractRequest、ExtractResult 和 FieldAnswers 使用。
请求
| 字段 | 规则 |
|---|---|
fields | 必填。至少一个具名字段。名称匹配 [A-Za-z_][A-Za-z0-9_.-]{0,63}。 |
state | 要读取的字符串。除非发送 images,否则必填且不能为空。文本答案的 span 指向这段字符串;span 是该值在 state 里的起止字符位置。 |
images | 可选。最多四张内嵌 PNG、JPEG 或 WebP(每张解码后 4MB,合计 8MB)。拒绝远程 URL。完整 JSON 请求体不得超过 13MB(目录可能限制得更严)。 |
model | 可选。托管默认值为 clairic。单次请求的 model 覆盖客户端设置。 |
referenceDate | 可选 ISO 日期(YYYY-MM-DD),用来补全没写年份的日期。HTTP 正文使用 reference_date。 |
options.nullThreshold | 可选 (0, 1],服务默认 0.5。应用于未单独设置门槛的标量字段。pNull 高于门槛时 value 为 null,guess 仍可能有值。 |
options.includeQuantiles | 可选。为 estimate 和 forecast 答案附加全部 99 个分位数。 |
options.returnStateText | 可选。同时返回 span 位置对应的原文。 |
Core 会在发送前校验字段名、各类型属性和图片表示。完整 JSON 请求体不得超过 13MB(目录可能限制得更严)。未设置 supportsExtract: true 的适配器会在发起网络请求前以 UnsupportedFeatureError 拒绝 extract()。
字段类型
工厂函数由 @system-one-ai/core 导出。内联 { type: 'text' } 对象同样有效。
| 类型 | 工厂函数 | value | 说明 |
|---|---|---|---|
text | textField() | string | null | 可选 span: [start, end]。 |
number | numberField({ unit, integer, decimals }) | number | null | decimals 为 0–6。 |
date | dateField() | string | null | 日历日期。 |
time | timeField() | string | null | 时刻。 |
datetime | dateTimeField() | string | null | 日期与时间。 |
duration | durationField({ unit, integer, decimals }) | number | null | 单位:seconds、minutes、hours、days、weeks、months、years。 |
list | listField({ items }) | readonly 数组 | items 必填:text、number 或 date。 |
estimate | estimateField({ min, max }) | number | string | min 与 max 必填。可选 step、scale(linear | log)、unit。 |
forecast | forecastField({ min, max }) | readonly 数组 | 范围选项与 estimate 相同,另有 horizon(1–64)和 interval。 |
每个字段都可以带 instructions;除 list 外还可以带 nullThreshold。list 可以带 unit 和 decimals。
import {
defineFields, dateTimeField, durationField, forecastField, timeField,
type ExtractRequest, type ExtractResult, type FieldAnswers,
} from '@system-one-ai/core';
const more = defineFields({
opens: timeField(),
signed: dateTimeField(),
delay: durationField({ unit: 'days' }),
travelers: forecastField({ min: 500_000, max: 4_000_000, horizon: 1, interval: 'day' }),
});
type MoreRequest = ExtractRequest<typeof more>;
type MoreResult = ExtractResult<typeof more>;
type MoreAnswers = FieldAnswers<typeof more>;响应
每个答案只保证有 value。标量类型在模型提供时还会带 guess、confidence 和 pNull。文本可能包含 span。列表包含 value 和可选 spans。estimate 与 forecast 包含 mean、median、p10、p90、pBelow、pAbove,不使用 confidence / pNull。forecast 的 value 是数组,按 horizon 每步一个值。
truncated 始终是布尔值。usage 将 token 计数规范为 inputTokens、outputTokens、totalTokens,以及可选的 stateTokens、imageTokens、schemaTokens、passes。没有返回的可选计数不会出现在结果里。
result.model 可能与请求的 ID 不同。请同时记录两者。
用 extract() 发送图片
Clairic 的 extract() 最多接受四张 PNG、JPEG 或 WebP。有图片时 state 可以为 ''。ImageInput 由 core 导出:内嵌 base64 data URL,或 { mediaType: 'image/png', base64: '...' }。
import { readFile } from 'node:fs/promises';
import { createSystemOne, textField, type ImageInput } 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 imagePath = process.argv[2];
if (!apiKey || !imagePath) throw new Error('Set SYSTEM_ONE_API_KEY and supply a PNG path.');
const images: readonly ImageInput[] = [{
mediaType: 'image/png',
base64: (await readFile(imagePath)).toString('base64'),
}];
const client = createSystemOne({
adapter: systemOneAdapter,
transport: createFetchTransport(),
apiKey,
timeoutMs: 30_000,
maxRetries: 0,
});
const result = await client.extract({
model: 'clairic',
state: '',
images,
fields: { invoice_number: textField() },
});
console.log(result.answers.invoice_number.value);这是抽取,不是决策。托管 Clef 的决策图片仍使用 Fetch,因为 systemOneAdapter 不会编码 evaluate() 的图片。
HTTP 等价请求
SDK 里的驼峰字段名,在实际 HTTP 请求中会改成下划线写法(如 referenceDate → reference_date)。下面是同一任务在 POST /v1/systemone 上的请求体:
{
"model": "clairic",
"state": "发票 INV-2291\n开票日期:2026-09-02,账期 30 天\n应付合计:1080.00",
"reference_date": "2026-10-19",
"fields": {
"invoice_number": { "type": "text" },
"total": { "type": "number", "decimals": 2 }
}
}认证、幂等(用同一把键重试同一次操作时,在重放记录仍有效期间不会再扣一次费)和响应头见 API 抽取契约。抽取积分按每次请求的输入大小计费,不乘以字段数。发送前查看当前积分费率。