OutlinesSkill outlines

Outlines是一个Python库,专门用于结构化文本生成,确保输出符合JSON、XML或代码结构。它集成Pydantic模型提供类型安全,支持本地AI模型如Transformers和vLLM,并通过有限状态机优化推理速度,适用于数据提取、分类和代码生成等场景。关键词:结构化文本生成、JSON生成、Pydantic、本地模型、推理优化、NLP、人工智能应用。

NLP 0 次安装 0 次浏览 更新于 3/21/2026

name: outlines description: 在生成过程中保证JSON/XML/代码结构的有效性,使用Pydantic模型进行类型安全输出,支持本地模型(Transformers、vLLM),并通过Outlines - dottxt.ai的结构化生成库最大化推理速度。 version: 1.0.0 author: Orchestra Research license: MIT tags: [提示工程, Outlines, 结构化生成, JSON模式, Pydantic, 本地模型, 基于语法的生成, vLLM, Transformers, 类型安全] dependencies: [outlines, transformers, vllm, pydantic]

Outlines:结构化文本生成

何时使用此技能

当您需要时使用Outlines:

  • 保证有效的JSON/XML/代码结构在生成过程中
  • 使用Pydantic模型进行类型安全输出
  • 支持本地模型(Transformers、llama.cpp、vLLM)
  • 最大化推理速度,通过零开销结构化生成
  • 自动针对JSON模式生成
  • 在语法级别控制令牌采样

GitHub星标:8,000+ | 来自dottxt.ai(原.txt)

安装

# 基础安装
pip install outlines

# 使用特定后端
pip install outlines transformers  # Hugging Face模型
pip install outlines llama-cpp-python  # llama.cpp
pip install outlines vllm  # vLLM用于高吞吐量

快速开始

基础示例:分类

import outlines
from typing import Literal

# 加载模型
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")

# 使用类型约束生成
prompt = "情感分析:'这个产品太棒了!': "
generator = outlines.generate.choice(model, ["positive", "negative", "neutral"])
sentiment = generator(prompt)

print(sentiment)  # "positive"(保证是其中之一)

使用Pydantic模型

from pydantic import BaseModel
import outlines

class User(BaseModel):
    name: str
    age: int
    email: str

model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")

# 生成结构化输出
prompt = "提取用户:John Doe,30岁,john@example.com"
generator = outlines.generate.json(model, User)
user = generator(prompt)

print(user.name)   # "John Doe"
print(user.age)    # 30
print(user.email)  # "john@example.com"

核心概念

1. 约束令牌采样

Outlines使用有限状态机(FSM)在日志级别约束令牌生成。

工作原理:

  1. 将模式(JSON/Pydantic/正则表达式)转换为上下文无关文法(CFG)
  2. 将CFG转换为有限状态机(FSM)
  3. 在生成过程中每个步骤过滤无效令牌
  4. 当只有一个有效令牌时快速跳过

优势:

  • 零开销:过滤在令牌级别进行
  • 速度提升:跳过确定性路径
  • 保证有效性:无效输出不可能
import outlines

# Pydantic模型 -> JSON模式 -> CFG -> FSM
class Person(BaseModel):
    name: str
    age: int

model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")

# 幕后:
# 1. Person -> JSON模式
# 2. JSON模式 -> CFG
# 3. CFG -> FSM
# 4. FSM在生成过程中过滤令牌

generator = outlines.generate.json(model, Person)
result = generator("生成人员:Alice,25")

2. 结构化生成器

Outlines提供针对不同输出类型的专门生成器。

选择生成器

# 多项选择
generator = outlines.generate.choice(
    model,
    ["positive", "negative", "neutral"]
)

sentiment = generator("评论:这太棒了!")
# 结果:三个选择之一

JSON生成器

from pydantic import BaseModel

class Product(BaseModel):
    name: str
    price: float
    in_stock: bool

# 生成符合模式的有效JSON
generator = outlines.generate.json(model, Product)
product = generator("提取:iPhone 15,$999,有货")

# 保证有效的Product实例
print(type(product))  # <class '__main__.Product'>

正则表达式生成器

# 生成匹配正则表达式的文本
generator = outlines.generate.regex(
    model,
    r"[0-9]{3}-[0-9]{3}-[0-9]{4}"  # 电话号码模式
)

phone = generator("生成电话号码:")
# 结果:"555-123-4567"(保证匹配模式)

整数/浮点数生成器

# 生成特定数字类型
int_generator = outlines.generate.integer(model)
age = int_generator("人员年龄:")  # 保证整数

float_generator = outlines.generate.float(model)
price = float_generator("产品价格:")  # 保证浮点数

3. 模型后端

Outlines支持多个本地和基于API的后端。

Transformers(Hugging Face)

import outlines

# 从Hugging Face加载
model = outlines.models.transformers(
    "microsoft/Phi-3-mini-4k-instruct",
    device="cuda"  # 或 "cpu"
)

# 与任何生成器一起使用
generator = outlines.generate.json(model, YourModel)

llama.cpp

# 加载GGUF模型
model = outlines.models.llamacpp(
    "./models/llama-3.1-8b-instruct.Q4_K_M.gguf",
    n_gpu_layers=35
)

generator = outlines.generate.json(model, YourModel)

vLLM(高吞吐量)

# 用于生产部署
model = outlines.models.vllm(
    "meta-llama/Llama-3.1-8B-Instruct",
    tensor_parallel_size=2  # 多GPU
)

generator = outlines.generate.json(model, YourModel)

OpenAI(有限支持)

# 基础OpenAI支持
model = outlines.models.openai(
    "gpt-4o-mini",
    api_key="your-api-key"
)

# 注意:API模型有些功能有限
generator = outlines.generate.json(model, YourModel)

4. Pydantic集成

Outlines具有一流的Pydantic支持,带有自动模式转换。

基础模型

from pydantic import BaseModel, Field

class Article(BaseModel):
    title: str = Field(description="文章标题")
    author: str = Field(description="作者姓名")
    word_count: int = Field(description="字数", gt=0)
    tags: list[str] = Field(description="标签列表")

model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, Article)

article = generator("生成关于AI的文章")
print(article.title)
print(article.word_count)  # 保证 > 0

嵌套模型

class Address(BaseModel):
    street: str
    city: str
    country: str

class Person(BaseModel):
    name: str
    age: int
    address: Address  # 嵌套模型

generator = outlines.generate.json(model, Person)
person = generator("生成在纽约的人员")

print(person.address.city)  # "New York"

枚举和字面量

from enum import Enum
from typing import Literal

class Status(str, Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"

class Application(BaseModel):
    applicant: str
    status: Status  # 必须是枚举值之一
    priority: Literal["low", "medium", "high"]  # 必须是字面量之一

generator = outlines.generate.json(model, Application)
app = generator("生成申请")

print(app.status)  # Status.PENDING(或APPROVED/REJECTED)

常见模式

模式1:数据提取

from pydantic import BaseModel
import outlines

class CompanyInfo(BaseModel):
    name: str
    founded_year: int
    industry: str
    employees: int

model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, CompanyInfo)

text = """
Apple Inc. 成立于1976年,属于科技行业。
该公司在全球雇佣约164,000人。
"""

prompt = f"提取公司信息:
{text}

公司:"
company = generator(prompt)

print(f"名称:{company.name}")
print(f"成立年份:{company.founded_year}")
print(f"行业:{company.industry}")
print(f"员工数:{company.employees}")

模式2:分类

from typing import Literal
import outlines

model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")

# 二分类
generator = outlines.generate.choice(model, ["spam", "not_spam"])
result = generator("邮件:现在购买!50%折扣!")

# 多类分类
categories = ["technology", "business", "sports", "entertainment"]
category_gen = outlines.generate.choice(model, categories)
category = category_gen("文章:Apple宣布新iPhone...")

# 带置信度
class Classification(BaseModel):
    label: Literal["positive", "negative", "neutral"]
    confidence: float

classifier = outlines.generate.json(model, Classification)
result = classifier("评论:这个产品还行,没什么特别的")

模式3:结构化表单

class UserProfile(BaseModel):
    full_name: str
    age: int
    email: str
    phone: str
    country: str
    interests: list[str]

model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, UserProfile)

prompt = """
从以下提取用户档案:
姓名:Alice Johnson
年龄:28
邮箱:alice@example.com
电话:555-0123
国家:USA
兴趣:徒步、摄影、烹饪
"""

profile = generator(prompt)
print(profile.full_name)
print(profile.interests)  # ["徒步", "摄影", "烹饪"]

模式4:多实体提取

class Entity(BaseModel):
    name: str
    type: Literal["PERSON", "ORGANIZATION", "LOCATION"]

class DocumentEntities(BaseModel):
    entities: list[Entity]

model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, DocumentEntities)

text = "Tim Cook 在Redmond的Microsoft总部会见了Satya Nadella。"
prompt = f"从以下提取实体:{text}"

result = generator(prompt)
for entity in result.entities:
    print(f"{entity.name} ({entity.type})")

模式5:代码生成

class PythonFunction(BaseModel):
    function_name: str
    parameters: list[str]
    docstring: str
    body: str

model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, PythonFunction)

prompt = "生成一个Python函数来计算阶乘"
func = generator(prompt)

print(f"def {func.function_name}({', '.join(func.parameters)}):")
print(f'    """{func.docstring}"""')
print(f"    {func.body}")

模式6:批处理

def batch_extract(texts: list[str], schema: type[BaseModel]):
    """从多个文本中提取结构化数据。"""
    model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
    generator = outlines.generate.json(model, schema)

    results = []
    for text in texts:
        result = generator(f"从以下提取:{text}")
        results.append(result)

    return results

class Person(BaseModel):
    name: str
    age: int

texts = [
    "John 30岁",
    "Alice 25岁",
    "Bob 40岁"
]

people = batch_extract(texts, Person)
for person in people:
    print(f"{person.name}: {person.age}")

后端配置

Transformers

import outlines

# 基础用法
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")

# GPU配置
model = outlines.models.transformers(
    "microsoft/Phi-3-mini-4k-instruct",
    device="cuda",
    model_kwargs={"torch_dtype": "float16"}
)

# 流行模型
model = outlines.models.transformers("meta-llama/Llama-3.1-8B-Instruct")
model = outlines.models.transformers("mistralai/Mistral-7B-Instruct-v0.3")
model = outlines.models.transformers("Qwen/Qwen2.5-7B-Instruct")

llama.cpp

# 加载GGUF模型
model = outlines.models.llamacpp(
    "./models/llama-3.1-8b.Q4_K_M.gguf",
    n_ctx=4096,         # 上下文窗口
    n_gpu_layers=35,    # GPU层
    n_threads=8         # CPU线程
)

# 完全GPU卸载
model = outlines.models.llamacpp(
    "./models/model.gguf",
    n_gpu_layers=-1  # 所有层在GPU上
)

vLLM(生产)

# 单GPU
model = outlines.models.vllm("meta-llama/Llama-3.1-8B-Instruct")

# 多GPU
model = outlines.models.vllm(
    "meta-llama/Llama-3.1-70B-Instruct",
    tensor_parallel_size=4  # 4 GPUs
)

# 带量化
model = outlines.models.vllm(
    "meta-llama/Llama-3.1-8B-Instruct",
    quantization="awq"  # 或 "gptq"
)

最佳实践

1. 使用特定类型

# ✅ 好:特定类型
class Product(BaseModel):
    name: str
    price: float  # 不是 str
    quantity: int  # 不是 str
    in_stock: bool  # 不是 str

# ❌ 坏:一切都作为字符串
class Product(BaseModel):
    name: str
    price: str  # 应该是 float
    quantity: str  # 应该是 int

2. 添加约束

from pydantic import Field

# ✅ 好:带约束
class User(BaseModel):
    name: str = Field(min_length=1, max_length=100)
    age: int = Field(ge=0, le=120)
    email: str = Field(pattern=r"^[\w\.-]+@[\w\.-]+\.\w+$")

# ❌ 坏:无约束
class User(BaseModel):
    name: str
    age: int
    email: str

3. 使用枚举进行分类

# ✅ 好:枚举用于固定集合
class Priority(str, Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"

class Task(BaseModel):
    title: str
    priority: Priority

# ❌ 坏:自由形式字符串
class Task(BaseModel):
    title: str
    priority: str  # 可以是任何内容

4. 在提示中提供上下文

# ✅ 好:清晰上下文
prompt = """
从以下文本中提取产品信息。
文本:iPhone 15 Pro 售价$999,目前有货。
产品:
"""

# ❌ 坏:最小上下文
prompt = "iPhone 15 Pro 售价$999,目前有货。"

5. 处理可选字段

from typing import Optional

# ✅ 好:可选字段用于不完整数据
class Article(BaseModel):
    title: str  # 必需
    author: Optional[str] = None  # 可选
    date: Optional[str] = None  # 可选
    tags: list[str] = []  # 默认空列表

# 即使作者/日期缺失也能成功

与替代方案比较

功能 Outlines Instructor Guidance LMQL
Pydantic 支持 ✅ 原生 ✅ 原生 ❌ 无 ❌ 无
JSON 模式 ✅ 是 ✅ 是 ⚠️ 有限 ✅ 是
正则表达式约束 ✅ 是 ❌ 无 ✅ 是 ✅ 是
本地模型 ✅ 完整 ⚠️ 有限 ✅ 完整 ✅ 完整
API 模型 ⚠️ 有限 ✅ 完整 ✅ 完整 ✅ 完整
零开销 ✅ 是 ❌ 无 ⚠️ 部分 ✅ 是
自动重试 ❌ 无 ✅ 是 ❌ 无 ❌ 无
学习曲线

何时选择 Outlines:

  • 使用本地模型(Transformers、llama.cpp、vLLM)
  • 需要最大推理速度
  • 想要Pydantic模型支持
  • 需要零开销结构化生成
  • 控制令牌采样过程

何时选择替代方案:

  • Instructor:需要API模型并自动重试
  • Guidance:需要令牌修复和复杂工作流
  • LMQL:偏好声明式查询语法

性能特征

速度:

  • 零开销:结构化生成与无约束一样快
  • 快速跳过优化:跳过确定性令牌
  • 比后生成验证方法快1.2-2倍

内存:

  • FSM 每个模式编译一次(缓存)
  • 最小运行时开销
  • 高效使用vLLM进行高吞吐量

准确性:

  • 100% 有效输出(由FSM保证)
  • 无需重试循环
  • 确定性令牌过滤

资源

另请参阅

  • references/json_generation.md - 全面的JSON和Pydantic模式
  • references/backends.md - 后端特定配置
  • references/examples.md - 生产就绪示例