outlines
JSON/XMLやコードなどの構造化データを生成する際に有効な形式を保証し、Pydanticモデルによる型安全な出力をサポートします。TransformersやvLLMなどのローカルモデルにも対応しており、dottxt.aiの構造化生成ライブラリ「Outlines」を活用して推論速度を最大化します。
description の原文を見る
Guarantee valid JSON/XML/code structure during generation, use Pydantic models for type-safe outputs, support local models (Transformers, vLLM), and maximize inference speed with Outlines - dottxt.ai's structured generation library
SKILL.md 本文
Outlines: 構造化テキスト生成
このスキルを使う場合
以下のような場合に Outlines を使用してください:
- 有効な JSON/XML/コード構造の保証 生成時に確実に正しい構造を生成
- Pydantic モデルの使用 型安全な出力
- ローカルモデルのサポート (Transformers、llama.cpp、vLLM)
- 推論速度の最大化 ゼロオーバーヘッドの構造化生成
- JSON スキーマに対する生成 自動的に
- 文法レベルでのトークンサンプリング制御
GitHub Stars: 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 = "Sentiment of 'This product is amazing!': "
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 = "Extract user: John Doe, 30 years old, 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) を使用して、ロジットレベルでトークン生成を制約します。
動作方法:
- スキーマ (JSON/Pydantic/正規表現) を文脈自由文法 (CFG) に変換
- CFG を有限状態機械 (FSM) に変換
- 生成時の各ステップで無効なトークンをフィルタリング
- 有効なトークンが1つのみの場合は高速スキップ
メリット:
- ゼロオーバーヘッド: トークンレベルでのフィルタリング
- 速度向上: 決定論的パスを高速スキップ
- 妥当性保証: 無効な出力は不可能
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("Generate person: Alice, 25")
2. 構造化ジェネレータ
Outlines は異なる出力タイプに対応した専門的なジェネレータを提供します。
Choice ジェネレータ
# 複数選択肢からの選択
generator = outlines.generate.choice(
model,
["positive", "negative", "neutral"]
)
sentiment = generator("Review: This is great!")
# 結果: 3つの選択肢のいずれか
JSON ジェネレータ
from pydantic import BaseModel
class Product(BaseModel):
name: str
price: float
in_stock: bool
# スキーマに一致する有効な JSON を生成
generator = outlines.generate.json(model, Product)
product = generator("Extract: iPhone 15, $999, available")
# 保証された Product インスタンス
print(type(product)) # <class '__main__.Product'>
正規表現ジェネレータ
# 正規表現にマッチするテキストを生成
generator = outlines.generate.regex(
model,
r"[0-9]{3}-[0-9]{3}-[0-9]{4}" # 電話番号パターン
)
phone = generator("Generate phone number:")
# 結果: "555-123-4567" (パターンに一致することが保証)
整数/浮動小数点ジェネレータ
# 特定の数値型を生成
int_generator = outlines.generate.integer(model)
age = int_generator("Person's age:") # 整数であることが保証
float_generator = outlines.generate.float(model)
price = float_generator("Product price:") # 浮動小数点であることが保証
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="Article title")
author: str = Field(description="Author name")
word_count: int = Field(description="Number of words", gt=0)
tags: list[str] = Field(description="List of tags")
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
generator = outlines.generate.json(model, Article)
article = generator("Generate article about 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("Generate person in New York")
print(person.address.city) # "New York"
Enum と Literal
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 # Enum 値のいずれかである必要あり
priority: Literal["low", "medium", "high"] # Literal のいずれか
generator = outlines.generate.json(model, Application)
app = generator("Generate application")
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. was founded in 1976 in the technology industry.
The company employs approximately 164,000 people worldwide.
"""
prompt = f"Extract company information:\n{text}\n\nCompany:"
company = generator(prompt)
print(f"Name: {company.name}")
print(f"Founded: {company.founded_year}")
print(f"Industry: {company.industry}")
print(f"Employees: {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("Email: Buy now! 50% off!")
# 多値分類
categories = ["technology", "business", "sports", "entertainment"]
category_gen = outlines.generate.choice(model, categories)
category = category_gen("Article: Apple announces new iPhone...")
# 信頼度付き
class Classification(BaseModel):
label: Literal["positive", "negative", "neutral"]
confidence: float
classifier = outlines.generate.json(model, Classification)
result = classifier("Review: This product is okay, nothing special")
パターン 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 = """
Extract user profile from:
Name: Alice Johnson
Age: 28
Email: alice@example.com
Phone: 555-0123
Country: USA
Interests: hiking, photography, cooking
"""
profile = generator(prompt)
print(profile.full_name)
print(profile.interests) # ["hiking", "photography", "cooking"]
パターン 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 met with Satya Nadella at Microsoft headquarters in Redmond."
prompt = f"Extract entities from: {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 = "Generate a Python function to calculate factorial"
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"Extract from: {text}")
results.append(result)
return results
class Person(BaseModel):
name: str
age: int
texts = [
"John is 30 years old",
"Alice is 25 years old",
"Bob is 40 years old"
]
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 個の GPU
)
# 量子化付き
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. カテゴリに Enum を使用
# ✅ 良い: 固定セットに Enum
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 = """
Extract product information from the following text.
Text: iPhone 15 Pro costs $999 and is currently in stock.
Product:
"""
# ❌ 悪い: 最小限の文脈
prompt = "iPhone 15 Pro costs $999 and is currently in stock."
5. オプショナルフィールドを処理
from typing import Optional
# ✅ 良い: 不完全なデータに対応したオプショナルフィールド
class Article(BaseModel):
title: str # 必須
author: Optional[str] = None # オプション
date: Optional[str] = None # オプション
tags: list[str] = [] # デフォルト空リスト
# author/date がなくても成功する
代替ツールとの比較
| 機能 | Outlines | Instructor | Guidance | LMQL |
|---|---|---|---|---|
| Pydantic サポート | ✅ ネイティブ | ✅ ネイティブ | ❌ なし | ❌ なし |
| JSON スキーマ | ✅ あり | ✅ あり | ⚠️ 限定的 | ✅ あり |
| 正規表現制約 | ✅ あり | ❌ なし | ✅ あり | ✅ あり |
| ローカルモデル | ✅ 完全 | ⚠️ 限定的 | ✅ 完全 | ✅ 完全 |
| API モデル | ⚠️ 限定的 | ✅ 完全 | ✅ 完全 | ✅ 完全 |
| ゼロオーバーヘッド | ✅ あり | ❌ なし | ⚠️ 部分的 | ✅ あり |
| 自動リトライ | ❌ なし | ✅ あり | ❌ なし | ❌ なし |
| 学習曲線 | 低い | 低い | 低い | 高い |
Outlines を選ぶべき場合:
- ローカルモデルを使用 (Transformers、llama.cpp、vLLM)
- 最大推論速度が必要
- Pydantic モデルサポートが欲しい
- ゼロオーバーヘッドの構造化生成が必要
- トークンサンプリングプロセスを制御したい
代替ツールを選ぶべき場合:
- Instructor: API モデルで自動リトライが必要
- Guidance: トークンヒーリングと複雑なワークフローが必要
- LMQL: 宣言的クエリ構文を好む
パフォーマンス特性
速度:
- ゼロオーバーヘッド: 制約なし生成と同等の速度
- 高速スキップ最適化: 決定論的トークンをスキップ
- 1.2-2 倍高速 生成後検証のアプローチと比較
メモリ:
- FSM はスキーマごとに1回コンパイル (キャッシュ)
- 最小限のランタイムオーバーヘッド
- vLLM での高スループット処理に効率的
精度:
- 100% 有効な出力 (FSM で保証)
- リトライループ不要
- 決定論的トークンフィルタリング
リソース
- ドキュメント: https://outlines-dev.github.io/outlines
- GitHub: https://github.com/outlines-dev/outlines (8,000 以上のスター)
- Discord: https://discord.gg/R9DSu34mGd
- ブログ: https://blog.dottxt.co
関連項目
references/json_generation.md- 包括的な JSON と Pydantic パターンreferences/backends.md- バックエンド固有の設定references/examples.md- 本番環境対応の例
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- davila7
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/davila7/claude-code-templates / ライセンス: MIT
関連スキル
agent-browser
AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。
anyskill
AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。
engram
AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。
skyvern
AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。
pinchbench
PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。
openui
OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。