如何使用LangChain与不同版本的Pydantic——详细指南

6 阅读3分钟
# 如何使用LangChain与不同版本的Pydantic——详细指南

在2023年6月,Pydantic v2发布,这一版本包含了许多重大变化。随着Pydantic 1在2024年6月走到生命周期的尽头,LangChain近期将不再支持Pydantic 1,内部会迁移到Pydantic 2,预计在今年9月的0.3.x版本中进行。本文将指导您如何在当前过渡阶段使用LangChain与不同版本的Pydantic。

## 引言

Pydantic 2的引入对于数据验证和解析带来了许多改进。然而,作为LangChain用户,我们必须小心处理与这些变化相关的兼容性问题。本文将深入探讨如何在LangChain中使用不同版本的Pydantic,提供实用的代码示例,并讨论常见问题和解决方法。

## 主要内容

### 1. 传递Pydantic对象到LangChain API

LangChain的大多数API已经更新,支持Pydantic v1和v2对象。对于已经安装的Pydantic 1,Pydantic v1对象是`pydantic.BaseModel`的子类或`pydantic.v1.BaseModel`的子类,如果安装了Pydantic 2则是`pydantic.BaseModel`的子类。

#### 兼容性检查
- **BaseChatModel.bind_tools**:在`langchain-core>=0.2.23`中支持
- **BaseChatModel.with_structured_output**:同上
- **Tool.from_function**:同上
- **StructuredTool.from_function**:同上

**合作包兼容性**:
- **langchain-mistralai**:支持Pydantic v2 `>=0.1.11`
- **langchain-anthropic**:支持Pydantic v2 `>=0.1.21`
- **langchain-robocorp**:支持Pydantic v2 `>=0.0.10`
- **langchain-openai**:支持Pydantic v2 `>=0.1.19`

### 2. 子类化LangChain模型

由于LangChain内部仍然使用Pydantic v1,如果您想子类化LangChain模型,推荐使用Pydantic v1的原语。

#### 示例:通过继承扩展
```python
from pydantic.v1 import validator
from langchain_core.tools import BaseTool

class CustomTool(BaseTool):
    x: int = Field(default=1)

    def _run(*args, **kwargs):
        return "hello"

    @validator('x')
    @classmethod
    def validate_x(cls, x: int) -> int:
        return 1
    

CustomTool(
    name='custom_tool',
    description="hello",
    x=1,
)

3. 在Pydantic v2模型中禁用LangChain对象的运行时验证

from typing import Annotated
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, SkipValidation

class Foo(BaseModel):
    model: Annotated[ChatOpenAI, SkipValidation()]

Foo(model=ChatOpenAI(api_key="hello"))

4. 使用LangServe时的OpenAPI文档生成限制

使用Pydantic 2时,LangServe无法生成OpenAPI文档。解决方法是安装Pydantic 1或使用LangChain的APIHandler手动创建API路由。

代码示例

预装langchain-core<0.2.23版本时,使用Pydantic v1对象:

from langchain_openai import ChatOpenAI
from pydantic.v1 import BaseModel

class Person(BaseModel):
    name: str
    
model = ChatOpenAI()
model = model.with_structured_output(Person)

model.invoke('Bob is a person.')

langchain-core>=0.2.23时,可以使用Pydantic v1或v2对象:

from langchain_openai import ChatOpenAI
from pydantic import BaseModel

class Person(BaseModel):
    name: str
    
model = ChatOpenAI()
model = model.with_structured_output(Person)

model.invoke('Bob is a person.')

常见问题和解决方案

  • 混合使用Pydantic v1和v2对象:会导致神秘错误。应避免这种情况,并在子类化LangChain模型时坚持使用Pydantic v1。
  • 运行时验证问题:当在Pydantic v2中使用LangChain对象时,请禁用特定对象的运行时验证。

总结和进一步学习资源

在使用LangChain与Pydantic时,开发者需要密切关注版本兼容性问题。Pydantic 2带来的新特性及其与LangChain的整合,将推动开发者采用更现代化的编码实践。

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!