From 4fab8996cf3a5a34bd5333c6848b0bccf798a6a0 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 29 Jul 2024 22:19:00 -0400 Subject: [PATCH] docs: Update pydantic compatibility (#24625) Update pydantic compatibility. This will only be true after we release the partner packages. --- docs/docs/how_to/pydantic_compatibility.md | 139 +++++++++++++++------ 1 file changed, 102 insertions(+), 37 deletions(-) diff --git a/docs/docs/how_to/pydantic_compatibility.md b/docs/docs/how_to/pydantic_compatibility.md index 50d64f42478..aaee2e0c77a 100644 --- a/docs/docs/how_to/pydantic_compatibility.md +++ b/docs/docs/how_to/pydantic_compatibility.md @@ -1,27 +1,97 @@ # How to use LangChain with different Pydantic versions -- Pydantic v2 was released in June, 2023 (https://docs.pydantic.dev/2.0/blog/pydantic-v2-final/) -- v2 contains has a number of breaking changes (https://docs.pydantic.dev/2.0/migration/) -- Pydantic v2 and v1 are under the same package name, so both versions cannot be installed at the same time +- Pydantic v2 was released in June, 2023 (https://docs.pydantic.dev/2.0/blog/pydantic-v2-final/). +- v2 contains has a number of breaking changes (https://docs.pydantic.dev/2.0/migration/). +- Pydantic 1 End of Life was in June 2024. LangChain will be dropping support for Pydantic 1 in the near future, +and likely migrating internally to Pydantic 2. The timeline is tentatively September. This change will be accompanied by a minor version bump in the main langchain packages to version 0.3.x. -## LangChain Pydantic migration plan +As of `langchain>=0.0.267`, LangChain allows users to install either Pydantic V1 or V2. -As of `langchain>=0.0.267`, LangChain will allow users to install either Pydantic V1 or V2. - * Internally LangChain will continue to [use V1](https://docs.pydantic.dev/latest/migration/#continue-using-pydantic-v1-features). - * During this time, users can pin their pydantic version to v1 to avoid breaking changes, or start a partial - migration using pydantic v2 throughout their code, but avoiding mixing v1 and v2 code for LangChain (see below). +Internally, LangChain continues to use the [Pydantic V1](https://docs.pydantic.dev/latest/migration/#continue-using-pydantic-v1-features) via +the v1 namespace of Pydantic 2. -User can either pin to pydantic v1, and upgrade their code in one go once LangChain has migrated to v2 internally, or they can start a partial migration to v2, but must avoid mixing v1 and v2 code for LangChain. +Because Pydantic does not support mixing .v1 and .v2 objects, users should be aware of a number of issues +when using LangChain with Pydantic. + +## 1. Passing Pydantic objects to LangChain APIs + +Most LangChain APIs that accept Pydantic objects have been updated to accept both Pydantic v1 and v2 objects. + +* Pydantic v1 objects correspond to subclasses of `pydantic.BaseModel` if `pydantic 1` is installed or subclasses of `pydantic.v1.BaseModel` if `pydantic 2` is installed. +* Pydantic v2 objects correspond to subclasses of `pydantic.BaseModel` if `pydantic 2` is installed. + + +| API | Pydantic 1 | Pydantic 2 | +|----------------------------------------|------------|----------------------------------------------------------------| +| `BaseChatModel.bind_tools` | Yes | langchain-core>=0.2.23, appropriate version of partner package | +| `BaseChatModel.with_structured_output` | Yes | langchain-core>=0.2.23, appropriate version of partner package | +| `Tool.from_function` | Yes | langchain-core>=0.2.23 | +| `StructuredTool.from_function` | Yes | langchain-core>=0.2.23 | + + +Partner packages that accept pydantic v2 objects via `bind_tools` or `with_structured_output` APIs: + +| Package Name | pydantic v1 | pydantic v2 | +|---------------------|-------------|-------------| +| langchain-mistralai | Yes | >=0.1.11 | +| langchain-anthropic | Yes | >=0.1.21 | +| langchain-robocorp | Yes | >=0.0.10 | +| langchain-openai | Yes | >=0.1.19 | +| langchain-fireworks | Yes | >=0.1.5 | + +Additional partner packages will be updated to accept Pydantic v2 objects in the future. + +If you are still seeing issues with these APIs or other APIs that accept Pydantic objects, please open an issue, and we'll +address it. + +Example: + +Prior to `langchain-core<0.2.23`, use Pydantic v1 objects when passing to LangChain APIs. + + +```python +from langchain_openai import ChatOpenAI +from pydantic.v1 import BaseModel # <-- Note v1 namespace + +class Person(BaseModel): + """Personal information""" + name: str + +model = ChatOpenAI() +model = model.with_structured_output(Person) + +model.invoke('Bob is a person.') +``` + +After `langchain-core>=0.2.23`, use either Pydantic v1 or v2 objects when passing to LangChain APIs. + +```python +from langchain_openai import ChatOpenAI +from pydantic import BaseModel + +class Person(BaseModel): + """Personal information""" + name: str + + +model = ChatOpenAI() +model = model.with_structured_output(Person) + +model.invoke('Bob is a person.') +``` + +## 2. Sub-classing LangChain models + +Because LangChain internally uses Pydantic v1, if you are sub-classing LangChain models, you should use Pydantic v1 +primitives. -Below are two examples of showing how to avoid mixing pydantic v1 and v2 code in -the case of inheritance and in the case of passing objects to LangChain. **Example 1: Extending via inheritance** **YES** ```python -from pydantic.v1 import root_validator, validator +from pydantic.v1 import validator from langchain_core.tools import BaseTool class CustomTool(BaseTool): # BaseTool is v1 code @@ -70,38 +140,33 @@ CustomTool( ) ``` -**Example 2: Passing objects to LangChain** -**YES** +## 3. Disable run-time validation for LangChain objects used inside Pydantic v2 models + +e.g., ```python -from langchain_core.tools import Tool -from pydantic.v1 import BaseModel, Field # <-- Uses v1 namespace +from typing import Annotated -class CalculatorInput(BaseModel): - question: str = Field() +from langchain_openai import ChatOpenAI # <-- ChatOpenAI uses pydantic v1 +from pydantic import BaseModel, SkipValidation -Tool.from_function( # <-- tool uses v1 namespace - func=lambda question: 'hello', - name="Calculator", - description="useful for when you need to answer questions about math", - args_schema=CalculatorInput -) + +class Foo(BaseModel): # <-- BaseModel is from Pydantic v2 + model: Annotated[ChatOpenAI, SkipValidation()] + +Foo(model=ChatOpenAI(api_key="hello")) ``` -**NO** +## 4: LangServe cannot generate OpenAPI docs if running Pydantic 2 -```python -from langchain_core.tools import Tool -from pydantic import BaseModel, Field # <-- Uses v2 namespace +If you are using Pydantic 2, you will not be able to generate OpenAPI docs using LangServe. -class CalculatorInput(BaseModel): - question: str = Field() +If you need OpenAPI docs, your options are to either install Pydantic 1: -Tool.from_function( # <-- tool uses v1 namespace - func=lambda question: 'hello', - name="Calculator", - description="useful for when you need to answer questions about math", - args_schema=CalculatorInput -) -``` +`pip install pydantic==1.10.17` + +or else to use the `APIHandler` object in LangChain to manually create the +routes for your API. + +See: https://python.langchain.com/v0.2/docs/langserve/#pydantic \ No newline at end of file