数据抽取校验

把单据交给 Jev 判断字段,置信度够就直接走规则,不够再交给人或大模型。

模型
jev-1.14.0
耗时
1104 ms
token
536
单次花费
$0.00002251
每千次
$0.022

痛点

让大模型从发票、合同、报关单这类单据里抽字段,偶尔会编出根本不存在的数字;上规则兜底,又得逐条人工核对,反而比直接抽字段更贵。把判断这一步拆出来交给 Jev,让大模型只在不确定时才上场,是这类场景的常见解法。

Jev 判断什么

state 里放了原文 document 和四个候选项 a/b/c/d,整轮判断围绕「这四个候选里哪一个是某字段」和「文档有没有陈述某事实」这两类题型展开。

total_amount(Choice):题面「Which candidate is the invoice's total amount?」,选项 a/b/c/d 分别指向 candidates.a/b/c/d 的文本。这次返回选了 a(即 ¥1,280.00),四个选项的概率是 a=1.0、b=0.0、c=0.0、d=0.0,置信度 1.0。选择题四个概率构成清晰分布,a 直接拉满,说明 Jev 锁死了候选 a 这串文本。代码直接读 choice 字段拿选项 id,再回查 candidates[id] 拿真实字符串,跳过任何二次加工。

has_due_date(Noul):题面「Does the document state when payment is due?」。这次返回答案「是」的概率为 0.85。Noul 只返回 true 的概率(即 1 - p_false),0.85 已经远离 0.5 的灰色地带,可以判定为「是」。代码读这个概率即可:高于自己设定的阈值判 true,低于则升级复核,不用关心它内部是怎么算的。

和大模型怎么配合

流程是:先把多条题目打包进一份 state 调 Jev,代码按每道题的返回结果走规则——置信度足够高、概率一边倒的(如这次 total_amount 置信度 1.0、a 概率 1.0)直接走程序,不调大模型;置信度不足或 Noul 概率贴近阈值的,升级交给大模型或人工复核。这套思路下,绝大部分单据在 Jev 这一步就能闭环,只有少数灰区样本才真的需要花大模型的预算。

实测这次调用是模型 jev-1.14.0,耗时 1104 毫秒,输入 536 个 token,单次花费 0.000023 美元,按此折算每 1000 次约 0.0225 美元。Jev 定价是每百万输入 token 0.042 美元、输出不收钱,校验这一层跑批量非常便宜。

上线前注意

  • 题面(question)用英文写,state 里的中文原文(如开票日期、付款期限)不要翻译成英文,否则 Jev 看到的关键线索会被你换掉。
  • 不要拍脑袋设阈值,先拿 20–30 条真实单据跑一遍,看一眼置信度和概率分布,再定 Choice 的最低置信度门槛和 Noul 的判定阈值。
  • 总价、金额这类关键字段,只要 Jev 置信度偏低或对应概率不一边倒,立刻升级人工或大模型复核,不要让规则直接放行。
  • 不需要的字段不要写题问,state 里少塞一个 candidate、Jev 就少算一次,整批调用的 token 也会更省;同一份 document 下能合并的题目尽量合并到一次请求里发出去。

真实调用

请求

bash
curl https://api.typesafe.ai/v1/systemone \
  -H "Authorization: Bearer $TYPESAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "jev-1.14.0",
  "state": {
    "document": "发票号:INV-20261015-007,开票日期 2026 年 10 月 15 日,合计金额 ¥1,280.00(含税),付款期限 30 天。",
    "candidates": {
      "a": "¥1,280.00",
      "b": "30 天",
      "c": "INV-20261015-007",
      "d": "2026 年 10 月 15 日"
    }
  },
  "questions": {
    "total_amount": {
      "type": "choice",
      "instructions": "Which candidate is the invoice's total amount?",
      "criteria": {
        "a": "The text in `candidates.a`",
        "b": "The text in `candidates.b`",
        "c": "The text in `candidates.c`",
        "d": "The text in `candidates.d`"
      }
    },
    "has_due_date": {
      "type": "noul",
      "instructions": "Does the document state when payment is due?"
    }
  }
}'

返回

json
{
  "model": "jev-1.14.0",
  "answers": {
    "total_amount": {
      "type": "choice",
      "choice": "a",
      "confidence": 1,
      "probabilities": {
        "a": 1,
        "b": 0,
        "c": 0,
        "d": 0
      }
    },
    "has_due_date": {
      "type": "noul",
      "noul": 0.85
    }
  },
  "usage": {
    "input_tokens": 536,
    "output_tokens": 65
  }
}

人话解读

  • Choice:选了 a,置信度 1.00
  • Noul:「是」的概率 0.85