Outlines 快速上手:三步生成 100% 合法的 JSON,告别脆弱的解析代码
【免费下载链接】outlinesStructured Outputs项目地址: https://gitcode.com/GitHub_Trending/ou/outlines
你多半也写过这样的代码:让 LLM「只返回 JSON」,然后用json.loads接住,再配上 try-except 和正则补丁——结果每次模型心情不好,管道就崩。Outlines 换了一个思路:不靠生成后解析,而是在生成过程中就锁定输出结构,保证模型吐出的每一段内容都严格符合你声明的类型。
3 分钟跑通 Outlines 安装与第一次结构化输出
最短路径就三步:装包、接模型、传一个 Python 类型。
pip install "outlines[transformers]"这段命令安装 Outlines 本体和 transformers 后端依赖;换 Ollama、OpenAI 等后端就把方括号里的 extras 换掉,可选列表在 pyproject.toml 里。
import outlines from typing import Literal from transformers import AutoTokenizer, AutoModelForCausalLM MODEL = "microsoft/Phi-3-mini-4k-instruct" model = outlines.from_transformers( AutoModelForCausalLM.from_pretrained(MODEL, device_map="auto"), AutoTokenizer.from_pretrained(MODEL), ) sentiment = model("Analyze: 'This product changed my life!'", Literal["Positive", "Negative", "Neutral"]) print(sentiment) # "Positive"这段代码加载一个本地模型并做情感分类。注意第二个参数是Literal——它是 Python 类型,不是字符串提示。模型只能从这三个词里选,输出天然是合法的枚举值,省掉了正则和 try-catch。
用 Pydantic 模型约束复杂字段:财报数字提取
复杂对象把 Pydantic 模型直接传进去即可:
from pydantic import BaseModel class Revenue(BaseModel): period: str revenue: int gross_profit: int net_income: int result = model(prompt, Revenue, max_new_tokens=200)这段代码把 Pydantic 类当作输出类型。它会被自动翻译成 JSON Schema 并约束生成过程:字段名、数字类型一个都跑不掉。
以这张 NVIDIA 利润表为例,把「提取最近一年的收入、毛利、净利润」写进 prompt,拿到的就是符合Revenue结构的 JSON,Revenue.model_validate_json(result)之后即可直接入库,中间没有解析环节。
批量分类:用 Template 复用提示词
处理一批文本时,提示词逻辑最好从循环里抽出来:
template = outlines.Template.from_string( "Classify this document as one of: report, contract, manual.\n" "Document:\n{{ document }}\nAnswer:" ) results = model([template(document=t) for t in docs], Literal["report", "contract", "manual"], max_new_tokens=10)这段代码用 Jinja 语法定义了可复用的模板,一次传入多个提示做批量生成。Template还支持from_file从文件加载,模板可以单独维护、单独测试,不用和调用代码混在一起。
模型与约束选型:一张表看明白
| 接入方式 | 模型 | 约束能力 | 适用场景 |
|---|---|---|---|
from_transformers | 本地 Transformers | 可转向:全部类型 + 后端切换 | 本地开发、完全控制 |
from_llamacpp | GGUF 模型 | 可转向 | 低配机器本地推理 |
from_mlxlm | Apple Silicon | 可转向 | Mac 本地推理 |
from_ollama | Ollama 服务 | 黑盒:JSON 结构 | 本机 Ollama 部署 |
from_openai | OpenAI 等 API | 黑盒:JSON 结构 | 云端 API 调用 |
from_vllm/from_sglang | 推理服务 | 黑盒:JSON 结构 | 高吞吐生产部署 |
本地可转向模型(transformers、llama.cpp、MLX)靠 logits 级动态掩码做约束,正则、JSON、上下文无关语法全都支持;API 类模型由服务端原生能力负责格式。约束后端默认用 outlines-core 处理 JSON Schema 与正则、llguidance 处理上下文无关语法,也可在创建生成器时显式指定 xgrammar,详见 docs/features/advanced/backends.md。
踩坑与调优
现象:同一份代码本地跑得好好的,切到 OpenAI 直接抛异常。原因:黑盒模型不支持 logits processor,正则和上下文无关语法这类约束只能在可转向模型上生效。解法:换用 JSON 结构这类 API 原生支持(如response_format)的输出类型;必须用严格语法时,回到本地模型。
现象:输出类型不知道选什么,写了一堆字符串提示。原因:Outlines 里「类型即约束」——类型注解本身就是提示词。解法:固定枚举用Literal,数字用int,复杂对象用 Pydantic 模型;模型字段保持精简,别塞无用的默认值。
现象:想对 Ollama 模型批量推理,batch报NotImplementedError。原因:ollama 库本身不支持批量接口(见 src/outlines/models/ollama.py)。解法:逐条循环生成,或者换 transformers、vLLM 等支持批量的后端。
现象:提示词里约束写了三遍,每加一条就全量重测。原因:提示逻辑散落在调用代码里,复测成本高。解法:提示词交给Template,约束交给类型,两边解耦后各自迭代。
从能用到可靠:接下来往哪走
Outlines 把「输出结构」从生成后校验变成了生成时保证:你的 Pydantic 模型不再是文档,而是硬约束。再往进阶走,可以看上下文无关语法与自定义 DSL(docs/features/advanced/logits_processors.md),或者参考 examples/ 里的 FastAPI + vLLM 部署示例,把结构化生成做成团队能调用的服务。
【免费下载链接】outlinesStructured Outputs项目地址: https://gitcode.com/GitHub_Trending/ou/outlines
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考