LangChainとVertexAIのgemini 2.0 flashで構造化出力に失敗するケースが直りそう

by
カテゴリ:

LangChainのStructured outputを使うと、文章中の構造を良い感じに読み取って、Pydanticで定義したデータ構造に落としてこんでくれます。

たとえばx: xという文字列をPythonの{"x": "x"}みたく変換してくれるイメージですね。

ところがこの変換、gemini 1.5 proからgemini 2.0 flashにしたとたん、失敗するケースを観測していました。

以下のようなコードを実行すると、x: x程度の簡単な構造でgemini 1.5 proでうまく処理できていた問題さえ、gemini 2.0 flashの場合に出力がNoneになるのです。

# "google-cloud-aiplatform[vertexai]==1.75.*"
# "langchain-core==0.2.*"
# "langchain-google-vertexai==1.0.*"
import langchain_core
from langchain_core.messages import HumanMessage
from langchain_google_vertexai import ChatVertexAI

if langchain_core.__version__ >= "0.3":
    from pydantic import BaseModel, Field
else:
    from langchain_core.pydantic_v1 import BaseModel, Field


class Data(BaseModel):
    x: str = Field()


def main():
    for model_name in [
        "gemini-1.5-pro-002",
        "gemini-2.0-flash-001",
    ]:
        print(model_name)
        llm = ChatVertexAI(
            model_name=model_name,
            temperature=0.0,
            max_tokens=8192,
            location="us-central1",
        )

        message = "x: x"

        for i in range(5):
            content = llm.with_structured_output(Data).invoke(
                [HumanMessage(content=[{"type": "text", "text": message}])]
            )
            print(content)


main()
$ uv run main.py
gemini-1.5-pro-002
x='x'
x='x'
x='x'
x='x'
x='x'
gemini-2.0-flash-001
None
None
None
None
None

AIモデルのバージョンアップが簡単ではないことをつきつけられますね。

この問題、langchain側にもあったようで、最新版を使うと解決します。

ところが最新のlangchainを使うと、今度は複雑なデータ構造を利用した場合に、Key '$defs' is not supported in schema, ignoringが発生して、正しく解釈できない問題を観測していました。

from pydantic import BaseModel, Field

class Data(BaseModel):
    x: str = Field(...)

class DataList(BaseModel):
    data: list[Data] = Field(...)

おかげでlangchainもgeminiもバージョンアップできない苦労を味わっていたのですが、5日前に解決したようです。

https://github.com/langchain-ai/langchain-google/issues/659

めでたしめでたし。

ちなみに、langchain 0.3系ではPydantic v2系を使うようになったので、以下を差し替えてあげるとGoodです。

- from langchain_core.pydantic_v1 import BaseModel, Field
+ from pydantic import BaseModel, Field

今回のデモに使ったpyproject.tomlは以下の通り。

[project]
name = "demo"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
    # >=1.76を使うと、`from langchain_google_vertexai import ChatVertexAI `に失敗する
    # langchain-google-vertexaiのバージョンを上げれば解決するが、下記の通り別の問題がある
    "google-cloud-aiplatform[vertexai]==1.75.*",
    "langchain-core==0.2.*",
    # 2系は<=2.0.20を使うとlist of classのstructured outputに失敗する
    # <https://github.com/langchain-ai/langchain-google/issues/659> のリリースで解決
    "langchain-google-vertexai==1.0.*",
]

ENJOY