Agent Skills by ALSEL
汎用LLM・AI開発⭐ リポ 2品質スコア 69/100

guidance

Guidanceを使用することで、正規表現やグラマーによってLLMの出力を制御し、有効なJSON/XML/コード生成を保証できます。構造化フォーマットの強制と複数ステップのワークフロー構築が可能です。Microsoft Researchが開発した制約付き生成フレームワークにより、LLMの出力を確実にコントロールします。

description の原文を見る

Control LLM output with regex and grammars, guarantee valid JSON/XML/code generation, enforce structured formats, and build multi-step workflows with Guidance - Microsoft Research's constrained generation framework

SKILL.md 本文

Guidance: 制約付きLLM生成

このスキルをいつ使うか

以下の場合にGuidanceを使用してください:

  • 正規表現または文法でLLM出力を制御したい
  • 有効なJSON/XML/コード生成を保証したい
  • 従来のプロンプト手法と比べてレイテンシを削減したい
  • 構造化フォーマット(日付、メール、IDなど)を強制したい
  • Pythonの制御フローを使用してマルチステップワークフローを構築したい
  • 文法的制約を通じて無効な出力を防ぎたい

GitHubスター: 18,000+ | 提供元: Microsoft Research

インストール

# 基本インストール
pip install guidance

# 特定のバックエンドを指定
pip install guidance[transformers]  # Hugging Faceモデル
pip install guidance[llama_cpp]     # llama.cppモデル

クイックスタート

基本例: 構造化生成

from guidance import models, gen

# モデルを読み込み(OpenAI、Transformers、llama.cppに対応)
lm = models.OpenAI("gpt-4")

# 制約付きで生成
result = lm + "The capital of France is " + gen("capital", max_tokens=5)

print(result["capital"])  # "Paris"

Anthropic Claudeを使用

from guidance import models, gen, system, user, assistant

# Claudeを設定
lm = models.Anthropic("claude-sonnet-4-5-20250929")

# チャット形式でコンテキストマネージャを使用
with system():
    lm += "You are a helpful assistant."

with user():
    lm += "What is the capital of France?"

with assistant():
    lm += gen(max_tokens=20)

コア概念

1. コンテキストマネージャ

GuidanceはチャットスタイルのインタラクションのためにPythonのコンテキストマネージャを使用します。

from guidance import system, user, assistant, gen

lm = models.Anthropic("claude-sonnet-4-5-20250929")

# システムメッセージ
with system():
    lm += "You are a JSON generation expert."

# ユーザーメッセージ
with user():
    lm += "Generate a person object with name and age."

# アシスタント応答
with assistant():
    lm += gen("response", max_tokens=100)

print(lm["response"])

メリット:

  • 自然なチャットフロー
  • 明確なロール分離
  • 読みやすく保守しやすい

2. 制約付き生成

Guidanceは、正規表現または文法を使用して、出力が指定されたパターンと一致することを確保します。

正規表現制約

from guidance import models, gen

lm = models.Anthropic("claude-sonnet-4-5-20250929")

# 有効なメール形式に制約
lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")

# 日付形式に制約(YYYY-MM-DD)
lm += "Date: " + gen("date", regex=r"\d{4}-\d{2}-\d{2}")

# 電話番号に制約
lm += "Phone: " + gen("phone", regex=r"\d{3}-\d{3}-\d{4}")

print(lm["email"])  # 有効なメール形式が保証される
print(lm["date"])   # YYYY-MM-DD形式が保証される

仕組み:

  • 正規表現はトークンレベルで文法に変換される
  • 生成中に無効なトークンがフィルタリングされる
  • モデルはマッチングする出力のみを生成できる

選択制約

from guidance import models, gen, select

lm = models.Anthropic("claude-sonnet-4-5-20250929")

# 特定の選択肢に制約
lm += "Sentiment: " + select(["positive", "negative", "neutral"], name="sentiment")

# 複数選択肢の選択
lm += "Best answer: " + select(
    ["A) Paris", "B) London", "C) Berlin", "D) Madrid"],
    name="answer"
)

print(lm["sentiment"])  # 以下のいずれか: positive, negative, neutral
print(lm["answer"])     # 以下のいずれか: A, B, C, D

3. トークンヒーリング

Guidanceはプロンプトと生成の間のトークン境界を自動的に「修復」します。

問題: トークン化により不自然な境界が生じます。

# トークンヒーリングなし
prompt = "The capital of France is "
# 最後のトークン: " is "
# 最初に生成されるトークンは " Par"(先頭にスペース)かもしれません
# 結果: "The capital of France is  Paris"(スペースが2つ!)

ソリューション: Guidanceは1トークン戻って再生成します。

from guidance import models, gen

lm = models.Anthropic("claude-sonnet-4-5-20250929")

# トークンヒーリングはデフォルトで有効
lm += "The capital of France is " + gen("capital", max_tokens=5)
# 結果: "The capital of France is Paris"(スペースが正しい)

メリット:

  • 自然なテキスト境界
  • 不自然なスペースの問題なし
  • より良いモデルパフォーマンス(自然なトークンシーケンスを認識)

4. 文法ベースの生成

文脈自由文法を使用して複雑な構造を定義します。

from guidance import models, gen

lm = models.Anthropic("claude-sonnet-4-5-20250929")

# JSON文法(簡略版)
json_grammar = """
{
    "name": <gen name regex="[A-Za-z ]+" max_tokens=20>,
    "age": <gen age regex="[0-9]+" max_tokens=3>,
    "email": <gen email regex="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}" max_tokens=50>
}
"""

# 有効なJSONを生成
lm += gen("person", grammar=json_grammar)

print(lm["person"])  # 有効なJSON構造が保証される

ユースケース:

  • 複雑な構造化出力
  • ネストされたデータ構造
  • プログラミング言語の構文
  • ドメイン固有言語

5. Guidance関数

@guidanceデコレータで再利用可能な生成パターンを作成します。

from guidance import guidance, gen, models

@guidance
def generate_person(lm):
    """名前と年齢を持つ人を生成します."""
    lm += "Name: " + gen("name", max_tokens=20, stop="\n")
    lm += "\nAge: " + gen("age", regex=r"[0-9]+", max_tokens=3)
    return lm

# 関数を使用
lm = models.Anthropic("claude-sonnet-4-5-20250929")
lm = generate_person(lm)

print(lm["name"])
print(lm["age"])

ステートフル関数:

@guidance(stateless=False)
def react_agent(lm, question, tools, max_rounds=5):
    """ツール使用を伴うReActエージェント."""
    lm += f"Question: {question}\n\n"

    for i in range(max_rounds):
        # 思考
        lm += f"Thought {i+1}: " + gen("thought", stop="\n")

        # 動作
        lm += "\nAction: " + select(list(tools.keys()), name="action")

        # ツール実行
        tool_result = tools[lm["action"]]()
        lm += f"\nObservation: {tool_result}\n\n"

        # 完了確認
        lm += "Done? " + select(["Yes", "No"], name="done")
        if lm["done"] == "Yes":
            break

    # 最終的な回答
    lm += "\nFinal Answer: " + gen("answer", max_tokens=100)
    return lm

バックエンド設定

Anthropic Claude

from guidance import models

lm = models.Anthropic(
    model="claude-sonnet-4-5-20250929",
    api_key="your-api-key"  # または ANTHROPIC_API_KEY 環境変数を設定
)

OpenAI

lm = models.OpenAI(
    model="gpt-4o-mini",
    api_key="your-api-key"  # または OPENAI_API_KEY 環境変数を設定
)

ローカルモデル(Transformers)

from guidance.models import Transformers

lm = Transformers(
    "microsoft/Phi-4-mini-instruct",
    device="cuda"  # または "cpu"
)

ローカルモデル(llama.cpp)

from guidance.models import LlamaCpp

lm = LlamaCpp(
    model_path="/path/to/model.gguf",
    n_ctx=4096,
    n_gpu_layers=35
)

一般的なパターン

パターン1: JSON生成

from guidance import models, gen, system, user, assistant

lm = models.Anthropic("claude-sonnet-4-5-20250929")

with system():
    lm += "You generate valid JSON."

with user():
    lm += "Generate a user profile with name, age, and email."

with assistant():
    lm += """{
    "name": """ + gen("name", regex=r'"[A-Za-z ]+"', max_tokens=30) + """,
    "age": """ + gen("age", regex=r"[0-9]+", max_tokens=3) + """,
    "email": """ + gen("email", regex=r'"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"', max_tokens=50) + """
}"""

print(lm)  # 有効なJSONが保証される

パターン2: 分類

from guidance import models, gen, select

lm = models.Anthropic("claude-sonnet-4-5-20250929")

text = "This product is amazing! I love it."

lm += f"Text: {text}\n"
lm += "Sentiment: " + select(["positive", "negative", "neutral"], name="sentiment")
lm += "\nConfidence: " + gen("confidence", regex=r"[0-9]+", max_tokens=3) + "%"

print(f"Sentiment: {lm['sentiment']}")
print(f"Confidence: {lm['confidence']}%")

パターン3: マルチステップ推論

from guidance import models, gen, guidance

@guidance
def chain_of_thought(lm, question):
    """段階的な推論を伴う回答を生成します."""
    lm += f"Question: {question}\n\n"

    # 複数の推論ステップを生成
    for i in range(3):
        lm += f"Step {i+1}: " + gen(f"step_{i+1}", stop="\n", max_tokens=100) + "\n"

    # 最終的な回答
    lm += "\nTherefore, the answer is: " + gen("answer", max_tokens=50)

    return lm

lm = models.Anthropic("claude-sonnet-4-5-20250929")
lm = chain_of_thought(lm, "What is 15% of 200?")

print(lm["answer"])

パターン4: ReActエージェント

from guidance import models, gen, select, guidance

@guidance(stateless=False)
def react_agent(lm, question):
    """ツール使用を伴うReActエージェント."""
    tools = {
        "calculator": lambda expr: eval(expr),
        "search": lambda query: f"Search results for: {query}",
    }

    lm += f"Question: {question}\n\n"

    for round in range(5):
        # 思考
        lm += f"Thought: " + gen("thought", stop="\n") + "\n"

        # 動作選択
        lm += "Action: " + select(["calculator", "search", "answer"], name="action")

        if lm["action"] == "answer":
            lm += "\nFinal Answer: " + gen("answer", max_tokens=100)
            break

        # 動作入力
        lm += "\nAction Input: " + gen("action_input", stop="\n") + "\n"

        # ツール実行
        if lm["action"] in tools:
            result = tools[lm["action"]](lm["action_input"])
            lm += f"Observation: {result}\n\n"

    return lm

lm = models.Anthropic("claude-sonnet-4-5-20250929")
lm = react_agent(lm, "What is 25 * 4 + 10?")
print(lm["answer"])

パターン5: データ抽出

from guidance import models, gen, guidance

@guidance
def extract_entities(lm, text):
    """テキストから構造化エンティティを抽出します."""
    lm += f"Text: {text}\n\n"

    # 人物を抽出
    lm += "Person: " + gen("person", stop="\n", max_tokens=30) + "\n"

    # 組織を抽出
    lm += "Organization: " + gen("organization", stop="\n", max_tokens=30) + "\n"

    # 日付を抽出
    lm += "Date: " + gen("date", regex=r"\d{4}-\d{2}-\d{2}", max_tokens=10) + "\n"

    # 場所を抽出
    lm += "Location: " + gen("location", stop="\n", max_tokens=30) + "\n"

    return lm

text = "Tim Cook announced at Apple Park on 2024-09-15 in Cupertino."

lm = models.Anthropic("claude-sonnet-4-5-20250929")
lm = extract_entities(lm, text)

print(f"Person: {lm['person']}")
print(f"Organization: {lm['organization']}")
print(f"Date: {lm['date']}")
print(f"Location: {lm['location']}")

ベストプラクティス

1. フォーマット検証に正規表現を使用する

# ✅ 良い: 正規表現は有効なフォーマットを保証
lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")

# ❌ 悪い: 自由生成では無効なメールが生成される可能性がある
lm += "Email: " + gen("email", max_tokens=50)

2. 固定カテゴリにselect()を使用する

# ✅ 良い: 有効なカテゴリが保証される
lm += "Status: " + select(["pending", "approved", "rejected"], name="status")

# ❌ 悪い: タイプミスや無効な値が生成される可能性がある
lm += "Status: " + gen("status", max_tokens=20)

3. トークンヒーリングを活用する

# トークンヒーリングはデフォルトで有効
# 特別なアクションは不要 - 自然に連結するだけ
lm += "The capital is " + gen("capital")  # 自動修復

4. ストップシーケンスを使用する

# ✅ 良い: 改行で停止(1行出力用)
lm += "Name: " + gen("name", stop="\n")

# ❌ 悪い: 複数行が生成される可能性がある
lm += "Name: " + gen("name", max_tokens=50)

5. 再利用可能な関数を作成する

# ✅ 良い: 再利用可能なパターン
@guidance
def generate_person(lm):
    lm += "Name: " + gen("name", stop="\n")
    lm += "\nAge: " + gen("age", regex=r"[0-9]+")
    return lm

# 複数回使用
lm = generate_person(lm)
lm += "\n\n"
lm = generate_person(lm)

6. 制約のバランスを取る

# ✅ 良い: 適切な制約
lm += gen("name", regex=r"[A-Za-z ]+", max_tokens=30)

# ❌ 厳しすぎる: 失敗するか非常に遅い可能性がある
lm += gen("name", regex=r"^(John|Jane)$", max_tokens=10)

代替手段との比較

機能GuidanceInstructorOutlinesLMQL
正規表現制約✅ はい❌ いいえ✅ はい✅ はい
文法サポート✅ CFG❌ いいえ✅ CFG✅ CFG
Pydantic検証❌ いいえ✅ はい✅ はい❌ いいえ
トークンヒーリング✅ はい❌ いいえ✅ はい❌ いいえ
ローカルモデル✅ はい⚠️ 限定的✅ はい✅ はい
APIモデル✅ はい✅ はい⚠️ 限定的✅ はい
Pythonシンタックス✅ はい✅ はい✅ はい❌ SQLのような
学習曲線

Guidanceを選ぶべき場合:

  • 正規表現/文法制約が必要
  • トークンヒーリングが必要
  • 制御フローを使用して複雑なワークフローを構築している
  • ローカルモデルを使用している(Transformers、llama.cpp)
  • Pythonシンタックスを好む

代替手段を選ぶべき場合:

  • Instructor: Pydantic検証と自動リトライが必要
  • Outlines: JSONスキーマ検証が必要
  • LMQL: 宣言的クエリシンタックスを好む

パフォーマンス特性

レイテンシ削減:

  • 制約付き出力では従来のプロンプト手法より30〜50%高速
  • トークンヒーリングは不必要な再生成を削減
  • 文法制約は無効なトークン生成を防止

メモリ使用量:

  • 制約なし生成と比べて最小限のオーバーヘッド
  • 文法コンパイルは最初の使用後にキャッシュされる
  • 推論時のトークンフィルタリングが効率的

トークン効率:

  • 無効な出力でトークンが浪費されない
  • リトライループが不要
  • 有効な出力への直接パス

リソース

関連項目

  • references/constraints.md - 包括的な正規表現と文法パターン
  • references/backends.md - バックエンド固有の設定
  • references/examples.md - 本番環境対応例

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
AlexiosBluffMara
リポジトリ
AlexiosBluffMara/mercury
ライセンス
MIT
最終更新
2026/5/12

Source: https://github.com/AlexiosBluffMara/mercury / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: AlexiosBluffMara · AlexiosBluffMara/mercury · ライセンス: MIT