跳到主要内容
AI教程

使用 Jeeves 构建基于推理的决策 API

学习安装 Jeeves、部署其已发布权重、提交兼容 Jev 的决策请求并集成 Python SDK。本教程还将介绍推理控制、延迟权衡、扩散起草器,以及项目的 SFT 和 CISPO 训练流程。

使用 Jeeves 构建基于推理的决策 API

什么是 Jeeves?

Jeeves 项目吉祥物

Jeeves 是一种 Jev 风格的分类器,会在做出结构化决策前生成推理链。它基于 Qwen3.5-9B 构建,配备 LoRA 适配器、指针头、校准概率和 block-4 扩散草稿器。该代码仓库包含模型和草稿器代码、训练流水线、评估工具,以及训练、开发和测试数据。

该项目面向需要的不只是自由文本生成的应用。给定共享状态和一个或多个问题后,Jeeves 会通过兼容 Jev 的 API 返回结构化答案和概率。一次请求可以处理多个问题。

主要功能

  • 三种决策类型:二元 noul、分类 choice 和有序 score 问题。
  • 先推理再决策:模型可以生成推理链,然后使用指针头为可用选项评分。
  • 经过校准的输出:最终选项概率使用在开发集上拟合的温度参数。
  • 兼容 Jev 的 API:现有 Jev 客户端可以提交核心请求格式,而 Jeeves 专用选项则用于控制推理。
  • Python SDK:随附的 sdk/ 软件包可以直接替代 Jev 的 typesafe-sdk。
  • 扩散草稿:block-4 草稿器可加速推理链生成,并支持 Qwen3.5 的 Gated DeltaNet 层。
  • 训练代码:代码仓库包含 SFT、CISPO、校准、评估、导出和草稿器训练组件。

在将贪心推理限制为 2,560 个 token 的情况下,README 报告其在留出测试集和域外测试集上的准确率为 0.889,在 231 个公开 JevBench 项目上的准确率为 0.935。不过,它在 MMLU 和 MMLU-Pro 上的知识测试结果落后于 Jev,因此是否适合某项基准测试取决于具体任务。

前置条件

你需要 Python 3.12 和一块 CUDA GPU。推理实现中的 FP8 内核需要 Hopper GPU。请从代码仓库根目录运行以下命令。

安装依赖

pip install -r requirements.txt

下载已发布的权重

使用 Hugging Face CLI 下载已发布的 9B 检查点及其 block-4 草稿器:

hf download PostHog/jeeves --local-dir jeeves-weights

已发布的模型可从 Hugging Face 获取。

启动 API 服务器

python -m inference.serve --model jeeves-weights --drafter jeeves-weights/drafter_k4.safetensors --port 8009

这会在端口 8009 上启动兼容 Jev 的服务。随附的 Python 客户端默认使用 http://127.0.0.1:8009,不需要 API 密钥,并会等待响应最多 120 秒。

发送第一个决策请求

/v1/systemone 端点接受一个 state、一个 questions 映射,以及可选的推理控制参数。以下请求要求 Jeeves 路由一个客户问题、判断是否需要升级处理,并评估客户的沮丧程度。

curl -s localhost:8009/v1/systemone \
  -H 'content-type: application/json' \
  -d '{
    "state": "鞋子晚到了两周,而且尺码不对。另外,我看到信用卡上有两笔扣款。",
    "questions": {
      "department": {
        "type": "choice",
        "instructions": "哪个团队应该处理这个问题?",
        "criteria": {
          "returns": "换货、退款、商品错误或损坏",
          "shipping": "配送状态、延迟、包裹丢失",
          "billing": "扣款、发票、支付问题"
        }
      },
      "escalate": {
        "type": "noul",
        "instructions": "这是否需要人工紧急处理?"
      },
      "frustration": {
        "type": "score",
        "instructions": "客户有多沮丧?",
        "criteria": ["平静", "沮丧", "非常愤怒"]
      }
    },
    "options": {"max_think": 512}
  }'

了解问题类型

  • choice:从命名的备选项中进行选择,并返回所选键、概率和置信度。
  • noul:表示是/否类型的决策,并返回数值型 noul 值。
  • score:评估有序标签列表,并返回数值分数、图例、概率和置信度。

响应还包含使用情况信息,包括输入、输出和推理 token 数量,以及总延迟。同一请求中的问题可以并行进行推理。

从 Python 使用 Jeeves

安装随附的 SDK

pip install ./sdk

创建类型化问题

from jeeves_sdk import Choice, Noul, Score, TypeSafeClient

with TypeSafeClient() as client:
    result = client.system_one(
        state="I was charged twice. Please help.",
        questions={
            "billing": Noul(
                instructions="Is this about billing?"
            ),
            "tone": Choice(
                instructions="What is the tone?",
                criteria={"calm": None, "angry": None},
            ),
            "urgency": Score(
                instructions="How urgent is this?",
                criteria=["can wait", "this week", "today"],
            ),
        },
        max_think=768,
        return_reasoning=True,
    )

    print(result.nouls["billing"].noul)
    print(result.choices["tone"].choice)
    print(result.scores["urgency"].score)
    print(result.reasoning["tone"].text)

TypeSafeClient 会按问题类型对返回值进行分组。设置 return_reasoning=True 后,还可以获取每个问题的推理文本。README 提醒,训练期间未使用语言一致性奖励,因此推理链不一定易于解读。

连接到其他服务器

客户端默认连接到 http://127.0.0.1:8009。如果服务器运行在其他地址,请设置 JEEVES_BASE_URL 环境变量。

export JEEVES_BASE_URL=http://your-server:8009

控制推理和延迟

可选的 options 对象提供四个推理控制项。对应的服务器标志可用于设置全局默认值。

  • think:默认为 true。将其设为 false 后,模型会直接根据提示作答,而不生成推理链。
  • max_think:默认为 2560。模型作答前,它会将每条推理链截断到指定的 token 数量。
  • nothink_threshold:默认为 null。配置后,当无需推理的置信度达到或超过该阈值时,Jeeves 会跳过推理。
  • return_reasoning:默认为 false。启用后,响应中会包含推理文本。

选择延迟配置

在 README 的 325 个问题开发集评估中,完整推理的准确率为 0.825,平均推理 token 数为 1,138,中位延迟为 3.3 秒。将 max_think 设为 768、nothink_threshold 设为 0.9 后,准确率为 0.806,平均推理 token 数为 344,中位延迟为 2.0 秒。禁用推理后的准确率为 0.775,耗时约 0.3 秒。

一种实用的均衡配置是:

{
  "options": {
    "max_think": 768,
    "nothink_threshold": 0.9,
    "return_reasoning": false
  }
}

完整推理的延迟长尾明显:报告的 p90 为 17.1 秒。响应时间很重要时,请使用更短的推理链或基于置信度的推理。

Jeeves 如何做出决策

Jeeves 使用 Qwen tokenizer 中的罕见 token 来格式化状态、问题说明和答案选项。随后,它会生成一条以 think 标记开头的推理链。推理完成后,系统会在决策标记之前再次列出问题和选项。

指针头会计算决策标记处的查询投影与每个选项边界处的键投影之间的缩放点积。softmax 会将这些分数转换为概率,开发集上拟合的温度参数则用于校准这些概率。根据 README 中的消融实验,将特殊提示 token 替换为普通标签,或省略重复的推理后问题,都会导致性能下降。

扩散草稿器

可选的草稿器通过推测解码加速推理生成。它将 Orthrus 扩散方法适配到 Qwen3.5 的 Gated DeltaNet 层,使掩码 token 能够跨注意力关注卷积后的键和值。

报告显示,对于单个问题,使用普通的 graphed 贪心解码时,推理链 token 吞吐量为每秒 109 个;使用 block 4 时提升到每秒 176 个。Block 8 可达到每秒 193 个,但 block 4 仍是默认配置,因为在批量处理多个问题时开销更低。使用 block 4 批量处理八个问题时,总吞吐量约为每秒 960 个推理链 token。

提供你训练的检查点

Jeeves 在训练期间使用 LoRA。在提供训练好的检查点之前,请将其融合为独立模型,并提供匹配的草稿器文件:

python export.py runs/cispo/final --out runs/fused
python -m inference.serve \
  --model runs/fused \
  --drafter runs/drafter_k4/drafter.safetensors \
  --port 8009

复现训练流程

准备数据集

准备脚本会从 Hugging Face 下载公共数据集,所使用的版本固定在 prep/public.py 中。每个源数据集仍遵循其各自的许可证。

python -m prep.prep

运行训练和评估

文档中的复现流程使用八块 GPU。该流程包括监督微调、CISPO 训练、测试与 JevBench 评估、模型导出、推理链生成,以及 block-4 草稿器训练。

torchrun --nproc_per_node 8 train.py sft --run-dir runs/sft

torchrun --nproc_per_node 8 train.py cispo \
  --run-dir runs/cispo \
  --init runs/sft/final

torchrun --nproc_per_node 8 test.py runs/cispo/final
torchrun --nproc_per_node 8 jevbench.py runs/cispo/final
python export.py runs/cispo/final --out runs/fused

torchrun --nproc_per_node 8 -m drafter.gen --model runs/fused

torchrun --nproc_per_node 8 train.py drafter \
  --model runs/fused \
  --block 4 \
  --run-dir runs/drafter_k4

发布的配方首先在来自 12 个公开数据集和合成策略数据的 19,126 个问题上进行两个 SFT 训练周期。随后对每个问题进行 8 次 rollout,温度设为 1,并将推理上限设为 2,560 个 token,以应用 CISPO。训练原计划进行 624 步,但在第 402 步停止,因为后续步骤使指针头在饱和的强化学习数据池上过度锐化。最后,在开发集上拟合了一个校准温度。

高级使用技巧

  1. 批量处理相关决策。 将多个问题置于同一个共享状态下,以便服务器并行处理它们的推理链。
  2. 简单情况使用直接回答。 配置 nothink_threshold,仅在无思考置信度低于你设定的阈值时保留推理。
  3. 在对延迟敏感的服务中限制推理。 当你希望在速度与准确性之间取得平衡时,降低 max_think,而不是完全禁用推理。
  4. 有选择地返回推理。 除非应用需要这些文本,否则保持 return_reasoning 禁用,尤其是因为这些推理链不保证易于解释。
  5. 在自己的领域进行评估。 Jeeves 在项目测试集和公开的 JevBench 分级评测中表现出色,但在报告的 MMLU 和 MMLU-Pro 知识评测中落后于 Jev。
  6. 谨慎解读比较结果。 在 JevBench 之外,已发布的 Kev 和 Jev 比较使用了来自相同底层来源的不同题目。

结论

Jeeves 将结构化的 Jev 风格输出与测试时推理、校准概率和加速的推理链生成相结合。你可以从已发布的权重和兼容 Jev 的 HTTP 端点开始,使用 Python SDK 编写类型安全的应用代码,并调整 max_think 与 nothink_threshold,在准确性和延迟之间取得平衡。如需进一步定制,代码仓库提供完整的 SFT、CISPO、校准、导出和 drafter 流程。