dottxt-ai/outlines
摘要
Outlines 是一个 Python 库,可确保在生成过程中从 LLM 获得结构化输出(JSON、Pydantic 模型等),跨多个模型提供商工作以消除解析错误。
查看缓存全文
缓存时间: 2026/07/21 12:36
dottxt-ai/outlines 来源:https://github.com/dottxt-ai/outlines 🗒️ LLM 的结构化输出 🗒️ 由 .txt 团队用 ❤👷️ 打造(https://dottxt.co)受 NVIDIA、Cohere、HuggingFace、vLLM 等信赖。[![PyPI 版本][pypi-version-badge]][pypi] [![下载量][downloads-badge]][pypistats] [![星标][stars-badge]][stars] [![Discord][discord-badge]][discord] [![博客][dottxt-blog-badge]][dottxt-blog] [![Twitter][twitter-badge]][twitter]
.txt API 目前处于早期访问阶段。立即申请访问 →(https://h1xbpbfsf0w.typeform.com/to/fwQNWmS8?utm_source=github&utm_medium=organic&utm_campaign=outlines)
🚀 构建结构化生成的未来
我们正在与选定的合作伙伴合作,开发新的结构化生成接口。需要 XML、FHIR、自定义模式或语法?请与我们联系。审计您的模式:共享一个模式,我们将展示生成过程中哪些部分会出错、修复问题的约束条件,以及前后的合规率。在此注册(https://h1xbpbfsf0w.typeform.com/to/rtFUraA2?typeform)。
目录
为什么选择 Outlines?
LLM 功能强大,但输出不可预测。大多数解决方案尝试在生成后通过解析、正则表达式或容易损坏的脆弱代码来修复错误的输出。Outlines 确保在生成过程中——直接来自任何 LLM——输出结构化结果。
- 适用于任何模型 – 相同的代码可在 OpenAI、Ollama、vLLM 等上运行
- 集成简单 – 只需传递所需的输出类型:
model(prompt, output_type) - 保证结构有效 – 无需再为解析头疼,也无需处理损坏的 JSON
- 提供商无关 – 无需更改代码即可切换模型
Outlines 理念
Outlines 遵循一种简单的模式,与 Python 自身的类型系统相呼应。只需指定所需的输出类型,Outlines 就能确保数据与该结构完全匹配:
- 对于是/否响应,使用
Literal["Yes", "No"] - 对于数值,使用
int - 对于复杂对象,使用 Pydantic 模型(https://docs.pydantic.dev/latest/)定义结构
快速开始
使用 outlines 非常简单:
1. 安装 outlines
shell pip install outlines
2. 连接到您偏好的模型
`` python import outlines from transformers import AutoTokenizer, AutoModelForCausalLM
MODEL_NAME = “microsoft/Phi-3-mini-4k-instruct”
model = outlines.from_transformers( AutoModelForCausalLM.from_pretrained(MODEL_NAME, device_map=“auto”), AutoTokenizer.from_pretrained(MODEL_NAME) ) ``
3. 从简单的结构化输出开始
`` python from typing import Literal from pydantic import BaseModel
简单分类
sentiment = model( “分析:‘这款产品彻底改变了我的生活!’”, Literal[“Positive”, “Negative”, “Neutral”] ) print(sentiment) # “Positive”
提取特定类型
temperature = model(“水的沸点是多少摄氏度?”, int) print(temperature) # 100 ``
4. 创建复杂结构
`` python from pydantic import BaseModel from enum import Enum
class Rating(Enum): poor = 1 fair = 2 good = 3 excellent = 4
class ProductReview(BaseModel): rating: Rating pros: list[str] cons: list[str] summary: str
review = model( “评测:XPS 13 电池续航出色,屏幕惊艳,但发热严重,摄像头质量差。”, ProductReview, max_new_tokens=200, ) review = ProductReview.model_validate_json(review) print(f“评分: {review.rating.name}“) # “评分: good” print(f“优点: {review.pros}“) # “优点: [‘great battery life’, ‘stunning display’]” print(f“总结: {review.summary}“) # “总结: Good laptop with great display but thermal issues” ``
真实世界示例
以下是可以直接投入生产的示例,展示 Outlines 如何解决常见问题:
🙋♂️ 客户支持工单分类
此示例展示了如何将自由格式的客户电子邮件转换为结构化的服务工单。通过解析优先级、类别和升级标志等属性,代码能够自动路由和处理支持问题。
`` python import outlines from enum import Enum from pydantic import BaseModel from transformers import AutoTokenizer, AutoModelForCausalLM from typing import List
MODEL_NAME = “microsoft/Phi-3-mini-4k-instruct”
model = outlines.from_transformers( AutoModelForCausalLM.from_pretrained(MODEL_NAME, device_map=“auto”), AutoTokenizer.from_pretrained(MODEL_NAME) )
def alert_manager(ticket): print(“警报!”, ticket)
class TicketPriority(str, Enum): low = “low” medium = “medium” high = “high” urgent = “urgent”
class ServiceTicket(BaseModel): priority: TicketPriority category: str requires_manager: bool summary: str action_items: List[str]
customer_email = “”“ 主题:紧急 - 付款后无法访问账户
我三小时前购买了高级计划,但仍然无法使用任何功能。我多次尝试退出并重新登录,但都没用。我一小时后有客户演示,需要分析仪表板,这让人无法接受。请立即解决这个问题,否则退款。 “”“
prompt = f““” <|im_start|>user 分析此客户电子邮件: {customer_email} <|im_end|> <|im_start|>assistant “”“
ticket = model( prompt, ServiceTicket, max_new_tokens=500 )
使用结构化数据路由工单
ticket = ServiceTicket.model_validate_json(ticket) if ticket.priority == “urgent” or ticket.requires_manager: alert_manager(ticket) ``
📦 电商产品分类
此用例演示 outlines 如何将产品描述转换为结构化的分类数据(例如主类别、子类别和属性),以简化库存管理等任务。每条产品描述都会自动处理,减少手动分类的开销。
``python import outlines from pydantic import BaseModel from transformers import AutoTokenizer, AutoModelForCausalLM from typing import List, Optional
MODEL_NAME = “microsoft/Phi-3-mini-4k-instruct”
model = outlines.from_transformers( AutoModelForCausalLM.from_pretrained(MODEL_NAME, device_map=“auto”), AutoTokenizer.from_pretrained(MODEL_NAME) )
def update_inventory(product, category, sub_category): print(f“已更新产品 {product.split(‘,’)[0]} 类别为 {category}/{sub_category}“)
class ProductCategory(BaseModel): main_category: str sub_category: str attributes: List[str] brand_match: Optional[str]
批量处理产品描述
product_descriptions = [ “Apple iPhone 15 Pro Max 256GB 钛金属,6.7 英寸超视网膜 XDR 显示屏,支持 ProMotion”, “有机棉 T 恤,男款中号,海军蓝,100% 可持续材料”, “KitchenAid 立式搅拌机,5 夸脱,红色,10 档速度,带面团钩附件” ]
template = outlines.Template.from_string(“”“ <|im_start|>user 将以下产品分类: {{ description }} <|im_end|> <|im_start|>assistant “”“)
对所有产品获取结构化分类
categories = model( [template(description=desc) for desc in product_descriptions], ProductCategory, max_new_tokens=200 )
使用分类进行库存管理
categories = [ ProductCategory.model_validate_json(category) for category in categories ]
for product, category in zip(product_descriptions, categories): update_inventory(product, category.main_category, category.sub_category) ``
📊 解析不完整数据中的事件详情
此示例使用 outlines 将事件描述解析为结构化信息(如事件名称、日期、地点、类型和主题),即使数据不完整也能处理。它利用联合类型返回结构化事件数据或回退的“我不知道”答案,确保在各种情况下都能稳健提取。
``python import outlines from typing import Union, List, Literal from pydantic import BaseModel from enum import Enum from transformers import AutoTokenizer, AutoModelForCausalLM
MODEL_NAME = “microsoft/Phi-3-mini-4k-instruct”
model = outlines.from_transformers( AutoModelForCausalLM.from_pretrained(MODEL_NAME, device_map=“auto”), AutoTokenizer.from_pretrained(MODEL_NAME) )
class EventType(str, Enum): conference = “conference” webinar = “webinar” workshop = “workshop” meetup = “meetup” other = “other”
class EventInfo(BaseModel): “”“关于技术事件的结构化信息”“” name: str date: str location: str event_type: EventType topics: List[str] registration_required: bool
创建一个联合类型,可以是结构化的 EventInfo 或文本 “I don’t know”
EventResponse = Union[EventInfo, Literal[“I don’t know”]]
示例事件描述
event_descriptions = [ # 完整信息 “”“ 欢迎参加 DevCon 2023,顶级开发者大会,将于 2023 年 11 月 15-17 日在旧金山会议中心举行。主题包括 AI/ML、云基础设施和 web3。需要注册。 “”“, # 信息不足 “”“ 下周有技术活动。更多详情即将公布! “”“ ]
处理事件
results = [] for description in event_descriptions: prompt = f““” <|im_start>system 你是一个有用的助手 <|im_end|> <|im_start>user 提取此技术事件的结构化信息: {description}
如果有足够信息,返回一个包含以下字段的 JSON 对象:
- name: 事件名称
- date: 事件举办日期
- location: 事件举办地点
- event_type: 可以是 ‘conference’, ‘webinar’, ‘workshop’, ‘meetup’ 或 ‘other’
- topics: 事件主题列表
- registration_required: 表示是否需要注册的布尔值
如果可用信息不足以填充此 JSON,则回答 ‘I don’t know’。 <|im_end|> <|im_start|>assistant “”“
# 联合类型允许模型返回结构化数据或 "I don't know"
result = model(prompt, EventResponse, max_new_tokens=200)
results.append(result)
显示结果
for i, result in enumerate(results): print(f“事件 {i+1}:“) if isinstance(result, str): print(f” {result}“) else: # 是 EventInfo 对象 print(f” 名称: {result.name}“) print(f” 类型: {result.event_type}“) print(f” 日期: {result.date}“) print(f” 主题: {’, ’.join(result.topics)}“) print()
在后续处理中使用结构化数据
structured_count = sum(1 for r in results if isinstance(r, EventInfo)) print(f“成功提取 {structured_count} / {len(results)} 个事件的数据“) ``
🗂️ 将文档归类为预定义类型
在此案例中,outlines 使用字面类型规范将文档分类为预定义类别(例如“财务报告”、“法律合同”)。分类结果以表格格式和类别分布摘要的形式显示,说明结构化输出如何简化内容管理。
``python import outlines from typing import Literal, List import pandas as pd from transformers import AutoTokenizer, AutoModelForCausalLM
MODEL_NAME = “microsoft/Phi-3-mini-4k-instruct”
model = outlines.from_transformers( AutoModelForCausalLM.from_pretrained(MODEL_NAME, device_map=“auto”), AutoTokenizer.from_pretrained(MODEL_NAME) )
使用 Literal 定义分类类别
DocumentCategory = Literal[ “Financial Report”, “Legal Contract”, “Technical Documentation”, “Marketing Material”, “Personal Correspondence” ]
待分类的示例文档
documents = [ “第三季度财务摘要:营收同比增长 15% 至 1240 万美元。EBITDA 利润率改善至 23%,去年同期为 19%。运营费用…”, “本协议由甲方和乙方(以下合称“双方”)于… 日签订”, “该 API 接受带有 JSON 负载的 POST 请求。必需参数包括 ‘user_id’ 和 ‘transaction_type’。成功时端点返回 200 状态码。” ]
template = outlines.Template.from_string(“”“ <|im_start|>user 将以下文档分类为以下类别之一:
- Financial Report
- Legal Contract
- Technical Documentation
- Marketing Material
- Personal Correspondence
文档:{{ document }} <|im_end|> <|im_start|>assistant “”“)
分类文档
def classify_documents(texts: List[str]) -> List[DocumentCategory]: results = [] for text in texts: prompt = template(document=text) # 模型必须返回预定义类别之一 category = model(prompt, DocumentCategory, max_new_tokens=200) results.append(category) return results
执行分类
classifications = classify_documents(documents)
创建简单结果表格
results_df = pd.DataFrame({ “文档”: [doc[:50] + “…” for doc in documents], “分类”: classifications }) print(results_df)
按类别统计文档数
category_counts = pd.Series(classifications).value_counts() print(“\n类别分布:”) print(category_counts) ``
📅 通过函数调用从请求中安排会议
此示例演示 outlines 如何解释自然语言会议请求,并将其转换为匹配预定义函数参数的结构化格式。一旦提取出会议详情(例如标题、日期、持续时间、参与者),即可自动安排会议。
``python import outlines import json from typing import List, Optional from datetime import date from transformers import AutoTokenizer, AutoModelForCausalLM
MODEL_NAME = “microsoft/phi-4”
model = outlines.from_transformers( AutoModelForCausalLM.from_pretrained(MODEL_NAME, device_map=“auto”), AutoTokenizer.from_pretrained(MODEL_NAME) )
定义具有类型参数的函数
def schedule_meeting( title: str, date: date, duration_minutes: int, attendees: List[str], location: Optional[str] = None, agenda_items: Optional[List[str]] = None ): “”“使用指定的详情安排会议”“” # 在实际应用中,这将创建会议 meeting = { “title”: title, “date”: date, “duration_minutes”: duration_minutes, “attendees”: attendees, “location”: location, “agenda_items”: agenda_items } return f“会议 ‘{title}’ 已安排在 {date},共有 {len(attendees)} 位参与者“
自然语言请求
user_request = “”“ 我需要在下周二下午 2 点与工程团队安排一次产品路线图评审。会议时长为 90 分钟。请邀请 [email protected]、[email protected] 以及产品团队 [email protected]。 “”“
Outlines 自动从函数签名推断所需结构
prompt = f““” <|im_start|>user 从此请求中提取会议详情: {user_request} <|im_end|> <|im_start|>assistant “”“
meeting_params = model(prompt, schedule_meeting, max_new_tokens=200)
结果是与函数参数匹配的字典
meeting_params = json.loads(meeting_params) print(meeting_params)
使用提取的参数调用函数
result = schedule_meeting(**meeting_params) print(result) # “会议 ‘Product Roadmap Review’ 已安排在 2023-10-17,共有 3 位参与者” ``
📝 使用可复用模板动态生成提示
此示例使用基于 Jinja 的模板,展示如何为情感分析等任务生成动态提示。它说明了如何轻松复用和自定义提示——包括少样本学习策略——以处理不同类型的内容,同时确保输出保持结构化。
``python import outlines from typing import List, Literal from transfo
相似文章
大型语言模型的高效引导生成
本文介绍了一种高效的方法,利用正则表达式和上下文无关文法引导LLM文本生成,开销极小,并在开源Python库Outlines中实现。
Pydantic AI 结构化输出与评估 · coles.codes
关于使用 Pydantic AI 和 Pydantic Evals 确保 LLM 结构化输出的详细指南,涵盖结构验证、内容正确性和开放式判断。
@mdancho84: 将任何文档转换为LLM就绪的数据!微软发布了MarkItDown,一个轻量级Python库,可将任何文档…
微软发布了MarkItDown,一个开源的Python库,可将任何文档转换为Markdown,以便与LLM配合使用。
@tom_doerr:通过无代码 GUI 微调大型语言模型 https://github.com/h2oai/h2o-llmstudio…
H2O LLM Studio 是一个开源框架和无代码图形界面,可简化大型语言模型的微调过程,支持 LoRA、DPO 等技术,并能与 Hugging Face 集成。
@techNmak: 从零构建LLMs 发现来自Vizuara的宝藏,一个43讲的系列课程,真正兑现了承诺:构建…
Vizuara的43讲系列课程教你如何从零构建LLMs,涵盖Transformer架构、GPT内部原理、分词(BPE)和注意力机制,并提供完整的Python实现。