mcpField
I
instructor

instructor

github.com/kalarislabsデータ・データベース7746 回インストール4 日前に更新
リポジトリ

instructor について

InstructorでLLMの応答を型付きの構造化データに変換し、検証するためのスキルです。開発者はPydanticスキーマ、無効出力の再試行、部分結果のストリーミング、複数プロバイダー向けの共通APIを活用できます。

主な機能

  1. 01Pydanticスキーマ検証
  2. 02無効な出力の自動再試行
  3. 03部分結果のストリーミング
  4. 04ネスト型とオプション項目
  5. 05プロバイダー共通API

活用シーン

  1. 01テキストからレコードを抽出
  2. 02スキーマに照らして生成JSONを検証
  3. 03構造化結果をリアルタイムで配信
  4. 04無効な抽出応答に対処

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/kalarislabs/research-agent-skills --skill instructor

インストール後、Claude Code で/instructorを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
advanced-features.md
common-patterns.md
error-handling.md
examples.md
provider-configuration.md
providers.md
validation.md

詳細

Instructor:LLM の構造化出力

このスキルを使用する場面

次のような場合に Instructor を使用してください。

  • LLM の応答から構造化データを確実に抽出する
  • Pydantic スキーマに対して出力を自動的に検証する
  • エラーを自動処理して、抽出の失敗を再試行する
  • 型安全性と検証機能を備えて、複雑な JSON を解析する
  • リアルタイム処理用に部分的な結果をストリーミングする
  • 一貫した API で複数の LLM プロバイダーに対応する

インストール

# Base installation
pip install instructor

# With specific providers
pip install "instructor[anthropic]"  # Anthropic Claude
pip install "instructor[openai]"     # OpenAI
pip install "instructor[all]"        # All providers

クイックスタート

基本例:ユーザーデータの抽出
import instructor
from pydantic import BaseModel
from anthropic import Anthropic

# Define output structure
class User(BaseModel):
    name: str
    age: int
    email: str

# Create instructor client
client = instructor.from_anthropic(Anthropic())

# Extract structured data
user = client.messages.create(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": "John Doe is 30 years old. His email is [email protected]"
    }],
    response_model=User
)

print(user.name)   # "John Doe"
print(user.age)    # 30
print(user.email)  # "[email protected]"
OpenAI を使用する
from openai import OpenAI

client = instructor.from_openai(OpenAI())

user = client.chat.completions.create(
    model="gpt-4o-mini",
    response_model=User,
    messages=[{"role": "user", "content": "Extract: Alice, 25, [email protected]"}]
)

基本概念

1. レスポンスモデル(Pydantic)

レスポンスモデルでは、LLM の出力の構造と検証ルールを定義します。

基本モデル
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 relevant tags")

article = client.messages.create(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": "Analyze this article: [article text]"
    }],
    response_model=Article
)

利点:

  • Python の型ヒントによる型安全性
  • 自動検証(word_count > 0)
  • Field の説明による自己文書化
  • IDE の自動補完に対応
ネストされたモデル
class Address(BaseModel):
    street: str
    city: str
    country: str

class Person(BaseModel):
    name: str
    age: int
    address: Address  # Nested model

person = client.messages.create(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": "John lives at 123 Main St, Boston, USA"
    }],
    response_model=Person
)

print(person.address.city)  # "Boston"
オプションフィールド
from typing import Optional

class Product(BaseModel):
    name: str
    price: float
    discount: Optional[float] = None  # Optional
    description: str = Field(default="No description")  # Default value

# LLM doesn't need to provide discount or description
制約に Enum を使用する
from enum import Enum

class Sentiment(str, Enum):
    POSITIVE = "positive"
    NEGATIVE = "negative"
    NEUTRAL = "neutral"

class Review(BaseModel):
    text: str
    sentiment: Sentiment  # Only these 3 values allowed

review = client.messages.create(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": "This product is amazing!"
    }],
    response_model=Review
)

print(review.sentiment)  # Sentiment.POSITIVE
2. 検証

Pydantic は LLM の出力を自動的に検証します。検証に失敗すると、Instructor が再試行します。

組み込みバリデーター
from pydantic import Field, EmailStr, HttpUrl

class Contact(BaseModel):
    name: str = Field(min_length=2, max_length=100)
    age: int = Field(ge=0, le=120)  # 0 <= age <= 120
    email: EmailStr  # Validates email format
    website: HttpUrl  # Validates URL format

# If LLM provides invalid data, Instructor retries automatically
カスタムバリデーター
from pydantic import field_validator

class Event(BaseModel):
    name: str
    date: str
    attendees: int

    @field_validator('date')
    def validate_date(cls, v):
        """Ensure date is in YYYY-MM-DD format."""
        import re
        if not re.match(r'\d{4}-\d{2}-\d{2}', v):
            raise ValueError('Date must be YYYY-MM-DD format')
        return v

    @field_validator('attendees')
    def validate_attendees(cls, v):
        """Ensure positive attendees."""
        if v < 1:
            raise ValueError('Must have at least 1 attendee')
        return v
モデルレベルの検証
from pydantic import model_validator

class DateRange(BaseModel):
    start_date: str
    end_date: str

    @model_validator(mode='after')
    def check_dates(self):
        """Ensure end_date is after start_date."""
        from datetime import datetime
        start = datetime.strptime(self.start_date, '%Y-%m-%d')
        end = datetime.strptime(self.end_date, '%Y-%m-%d')

        if end < start:
            raise ValueError('end_date must be after start_date')
        return self
3. 自動再試行

検証に失敗すると、Instructor は LLM にエラーのフィードバックを返して自動的に再試行します。

# Retries up to 3 times if validation fails
user = client.messages.create(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": "Extract user from: John, age unknown"
    }],
    response_model=User,
    max_retries=3  # Default is 3
)

# If age can't be extracted, Instructor tells the LLM:
# "Validation error: age - field required"
# LLM tries again with better extraction

仕組み:

  1. LLM が出力を生成します
  2. Pydantic が検証します
  3. 無効な場合:エラーメッセージが LLM に返されます
  4. LLM はエラーのフィードバックを基に再試行します
  5. max_retries の回数まで繰り返します
4. ストリーミング

リアルタイム処理用に部分的な結果をストリーミングします。

部分オブジェクトのストリーミング
from instructor import Partial

class Story(BaseModel):
    title: str
    content: str
    tags: list[str]

# Stream partial updates as LLM generates
for partial_story in client.messages.create_partial(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": "Write a short sci-fi story"
    }],
    response_model=Story
):
    print(f"Title: {partial_story.title}")
    print(f"Content so far: {partial_story.content[:100]}...")
    # Update UI in real-time
イテラブルのストリーミング
class Task(BaseModel):
    title: str
    priority: str

# Stream list items as they're generated
tasks = client.messages.create_iterable(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": "Generate 10 project tasks"
    }],
    response_model=Task
)

for task in tasks:
    print(f"- {task.title} ({task.priority})")
    # Process each task as it arrives

プロバイダーの設定

詳細、コード例、パラメーター表については、references/provider-configuration.md を参照してください。この手順が該当する場合にお読みください。

よく使われるパターン

詳細、コード例、パラメーター表については、references/common-patterns.md を参照してください。この手順が該当する場合にお読みください。

高度な機能

詳細、コード例、パラメーター表については、references/advanced-features.md を参照してください。この手順が該当する場合にお読みください。

エラー処理

詳細、コード例、パラメーター表については、references/error-handling.md を参照してください。この手順が該当する場合にお読みください。

ベストプラクティス

1. フィールドの説明を明確にする
# ❌ Bad: Vague
class Product(BaseModel):
    name: str
    price: float

# ✅ Good: Descriptive
class Product(BaseModel):
    name: str = Field(description="Product name from the text")
    price: float = Field(description="Price in USD, without currency symbol")
2. 適切な検証を使用する
# ✅ Good: Constrain values
class Rating(BaseModel):
    score: int = Field(ge=1, le=5, description="Rating from 1 to 5 stars")
    review: str = Field(min_length=10, description="Review text, at least 10 chars")
3. プロンプトに例を含める
messages = [{
    "role": "user",
    "content": """Extract person info from: "John, 30, engineer"

Example format:
{
  "name": "John Doe",
  "age": 30,
  "occupation": "engineer"
}"""
}]
4. 固定カテゴリには Enum を使用する
# ✅ Good: Enum ensures valid values
class Status(str, Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"

class Application(BaseModel):
    status: Status  # LLM must choose from enum
5. 欠損データを適切に処理する
class PartialData(BaseModel):
    required_field: str
    optional_field: Optional[str] = None
    default_field: str = "default_value"

# LLM only needs to provide required_field

他の選択肢との比較

機能Instructor手動 JSONLangChainDSPy
型安全性✅ あり❌ なし⚠️ 一部対応✅ あり
自動検証✅ あり❌ なし❌ なし⚠️ 制限あり
自動再試行✅ あり❌ なし❌ なし✅ あり
ストリーミング✅ あり❌ なし✅ あり❌ なし
複数プロバイダー✅ あり⚠️ 手動✅ あり✅ あり
学習曲線低い低い中程度高い

Instructor を選ぶ場合:

  • 構造化され、検証済みの出力が必要な場合
  • 型安全性と IDE のサポートが必要な場合
  • 自動再試行が必要な場合
  • データ抽出システムを構築する場合

他の選択肢を選ぶ場合:

  • DSPy:プロンプトを最適化したい場合
  • LangChain:複雑なチェーンを構築する場合
  • 手動:単純な単発の抽出を行う場合

リソース

関連項目

  • references/validation.md - 高度な検証パターン
  • references/providers.md - プロバイダー固有の設定
  • references/examples.md - 実際のユースケース

エージェントの運用手順

  1. 環境を確認します。 フレームワークのバージョン、モデルプロバイダー、API キー、レート制限を確認します。
  2. 入力を明確にします。 データまたはユーザーから、形式、識別子、パラメーターを確認します。結果を左右する値は推測せず、質問してください。
  3. まず小規模に実行します。 既知の入力で単一の呼び出しまたはチェーンをテストし、生の出力を確認します。
  4. 上記の指示と参考情報を使用して、タスク全体を実行します。
  5. 結果を検証します。 小規模なラベル付きデータセットで評価し、構造化出力をスキーマと照合して、プロンプトと応答をログに記録します。
  6. 報告します。 実行した内容(バージョン、コマンド、パラメーター)、確認した内容、未確認の事項を明示します。
このような場合対応
出力が想定されたスキーマと一致しない検証と再試行を追加し、スキーマを厳密にするか、プロンプトを簡素化します。
この手順に記載された関数、フラグ、エンドポイントがインストール済みのバージョンにないインストール済みバージョンのドキュメント(help()、--help、公式ドキュメント)を確認して対応し、ユーザーに伝えます。API を捏造してはいけません。
必須の入力、識別子、パラメーターが曖昧であるユーザーに確認するか、実行前に仮定を明示します。

誠実性に関するルール

  • 結果、パラメーター、識別子、引用、統計を捏造してはいけません。実行または検証できない場合は、その旨を明確に伝えます。
  • ユーザーの同意なしに、個人情報や機密データを外部 API に送信してはいけません。
  • ここに記載されたバージョン固有の詳細は古くなっている可能性があるため、インストール済みバージョンの公式ドキュメントで確認します。
  • 費用が発生する操作、共有 GPU やクラウドのクォータを消費する操作、個人データや患者データに触れる操作、取り消せない操作を行う前に確認します。

コメント