Microsoftが開発した革新的なPythonライブラリで、大規模言語モデル(LLM)の制御を新たなレベルへ引き上げましょう。
近年、ChatGPTをはじめとする大規模言語モデル(LLM)の進化は目覚ましく、様々な分野での応用が期待されています。しかし、LLMはその性質上、常に期待通りの出力をするとは限りません。プロンプトエンジニアリングによってある程度の制御は可能ですが、より複雑なタスクや厳密な出力形式が求められる場合、限界が生じることがありました。
そこで登場したのが、Microsoft Researchが開発したPythonライブラリ guidance です。guidanceは、LLMのプロンプトと制御ロジックをシームレスに統合し、まるでプログラミング言語のようにLLMの挙動を細かく制御できる画期的なフレームワークです。従来のプロンプトやチェイニング(複数のプロンプトを連鎖させる手法)よりも効率的かつ効果的にLLMを制御できると注目を集めています。
この記事では、guidanceライブラリの基本的な考え方から主要な機能、具体的な使い方、そしてその利点と注意点まで、網羅的に解説します。guidanceを使いこなすことで、あなたのLLMアプリケーション開発は新たな次元へと進化するでしょう! ✨
guidanceの基本
インストール
guidanceのインストールは非常に簡単です。pipコマンドを使ってインストールできます。
pip install guidance
依存関係によっては追加のライブラリが必要になる場合がありますが、基本的な利用はこのコマンドで開始できます。
基本的な考え方:Guidanceプログラム
guidanceの中核となるのは「Guidanceプログラム」という概念です。これは、PythonのコードとLLMへの指示(プロンプトテキストや生成コマンド)を組み合わせたものです。F-stringのような構文を使い、テキスト生成、選択、条件分岐、ループなどをプログラム内に記述できます。
従来のプロンプトエンジニアリングでは、プロンプトは単なるテキスト文字列でしたが、guidanceではプロンプト自体が実行可能なプログラムとなります。これにより、LLMの生成プロセス中にPythonのロジックを介入させ、より動的で精密な制御が可能になります。
Guidanceプログラムは、モデルオブジェクト(LLMへのインターフェース)に対してテキストやguidanceの関数を追加していく形で構築されます。実行すると、guidanceがLLMとのやり取りを管理し、指定された制御に従ってテキストを生成します。
簡単なコード例:Hello, guidance!
まずは、guidanceを使って簡単なテキスト生成を行ってみましょう。ここではOpenAIのモデルを使う例を示します(他のモデルも利用可能です)。
import guidance
# OpenAIモデルをロード(APIキーの設定が必要)
# guidance.llm = guidance.llms.OpenAI("text-davinci-003")
# または、ローカルモデルを使う場合 (例: LlamaCpp)
# guidance.llm = guidance.models.LlamaCpp("/path/to/your/model.gguf")
# Guidanceプログラムを定義
program = guidance(
'''こんにちは! guidanceライブラリを使って、{{topic}} について短い説明文を生成してください。
{{gen 'explanation' max_tokens=50}}'''
)
# プログラムを実行し、変数を渡す
executed_program = program(topic="プロンプトエンジニアリング")
# 生成されたテキストを表示
print(executed_program['explanation'])
この例では、guidance(...)
でプログラムテンプレートを作成し、{{topic}}
という変数と {{gen 'explanation' max_tokens=50}}
という生成コマンドを含めています。program(topic="...")
で変数を渡し、プログラムを実行します。{{gen ...}}
の部分でLLMによるテキスト生成が行われ、その結果が executed_program['explanation']
に格納されます。
実行結果は、guidance
がテンプレートの {{gen ...}}
部分をLLMの生成結果で置き換えた形になります。Jupyter Notebookなどで実行すると、生成された部分が色付きで表示され、どの部分が生成されたか分かりやすくなっています。
主要な機能と制御構文 🛠️
guidanceが提供する強力な制御機能を見ていきましょう。
guidanceの真価は、その豊富な制御構文にあります。これらを組み合わせることで、複雑なLLMの振る舞いをデザインできます。
高度な制約:正規表現とJSONスキーマ
guidanceの強力な機能の一つが、生成されるテキストの形式を厳密に制約できる点です。
- 正規表現 (Regex):
gen
コマンドにregex=r"..."
パラメータを指定することで、生成されるテキストが特定の正規表現パターンに一致するように強制できます。これは、電話番号、メールアドレス、特定のIDフォーマットなどを生成させたい場合に役立ちます。 - JSONスキーマ:
gen
コマンドでjson_schema=...
を指定すると、生成されるテキストが指定されたJSONスキーマに準拠した有効なJSONオブジェクトであることを保証します。これは、構造化データをLLMに生成させる際に非常に強力です。
# JSONスキーマを使った例
import json
character_schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"class": {"type": "string", "enum": ["Warrior", "Mage", "Rogue"]},
"level": {"type": "integer", "minimum": 1, "maximum": 99},
"hp": {"type": "integer"}
},
"required": ["name", "class", "level", "hp"]
}
program = guidance(
'''RPGキャラクターのプロフィールをJSON形式で生成してください。
```json
{{gen 'character_json' json_schema=character_schema temperature=0}}
```'''
)
executed_program = program()
try:
# 生成されたJSONをパース
character_data = json.loads(executed_program['character_json'])
print(json.dumps(character_data, indent=2, ensure_ascii=False))
except json.JSONDecodeError:
print("生成された出力は有効なJSONではありませんでした。")
print(executed_program['character_json'])
guidanceは、トークンレベルでの制御(マスキングやバイアス調整)を行うことで、これらの制約を効率的に実現します。これにより、無効な形式の出力を生成してしまい、後処理で修正したり再生成したりするコストを削減できます。
具体的なユースケース 💡
guidanceがどのように活用できるか、いくつかの例を見てみましょう。
-
🤖 高度なチャットボット開発:
role
タグを使って対話の流れを管理し、if
やawait
を使ってユーザーの発言内容に応じた条件分岐や外部API連携(天気情報取得、データベース検索など)を組み込むことで、単なる応答生成を超えたインテリジェントなチャットボットを構築できます。会話履歴もguidanceプログラム内で自然に扱えます。 -
📄 構造化データの抽出:
非構造化テキスト(メール、レポート、記事など)から特定の情報を抽出し、JSON形式で出力させることが容易になります。JSONスキーマ制約を使えば、抽出結果が必ず定義したフォーマットに従うことを保証できます。これにより、後続のシステムでのデータ処理が格段に楽になります。
# 請求書テキストから情報を抽出しJSONにする例 invoice_text = """ 請求書番号: INV-00123 発行日: 2025年4月1日 支払期日: 2025年4月30日 請求元: 株式会社サンプルテック 請求先: ABC株式会社 御中 商品: 製品X, 数量: 2, 単価: 10000 商品: 製品Y, 数量: 1, 単価: 5000 合計金額: 25000円 (税抜) """ extraction_schema = { "type": "object", "properties": { "invoice_number": {"type": "string"}, "issue_date": {"type": "string", "format": "date"}, "due_date": {"type": "string", "format": "date"}, "biller_name": {"type": "string"}, "client_name": {"type": "string"}, "total_amount": {"type": "integer"} }, "required": ["invoice_number", "issue_date", "due_date", "biller_name", "client_name", "total_amount"] } program = guidance( '''以下の請求書テキストから指定された情報を抽出し、JSON形式で出力してください。 テキスト: {{invoice_text}} 抽出結果: ```json {{gen 'extracted_data' json_schema=extraction_schema temperature=0}} ```''' ) executed_program = program(invoice_text=invoice_text) print(executed_program['extracted_data'])
-
📝 多様な出力形式の生成:
select
や正規表現制約、ループ構文 (each
) などを組み合わせることで、箇条書きリスト、表形式のテキスト、特定のフォーマットに従ったコードスニペットなど、様々な形式のテキストを確実に生成させることができます。 -
🤔 思考連鎖 (Chain-of-Thought) の実装:
複雑な問題解決プロセスをLLMに段階的に実行させ、その思考プロセス(中間的な推論)も出力させることができます。
gen
やset
を使って中間結果を保持し、if
で条件分岐させることで、より信頼性の高い推論を実現できます。 -
🔧 外部ツールとの連携 (エージェント):
await
を活用して、LLMが判断したタイミングで外部の計算ツール(電卓、コード実行環境)、情報検索API、データベースなどを呼び出すエージェントを構築できます。LLMは思考や計画を行い、実際の計算や情報取得は外部ツールに任せる、といった分業が可能になります。
guidanceの利点と注意点 🤔
他のライブラリとの比較 (LangChainなど)
LLMアプリケーション開発フレームワークとしては、LangChain も非常に有名です。guidanceとLangChainは目的が一部重なりますが、アプローチに違いがあります。
guidance vs LangChain
特徴 | guidance | LangChain |
---|---|---|
主な焦点 | LLMの生成プロセスに対する細かな制御と出力形式の保証。プロンプトと制御ロジックの統合。 | LLMを中心としたアプリケーションコンポーネントの連鎖 (Chaining) と統合。エージェント、メモリ、外部ツール連携など、広範な機能を提供。 |
制御の粒度 | トークンレベルでの制御が可能。プロンプト内に直接制御構文を埋め込む。 | コンポーネント(LLM、PromptTemplate、OutputParserなど)を組み合わせて制御。制御は主にコンポーネント間のインターフェースで行われる。 |
プロンプト記述 | 独自のテンプレート構文 (F-string like + guidanceコマンド)。プロンプト自体がプログラム。 | PromptTemplateクラスなどを使用。プロンプトは主にデータ構造として扱われる。 |
出力形式の保証 | 正規表現やJSONスキーマによる強力な保証機能が組み込まれている。 | OutputParserを使用するが、LLMの生成後にパースするため、失敗する可能性がある。Function Callingを利用する場合はより確実。 |
複雑さ | 独自の構文を学ぶ必要はあるが、プロンプトとロジックが一体化しているため、特定のタスクではシンプルになることも。 | 多くの概念(Agent, Tool, Memory, Chainなど)があり、全体像を把握するのに学習コストがかかる場合がある。 |
柔軟性 | プロンプト内での自由なロジック記述が可能。 | 豊富なコンポーネントと抽象化により高い柔軟性を持つが、内部実装のカスタマイズはguidanceより複雑になる場合がある。 |
どちらを選ぶべきか?
- LLMの出力を厳密なフォーマットに制御したい、または生成プロセス自体に細かく介入したい場合は、guidance が強力な選択肢となります。
- 様々なツールやデータソースを連携させ、複雑なアプリケーションフローを構築したい場合は、コンポーネントが豊富な LangChain が適している場合が多いでしょう。
両者は競合するというよりは、異なる強みを持つツールであり、プロジェクトの要件に応じて使い分けたり、部分的に組み合わせたりすることも考えられます。
また、構造化出力に特化した Outlines や、OpenAIのFunction Callingを使いやすくする Instructor といったライブラリも存在します。guidanceはこれらの機能を取り込みつつ、より汎用的な制御フレームワークを目指していると言えるでしょう。
まとめ
Microsoftが開発した guidance ライブラリは、LLMの制御を新たなレベルに引き上げる可能性を秘めた、非常に強力で革新的なツールです。プロンプトと制御ロジックをシームレスに統合し、PythonコードのようにLLMの挙動を記述できるため、開発者はより意図した通りにLLMを動作させることができます。
特に、出力形式の厳密な制御、条件に応じた動的なプロンプト生成、外部ツールとの連携といった点で、従来のプロンプトエンジニアリングや単純なAPIコールでは難しかった高度なタスクを実現可能にします。
学習コストや一部モデルでの機能制限といった注意点もありますが、そのメリットは非常に大きく、LLMアプリケーション開発の効率と品質を大幅に向上させることが期待できます。今後のLLM開発において、guidanceのような制御フレームワークはますます重要な役割を担っていくでしょう。
ぜひ、guidanceを試してみて、そのパワーを体験してください! 🚀
学習リソース
さらに詳しく学びたい方は、以下の公式リソースを参照することをお勧めします。
- GitHubリポジトリ: https://github.com/guidance-ai/guidance (最新情報、Issue、コントリビューション)
- 公式ドキュメント: https://guidance.readthedocs.io/en/latest/ (チュートリアル、APIリファレンス、使用例)
コメント