跳至主要内容
返回博客

Jev 开源替代有哪些?2026 决策模型选型地图与 TypeScript 方案

具体来说,OpenAI Decisions API、Microsoft-Decision-1、Cloudflare Clef 等托管模型,RouterPlus、OpenRouter 等多模型网关,以及 Clef 的开源权重和 EdgeJev 这类兼容 POST /v1/systemone 接口格式的开源项目,都能提供 Choice、Score 和 Noul(是非题)这一类能力。

还不熟悉决策模型的话,可以先读 决策模型是什么?System One 模型、Jev 与 OpenAI Decisions API 对比。

决策模型选型地图(2026 年 10 月)

按“谁来跑模型、你写什么格式”,大致可以分成四类:

1. 托管单模型:厂商自己训练、自己托管,你调用它的 API。

  • Jev(TypeSafe):POST /v1/systemone,目前只接受文本。也可以通过 OpenRouter 调用。
  • OpenAI Decisions API:POST /v1/decisions,目前只有 gpt-6-luna 一个模型,处于公测阶段,支持文本和图片。
  • Microsoft-Decision-1:在 Microsoft Foundry 中部署,也可以通过 OpenRouter 使用。微软说它是在 Qwen3.5-9B 的基础上后训练得到的。
  • Cloudflare Clef / Clef-flash:托管在 Workers AI 上。Cloudflare 说它遵循 POST /v1/systemone 接口格式,可以读取文本、JSON、图片或视频。

2. 多模型网关:一个密钥、一个端点,背后路由到多家决策模型。

  • RouterPlus:POST /v1/decisions。目录里有十个决策模型,其中九个使用同一套 POST /v1/systemone 接口格式;自有模型 Decider 2B 和 Kev 4B 标价为 $0。
  • OpenRouter:Jev 可以走 POST /api/alpha/decisions,也可以走兼容 TypeSafe SDK 的 POST /api/v1/systemone。OpenRouter 文档说不需要排队,也不需要单独的 TypeSafe 账户。

3. 开源权重与开源复现:模型可以下载到自己的机器上运行。

  • Clef 开源权重:Cloudflare 以 Apache 2.0 许可在 Hugging Face 上开源了 Clef 和 Clef-flash 的权重。
  • EdgeJev(Apache-2.0):把 laya、kev、NanoJev、PlayJev 等开源复现统一成“转换 → 量化 → 部署”的流程,在 CPU 上离线运行,并提供 POST /v1/systemone 本地服务。项目自述“数据不出本机”。
  • 还有 jev-clone 这类独立复现。它们都声明与 TypeSafe 无隶属关系。

4. SDK 抽象层:本身不是模型,而是在你的代码和上面这些服务之间加一层。

  • System One SDK(本站):用 TypeScript 定义 Choice / Score / Noul 问题,通过适配器连接不同的模型服务。

要注意,SDK 开源不等于模型可以自托管。System One 开源的是 SDK;System One 本身不提供可下载的模型权重。SDK 能否直接连接你自建的模型服务,见下文“自托管要考虑什么”。

为什么会被锁定:请求格式、问题定义与阈值

锁定风险通常不在“调用了哪家 API”,而在于问题定义被写成了某一家的请求格式。对比官方文档,可以看到两套不同的写法:

| | TypeSafe Jev / Microsoft-Decision-1 / Cloudflare Clef | OpenAI Decisions API | | --- | --- | --- | | 输入字段 | state(字符串或 JSON) | input(字符串,或包含文本和图片的 user 消息) | | 问题结构 | questions 是一个对象,键是你起的问题 ID | questions 是一个数组,每个问题用 name 标识 | | 是非题 | type: "noul" | type: "predicate" | | 选项与档位 | 都写在 criteria 里(Choice 用对象,Score 用有序数组) | Choice 写在 choices: [{ value, description }],Score 写在 levels: [{ label, description }] |

RouterPlus 的文档也写明,OpenAI 的 API 不使用 POST /v1/systemone 接口格式,它的网关需要在中间做一次翻译。此外,各家的 confidence 算法并不相同。RouterPlus 文档举的例子是:在 Jev 上调好的 confidence 阈值,不能直接搬到 Clef 或 GPT-6 Luna Decisions 上用。

所以要能随时换模型,需要守住三样东西:

  1. 问题定义:问题、选项、评分档位写在你自己的代码里,不散落在某家的控制台或请求体里。
  2. 阈值和业务规则:“低于多少分就转人工”这类策略属于应用代码,换模型时要重新验证。
  3. 调用层:换模型时,只改适配器和凭据。

还有一个现实情况:各家都发布了“自己最强”的自测结果。微软称 Microsoft-Decision-1 在其 36 项基准对比中准确率最高(微软自测);Cloudflare 称在 10 个决策基准中,Clef 系列有 7 个最高(Cloudflare 自测)。这些结论无法互相印证。能在你自己的标注数据上方便地对比几个后端,本身就是不被锁定的价值所在。

用 System One SDK 写一次、换后端

下面这段代码来自开发团队提供的示例(examples/decision-articles/02-swappable-provider.ts)。问题、评分量表和动作阈值都留在这一个文件里,切换后端时只换适配器和凭据:

  • hosted:System One 托管 API(@system-one-ai/adapter-system-one)。system-one.dev 提供 Jev(typesafe/jev)、Clef Flash(cloudflare/clef-flash)和 Clef(cloudflare/clef)模型服务。
  • typesafe:同一个适配器,指向 https://api.typesafe.ai/v1。
  • openrouter:@system-one-ai/adapter-openrouter。
  • cloudflare:@system-one-ai/adapter-cloudflare,需要 Cloudflare 账户 ID。
ts/**
 * Article 2 — Keep the problem definition in your code so the provider is swappable.
 *
 * The SDK is an open-source TypeScript toolkit. Questions, rubrics, and
 * action thresholds live in this file. Only the adapter / credentials change.
 *
 * Adapters this repository actually depends on:
 *   - @system-one-ai/adapter-system-one  → System One hosted API or TypeSafe HTTP
 *   - @system-one-ai/adapter-openrouter  → OpenRouter Decisions
 *   - @system-one-ai/adapter-cloudflare  → Cloudflare REST (needs accountId)
 *
 * `@system-one-ai/adapter-vercel` is mentioned in docs but is not a dependency
 * of this repo, so this file does not import it.
 *
 * Hosted credits apply only to POST /v1/systemone. TypeSafe, OpenRouter, and
 * Cloudflare bill on their own accounts. Adapter support is not the hosted
 * model catalog — use GET /v1/models for what this site currently hosts.
 */
import { createSystemOne, choice, score, booleanQuestion } from '@system-one-ai/core';
import type { EvaluationClient } from '@system-one-ai/core';
import { systemOneAdapter } from '@system-one-ai/adapter-system-one';
import { openRouterAdapter } from '@system-one-ai/adapter-openrouter';
import { cloudflareAdapter } from '@system-one-ai/adapter-cloudflare';
import { createFetchTransport } from '@system-one-ai/transport-fetch';

/** Application-owned problem definition. Do not move these labels into the provider dashboard. */
export const reviewQuestions = {
  team: choice('Choose the team that should review this message.', {
    billing: 'Payments and refunds',
    support: 'Technical issues',
    review: 'More information or a person is required',
  }),
  completeness: score('How completely does the draft reply address the message?', [
    'Does not address the message',
    'Partially addresses the message',
    'Fully addresses the message',
  ]),
};

/** Application-owned policy. Unknown or missing scores are unresolved, not a pass. */
export const REVIEW_IF_SCORE_BELOW = 1.5;

export type ProviderKind = 'hosted' | 'typesafe' | 'openrouter' | 'cloudflare';

export function createProviderClient(kind: ProviderKind): EvaluationClient {
  const transport = createFetchTransport();
  if (kind === 'hosted') {
    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) {
      throw new Error('Hosted client needs SYSTEM_ONE_API_KEY, SYSTEM_ONE_BASE_URL, SYSTEM_ONE_MODEL.');
    }
    return createSystemOne({
      apiKey, baseURL, model, adapter: systemOneAdapter, transport, maxRetries: 0, timeoutMs: 30_000,
    });
  }
  if (kind === 'typesafe') {
    const apiKey = process.env.TYPESAFE_API_KEY;
    const model = process.env.TYPESAFE_MODEL;
    if (!apiKey || !model) throw new Error('TypeSafe client needs TYPESAFE_API_KEY and TYPESAFE_MODEL.');
    return createSystemOne({
      apiKey,
      baseURL: 'https://api.typesafe.ai/v1',
      model,
      adapter: systemOneAdapter,
      transport,
      maxRetries: 0,
      timeoutMs: 30_000,
    });
  }
  if (kind === 'openrouter') {
    const apiKey = process.env.OPENROUTER_API_KEY;
    const model = process.env.OPENROUTER_MODEL;
    if (!apiKey || !model) throw new Error('OpenRouter client needs OPENROUTER_API_KEY and OPENROUTER_MODEL.');
    return createSystemOne({
      apiKey, model, adapter: openRouterAdapter, transport, maxRetries: 0, timeoutMs: 30_000,
    });
  }
  const apiKey = process.env.CLOUDFLARE_API_TOKEN;
  const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;
  const model = process.env.CLOUDFLARE_MODEL;
  if (!apiKey || !accountId || !model) {
    throw new Error('Cloudflare REST client needs CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_MODEL.');
  }
  return createSystemOne({
    apiKey,
    model,
    adapter: cloudflareAdapter({ accountId }),
    transport,
    maxRetries: 0,
    timeoutMs: 30_000,
  });
}

export type ReviewNext = 'revise_draft' | 'keep_draft' | 'needs_review';

export function applyReviewPolicy(completeness: number | null | undefined): ReviewNext {
  if (completeness == null || Number.isNaN(completeness)) {
    return 'needs_review';
  }
  return completeness < REVIEW_IF_SCORE_BELOW ? 'revise_draft' : 'keep_draft';
}

export async function reviewDraft(
  client: EvaluationClient,
  input: { message: string; draft: string },
) {
  const result = await client.evaluate({
    state: { message: input.message, answer: input.draft },
    questions: reviewQuestions,
  });
  return {
    team: result.answers.team.choice,
    completeness: result.answers.completeness.score,
    next: applyReviewPolicy(result.answers.completeness.score),
    model: result.model,
  };
}

async function main() {
  const kind = (process.env.EXAMPLE_PROVIDER ?? 'hosted') as ProviderKind;
  const allowed: ProviderKind[] = ['hosted', 'typesafe', 'openrouter', 'cloudflare'];
  if (!allowed.includes(kind)) {
    throw new Error(`EXAMPLE_PROVIDER must be one of ${allowed.join(', ')}.`);
  }
  const decision = await reviewDraft(createProviderClient(kind), {
    message: 'I was charged twice for the same order.',
    draft: 'Please send your order number so we can review both charges.',
  });
  console.log(JSON.stringify(decision, null, 2));
}

if (process.argv[1] && import.meta.url.endsWith(process.argv[1].split(/[\\/]/).pop() ?? '')) {
  main().catch((error: unknown) => {
    console.error(error instanceof Error ? error.message : error);
    process.exitCode = 1;
  });
}

示例里有几点值得注意(均出自示例注释和 README):

  • 问题定义归应用所有:reviewQuestions 的注释写明,不要把这些标签挪到供应商的控制台里。
  • 阈值归应用所有:REVIEW_IF_SCORE_BELOW = 1.5 是应用自己的策略。示例的 applyReviewPolicy() 分三种情况:分数缺失(undefined 或 null)或不是数字(NaN)时返回 needs_review,交给人工审核;分数低于 1.5 返回 revise_draft;其余返回 keep_draft。也就是说,缺失或未知的分数按“未解决”处理,不算通过。
  • 计费各自独立:System One 积分只用于 System One 托管 API;TypeSafe、OpenRouter、Cloudflare 由各自的账户计费。
  • 适配器支持不等于托管目录:本站当前托管了哪些模型,请以 GET /v1/models 为准。system-one.dev 提供 Jev(typesafe/jev)、Clef Flash(cloudflare/clef-flash)和 Clef(cloudflare/clef)模型服务。
  • 有文档提到过 @system-one-ai/adapter-vercel,但它不是这个仓库的依赖,所以示例没有引入。

运行时用 EXAMPLE_PROVIDER=typesafe|openrouter|cloudflare 选择后端,并提供该服务自己的凭据。这些调用由对应服务计费,不消耗 System One 积分。

另外,@system-one-ai/core 的 npm 说明里提到,请求可以携带图片,但只有显式声明 supportsImages: true 的适配器才接受;不支持图片的适配器会直接报错,不会悄悄把图片降级成文本。

自托管要考虑什么

想让“数据不出内网”,需要的是可以自己运行的模型,而不只是开源的 SDK。目前能核实的选择有 Clef 的开源权重,以及 EdgeJev 这类开源复现。评估时建议看这几点:

  • 数据驻留:EdgeJev 自述推理过程不发任何网络请求、没有遥测、state 和问题都不离开本机(项目自述)。托管服务的数据处理以各家条款为准:OpenAI 文档提到对符合条件的客户支持 ZDR,Jev 文档说不用客户请求训练模型。
  • 准确率与校准:开源复现和官方模型差多少,目前只有项目自报的数字。比如 EdgeJev 在 README 里公布了自测成绩,并附有测试条件说明。jev-clone 在 README 中写道:已有的公开复现开源了“接口形状”,但没有一份做过校准评估(项目自述)。上线前请用自己的标注数据测一遍。
  • 语言:TypeSafe 文档说 Jev 以英语为主要训练语言,中日韩文字可以处理,但效果不一定一样好。中文场景无论选哪家,都建议先测。
  • 延迟:EdgeJev 自报在 4 核 CPU 上单题 15.6 ms(项目自报,测试条件见其 README)。厂商公布的延迟同样是自测数字。
  • 运维成本:模型转换、量化、部署、监控和版本升级都要自己负责。比如 EdgeJev 的转换步骤需要 torch 并且要联网下载权重,之后才能离线运行。
  • 和 SDK 怎么接:EdgeJev 提供 POST /v1/systemone,System One 托管端也使用 {baseURL}/systemone 这个路径。System One SDK 能否直接连接这类自建服务,目前还没有验证,本文不作承诺。

怎么选:一个简单的判断顺序

  1. 数据能不能出内网? 不能,就看开源权重或开源复现,并为自己做校准验证留出时间。
  2. 需不需要图片? 按各家官方文档,Jev 目前只接受文本;OpenAI Decisions API 和 Clef 支持图片。
  3. 想不想同时试几家? 用网关或 SDK 抽象层,在同一份问题定义上对比。
  4. 无论选哪家:把问题定义和阈值留在自己的代码里,换后端后用同一份标注数据重新验证阈值。

表中不收录延迟和准确率数字。厂商与开源项目公布的这类数字都是各自自测,本文没有实测。

决策模型选型对比(核验日期 2026-10-11)

方案类别托管 / 自托管输入类型请求格式与问题类型是否返回概率公开价格
Jev(TypeSafe)来源: TypeSafe: Models · 核验日期 2026-10-11托管单模型托管(TypeSafe API,也可经 OpenRouter);自托管:未公布来源: OpenRouter: Jev · 核验日期 2026-10-11仅文本:字符串、JSON 对象、文本数组来源: TypeSafe: Models · 核验日期 2026-10-11POST /v1/systemone;Choice / Score / Noul来源: TypeSafe: System One · 核验日期 2026-10-11是:Choice、Score 返回 probabilities 和 confidence;Noul 返回“是”的概率来源: TypeSafe: Confidence · 核验日期 2026-10-11每百万输入 token $0.042,输出免费来源: TypeSafe: Models · 核验日期 2026-10-11
OpenAI Decisions API来源: OpenAI: Decisions · 核验日期 2026-10-11托管单模型托管,公测中,目前只有 gpt-6-luna;自托管:未公布来源: OpenAI: Decisions · 核验日期 2026-10-11文本、图片或两者组合(图片须为内联 base64)来源: OpenAI: Decisions · 核验日期 2026-10-11POST /v1/decisions;predicate / choice / score(OpenAI 自有格式)来源: OpenAI: Decisions · 核验日期 2026-10-11是:predicate 返回 probability;choice、score 返回 probabilities 和 confidence来源: OpenAI: Decisions · 核验日期 2026-10-11每百万输入 token $0.10,无输出费用来源: OpenAI: Decisions · 核验日期 2026-10-11
Microsoft-Decision-1来源: Microsoft 发布博客 · 核验日期 2026-10-11托管单模型托管(Microsoft Foundry,也可经 OpenRouter);自托管:未公布来源: Microsoft 发布博客 · 核验日期 2026-10-11文本或 JSON 状态来源: Microsoft Learn · 核验日期 2026-10-11{Foundry 端点}/providers/microsoft/v1/systemone;noul / choice / score(state + questions + criteria)来源: Microsoft Learn · 核验日期 2026-10-11是:noul 返回概率;choice 返回每个选项的概率;score 返回每档概率来源: Microsoft Learn · 核验日期 2026-10-11每百万输入 token $0.042,输出免费来源: Microsoft 发布博客 · 核验日期 2026-10-11
Cloudflare Clef来源: Cloudflare Changelog · 核验日期 2026-10-11托管单模型 + 开源权重托管于 Workers AI;权重以 Apache 2.0 许可在 Hugging Face 开源来源: Cloudflare Changelog · 核验日期 2026-10-11文本、JSON、图片或视频来源: Cloudflare: clef · 核验日期 2026-10-11遵循 `POST /v1/systemone` 接口格式;noul / choice / score,每次请求最多 64 个问题来源: Cloudflare Changelog · 核验日期 2026-10-11是:noul 返回概率;choice 返回逐项概率和 confidence;score 返回每档概率来源: Cloudflare Changelog · 核验日期 2026-10-11Clef:每百万输入 token $0.24(Workers AI)来源: Cloudflare: clef · 核验日期 2026-10-11
RouterPlus来源: RouterPlus: POST /v1/decisions · 核验日期 2026-10-11多模型网关托管网关;自有模型 Decider 2B、Kev 4B 运行在 RouterPlus 自有的美国 GPU 上来源: RouterPlus: POST /v1/decisions · 核验日期 2026-10-11文本和 JSON来源: RouterPlus: POST /v1/decisions · 核验日期 2026-10-11POST /v1/decisions;十个模型中九个使用 `POST /v1/systemone` 接口格式来源: RouterPlus: POST /v1/decisions · 核验日期 2026-10-11是(按各模型返回)来源: RouterPlus: POST /v1/decisions · 核验日期 2026-10-11Decider 2B、Kev 4B 为 $0;其他模型按各自标价来源: RouterPlus: POST /v1/decisions · 核验日期 2026-10-11
OpenRouter来源: OpenRouter: Jev · 核验日期 2026-10-11多模型网关托管网关;Jev 无需排队,也不需要 TypeSafe 账户来源: OpenRouter: Jev · 核验日期 2026-10-11Jev:文本来源: OpenRouter: Jev · 核验日期 2026-10-11POST /api/alpha/decisions,或 POST /api/v1/systemone(兼容 TypeSafe SDK)来源: OpenRouter: Jev · 核验日期 2026-10-11是:Choice、Score 返回 probabilities 和 confidence;Noul 返回“是”的概率来源: OpenRouter: Jev · 核验日期 2026-10-11按输入 token 计费,输出免费;具体价格见 OpenRouter 模型页来源: OpenRouter: Jev · 核验日期 2026-10-11
EdgeJev(开源复现示例)来源: EdgeJev README · 核验日期 2026-10-11开源复现自托管:本地 CPU 离线运行,Apache-2.0;与 TypeSafe 无隶属关系来源: EdgeJev README · 核验日期 2026-10-11以所选后端为准(项目自述)来源: EdgeJev README · 核验日期 2026-10-11本地服务 POST /v1/systemone;choice / score / noul来源: EdgeJev README · 核验日期 2026-10-11是:示例返回 probabilities 和 confidence(项目自述)来源: EdgeJev README · 核验日期 2026-10-11本地运行无 API 调用费用;硬件与运维自担来源: EdgeJev README · 核验日期 2026-10-11
System One SDK(本站)来源: npm @system-one-ai/core · 核验日期 2026-10-11SDK 抽象层SDK 开源;system-one.dev 提供 Jev(`typesafe/jev`)、Clef Flash(`cloudflare/clef-flash`)和 Clef(`cloudflare/clef`)模型服务;不提供可下载的模型权重来源: System One /docs · 核验日期 2026-10-11由所连模型服务决定;图片只在声明 supportsImages 的适配器上可用来源: npm @system-one-ai/core · 核验日期 2026-10-11在代码中定义 choice / score / booleanQuestion;适配器:System One 托管 API / TypeSafe、OpenRouter、Cloudflare来源: System One SDK 文档 · 核验日期 2026-10-11是:原生 Choice 返回各选项 probabilities 和 confidence,Score 另含 legend,Noul 返回 P(true)来源: System One 决策原语 · 核验日期 2026-10-11SDK 为 MIT 许可;托管 API 用预付决策积分,10,000 积分 $10 起;第三方服务由各自账户计费;[System One 定价](https://system-one.dev/zh-CN/pricing) · 2026-10-11来源: npm @system-one-ai/core · 核验日期 2026-10-11

常见问题

Jev 有开源替代吗?
有两类。一类是开源权重,比如 Cloudflare 以 Apache 2.0 许可开源的 Clef 和 Clef-flash;另一类是社区复现,比如 EdgeJev 和 jev-clone。社区复现与 TypeSafe 无隶属关系,准确率和校准数据都是项目自报,使用前请用自己的数据验证。
能离线运行、数据不出内网吗?
可以,但需要能自己运行的模型,比如下载开源权重,或者使用 EdgeJev 这类本地服务(项目自述可以完全离线)。System One 开源的是 TypeScript SDK,不提供可下载的模型;SDK 能否直接连接自建服务,目前还没有验证,本文不作承诺。
开源模型准不准?
目前没有中立的统一评测。开源项目和厂商公布的数字都是各自自测,测试集、条件和指标都不一样,不能直接横向比较。建议用你自己的标注样本,在同一份问题定义上对比几个候选。
换模型时,阈值能直接沿用吗?
不建议。各家的 confidence 算法不同,RouterPlus 文档举例说,在 Jev 上调好的阈值不能直接用于 Clef 或 GPT-6 Luna Decisions。换模型后,请用同一份标注数据重新验证阈值。
System One SDK 能连接哪些模型服务?
[SDK 文档](https://docs.system-one.dev/zh-CN/docs/sdk)列出的公开集成选项有四个适配器:`@system-one-ai/adapter-system-one`(System One 托管 API,也可以把 baseURL 指向 TypeSafe HTTP)、`@system-one-ai/adapter-openrouter`、`@system-one-ai/adapter-cloudflare`(另有 `@system-one-ai/adapter-cloudflare/workers` 子入口),以及 `@system-one-ai/adapter-vercel`(Vercel AI Gateway)。文档也说明,这是 SDK 的集成选项,不是本站托管服务或模型的列表。本文示例用到了其中前三个。system-one.dev 提供 Jev(`typesafe/jev`)、Clef Flash(`cloudflare/clef-flash`)和 Clef(`cloudflare/clef`)模型服务。
价格怎么比?
公开标价见上方对比表。System One 托管 API 使用预付决策积分,[定价页](https://system-one.dev/zh-CN/pricing)列出三档:10,000 积分 $10、60,000 积分 $50、300,000 积分 $200,均为一次性购买、不自动续费。通过 SDK 连接第三方服务时,费用由该服务按自己的账户收取。