If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`

该文章已生成可运行项目,

今天使用遇到一个pydantic 包的错误

File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/langchain/schema.py", line 140, in ChatGeneration
    def set_text(cls, values: Dict[str, Any]) -> Dict[str, Any]:
  File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/deprecated/class_validators.py", line 222, in root_validator
    return root_validator()(*__args)  # type: ignore
  File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/deprecated/class_validators.py", line 228, in root_validator
    raise PydanticUserError(
pydantic.errors.PydanticUserError: If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`. Note that `@root_validator` is deprecated and should be replaced with `@model_validator`.
 

环境,python 3.10,pydantic 版本2.1.0,按照参考资料1 的说法,降低版本至1.10.x,但是整个程序(不是上面那一行)又会报如下这个错误

ImportError: cannot import name 'BeforeValidator' from 'pydantic' (/home/ubuntu/anaconda3/envs/memory/**/lib/python3.10/site-packages/pydantic/__init__.cpython-310-x86_64-linux-gnu.so)

而这个包BeforeValidator 只有在2.0以上才会有,所以两个版本都不行,那就改其中一个源码吧

第一个错误是使用langchain,版本0.0.144

 from langchain.llms import AzureOpenAI,OpenAIChat

此语句调用底层langchain/scheam.py, 如下的相关行

from abc import ABC, abstractmethod
from typing import Any, Dict, Generic, List, NamedTuple, Optional, TypeVar, Union

from pydantic import BaseModel, Extra, Field, root_validator


class Generation(BaseModel):
    """Output of a single generation."""

    text: str
    """Generated text output."""

    generation_info: Optional[Dict[str, Any]] = None
    """Raw generation info response from the provider"""
    """May include things like reason for finishing (e.g. in OpenAI)"""
    # TODO: add log probs
    
    
    
class ChatGeneration(Generation):
    """Output of a single generation."""

    text = ""
    message: BaseMessage

    @root_validator
    def set_text(cls, values: Dict[str, Any]) -> Dict[str, Any]:
        values["text"] = values["message"].content
        return values    

可以看到在类子类ChatGeneration中声明了一个装时器函数set_text,使用装饰器root_validator进行修饰的,而root_validator 在2.0版本以上已经属于deprecated,而且要求传参skip_on_failure=True才可以执行

root_validator的源码在**/pydantic/deprecated/class_validators.py里

def root_validator(
    *__args,
    pre: bool = False,
    skip_on_failure: bool = False,
    allow_reuse: bool = False,
) -> Any:
    """Decorate methods on a model indicating that they should be used to validate (and perhaps
    modify) data either before or after standard model parsing/validation is performed.

    Args:
        pre (bool, optional): Whether this validator should be called before the standard
            validators (else after). Defaults to False.
        skip_on_failure (bool, optional): Whether to stop validation and return as soon as a
            failure is encountered. Defaults to False.
        allow_reuse (bool, optional): Whether to track and raise an error if another validator
            refers to the decorated function. Defaults to False.

    Returns:
        Any: A decorator that can be used to decorate a function to be used as a root_validator.
    """
    warn(
        'Pydantic V1 style `@root_validator` validators are deprecated.'
        ' You should migrate to Pydantic V2 style `@model_validator` validators,'
        ' see the migration guide for more details',
        DeprecationWarning,
        stacklevel=2,
    )

    if __args:
        # Ensure a nice error is raised if someone attempts to use the bare decorator
        return root_validator()(*__args)  # type: ignore

    if allow_reuse is True:  # pragma: no cover
        warn(_ALLOW_REUSE_WARNING_MESSAGE, DeprecationWarning)
    mode: Literal['before', 'after'] = 'before' if pre is True else 'after'
    if pre is False and skip_on_failure is not True:
        raise PydanticUserError(
            'If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`.'
            ' Note that `@root_validator` is deprecated and should be replaced with `@model_validator`.',
            code='root-validator-pre-skip',
        )

    wrap = partial(_decorators_v1.make_v1_generic_root_validator, pre=pre)

可以看到源码root_validator有多个入参,也可以看到报错的真正原因:pre为False 且skip_on_failure 也是False,pre 默认为False,skip_on_failure默认也是False ,所以报错

那么修改其中1个参数skip_on_failure,更改为True,在ChatGeneration的修饰器 @root_validator添加参数,修改为 @root_validator(skip_on_failure=True)

然后运行,报如下错误:

  File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/_internal/_model_construction.py", line 98, in __new__
    private_attributes = inspect_namespace(
  File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/_internal/_model_construction.py", line 337, in inspect_namespace
    raise PydanticUserError(
pydantic.errors.PydanticUserError: Field 'text' defined on a base class was overridden by a non-annotated attribute. All field definitions, including overrides, require a type annotation.
这个ChatGeneration 有个元素是text,它也要有类型约束,那就添加类型约束,改为

 text :str = ""

然后又报错:

name = Field(default="", const=True)

File "/home/ubuntu/anaconda3/envs/**/lib/python3.10/site-packages/pydantic/fields.py", line 741, in Field
    raise PydanticUserError('`const` is removed, use `Literal` instead', code='removed-kwargs')
pydantic.errors.PydanticUserError: `const` is removed, use `Literal` instead
 

然后再修改const 为Literal ,不过后面也报了不少错误,原因是2.0在1。0版本上做了很大改动,所以不建议在2.0版本直接进行修改,看了参考资料2 和3后,具体的解决方法如下:

当pydantic 只需要1.0版本即可满足要求时,果断从2.x的版本降为1.0的版本

但如果1.0版本和2.0版本都需要使用时,则需要安装2.0以上的版本,同时在使用1.0版本的程序或者源码上,添加pydantic.v1,如原语句from pydantic import Extra, root_validator,则需要改为from pydantic.v1 import Extra, root_validator,不过这个工作量可能很大,比较容易出错,最好的办法是避免2个版本同时使用,但尽管如此,这也是一种解决方法,可以试试

参考资料:

pydantic.errors.PydanticUserError: If you use `@root_validator`...._pydantic.errors.pydanticusererror: a non-annotated-优快云博客

2  https://github.com/run-llama/llama_index/issues/11401

3如何在不同的Pydantic版本中使用LangChain_pydantic版本如何从v2降回v1-优快云博客

本文章已经生成可运行项目
<think>我们正在解决一个Pydantic版本引发的错误:用户在使用LangChain时,导入langchain就报错,错误信息涉及`@root_validator`的使用,提示必须设置`skip_on_failure=True`,并建议使用`@model_validator`替代。 根据引用[1][2][3][4]的信息,该问题主要是由于Pydantic版本过高(>=2.0)导致的兼容性问题。引用[4]明确指出,根本原因是pydantic的版本问题,建议将pydantic降级到1.10.13版本。 解决方案有两种: 1. 降级pydantic到1.10.x版本(推荐,因为LangChain在很长时间内兼容1.10.x)。 2. 升级LangChain到最新版本(可能已适配Pydantic 2.x),但需注意LangChain最新版本可能尚未完全支持Pydantic 2.x,或者需要同时升级其他依赖。 考虑到用户可能希望保持LangChain的较新版本,我们还应检查LangChain的版本。如果用户使用的是较旧的LangChain版本(如0.0.x),那么降级pydantic是更安全的选择。 步骤: 1. 首先尝试降级pydantic,因为这是最直接的方法(引用[4]的方案)。 2. 如果降级pydantic后问题仍然存在,则考虑升级LangChain到最新版本(确保该版本已经支持Pydantic 2.x)。 3. 另外,也可以尝试升级LangChain到0.0.346版本(根据社区反馈,该版本修复了此问题)。 具体操作如下: ### 解决方案 #### 方法一:降级 Pydantic(推荐) ```bash # 卸载当前pydantic并安装1.10.13版本 pip uninstall -y pydantic pip install pydantic==1.10.13 # 同时,为了确保兼容,建议也降级pydantic-core(如果存在) pip install pydantic-core==1.10.13 ``` **验证**:重新运行Python,导入langchain,检查是否报错。 #### 方法二:升级 LangChain(如果可能) 如果希望保持Pydantic 2.x,则需要升级LangChain到修复该问题的版本(0.0.346或更高版本)[^2]。 ```bash # 升级langchain到最新版本 pip install --upgrade langchain # 或者指定版本 pip install langchain==0.0.346 ``` 注意:在升级LangChain后,可能还需要升级其他依赖(如langchain-core, langchain-community等)以避免版本冲突。 #### 方法三:临时修改代码(不推荐,仅应急) 如果无法立即升级或降级,可以在自己的代码中修改根验证器,添加`skip_on_failure=True`(但注意,这是LangChain内部代码的问题,通常用户无法直接修改第三方库的代码,所以此方法仅适用于修改自己的模型代码)。 例如,如果你在自己的代码中使用了`@root_validator`,需修改为: ```python from pydantic import root_validator class YourModel(BaseModel): ... # 字段定义 @root_validator(pre=False, skip_on_failure=True) # 加上skip_on_failure=True def validate_all_fields(cls, values): ... # 验证逻辑 ``` 但注意,该错误通常出现在第三方库(如LangChain)内部,因此我们无法直接修改。所以优先推荐方法一或方法二。 ### 错误原因分析 Pydantic 2.0 引入了一系列重大变更,其中`@root_validator`的行为发生了变化。在Pydantic 2.0中,如果使用`@root_validator`且`pre=False`(默认),必须指定`skip_on_failure=True`,否则会抛出此异常[^1][^2]。同时,Pydantic 2.0推荐使用`@model_validator`替代`@root_validator`。 由于LangChain的部分版本在编写时依赖于Pydantic 1.x,当环境中安装了Pydantic 2.x时,就会出现兼容性问题。 ### 预防措施 1. **固定版本**:在`requirements.txt`中明确指定关键库的版本,例如: ``` pydantic==1.10.13 langchain==0.0.346 ``` 2. **使用虚拟环境**:为每个项目创建独立的虚拟环境,避免版本冲突。 ### 相关问题 根据上述内容,生成相关问题: 1. 如何检查当前安装的pydantic版本? 2. 升级LangChain后出现其他兼容性问题怎么办? 3. 除了降级pydantic,还有其他方法解决Pydantic 2.0的兼容性问题吗? 4. 如何创建Python虚拟环境来管理依赖版本? 5. Pydantic 2.0与1.x的主要区别有哪些? </think>### 解决 `PydanticUserError: If you use @root_validator with pre=False...` 错误 #### 错误原因分析 1. **Pydantic 版本冲突** 该错误是由于 Pydantic 2.0+ 的重大变更导致: - `@root_validator` 已被弃用,推荐使用 `@model_validator`[^1][^2] - Pydantic ≥2.0 要求必须显式设置 `skip_on_failure=True` 参数[^3] - LangChain 的部分版本尚未完全适配 Pydantic 2.0 的新规范[^4] 2. **依赖关系不兼容** 当环境中同时存在: - 高版本 Pydantic (≥2.0) - 未适配的 LangChain 版本 #### 完整解决方案 ##### 方法一:降级 Pydantic(推荐) ```bash # 卸载当前版本 pip uninstall -y pydantic pydantic-core # 安装兼容版本 pip install "pydantic==1.10.13" "pydantic-core==1.10.13" ``` ##### 方法二:升级 LangChain(推荐) ```bash # 升级到最新兼容版本 (0.0.346+) pip install --upgrade "langchain>=0.0.346" ``` ##### 方法三:修改代码(临时方案) 在自定义验证器中添加必需参数: ```python from pydantic import root_validator class YourModel(BaseModel): ... # 添加 skip_on_failure=True @root_validator(pre=False, skip_on_failure=True) def custom_validator(cls, values): # 验证逻辑 return values ``` #### 验证步骤 ```python # 检查版本兼容性 import pydantic, langchain print(f"Pydantic: {pydantic.__version__}, LangChain: {langchain.__version__}") # 测试导入是否报错 import langchain.docstore # 应无报错 ``` #### 预防措施 1. **版本锁定** 在 `requirements.txt` 中固定版本: ```text pydantic==1.10.13 langchain==0.0.346 ``` 2. **兼容性检查表** | Pydantic 版本 | LangChain 兼容版本 | |---------------|---------------------| | 1.10.x | 0.0.x 全系列 | | ≥2.0 | ≥0.0.346 | 3. **环境隔离** 使用虚拟环境避免冲突: ```bash python -m venv langchain_env source langchain_env/bin/activate # Linux/Mac langchain_env\Scripts\activate # Windows ``` > **注意**:优先推荐升级LangChain方案,因其能同时获得安全更新和新功能[^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值