スキップしてメイン コンテンツに移動

JSONが欲しいのに!AIの回答を確実に構造化する「OutputParser」の奥義

JSONが欲しいのに!AIの回答を確実に構造化する「OutputParser」の奥義

はじめに

APIとしてLLMを利用する際、最大の悩みの一つが「出力形式の不安定さ」です。「JSONで返して」と頼んでも、余計な前置き("Sure! Here is the JSON...")が入ったり、プロパティ名が勝手に変わったりして、json.loads() でパースエラーになった経験はありませんか?

LangChainのOutputParserを使えば、スキーマ定義から自動的に指示プロンプトを生成し、返答をPythonオブジェクト(辞書やデータクラス)に確実に変換することができます。

LLMの出力はただの文字列

Requirement

単なる文字列が欲しい場合は `StrOutputParser` を使いますが、アプリ開発では `PydanticOutputParser` が主役になります。

プログラムとAIを連携させる上で、「非構造化データ(テキスト)」を「構造化データ(JSONなど)」に変換することは必須のプロセスです。これを安定させるために、LangChainは以下の戦略をとります。

  1. Pythonの型定義(Pydantic)からスキーマを作る。
  2. スキーマに基づいた「JSONフォーマット指示」をプロンプトに注入する。
  3. AIの返答からJSON部分だけを切り出してパースする。

PydanticOutputParserの基本

まずはPydanticを使って、欲しいデータの形を定義します。

from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_core.output_parsers import PydanticOutputParser

# 1. データ構造の定義
class Recipe(BaseModel):
    name: str = Field(description="料理の名前")
    ingredients: list[str] = Field(description="材料のリスト")
    steps: list[str] = Field(description="調理手順")

# 2. パーサーの作成
parser = PydanticOutputParser(pydantic_object=Recipe)

# 3. フォーマット指示の取得
format_instructions = parser.get_format_instructions()
print(format_instructions)
# 出力: The output should be formatted as a JSON instance that conforms to the JSON schema...

実践:レシピ生成AI

プロンプトテンプレートにフォーマット指示を組み込みます。

template = """
あなたはプロの料理研究家です。
以下の食材を使った料理を1つ考案してください。

食材: {ingredients}

{format_instructions}
"""

prompt = PromptTemplate(
    template=template,
    input_variables=["ingredients"],
    partial_variables={"format_instructions": format_instructions},
)

chain = prompt | llm | parser

result = chain.invoke({"ingredients": "卵, 玉ねぎ, 鶏肉"})

# 結果はPydanticモデルとして返ってくる
print(f"料理名: {result.name}")
print(f"材料数: {len(result.ingredients)}")

これにより、result.name のようにドットアクセスでデータを扱えるようになり、アプリへの組み込みが圧倒的に楽になります。

エラーハンドリング(RetryParser)

稀に、AIが壊れたJSONを返すことがあります。そんな時のために、LangChainには「自動修復」の仕組みがあります。

OutputFixingParserRetryOutputParser を使うと、パースエラーが発生した際に、AIに対して「このJSONは壊れています。修正してください」と再送(リトライ)要求を自動で行い、正しい形式を取得しようと試みます。

まとめ

OutputParserを制する者はLangChainを制します。AIを「ただのチャットボット」から「信頼できるAPIバックエンド」に昇格させるためには、この構造化出力の技術が不可欠です。

次回は、チャットボットに必須の機能である「Memory(会話履歴の保持)」の実装方法について解説します。

このブログ記事はAIを利用して自動生成されました。

コメント