Jev 案例:发票审批门禁与兜底(完整代码)
更新于 适用版本 Jev 1.13 示例数据(example fixture)
TL;DR: 本示例用一道判断题搭建发票审批门禁:Jev 1.13 以
yes/no/unclear加置信度回答”符合政策是否应该自动批准?“,只有yes且置信度不低于 0.8 才自动批准,其余一律兜底转人工。完整 Python 脚本见下文。
场景
我们的应付账款团队每月处理几千张发票。绝大多数毫无悬念——金额低于 500 美元、对得上采购单(PO)、供应商正确。但初级会计还是要把每张发票打开,对着 PO 核三个字段,再点一下批准:每张十秒钟的专业注意力,一个月重复几千次。
政策本身一句话就能说清,于是我们把它变成了一道判断题:
这张发票符合政策(金额低于 500 美元且匹配采购单),是否应该自动批准?
再加一条兜底规则——这才是本案例真正想讲的东西:
answer: "yes"且confidence >= 0.8→ 自动批准,归档 rationale;answer: "no"→ 拒绝,附 rationale 通知应付团队;answer: "unclear"或confidence < 0.8→ 转人工审核队列。
门禁绝不会在一声耳语上自动批准。一个判断模型说”yes,0.55”,等于在告诉你这张发票处在灰色地带——PO 号缺失、行项目反常、供应商名字对不上。这些恰恰是人应该看的发票,也恰恰说明 Jev——TypeSafe AI 发布的 System One 判断模型(2026 年 9 月)——为什么把置信度作为类型化输出的一等字段返回,而不是埋在一段散文里。调用走 OpenRouter 的 OpenAI 兼容端点。
请求
{
"model": "typesafe/jev-1.13",
"messages": [
{
"role": "system",
"content": "Judgment question. Should this invoice be auto-approved under policy (amount under $500, matching a purchase order)? Answer yes, no, or unclear. Reply with JSON only: {\"answer\": <yes|no|unclear>, \"confidence\": <0-1>, \"rationale\": <one sentence>}"
},
{
"role": "user",
"content": "Invoice INV-2041 from Northwind Office Supply\nAmount: $412.80 | PO: PO-8877 | Terms: Net 30\nLine items: 12 ergonomic chair mats, matching PO-8877 pricing."
}
]
}
响应
示例数据(example fixture)——用于说明格式,不是线上实测抓包:
{
"answer": "yes",
"confidence": 0.97,
"rationale": "Amount is under $500, the invoice references PO-8877, and line items match the purchase order pricing."
}
这个示例刻意选了最平淡的情况:干净的 yes、高置信度、自动批准。门禁真正的价值在两个字段任何一个变差的情形里——见下面的兜底分支。
复现脚本
保存为 gate.py,设置环境变量 OPENROUTER_API_KEY 后运行 python3 gate.py:
import json, os, urllib.request
URL = "https://openrouter.ai/api/v1/chat/completions"
MODEL = "typesafe/jev-1.13" # confirm exact slug on the OpenRouter model page
HUMAN_REVIEW_CONFIDENCE = 0.8
SYSTEM = ('Judgment question. Should this invoice be auto-approved under '
'policy (amount under $500, matching a purchase order)? '
'Answer yes, no, or unclear. Reply with JSON only: '
'{"answer": <yes|no|unclear>, "confidence": <0-1>, "rationale": <one sentence>}')
def gate(invoice_text):
body = {"model": MODEL, "messages": [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": invoice_text}]}
req = urllib.request.Request(URL, data=json.dumps(body).encode(),
headers={"Authorization": "Bearer " + os.environ["OPENROUTER_API_KEY"],
"Content-Type": "application/json"})
with urllib.request.urlopen(req) as res:
payload = json.load(res)
result = json.loads(payload["choices"][0]["message"]["content"])
if result["answer"] == "yes" and result["confidence"] >= HUMAN_REVIEW_CONFIDENCE:
return "auto-approved", result
return "human-review", result
invoice = """Invoice INV-2041 from Northwind Office Supply
Amount: $412.80 | PO: PO-8877 | Terms: Net 30
Line items: 12 ergonomic chair mats, matching PO-8877 pricing."""
print(gate(invoice))
关键参数
| 字段 | 取值 | 说明 |
|---|---|---|
model | typesafe/jev-1.13 | 固定版本——审批政策的行为不允许悄悄漂移。准确 slug 请以 OpenRouter 模型页为准。 |
messages[0](system) | 判断题 + 完整政策 + JSON 结构 | 政策那句话就是审批规则。政策变了,只需要改这一行。 |
messages[1](user) | 发票结构化字段 | 传应付团队本来就抽取好的字段,不需要传 PDF。 |
answer(响应) | yes | 与置信度一起决定分支:批准 / 拒绝 / 转人工。 |
confidence(响应) | 0.97(示例数据) | 兜底触发器:yes 但低于 0.8 依然转人工。 |
rationale(响应) | 一句话 | 随决策一起归档,就是每一次自动批准的审计线索。 |
| 价格 | $0.0462 / 1M input tokens | 每张发票一次调用;预算前请在 OpenRouter 核对当前价格。 |
注意事项
- 响应为示例数据(example fixture);字段名请与官方文档核对后再依赖。官方 API 细节在 typesafe.ai,入口是System One 模型发布公告。
- 上线前请在 OpenRouter 模型页确认准确的模型 slug(
typesafe/jev-1.13)。 - 生产环境要做防御式解析:
confidence缺失或不是数字时,一律按转人工处理,绝不能当作批准。 - 每周记录置信度分布。低置信度占比突然上升,通常说明你们的发票构成变了,而不是模型变了。
- system 提示词里的政策句子要与书面审批政策保持同步——模型只知道你写进去的那条规则。
- 适用于 Jev 1.13(2026 年 9 月发布),演示渠道为 OpenRouter。