如何将LangChain与不同版本的Pydantic一起使用
概述
本文介绍了如何在LangChain中使用不同版本的Pydantic,并提供了迁移计划和示例代码,以避免在使用过程中出现版本冲突。
Pydantic版本更新历史
LangChain的Pydantic迁移计划
从langchain>=0.0.267
版本开始,LangChain将允许用户安装Pydantic V1或V2。
- LangChain内部将继续使用V1版本。
- 在此期间,用户可以将Pydantic版本固定在v1以避免重大变更,或者开始逐步使用Pydantic v2进行迁移,但要避免在LangChain代码中混合使用v1和v2(见下文)。
- 用户可以选择将Pydantic固定在v1,并在LangChain内部迁移到v2后一次性升级代码,或者他们可以开始部分迁移到v2,但必须避免在LangChain中混合使用v1和v2代码。
以下是两个示例,展示了如何在继承和向LangChain传递对象的情况下避免混合使用Pydantic v1和v2代码。
示例1:通过继承扩展
推荐做法
from pydantic.v1 import root_validator, validator
from langchain_core.tools import BaseTool
class CustomTool(BaseTool): # BaseTool是v1代码
x: int = Field(default=1)
def _run(*args, **kwargs):
return "hello"
@validator('x') # v1代码
@classmethod
def validate_x(cls, x: int) -> int:
return 1
CustomTool(
name='custom_tool',
description="hello",
x=1,
)
混合使用Pydantic v2和v1原语可能会引发难以理解的错误。
不推荐做法
from pydantic import Field, field_validator # pydantic v2
from langchain_core.tools import BaseTool
class CustomTool(BaseTool): # BaseTool是v1代码
x: int = Field(default=1)
def _run(*args, **kwargs):
return "hello"
@field_validator('x') # v2代码
@classmethod
def validate_x(cls, x: int) -> int:
return 1
CustomTool(
name='custom_tool',
description="hello",
x=1,
)
示例2:向LangChain传递对象
推荐做法
from langchain_core.tools import Tool
from pydantic.v1 import BaseModel, Field # <-- 使用v1命名空间
class CalculatorInput(BaseModel):
question: str = Field()
Tool.from_function( # <-- 工具使用v1命名空间
func=lambda question: 'hello',
name="Calculator",
description="useful for when you need to answer questions about math",
args_schema=CalculatorInput
)
不推荐做法
from langchain_core.tools import Tool
from pydantic import BaseModel, Field # <-- 使用v2命名空间
class CalculatorInput(BaseModel):
question: str = Field()
Tool.from_function( # <-- 工具使用v1命名空间
func=lambda question: 'hello',
name="Calculator",
description="useful for when you need to answer questions about math",
args_schema=CalculatorInput
)
总结
本文提供了LangChain与不同Pydantic版本共存的解决方案和最佳实践。通过示例代码,我们了解到如何避免在代码中混合使用Pydantic v1和v2,以及如何在LangChain中正确地使用Pydantic模型。这对于维护代码的兼容性和稳定性至关重要。