🦁
【LangChain基礎学習】PydanticOutputParser(その1)
LangChain
LangChainの学習を進め、ようやくLangGraphについて理解してきた。
そして、LangGraphを効果的に使うには、応答整形はについてはキッチリやっておかないと駄目そうですね。
今まで曖昧にしていたPydanticOutputParserについて慣れておくべき時が来たようです。
PydanticOutputParser
LLMが便利すぎるので、なぁなぁにしてきたけど基本が大事ということで3例ほどサンプル使ってお勉強しておきます。
スポットで理解を深めておくのが基本ですし。
ユーザープロフィール
UserProfile.py
from pydantic import BaseModel, Field
from langchain_core.output_parsers import PydanticOutputParser
class UserProfile(BaseModel):
name: str = Field(description="ユーザーのフルネーム")
age: int = Field(description="ユーザーの年齢")
interests: list[str] = Field(description="ユーザーの興味・趣味のリスト")
if __name__=="__main__":
output_parser = PydanticOutputParser(pydantic_object=UserProfile)
# format_instructions = output_parser.get_format_instructions() # デバッグ用
# print(format_instructions) # デバッグ用
# 正常なJSONデータ
valid_json = '''
{
"name": "山田太郎",
"age": "30",
"interests": ["読書", "旅行", "プログラミング"]
}
'''
# エラー系のなJSONデータ
valid_json_error = '''
{
"name": "山田太郎",
"age": ["30"],
"interests": ["読書", "旅行", "プログラミング"]
}
'''
try:
# JSONをパース
parsed_output = output_parser.parse(valid_json)
print("正常ケース:")
print(parsed_output)
parsed_output = output_parser.parse(valid_json_error)
print("異常ケース:") # ここに入らず、exceptへ
print(parsed_output) # ここに入らず、exceptへ
except Exception as e:
print(f"エラー: {e}")
正常ケース:
name='山田太郎' age=30 interests=['読書', '旅行', 'プログラミング']
エラー: Failed to parse UserProfile from completion {"name": "\u5c71\u7530\u592a\u90ce", "age": ["30"], "interests": ["\u8aad\u66f8", "\u65c5\u884c", "\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0"]}. Got: 1 validation error for UserProfile
age
Input should be a valid integer [type=int_type, input_value=['30'], input_type=list]
For further information visit https://errors.pydantic.dev/2.10/v/int_type
For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE
異常系
validation error for UserProfile
age
Input should be a valid integer [type=int_type, input_value=['30'], input_type=list]
# エラー系のなJSONデータ
valid_json_error = '''
{
"name": "山田太郎",
"age": ["30"],
"interests": ["読書", "旅行", "プログラミング"]
}
'''
のage変数をListで寄越すな!というエラーですね。
正常系で、ageを文字列で送ったところ、これは普通に変換してくれましたが、数値変換できない"a"とかを送るとエラーを返してくれました。
後続構文
これをChatTemplateで設定し、partialメソッドで設定を反映させてinvokeすれば、指定した型で応答してくれるってことですね。
あと2つほど試しておきます。
映画レビュー
MovieReview.py
from pydantic import BaseModel, Field
from langchain_core.output_parsers import PydanticOutputParser
class MovieReview(BaseModel):
title: str = Field(description="映画のタイトル")
rating: float = Field(description="5段階評価での評価点")
pros: list[str] = Field(description="映画の良かった点のリスト")
cons: list[str] = Field(description="映画の改善点のリスト")
if __name__=="__main__":
output_parser = PydanticOutputParser(pydantic_object=MovieReview)
# format_instructions = output_parser.get_format_instructions()
# print(format_instructions)
# 正常なJSONデータ
valid_json = '''
{
"title": "xxx",
"rating": 3.0,
"pros": ["pros01", "pros02", "pros03"],
"cons": ["cons01", "cons02"]
}
'''
# エラー系のなJSONデータ(型が定義と異なる)
valid_json_error = '''
{
"title_error": "xxx",
"rating": 3.0,
"pros": ["pros01", "pros02", "pros03"],
"cons": ["cons01", "cons02"]
}
'''
try:
# JSONをパース
parsed_output = output_parser.parse(valid_json)
print("正常ケース:")
print(parsed_output)
parsed_output = output_parser.parse(valid_json_error)
print("異常ケース:")
print(parsed_output)
except Exception as e:
print(f"エラー: {e}")
異常系
validation error for MovieReview
title
Field required [type=missing, input_value={'title_error': 'xxx', 'r...': ['cons01', 'cons02']}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE
# エラー系のなJSONデータ(型が定義と異なる)
valid_json_error = '''
{
"title_error": "xxx",
"rating": 3.0,
"pros": ["pros01", "pros02", "pros03"],
"cons": ["cons01", "cons02"]
}
'''
のtitle_errorが定義されていない!というエラーですね。
製品仕様
ProductSpec.py
from pydantic import BaseModel, Field
from langchain_core.output_parsers import PydanticOutputParser
class ProductSpecification(BaseModel):
name: str = Field(description="製品名")
category: str = Field(description="製品カテゴリー")
price: float = Field(description="製品価格(円)")
features: list[str] = Field(description="製品の主な特徴のリスト")
dimensions: dict = Field(description="製品の寸法(幅、高さ、奥行き)")
if __name__=="__main__":
output_parser = PydanticOutputParser(pydantic_object=ProductSpecification)
# format_instructions = output_parser.get_format_instructions()
# print(format_instructions)
# 正常なJSONデータ
valid_json = '''
{
"name": "ノートパソコン",
"category": "電子機器",
"price": 120000.0,
"features": ["軽量設計", "高性能プロセッサ", "長時間バッテリー"],
"dimensions": {
"width": 32.5,
"height": 1.8,
"depth": 22.7
}
}
'''
# エラー系のなJSONデータ(型が定義と異なる)
valid_json_error = '''
{
"name": "ノートパソコン",
"category": "電子機器",
"price": 120000.0,
"dimensions": {
"width": 32.5,
"height": 1.8,
"depth": 22.7
}
}
'''
try:
# JSONをパース
parsed_output = output_parser.parse(valid_json)
print("正常ケース:")
print(parsed_output)
parsed_output = output_parser.parse(valid_json_error)
print("異常ケース:")
print(parsed_output)
except Exception as e:
print(f"エラー: {e}")
正常ケース:
name='ノートパソコン' category='電子機器' price=120000.0 features=['軽量設計', '高性能プロセッサ', '長時間バッテリー'] dimensions={'width': 32.5, 'height': 1.8, 'depth': 22.7}
エラー: Failed to parse ProductSpecification from completion {"name": "\u30ce\u30fc\u30c8\u30d1\u30bd\u30b3\u30f3", "category": "\u96fb\u5b50\u6a5f\u5668", "price": 120000.0, "dimensions": {"width": 32.5, "height": 1.8, "depth": 22.7}}. Got: 1 validation error for ProductSpecification
features
Field required [type=missing, input_value={'name': 'ノートパソ...t': 1.8, 'depth': 22.7}}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE
異常系
validation error for ProductSpecification
features
Field required [type=missing, input_value={'name': 'ノートパソ...t': 1.8, 'depth': 22.7}}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE
# エラー系のなJSONデータ(featuresキーがない)
valid_json_error = '''
{
"name": "ノートパソコン",
"category": "電子機器",
"price": 120000.0,
"dimensions": {
"width": 32.5,
"height": 1.8,
"depth": 22.7
}
}
のfeaturesキーがない!というエラーですね。
希望する型でLLMから応答返してくれたら確かにありがたいので、もう少し詰めたいと思います。
Discussion