mcpField
G
guidance

guidance

github.com/kalarislabsエージェントワークフロー7746 回インストール4 日前に更新
リポジトリ

guidance について

Guidanceは、制約付きLLM生成フローを構築するPythonライブラリです。形式に沿った出力を必要とする開発者向けに、正規表現や文法による制約、トークン境界の修正、Pythonの制御フローを提供します。

主な機能

  1. 01正規表現と文法による制約
  2. 02選択肢を限定した生成
  3. 03トークン境界の修正
  4. 04再利用可能なPython生成関数
  5. 05OpenAI、Anthropic、ローカルモデルに対応

活用シーン

  1. 01構造に沿ったJSONやXMLの生成
  2. 02日付やメールアドレスなどの生成
  3. 03複数ステップの生成ワークフロー構築

インストール

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

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

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

同梱ファイル

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

references/
backends.md
common-patterns.md
constraints.md
examples.md
scripts/
safe_arithmetic.py

詳細

ガイダンス:LLM 生成の制約

このスキルを使う場面

次のような場合に Guidance を使います。

  • 正規表現や文法でLLM の出力構文を制御する
  • 有効な JSON/XML/コードの生成を保証する
  • 従来のプロンプト方式と比べてレイテンシを削減する
  • 日付、メールアドレス、ID などの構造化形式を強制する
  • Python 風の制御フローで複数ステップのワークフローを構築する
  • 文法による制約で無効な出力を防止する

インストール

# Base installation
pip install guidance

# With specific backends
pip install guidance[transformers]  # Hugging Face models
pip install guidance[llama_cpp]     # llama.cpp models

クイックスタート

基本例:構造化生成
from guidance import models, gen

# Load model (supports OpenAI, Transformers, llama.cpp)
lm = models.OpenAI("gpt-4")

# Generate with constraints
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

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

# Use context managers for chat format
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")

# System message
with system():
    lm += "You are a JSON generation expert."

# User message
with user():
    lm += "Generate a person object with name and age."

# Assistant response
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")

# Constrain to valid email format
lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")

# Constrain to date format (YYYY-MM-DD)
lm += "Date: " + gen("date", regex=r"\d{4}-\d{2}-\d{2}")

# Constrain to phone number
lm += "Phone: " + gen("phone", regex=r"\d{3}-\d{3}-\d{4}")

print(lm["email"])  # Guaranteed valid email
print(lm["date"])   # Guaranteed YYYY-MM-DD format

仕組み:

  • 正規表現をトークンレベルの文法に変換します
  • 生成中に無効なトークンを除外します
  • モデルは一致する出力のみを生成できます
選択肢による制約
from guidance import models, gen, select

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

# Constrain to specific choices
lm += "Sentiment: " + select(["positive", "negative", "neutral"], name="sentiment")

# Multiple-choice selection
lm += "Best answer: " + select(
    ["A) Paris", "B) London", "C) Berlin", "D) Madrid"],
    name="answer"
)

print(lm["sentiment"])  # One of: positive, negative, neutral
print(lm["answer"])     # One of: A, B, C, or D
3. トークンの修復

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

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

# Without token healing
prompt = "The capital of France is "
# Last token: " is "
# First generated token might be " Par" (with leading space)
# Result: "The capital of France is  Paris" (double space!)

解決策: Guidance は1つ前のトークンに戻り、再生成します。

from guidance import models, gen

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

# Token healing enabled by default
lm += "The capital of France is " + gen("capital", max_tokens=5)
# Result: "The capital of France is Paris" (correct spacing)

メリット:

  • 自然なテキスト境界
  • 不自然なスペースの問題がない
  • モデルのパフォーマンスが向上する(自然なトークン列をモデルが確認できる)
4. 文法ベースの生成

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

from guidance import models, gen

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

# JSON grammar (simplified)
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>
}
"""

# Generate valid JSON
lm += gen("person", grammar=json_grammar)

print(lm["person"])  # Guaranteed valid JSON structure

用途:

  • 複雑な構造化出力
  • 入れ子になったデータ構造
  • プログラミング言語の構文
  • ドメイン固有言語
5. Guidance 関数

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

from guidance import guidance, gen, models

@guidance
def generate_person(lm):
    """Generate a person with name and age."""
    lm += "Name: " + gen("name", max_tokens=20, stop="\n")
    lm += "\nAge: " + gen("age", regex=r"[0-9]+", max_tokens=3)
    return lm

# Use the function
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 agent with tool use."""
    lm += f"Question: {question}\n\n"

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

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

        # Execute tool
        tool_result = tools[lm["action"]]()
        lm += f"\nObservation: {tool_result}\n\n"

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

    # Final answer
    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"  # Or set ANTHROPIC_API_KEY env var
)
OpenAI
lm = models.OpenAI(
    model="gpt-4o-mini",
    api_key="your-api-key"  # Or set OPENAI_API_KEY env var
)
ローカルモデル(Transformers)
from guidance.models import Transformers

lm = Transformers(
    "microsoft/Phi-4-mini-instruct",
    device="cuda"  # Or "cpu"
)
ローカルモデル(llama.cpp)
from guidance.models import LlamaCpp

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

よく使われるパターン

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

ベストプラクティス

1. 形式の検証には正規表現を使う
# ✅ Good: Regex ensures valid format
lm += "Email: " + gen("email", regex=r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")

# ❌ Bad: Free generation may produce invalid emails
lm += "Email: " + gen("email", max_tokens=50)
2. 固定カテゴリには select() を使う
# ✅ Good: Guaranteed valid category
lm += "Status: " + select(["pending", "approved", "rejected"], name="status")

# ❌ Bad: May generate typos or invalid values
lm += "Status: " + gen("status", max_tokens=20)
3. トークンの修復を活用する
# Token healing is enabled by default
# No special action needed - just concatenate naturally
lm += "The capital is " + gen("capital")  # Automatic healing
4. stop シーケンスを使う
# ✅ Good: Stop at newline for single-line outputs
lm += "Name: " + gen("name", stop="\n")

# ❌ Bad: May generate multiple lines
lm += "Name: " + gen("name", max_tokens=50)
5. 再利用可能な関数を作成する
# ✅ Good: Reusable pattern
@guidance
def generate_person(lm):
    lm += "Name: " + gen("name", stop="\n")
    lm += "\nAge: " + gen("age", regex=r"[0-9]+")
    return lm

# Use multiple times
lm = generate_person(lm)
lm += "\n\n"
lm = generate_person(lm)
6. 制約のバランスを取る
# ✅ Good: Reasonable constraints
lm += gen("name", regex=r"[A-Za-z ]+", max_tokens=30)

# ❌ Too strict: May fail or be very slow
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 - 本番環境ですぐに使える例

エージェントの作業手順

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

誠実性に関するルール

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

コメント