ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

别再手动校验 LLM 输出:Outlines 结构化生成 30 分钟上手

别再手动校验 LLM 输出:Outlines 结构化生成 30 分钟上手 别再手动校验 LLM 输出Outlines 结构化生成 30 分钟上手【免费下载链接】outlinesStructured Outputs项目地址: https://gitcode.com/GitHub_Trending/ou/outlinesOutlines 结构化生成只做一件事LLM 每吐一个 token 之前先和你定义的结构对一遍不符合的 token 根本不会被生成出来。你不需要再为模型返回的 JSON 手写校验代码、写格式不对请重试的兜底提示——输出天然落在你的 Pydantic 模型、正则或上下文无关文法里。翻车现场把 JSON 吐给你的 API 那一瞬间所有让模型重试一下的兜底代码都可以删了。先说最常见的线上事故上游服务约定返回 JSON你在 prompt 里写了请只输出 JSON结果模型前面吐了半截{name:后面开始解释以下是您要的角色设定。于是你写后处理正则去抠抠不出来就调模型重生成重试三次还失败就吞掉异常。prompt 约束本质是求模型配合后处理校验本质是生成完了再擦屁股两条路都在浪费 token。Outlines 的解法换个思路不让模型尽量生成合法 JSON而是让它只能生成合法 JSON。下面这套流程在本地就能跑不依赖任何 API key。先装好它三步加载模型# pip install outlines[transformers] import transformers import outlines name HuggingFaceTB/SmolLM2-135M-Instruct model outlines.from_transformers( transformers.AutoModelForCausalLM.from_pretrained(name), transformers.AutoTokenizer.from_pretrained(name), ) # 不传约束模型自由发挥 print(model(22? 用一个单词回答))装完加载model就是一个可调用对象。同一个model第二个参数传什么类型输出就长什么结构——这是后文所有玩法的开关。注意它只封装了本地推理Transformers、llama.cpp、MLXLM 这三类模型能直接操控生成过程OpenAI、Anthropic、Gemini、vLLM 等 API 模型也接入了 Outlines约束会通过服务端的 guided decoding 完成调用方式不变。⚡ 用 Pydantic 模型锁定输出字段把一个 Pydantic 类作为第二个参数传进去模型输出的每个 token 都在你的 schema 约束下拿到手就能model_validate_json一步都不用修。from datetime import date from pydantic import BaseModel class Character(BaseModel): name: str birth_date: date skills: list[str] result model(创建一个游戏角色, Character) print(result) # {name: Aurora, birth_date: 1990-06-15, ...} print(Character.model_validate_json(result)) # 直接拿到 Pydantic 对象字段怎么定的输出就怎么长birth_date: date保证日期格式永远合法skills: list[str]保证是个数组缺字段、多字段、类型错位这类事在生成阶段就物理上不可能发生。把这套能力用在数据抽取上就很直观——比如仓库里有个超市小票数字化的例子把小票图片丢给多模态模型让它把商品、数量、金额抽成结构化记录每条记录都是一个 Pydantic 实例直接入库。不止 JSONint、枚举、正则都是合法的输出模具约束类型不只有 JSON Schema基础类型、枚举、正则甚至一整篇 Lark 文法都能当模具直接传给model。from enum import Enum from outlines.types import Regex class Food(Enum): pizza pizza burger burger print(model(世界上大约有多少个国家, int)) # 200只会生成整数不会生成大约 200 print(model(披萨还是汉堡, Food)) # pizza只会生成枚举里定义的取值 print(model(写一个三位数, Regex(r[0-9]{3}))) # 236恰好三位数字多一位少一位都不行正则还能用组合子拼either、at_least、optional这些运算符在 src/outlines/types/ 里都有另外内置了uuid4、ipv4、semver、email这类现成的正则类型拿来即用。更重的玩法是上下文无关文法把一段 Lark 语法规则比如四则运算表达式作为CFG对象传进去模型就只能生成该文法接受的字符串——官方文档里的算术文法示例可以直接抄。高频调用时把模型和约束打包成Generator约束只编译一次from outlines import Generator # 模型 约束打包成一个对象约束的编译只做一次 gen Generator(model, Character) print(gen(创建一个角色)) print(gen(再创建一个角色换个职业))对本地模型来说这一步很关键把 schema 编译成约束处理器可能要几百毫秒Generator让这活儿只在初始化时付一次后续调用直接复用。核心实现在 src/outlines/generator.py。它是怎么做到的logits 处理器给模型戴了个嘴套原理一句话模型每生成一个 token 前先看当前词表里哪些 token 会把输出带出合法轨道把这些 token 的概率直接砍成 -inf剩下的才参与采样。就像给模型戴了个嘴套每次张嘴前先过一遍滤网——模型想说错话但嘴上只可能说出对的话。具体分工是这样的约束Pydantic 类、正则、CFG先被编译成有限状态机生成过程中状态机跟着 token 走每步给出当前合法 token 集合。Outlines 内置三个编译后端——xgrammar、outlines-core、llguidance源码在 src/outlines/backends/可以按模型和约束类型选logits 处理器文档里还有一个只允许输出 0 和 1的自定义处理器示例能直观看到掩码是怎么加的。API 类模型OpenAI 等没有本地词表可拦Outlines 会把 schema 转成服务端的结构化输出请求效果等价写法不变。下一步跑完这三件事用上面第一个代码块在本地跑通自由文本生成确认 transformers 环境没问题换 Pydantic 约束重跑用Character.model_validate_json(result)验证输出再试试故意把字段改成conint(ge18, le99)看年龄被锁在区间里把Regex(r[0-9]{3})换成CFG文法约束抄文档里的四则运算语法感受生成即合法的边界在哪【免费下载链接】outlinesStructured Outputs项目地址: https://gitcode.com/GitHub_Trending/ou/outlines创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表