【免费下载链接】TypeLLM
TypeLLM: LLMs with type-safe generation
TypeLLM 是一个让大语言模型"按类型说话"的开源框架:它不改模型架构和权重,通过 JSON Schema 约束,让 LLM 输出零幻觉的结构化结果。本文完整解析 TypeLLM 支持的 7 种字段类型(string、integer、number、boolean、enum 选择、object、array),带你快速上手类型安全生成(type-safe generation),告别"模型说一套、程序收到另一套"的解析噩梦。
为什么需要类型安全的 LLM 输出?
普通 LLM 输出的是自由文本,下游程序要靠正则、prompt 技巧和后处理来"猜"出结构化数据,稍有不慎就得到格式错误、数值越界或根本不存在的枚举值。
TypeLLM 的思路是:把"类型"直接交给解码器。每个字段由 JSON Schema 片段描述,模型在生成时就被限制在合法候选内——枚举值只能从列表里选、布尔只能是 true/false、数值按有界十进制逐位解码。配合 SGLang 的共享前缀 KV 缓存,多个字段一次调用批量完成,token 成本极低。
核心卖点一览:
- ✅无越界幻觉:选择类字段永远落在允许的候选值内
- ⚡输出 token 开销可忽略:枚举/布尔字段各只花 1 个输出 token
- 🧩依赖感知执行:
depends_on声明依赖图,独立字段并行运行 - 💭可选思考模式:需要推理的字段可先想后答,
"thinking": "auto"自动选档 - 🖼️图片输入:支持视觉语言模型,还能返回图像中目标的位置框
7 种字段类型速览
TypeLLM 的 7 种输出字段类型及返回值对照如下(来源:README.md#L193-L207):
| 字段类型 | Schema 写法 | 返回的 Python 值 |
|---|---|---|
| 文本 | {"type": "string"} | str |
| 整数 | {"type": "integer"} | int |
| 数值 | {"type": "number"} | float |
| 布尔 | {"type": "boolean"} | bool |
| 枚举选择 | {"type": "string", "enum": ["meal", "travel"]} | 候选类型之一:str/int/float |
| 对象 | {"type": "object", "properties": {...}} | dict |
| 数组 | {"type": "array", "items": {...}} | list |
1️⃣ string:自由文本与枚举选择
string是最灵活的类型,分两种用法:
- 不带
enum:自由文本生成,默认最多 128 token,可用text_max_tokens放宽; - 带
enum:枚举选择,候选 2~26 个(上限见 typellm/schema.py#L12 的MAX_ENUM_CHOICES),答案必然是其中之一。
questions = { "expense_type": { "type": "string", "enum": ["meal", "travel", "equipment"], "instructions": "What type of expense is this?", }, } # 结果必然是 "meal"、"travel" 或 "equipment",绝无第四种枚举还支持choices写法,为每个候选附加描述,帮助模型理解含义。想要"答案有多确定",给该字段加return_probabilities: True,即可拿到每个候选的概率和confidence置信度。
2️⃣ integer 与 number:有界数值解码
不需要把 0~999999 全列成枚举。integer返回int、number返回float,模型用有界十进制逐位解码数字,默认最多 32 位(numeric_max_digits可调)。
"total": {"type": "number", "instructions": "Extract the total amount in GBP."} # {"total": 324.5}进阶技巧:给number字段加levels(带顺序标签的等级),还能得到"评分(Score)"字段——返回各等级概率加权后的分数,如1.1表示介于"有替代方案"和"完全阻塞"之间。
3️⃣ boolean:是/否判断
boolean只输出True或False,适合"是否符合政策""是否已付款"这类二值判断。同样支持return_probabilities拿到两者的概率分布,配合temperature还可做有随机性的采样。
4️⃣ object 与 array:嵌套结构化数据
- object把多个带类型的属性聚合成一个值,属性内部照样可用
enum、thinking、depends_on; - array返回不定数量的同构条目,每条最多 50 个,支持
minItems/maxItems约束,条目可以是枚举值,也可以是对象。
"employees": { "type": "array", "items": {"type": "object", "properties": { "name": {"type": "string"}, "role": {"type": "string"}, }}, "instructions": "Return all employees.", } # {"employees": [{"name": "Ada", "role": "CTO"}, ...]}输入太长放不下一次调用时,用continue_from把上一段已得的条目传进去,数组会接着长、永不改写已有条目。
5️⃣ 组合拳:nullable 与字段依赖
- 任意类型加
"null"(如["number", "null"])即可表达"可能缺失",没有值时返回None; depends_on让字段引用上游结果,形成依赖图——先跑system,再并行跑severity和deployment_related,最后跑依赖二者的rollback;when条件字段:依赖字段的取值满足条件才执行,否则跳过并记入response.skipped,还支持按confidence判断"答案够不够确定"。
字段编译的完整逻辑见 typellm/schema.py(Decision/ArrayField数据类,typellm/schema.py#L24 起)。
实战:一张皱巴巴的收据,14 个类型化字段
官方示例 examples/receipt/receipt.py 把一张真实拍摄的餐厅收据照片喂给模型,一次generate()调用同时读出:
string:三行商品名(含原样保留的拼写错误)integer:行数、数量number:小计、折扣、总额、现金、找零boolean:是否现金支付- 通过
depends_on由前序字段计算出的派生字段:折扣百分比、找零是否正确、一句话报销备注
在 Qwen3.8-27B 上,不开思考 6.6 秒匹配 11/13,开思考 27.7 秒匹配 12/13,所有数值都精确命中。完整输出见 examples/receipt/result.json 与 examples/receipt/result_thinking.json,运行说明在 examples/receipt/README.md。
精度验证:JevBench 231 题基准测试
"零幻觉"只是底线,答得准才是本事。TypeLLM 在 231 道公开 JevBench 任务上的成绩:不开思考 195/231,开思考228/231(98.70%),且未做任何微调。
方法与配置细节见 evals/jevbench/METHOD.md,逐题答案见 evals/jevbench/README.md。
快速上手
pip install -U typellmfrom typellm import TypeLLMClient client = TypeLLMClient("http://127.0.0.1:30000", model="Qwen/Qwen3.8-27B") response = client.generate( context="Receipt from Hilton London. Total: £324.50", questions={ "merchant": {"type": "string", "instructions": "Return only the merchant name."}, "total": {"type": "number", "instructions": "Extract the total amount in GBP."}, "expense_type": {"type": "string", "enum": ["meal", "travel", "equipment"]}, "reimbursable": {"type": "boolean"}, }, ) print(response.result) # {"merchant": "Hilton London", "total": 324.5, "expense_type": "travel", "reimbursable": True}客户端实现位于 typellm/runtime.py,一次性请求可用便捷函数run_schema。行为测试覆盖在 tests/ 目录,其中 tests/test_structured.py 专门验证 object/array 等结构化类型。
选型建议:7 种字段类型怎么选?
| 你的场景 | 推荐字段类型 |
|---|---|
| 分类打标签、路由工单 | string+enum(加choices描述更稳) |
| 金额、数量、百分比 | number/integer |
| 合规判断、是否通过 | boolean(加return_probabilities) |
| 摘要、备注、自由描述 | string(纯文本) |
| 一组相关属性打包 | object |
| 不定数量条目:技能列表、员工清单 | array |
| 可能缺失的字段 | 任意类型 +"null" |
一句话总结:能枚举就枚举,能布尔就布尔,数值交给 integer/number,结构用 object/array 打包——把每个字段都钉死在类型里,TypeLLM 的解码器就会把"幻觉"挡在门外。
参考资料
- 项目总览与更新日志:README.md
- 类型定义与依赖图执行:typellm/schema.py、typellm/runtime.py
- 收据实战示例:examples/receipt/receipt.py
- 结构化类型测试:tests/test_structured.py
- JevBench 基准与逐题答案:evals/jevbench/
【免费下载链接】TypeLLM
TypeLLM: LLMs with type-safe generation
相关推荐
TypeChat Schema Engineering 实战指南:用 TypeScript 类型约束 LLM 输出并抑制幻觉
TypeChat Schema Engineering 实战指南:用 TypeScript 类型约束 LLM 输出并抑制幻觉 TypeChat 以"类型"为核心
大模型AI 应用后端mistral.rs JSON Schema 约束生成实战:用 Rust 客户端实现类型化结构化输出
mistral.rs JSON Schema 约束生成实战:用 Rust 客户端实现类型化结构化输出 在需要让大模型输出严格符合某种数据格式的场景(如地址解析、
推理引擎模型推理服务AI Agent多模态TypeLLM源码解析:单token分类选择与受限数字解码如何实现类型安全输出
TypeLLM源码解析:单token分类选择与受限数字解码如何实现类型安全输出 TypeLLM 是一个让大语言模型(LLM)产出 类型安全输出(type saf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考