Zenn
🐍

LLM から出力した JSON が Pydantic のバリデーションに引っかかるときに上手いことフォールバックする方法

2025/02/16に公開
1

背景

システムに LLM を組み込む際に、所望の JSON の書式に従わせるために Pydantic を使って JSON Schema を作成して、それを記載したプロンプトを LLM へ与えることがあるかと思います。例えば以下のような Pydantic モデルを考えます。

class Table(BaseModel):
    foo: int

このときに LLM が以下のような JSON を出力してきて、型が異なるためバリデーションエラーが起こってしまうとき、あると思います。本記事ではその対処法を GitHub Gist に書き留めました。

{
    "foo": "123"
}

対処例

以下の Gist に記載の通り、WrapValidator を使って handler から ValueError が送出された際にあらかじめ指定したフォールバック値を返すような振る舞いを登録することで、ValidationError が送出されることなく、代わりにアトリビュートに指定したフォールバック値がデータに書き込まれるといった仕組みです。

def Fallback(fallback_value: Any):
    def use_fallback(
        v: Any,
        handler: ValidatorFunctionWrapHandler,
        info: ValidationInfo,
    ) -> Any:
        try:
            return handler(v)
        except ValueError:
            return fallback_value
    return WrapValidator(use_fallback)
     

class Hoge(BaseModel):
    ...
    hoge_str: Annotated[str, Field(default="hoge"), Fallback("fallback-str")]

はじめからこの問題が起こらないようにするには

OpenAI/ChatGPT と Google/Gemini の場合は Structured Outputs という機能があり、これを使えばそもそもこのような問題は起こらない。しかし、DeepseekV3 や Gemini だと対応していなかったり、対応状況が実用に耐えるレベルでなかったりするので、そのときは本記事の方法でフォールバックさせると良いかも。

参考

https://github.com/pydantic/pydantic/discussions/7867

1

Discussion

ログインするとコメントできます