TheoLeeCJ/SemIf · 上手攻略
- 仓库:TheoLeeCJ/SemIf
- 链接:https://github.com/TheoLeeCJ/SemIf
- 分类:AI Agent 工具链 · 决策推理
- 作者:Tom
- 更新:2026-09-19
是什么
SemIf(Semantic Ifs)是一个用开源 LLM 直接读取 typed option logits做运行时决策的开源工具。它让模型在单次前向传播内直接输出选项概率,而无需生成文本再解析——"不要 token,只要 logits"。
原名 OpenJev,后改名 SemIf,是独立研究项目,非 Jev / TypeSafe 官方。Jev 是 TypeSafe 的闭源托管服务,提供类似的语义决策接口;SemIf 复现了其接口模式,但用的是自己的提示工程和开源模型(非 Jev 闭源模型)。
核心思想:大多数 Agent 的决策是小的 if-then:route this、retry that、does evidence support X?本可以由 chat model 回答,但传统做法要先生成文本再 parse 回 if 语句。SemIf 直接从 model logit 读 typed option 概率,去掉了解码循环,延迟降低 5 倍以上(见下方 benchmark 数据)。
解决什么问题
- 省掉生成-解析开销:传统方案让 LLM 生成 "yes/no" 或 JSON,再软件解析;SemIf 直接读取 option token logits,一次 forward pass 出结果。
- 共享状态复用:长 state 只需 prefilled 一次,多个 criteria 并行分支评估,减少重复计算。
- 本地可复现:不依赖任何闭源 API,用自己的 GPU(实测 RTX 3090)就能跑 4B 模型。
- 可审计:所有 fixture、runner、row-level outputs、revisions、prompts 均 committed 到 repo,实验可复现。
快速安装
环境要求
- Python 3.10+
- CUDA + NVIDIA GPU(至少能装下 4B BF16 模型,≈8 GB VRAM)
- ⚠️ 实测环境:Ubuntu 22.04 / NVIDIA driver 595.71.05 / CUDA 12.8 / PyTorch 2.10.0+cu128 / Transformers 5.17.0 / BF16 / RTX 3090。CUDA 版本兼容性是坑,建议严格对齐。
安装步骤
# 1. 创建虚拟环境
python -m venv .venv
source .venv/bin/activate
# 2. 指定模型缓存路径(需要较大存储空间)
export HF_HOME=/path/to/large-drive/huggingface
# 3. 安装
pip install -r requirements.txt
pip install -e '.[test]'
# 4. 验证
pytest -q
⚠️
requirements.txtpinned 了实测过的 Python 包;CUDA-enabled PyTorch wheel 仍需兼容的 NVIDIA driver。CUDA 12.8 比较新,部分旧 driver 可能不支持。
Apple Silicon(macOS arm64)使用 MLX 后端:
pip install -e '.[test,mlx]'
# 运行 scorer 命令时加 --backend mlx
核心用法
基本评分命令
SemIf 通过 semif-score CLI 对 JSONL 输入文件输出评分结果:
# 直接评分(每次独立前向)
CUDA_VISIBLE_DEVICES=0 semif-score \
--mode direct \
--model Qwen/Qwen3.5-4B \
--revision 851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a \
--input examples/decisions.jsonl \
--output results.jsonl
三种模式:
| 模式 | 说明 | 适用场景 |
|---|---|---|
direct |
每次独立评分 | 不同 state 不同 criteria |
serial |
相同 state 复用 KV-cache | 连续多个 criteria 评估同一 state |
shared |
所有 row 同 exact state | 并行分支评估同一 state 的多个 criteria |
reranker |
使用 Qwen3-Reranker-4B |
候选 ranking 任务(检索类) |
输入格式(JSONL)
每行一个 JSON 决策请求:
{
"id": "route-1",
"state": "Customer cannot access an account after a password reset.",
"question": "Which queue should handle this request?",
"options": [
{"id": "access", "description": "Account access support."},
{"id": "billing", "description": "Billing support."}
]
}
state:非空字符串、JSON 对象或 JSON 数组均可options:含id和description- 返回每行包含 typed option scores、timing、exact model revision、prompt hash
Benchmark 数据(单卡 RTX 3090,Qwen3.5-4B)
决策延迟对比:
| 方法 | 中位延迟 | 输出 token |
|---|---|---|
| Direct typed logits(SemIf) | 1.023 s | 0 |
| Autoregressive JSON array | 5.332 s | 111 |
直接 logit 读取比生成完整 JSON array 快 5.21×,且不采样任何 output token。
大规模并行场景(37 states × 21 criteria = 777 decisions):
| 执行路径 | Decisions/s | 总耗时 |
|---|---|---|
| Fresh direct scoring | 2.33 | 333.1 s |
| Serial prefix reuse | 10.75 | 72.3 s |
| Parallel suffixes | 20.03 | 38.8 s |
串行复用提速 4.6×,并行后缀提速 8.6×。
质量数据(⚠️ 以下为 repo 内 committed 实验结果,未经独立第三方验证)
模型在各类任务上的 balanced accuracy(直接 logits vs reranker):
| 模型 | 量化格式 | 显存 | Authored decisions | WANLI | TypeSafe 子集 agreement |
|---|---|---|---|---|---|
| Qwen3-0.6B | Q8_0 | 639 MB | 0.440 | 0.528 | 0.407 |
| MiniCPM5-2B | Q4_K_M | 1.56 GB | 0.686 | 0.693 | 0.637 |
| Qwen3.5-4B | Q4_K_M | 3.01 GB | 0.813 | 0.766 | 0.845 |
| Jev(闭源参考) | — | — | — | — | 0.883 |
⚠️ Jev 数字来自 TypeSafe 公开记录,非 live endpoint 结果;对比基于能从公开 artifact 对齐的 102 行,而非 Jev 报告的 711 行 aggregate。
性能对比:Direct vs Reranker
- 检索类任务(code retrieval / company knowledge):reranker 强
- 通用决策类任务:direct logits 是更好的 baseline
- ⚠️ reranker 在 categorical threshold 指标上不应与 ranking quality 混淆
典型适用场景
- Agent 路由决策:route、retry、evidence check 等小决策,无需完整生成路径
- 多标准并行评估:同一 state 需要同时过多个 criteria(如合规检查、安全过滤)
- LLM-based 分类/筛选:在 pipeline 中做 fast typed classification
- 本地实验研究:无 API 依赖,自托管decision-making 模块
- 检索排序辅助:reranker 模式用于 RAG 或搜索结果的 reranking
坑与注意
- ⚠️ CUDA/PyTorch 版本严格:实测 CUDA 12.8 + PyTorch 2.10.0+cu128 + Transformers 5.17.0,其他组合未经验证,踩坑概率高
- ⚠️ prefix cache 提速是实验性结果:BF16 执行相对 fresh scoring 改变了 5-6 / 777 个 argmax 决策,边界情况注意
- ⚠️ 量化版与 BF16 质量有差距:Browser demo 用 GGUF 量化版,smoke test 只验证能跑,不代表量化版达到 BF16 质量
- ⚠️ Softmax over options 不是 calibrated confidence:概率是条件于提供的 options 的,不是操作层面的置信度,需要自行校准
- ⚠️ forced typed output 可能语义错误:logits 正确不代表语义判断正确,选项描述设计影响很大
- ⚠️ reranker 模式不等于通用决策:reranker 适合 ranking 类任务,通用决策场景直接 logits 模式更优
- 无生产级保障:研究原型,无 SLA,错误处理和边界情况需自己加固
- 输出路径保护:命令拒绝覆盖已存在的输出文件;输入截断也不会静默发生
与同类对比
| 方案 | 类型 | 闭源 | 本地运行 | 生成解码 | 速度 | 适用场景 |
|---|---|---|---|---|---|---|
| SemIf | 直接 logit 读取 | ❌ 开源 | ✅ RTX 3090 | ❌ 无 | 最快 | 小决策、并行评估、routing |
| Jev(TypeSafe) | 同接口模式 | ✅ 闭源 | ❌ API | 未知 | 未知 | 闭源参考基准 |
| 标准 chat API + JSON parse | 生成式 | 视提供商 | 视本地模型 | ✅ 完整生成 | 慢(5×+) | 需要完整解释/上下文 |
| vLLM / SGLang batch scoring | 批量 logit | ❌ 开源 | ✅ | ❌ | 快 | 高并发批量推理 |
| Qwen3-Reranker-4B 独立使用 | 专用 reranker | ❌ 开源 | ✅ | ❌ | 快 | 检索排序 |
SemIf 的独特价值:提供完整的研究级 benchmark 证据(706 行 fixture、revisions、raw outputs),让决策系统可以在本地以可复现方式验证质量,而非黑盒依赖 API。
一句话推荐结论
SemIf 把「LLM 做决策」的延迟从生成模式降到了接近 pure inference,价格透明、结果可复现,适合所有想在本地用开源模型做 typed decision 而非套壳生成的应用场景。 RTX 3090 就能跑,5× 速度优势明显,但注意它目前是研究原型、CUDA 版本要求较新、prefix cache 提速有边界风险。**