outlines について
Outlines は、トークンのサンプリング時に制約を適用して構造化テキストを生成する Python ライブラリのスキルです。スキーマに沿った出力を必要とする開発者向けで、Pydantic、JSON Schema、選択肢、正規表現と複数のモデルバックエンドに対応します。
主な機能
- 01文法による生成制約
- 02JSON Schema と Pydantic モデルからの JSON 生成
- 03選択肢・正規表現・整数・浮動小数点数の出力
- 04Transformers、llama.cpp、vLLM への接続
- 05限定的な OpenAI 対応
活用シーン
- 01データを型付き Pydantic モデルへ抽出
- 02スキーマに適合する JSON の生成
- 03生成テキストを正規表現や固定選択肢に制約
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ kalarislabs/ research-agent-skills --skill outlinesインストール後、Claude Code で/outlinesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/backend-configuration.mdbackends.mdcommon-patterns.mdexamples.mdjson_generation.md詳細
Outlines:構造化テキスト生成
このスキルを使用する場面
次のような場合に Outlines を使用します。
- 生成時に有効な JSON/XML/コードの構造を保証する
- 型安全な出力にPydantic モデルを使用する
- ローカルモデル(Transformers、llama.cpp、vLLM)をサポートする
- オーバーヘッドゼロの構造化生成で推論速度を最大化する
- JSON スキーマに基づいて自動生成する
- 文法レベルでトークンサンプリングを制御する
インストール
# Base installation
pip install outlines
# With specific backends
pip install outlines transformers # Hugging Face models
pip install outlines llama-cpp-python # llama.cpp
pip install outlines vllm # vLLM for high-throughput
クイックスタート
基本例:分類
import outlines
from typing import Literal
# Load model
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
# Generate with type constraint
prompt = "Sentiment of 'This product is amazing!': "
generator = outlines.generate.choice(model, ["positive", "negative", "neutral"])
sentiment = generator(prompt)
print(sentiment) # "positive" (guaranteed one of these)
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")
# Generate structured output
prompt = "Extract user: John Doe, 30 years old, [email protected]"
generator = outlines.generate.json(model, User)
user = generator(prompt)
print(user.name) # "John Doe"
print(user.age) # 30
print(user.email) # "[email protected]"
基本概念
1. 制約付きトークンサンプリング
Outlines は有限状態機械(FSM)を使用して、ロジットレベルでトークン生成を制約します。
仕組み:
- スキーマ(JSON/Pydantic/正規表現)を文脈自由文法(CFG)に変換します
- CFG を有限状態機械(FSM)に変換します
- 生成中の各ステップで無効なトークンを除外します
- 有効なトークンが 1 つしかない場合は、先に進みます
メリット:
- オーバーヘッドゼロ:トークンレベルでフィルタリングします
- 速度の向上:決定的な経路を先に進みます
- 有効性の保証:無効な出力は生成されません
import outlines
# Pydantic model -> JSON schema -> CFG -> FSM
class Person(BaseModel):
name: str
age: int
model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
# Behind the scenes:
# 1. Person -> JSON schema
# 2. JSON schema -> CFG
# 3. CFG -> FSM
# 4. FSM filters tokens during generation
generator = outlines.generate.json(model, Person)
result = generator("Generate person: Alice, 25")
2. 構造化ジェネレーター
Outlines は、出力タイプごとに特化したジェネレーターを提供します。
選択肢ジェネレーター
# Multiple choice selection
generator = outlines.generate.choice(
model,
["positive", "negative", "neutral"]
)
sentiment = generator("Review: This is great!")
# Result: One of the three choices
JSON ジェネレーター
from pydantic import BaseModel
class Product(BaseModel):
name: str
price: float
in_stock: bool
# Generate valid JSON matching schema
generator = outlines.generate.json(model, Product)
product = generator("Extract: iPhone 15, $999, available")
# Guaranteed valid Product instance
print(type(product)) # <class '__main__.Product'>
正規表現ジェネレーター
# Generate text matching regex
generator = outlines.generate.regex(
model,
r"[0-9]{3}-[0-9]{3}-[0-9]{4}" # Phone number pattern
)
phone = generator("Generate phone number:")
# Result: "555-123-4567" (guaranteed to match pattern)
整数/浮動小数点数ジェネレーター
# Generate specific numeric types
int_generator = outlines.generate.integer(model)
age = int_generator("Person's age:") # Guaranteed integer
float_generator = outlines.generate.float(model)
price = float_generator("Product price:") # Guaranteed float
3. モデルバックエンド
Outlines は複数のローカルバックエンドと API ベースのバックエンドをサポートしています。
Transformers(Hugging Face)
import outlines
# Load from Hugging Face
model = outlines.models.transformers(
"microsoft/Phi-3-mini-4k-instruct",
device="cuda" # Or "cpu"
)
# Use with any generator
generator = outlines.generate.json(model, YourModel)
llama.cpp
# Load GGUF model
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(高スループット)
# For production deployments
model = outlines.models.vllm(
"meta-llama/Llama-3.1-8B-Instruct",
tensor_parallel_size=2 # Multi-GPU
)
generator = outlines.generate.json(model, YourModel)
OpenAI(サポートに制限あり)
# Basic OpenAI support
model = outlines.models.openai(
"gpt-4o-mini",
api_key="your-api-key"
)
# Note: Some features limited with API models
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) # Guaranteed > 0
ネストされたモデル
class Address(BaseModel):
street: str
city: str
country: str
class Person(BaseModel):
name: str
age: int
address: Address # Nested model
generator = outlines.generate.json(model, Person)
person = generator("Generate person in New York")
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 # Must be one of enum values
priority: Literal["low", "medium", "high"] # Must be one of literals
generator = outlines.generate.json(model, Application)
app = generator("Generate application")
print(app.status) # Status.PENDING (or APPROVED/REJECTED)
よくあるパターン
詳細、コード例、パラメーター表については、references/common-patterns.md を参照してください。このステップに該当する場合に読んでください。
バックエンドの設定
詳細、コード例、パラメーター表については、references/backend-configuration.md を参照してください。このステップに該当する場合に読んでください。
ベストプラクティス
1. 具体的な型を使用する
# ✅ Good: Specific types
class Product(BaseModel):
name: str
price: float # Not str
quantity: int # Not str
in_stock: bool # Not str
# ❌ Bad: Everything as string
class Product(BaseModel):
name: str
price: str # Should be float
quantity: str # Should be int
2. 制約を追加する
from pydantic import Field
# ✅ Good: With constraints
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+$")
# ❌ Bad: No constraints
class User(BaseModel):
name: str
age: int
email: str
3. カテゴリには列挙型を使用する
# ✅ Good: Enum for fixed set
class Priority(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class Task(BaseModel):
title: str
priority: Priority
# ❌ Bad: Free-form string
class Task(BaseModel):
title: str
priority: str # Can be anything
4. プロンプトにコンテキストを含める
# ✅ Good: Clear context
prompt = """
Extract product information from the following text.
Text: iPhone 15 Pro costs $999 and is currently in stock.
Product:
"""
# ❌ Bad: Minimal context
prompt = "iPhone 15 Pro costs $999 and is currently in stock."
5. オプションフィールドを処理する
from typing import Optional
# ✅ Good: Optional fields for incomplete data
class Article(BaseModel):
title: str # Required
author: Optional[str] = None # Optional
date: Optional[str] = None # Optional
tags: list[str] = [] # Default empty list
# Can succeed even if author/date missing
代替手段との比較
| 機能 | Outlines | Instructor | Guidance | LMQL |
|---|---|---|---|---|
| Pydantic のサポート | ✅ ネイティブ | ✅ ネイティブ | ❌ なし | ❌ なし |
| JSON スキーマ | ✅ あり | ✅ あり | ⚠️ 制限あり | ✅ あり |
| 正規表現の制約 | ✅ あり | ❌ なし | ✅ あり | ✅ あり |
| ローカルモデル | ✅ 完全 | ⚠️ 制限あり | ✅ 完全 | ✅ 完全 |
| API モデル | ⚠️ 制限あり | ✅ 完全 | ✅ 完全 | ✅ 完全 |
| オーバーヘッドゼロ | ✅ はい | ❌ いいえ | ⚠️ 部分的 | ✅ はい |
| 自動再試行 | ❌ なし | ✅ あり | ❌ なし | ❌ なし |
| 学習曲線 | 低い | 低い | 低い | 高い |
Outlines を選ぶ場合:
- ローカルモデル(Transformers、llama.cpp、vLLM)を使用する
- 推論速度を最大化したい
- Pydantic モデルのサポートが必要
- オーバーヘッドゼロの構造化生成が必要
- トークンサンプリングのプロセスを制御したい
代替手段を選ぶ場合:
- Instructor:自動再試行に対応した API モデルが必要
- Guidance:トークン修復と複雑なワークフローが必要
- LMQL:宣言的なクエリ構文を使いたい
パフォーマンス特性
速度:
- オーバーヘッドゼロ:制約なしの生成と同じ速度で構造化生成できます
- 先読み最適化:決定的なトークンをスキップします
- 生成後に検証する方式より1.2~2 倍高速です
メモリ:
- FSM はスキーマごとに一度だけコンパイルされます(キャッシュされます)
- 実行時のオーバーヘッドは最小限です
- 高スループットでは vLLM と組み合わせると効率的です
精度:
- 有効な出力を 100%保証します(FSM による保証)
- 再試行ループは不要です
- トークンを決定的にフィルタリングします
リソース
- ドキュメント: https://outlines-dev.github.io/outlines
- GitHub: https://github.com/outlines-dev/outlines
- Discord: https://discord.gg/R9DSu34mGd
- ブログ: https://blog.dottxt.co
関連項目
references/json_generation.md- JSON および Pydantic の包括的なパターンreferences/backends.md- バックエンド固有の設定references/examples.md- 本番環境向けの実用例
エージェントの作業手順
- 環境を確認します。 フレームワークのバージョン、モデルプロバイダー、API キー、レート制限を確認します。
- 入力を明確にします。 データまたはユーザーから、形式、識別子、パラメーターを確認します。結果に影響する値は推測せず、質問してください。
- まず小規模に実行します。 既知の入力で単一の呼び出しまたはチェーンをテストし、生の出力を確認します。
- 上記の手順と参考資料を使用して、タスク全体を実行します。
- 結果を検証します。 小規模なラベル付きデータセットで評価し、構造化出力をスキーマと照合して確認し、プロンプトと応答を記録します。
- 報告します。 実行した内容(バージョン、コマンド、パラメーター)、確認した内容、未解決の点を記載します。
| このような場合 | 対応 |
|---|---|
| 出力が期待されるスキーマと一致しない | 検証と再試行を追加する、スキーマを厳密にする、またはプロンプトを簡潔にします。 |
| これらの手順に記載されている関数、フラグ、エンドポイントがインストール済みのバージョンに存在しない | インストール済みバージョンのドキュメント(help()、--help、公式ドキュメント)を確認して適切に対応し、ユーザーに伝えます。API をでっち上げてはいけません。 |
| 必須の入力、識別子、またはパラメーターが曖昧 | ユーザーに質問するか、実行前に仮定を明示します。 |
整合性に関するルール
- 結果、パラメーター、識別子、引用、統計を決して捏造しないでください。実行または検証できない場合は、その旨を明確に伝えてください。
- ユーザーの同意なしに、個人情報や機密データを外部 API に送信しないでください。
- ここに記載されているバージョン固有の情報は古くなっている可能性があります。インストール済みバージョンの公式ドキュメントで確認してください。
- 費用が発生する操作、共有 GPU やクラウドのクォータを消費する操作、個人データや患者データを扱う操作、または取り消せない操作を行う前に、ユーザーに確認してください。
コメント
Markdown 対応