多数大模型应用都遵循“输入提示词、生成文本、再解析结果”的链路。Jeff 选择了另一条路线:把模型收缩为专门处理决策问题的 zero-shot 分类器。调用方描述场景并给出候选项,模型通过一次前向计算直接返回各选项的校准概率,不生成解释文本,也不要求业务代码从自然语言中提取答案。
项目提供基于 Qwen3.5 和 Gemma 4 的微调版本。来源给出的性能数据是:在 RTX PRO 6000 上,一次决策约需 22 毫秒;其中 0.8B 版本在 benchmark 上已经逼近 Jev。这里更值得关注的并不只是单项成绩,而是它呈现出的工程取舍——如果任务最终只需要从有限选项中做判断,生成式模型可能并不是最合适的执行器。
从“生成答案”切换为“计算选项概率”
假设系统要判断一张工单应该进入哪个队列。传统做法可能要求模型输出 JSON:
你是工单分类器。请返回 JSON,不要输出其他内容。
工单:用户登录后立即被强制退出。
类别:账号安全、支付问题、产品建议、其他
即使提示词写得很严格,调用方仍要处理 Markdown 代码块、字段缺失、类别拼写变化和额外解释。生成过程还可能输出多个实际没有价值的 token。
Jeff 的接口思路可以抽象为:
{
"scenario": "用户登录后立即被强制退出",
"options": ["账号安全", "支付问题", "产品建议", "其他"]
}
返回值则应接近下面这种结构:
{
"probabilities": {
"账号安全": 0.82,
"支付问题": 0.03,
"产品建议": 0.01,
"其他": 0.14
}
}
以上 JSON 只是便于说明集成方式的接口示例,并非项目已公布的固定 API。真正接入时应以 Jeff 的模型调用方式和输出格式为准。
这种模式带来三个直接变化:
- 延迟更稳定:计算量不再取决于生成答案的长度。
- 结果更容易消费:业务代码读取概率数组即可,不需要容错式文本解析。
- 决策可以分层:最高概率、置信度阈值和前两名差值都能参与后续路由。
22 毫秒的价值在服务链路里,而不只在模型里
约 22 毫秒是 RTX PRO 6000 上的模型决策数据,不等于线上请求一定能在 22 毫秒内完成。实际延迟还包含排队、序列化、网络传输、分词和服务框架开销。部署时应至少分别记录:
总延迟 = 排队时间 + 预处理 + 模型前向计算 + 后处理 + 网络开销
不过,一次前向计算、不进行自回归生成,仍然让系统更适合这些场景:
- API 网关中的请求分流;
- 客服工单和邮件分类;
- 内容审核的初筛;
- Agent 在有限工具集合中选择下一步动作;
- 推荐或风控系统中的轻量级策略节点。
0.8B 参数规模也意味着它更有机会部署在成本受限或本地推理环境中。但“benchmark 逼近 Jev”不能直接推导出它在所有业务数据上都同样准确。候选项表述、领域术语、类别不平衡和分布漂移都会影响结果,正式替换现有分类器前仍需运行自己的离线测试。
可以这样设计一层稳定的决策 API
由于摘要没有给出 Jeff 的正式 Python API,下面提供的是一个可直接运行的集成骨架。它先用确定性的模拟评分器跑通 HTTP 契约;接入 Jeff 时,只需替换 score_with_model 函数,不必改动上游业务系统。
安装依赖:
python -m venv .venv
source .venv/bin/activate
pip install fastapi 'uvicorn[standard]' pydantic
创建 app.py:
from math import exp
from typing import List
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
app = FastAPI(title="Decision Classifier")
class DecisionRequest(BaseModel):
scenario: str = Field(min_length=1, max_length=4000)
options: List[str] = Field(min_length=2, max_length=50)
class Choice(BaseModel):
option: str
probability: float
class DecisionResponse(BaseModel):
choices: List[Choice]
selected: str
confidence: float
needs_review: bool
def softmax(logits: list[float]) -> list[float]:
peak = max(logits)
values = [exp(value - peak) for value in logits]
total = sum(values)
return [value / total for value in values]
def score_with_model(scenario: str, options: list[str]) -> list[float]:
"""演示评分器。
接入 Jeff 时,将函数体替换为真实推理调用,并返回与 options
顺序一致的 logits 或分数。当前实现仅用于跑通服务契约,不能用于生产分类。
"""
scenario_terms = set(scenario.lower().split())
logits = []
for index, option in enumerate(options):
option_terms = set(option.lower().split())
overlap = len(scenario_terms & option_terms)
logits.append(float(overlap) - index * 0.01)
return logits
@app.post("/v1/decide", response_model=DecisionResponse)
def decide(request: DecisionRequest) -> DecisionResponse:
if len(set(request.options)) != len(request.options):
raise HTTPException(400, "options must be unique")
logits = score_with_model(request.scenario, request.options)
if len(logits) != len(request.options):
raise HTTPException(500, "model returned an invalid score count")
probabilities = softmax(logits)
ranked = sorted(
zip(request.options, probabilities),
key=lambda item: item[1],
reverse=True,
)
confidence = ranked[0][1]
return DecisionResponse(
choices=[
Choice(option=option, probability=round(probability, 6))
for option, probability in ranked
],
selected=ranked[0][0],
confidence=round(confidence, 6),
needs_review=confidence < 0.70,
)
启动服务并发送请求:
uvicorn app:app --host 0.0.0.0 --port 8000
curl -s http://127.0.0.1:8000/v1/decide \
-H 'Content-Type: application/json' \
-d '{
"scenario": "用户登录后立即被强制退出,需要检查账号安全状态",
"options": ["账号安全", "支付问题", "产品建议", "其他"]
}'
生产接入 Jeff 时,score_with_model 应负责模型需要的模板构造、推理和输出映射。API 层则继续承担输入限制、重复选项检查、阈值策略和稳定响应格式。这样即使以后替换模型,上游调用方也不需要跟着修改。
概率不能只看最大值
“返回校准概率”比只返回类别更有用,但概率仍需要在真实数据上验证。一个模型输出 0.90,理想情况下意味着类似样本中约九成判断正确;如果实际正确率只有六成,这个数值就不能直接用于自动化审批。
上线前可以至少观察三项指标:
- 准确率或宏平均 F1:检查整体分类质量,并避免大类别掩盖小类别问题。
- 校准误差:比较置信度区间与真实正确率,例如预测概率在 0.8 到 0.9 的样本究竟有多少判断正确。
- 拒答覆盖曲线:逐步提高自动处理阈值,观察人工复核量与错误率如何变化。
业务规则也不应只使用最高概率。可以增加前两名概率差值:
def routing_policy(probabilities: list[float]) -> str:
ranked = sorted(probabilities, reverse=True)
top1 = ranked[0]
margin = ranked[0] - ranked[1]
if top1 >= 0.85 and margin >= 0.25:
return "auto_execute"
if top1 >= 0.60:
return "human_review"
return "fallback_model"
阈值只是示例,应根据误判成本调整。内容推荐可以容忍更多错误,资金操作、封禁账号或医疗分流则需要更保守的阈值和人工确认。
适合采用 Jeff 的判断清单
Jeff 最适合“候选项明确、需要快速重复决策”的节点,而不是开放式写作或复杂推理。试点时可以按下面的清单推进:
- 固定候选项定义,避免同义、重叠或边界模糊的类别;
- 用真实流量构建验证集,不只依赖公开 benchmark;
- 同时测量模型前向延迟和端到端 P95、P99 延迟;
- 为低置信度、概率接近和越界输入设置回退路径;
- 记录模型版本、候选项、概率与最终人工结果;
- 在高风险动作前保留权限检查和确定性业务规则。
这类小模型的核心优势不是“用更少参数完成所有事情”,而是让模型只承担它擅长的一项工作:在已知选项之间快速打分。只要问题能够被可靠地表达为分类或选择,Jeff 展示的单次前向决策方式就可能比“让大模型先写一段话,再猜它选了什么”更简单、更快,也更容易运营。