ESC
开源 3 分钟阅读

LocalJev 发布:基于 Bun 的本地 Jev 兼容决策 API,通过 DiffusionGemma 提供支持

开源项目 LocalJev 发布,这是一个用 TypeScript 编写、面向 Bun 的本地 Jev 兼容 API,通过 OpenAI 兼容的 Chat Completions 端点桥接 DiffusionGemma 模型。它将类型化决策问题转换为分类提示词,由模型自报概率并计算期望得分与熵置信度,与依赖 vLLM 未合并扩展的 OpenJev 实现协议兼容但非数学等价。项目还提供跨模型评测框架

来源:GitHub

LocalJev

一个本地运行的、Jev 兼容的 POST /v1/systemone API,使用 TypeScript 编写、面向 Bun,通过 OpenAI 兼容的 Chat Completions 端点由 DiffusionGemma 提供支持。

默认配置目标为:

  • 推理服务器:http://127.0.0.1:8000
  • 模型:diffusiongemma-26B-A4B-it-4bit
  • LocalJev API:http://127.0.0.1:8080

为什么需要桥接

Jev 使用的是类型化决策 API,而非 OpenAI 聊天 API。 OpenJev 实现了 Jev 线上协议,并通过特殊的单步 DiffusionGemma 结构化读取来获取概率。其后端依赖于尚未合并的 vLLM 请求扩展,例如 diffusion_seed_canvas、diffusion_read_only 以及所请求 token 的 logprobs。

常规的 oMLX API 并不暴露这些原语。因此 LocalJev 采取了可移植的方案:

  1. 将 state 和类型化的 Jev 问题转换为分类提示词;
  2. 让 DiffusionGemma 输出 JSON 概率标量/向量;
  3. 校验完整结果并对格式错误的输出进行重试;
  4. 归一化向量并计算 Jev 兼容的选项、期望得分以及基于熵的置信度;
  5. 返回标准的 Jev 响应结构。

这种方式实现了线上协议兼容,但在数学上并不等同于 OpenJev 的 logit 读取。概率是由模型生成/自报的,而非直接从其 logits 中读取。在依赖这些概率做出重要决策之前,请先在你自己的工作负载上评估其校准程度。

使用 oMLX 运行

需要 Bun 1.2+ 以及一个运行中的 oMLX 服务器。

bun install
cp .env.example .env
$EDITOR .env # 替换上游 API 密钥占位符
bun run start

Bun 会自动加载 .env。或者,你也可以在启动服务器之前在 shell 中设置密钥:

# fish
set -gx LOCALJEV_UPSTREAM_API_KEY 'your-local-omlx-key'
# bash/zsh
export LOCALJEV_UPSTREAM_API_KEY='your-local-omlx-key'

LocalJev 监听 http://127.0.0.1:8080。检查所配置的模型是否可用:

curl http://127.0.0.1:8080/ready

发起一次决策:

curl http://127.0.0.1:8080/v1/systemone \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "jev-latest",
    "state": "Hi, I have been trying to connect Stripe but keep getting a 403 error.",
    "questions": {
      "department": {
        "type": "choice",
        "instructions": "Which team should handle this?",
        "criteria": {
          "billing": "Payment or subscription issues",
          "technical": "Bugs or integration problems",
          "sales": "Pricing or account questions"
        }
      },
      "frustration": {
        "type": "score",
        "instructions": "How frustrated does the customer appear?",
        "criteria": ["Calm", "Frustrated but civil", "Very angry"]
      },
      "urgent": {
        "type": "noul",
        "instructions": "Does this require an immediate response?"
      }
    }
  }'

使用 TypeSafe SDK

SDK 需要一个 API 密钥值。除非配置了 LOCALJEV_API_KEY,否则 LocalJev 接受任意值。为你的 shell 设置 SDK 环境变量:

# fish
set -gx TYPESAFE_BASE_URL http://127.0.0.1:8080
set -gx TYPESAFE_API_KEY local
# bash/zsh
export TYPESAFE_BASE_URL=http://127.0.0.1:8080
export TYPESAFE_API_KEY=local
from typesafe_sdk import TypeSafeClient

client = TypeSafeClient()
response = client.system_one(
    "I was charged twice this month.",
    {
        "billing": {
            "type": "noul",
            "instructions": "Is this a billing issue?",
        }
    },
)
print(response.nouls["billing"].noul)

jev-latest 和 jev-preview 是被接受的别名,因此 SDK 默认值无需更改即可正常工作。

配置

变量默认值用途
LOCALJEV_UPSTREAMhttp://127.0.0.1:8000OpenAI 兼容的基础 URL,带或不带 /v1
LOCALJEV_UPSTREAM_API_KEY空发送给推理服务器的 Bearer 密钥
LOCALJEV_UPSTREAM_MODELdiffusiongemma-26B-A4B-it-4bit上游模型标识符
LOCALJEV_API_KEY空LocalJev 客户端需提供的可选 Bearer 密钥
LOCALJEV_HOST127.0.0.1监听地址
LOCALJEV_PORT8080监听端口
LOCALJEV_TIMEOUT180上游超时时间(秒)
LOCALJEV_MAX_INFLIGHT2允许的上游并发调用数
LOCALJEV_MAX_QUEUE64返回 HTTP 529 之前的等待决策数
LOCALJEV_MALFORMED_RETRIES2对无效模型 JSON 的纠错重试次数
LOCALJEV_MAX_OUTPUT_TOKENS2048每次补全的输出上限
LOCALJEV_QUESTIONS_PER_CALL16每次模型调用的分块限制
LOCALJEV_OUTCOMES_PER_CALL128每次模型调用的选项/得分结果数

Bun 会自动加载 .env,因此你也可以复制 .env.example、替换其中的占位符,然后运行服务器。

开发

bun install
bun test
bun run typecheck
bun run smoke       # 对所配置的推理服务器进行实际调用

评估不同模型

可重复的对比评测使用公开的黄金标签数据:新闻分类(AG News)、是非型阅读理解(BoolQ)以及五级情感分析(SST-5)。它使用同一个 LocalJev 引擎,在两种实际输入长度下对五个已安装的模型进行测试,比较质量、校准、重试次数和完整决策延迟。

# 快速集成检查(30 次请求,并非有意义的质量样本)
bun run eval --out eval/runs/pilot --limit 3

# 5 个模型 × 120 个标注样本 × 2 种输入长度 = 1,200 次请求
bun run eval --out eval/runs/my-bakeoff

# 无需运行推理即可重新生成已完成或部分完成的报告
bun run eval:report eval/runs/my-bakeoff

需要 oMLX 以及 .env 中的上游密钥;无需运行 LocalJev HTTP 服务器或 Python。有关固定的数据来源、方法、配置、恢复运行方式和局限性,请参阅评估指南。

首次完成的对比评测在 M5 Max 上包含 1,200 次请求。Gemma 4 26B-A4B 和 Qwen3.6 在这个小规模筛选样本中是综合表现最强的候选;报告包含各任务结果、延迟、上下文影响和注意事项,而非断言明确的赢家。

应该改用 LM Studio 吗?

目前对该模型而言不适合。截至 2026 年 9 月 18 日,DiffusionGemma 支持在 lmstudio-ai/mlx-engine#336 和 lmstudio-ai/lmstudio-bug-tracker#2037 中仍被追踪为未解决。报告显示 MLX 后端无法加载 diffusion_gemma,而常规 llama.cpp 后端则报告架构未知。oMLX 已经成功加载并服务你确切的检查点,因此它是当前 Mac 上更好的运行器。

即使 LM Studio 之后添加了普通生成支持,仅更换运行器也不会使结果等同于 OpenJev。运行器必须暴露带种子的扩散画布、只读去噪以及选定 token 的 logits/logprobs。如果 LM Studio 仅提供标准 Chat Completions,LocalJev 可以通过修改 LOCALJEV_UPSTREAM 来使用它,但概率路径仍将是提示词/自报式的。

若要直接获取模型概率,最佳路径是:

  1. 在 oMLX 的 DiffusionGemma 通道中添加结构化读取原语并在此处使用;或
  2. 在受支持的 NVIDIA 机器上运行 OpenJev 的修补版 vLLM 后端。