使用Pydantic BaseModel约束可变长输出时,botocore为何抛出ValidationException?
使用Pydantic AI时的ValidationException问题及可变长返回类型解决方法
问题描述
在使用Pydantic AI,通过Pydantic BaseModel设置回答的output_type时,偶尔会遇到ValidationException,但无法准确定位问题根源。推测该问题可能与任务复杂度或所使用的Amazon Nova Lite模型能力有关,希望了解是否有类似情况的解决方案。
示例代码(WebNLG挑战实体提取)
import dotenv import pathlib from pydantic_ai.models.bedrock import BedrockConverseModel from loguru import logger from pydantic_ai import Agent from pydantic_ai.settings import ModelSettings import asyncio from pydantic import BaseModel, Field dotenv.load_dotenv(pathlib.Path().cwd().joinpath(".env"), override=True) class Triplet(BaseModel): subject: str = Field(description="三元组的两个主要部分之一。主体通过关系与对象关联。") relation: str = Field(description="关联主体和对象的陈述性谓词。") objct: str = Field(description="主体对应的关系参数。") class EntityTriplets(BaseModel): extraction_list: list[Triplet] = Field(description="从对话中提取的三元组列表") model = BedrockConverseModel('amazon.nova-lite-v1:0') agent = Agent( model, output_type=EntityTriplets, system_prompt="你的任务是将给定文本转换为三元组列表形式的语义图。三元组必须采用(主体, 关系, 对象)的格式。回答中请严格只包含三元组,不要添加任何解释或致歉内容。提取所有三元组。", model_settings=ModelSettings(temperature=0.0), ) logger.info("Agent初始化完成") async def foo(): logger.info("运行Agent") return await agent.run(""" 以下是示例: 示例1: 文本:Trane的所在地是都柏林的Swords。 三元组:[('Trane', 'location', 'Swords,_Dublin')] 示例2: 文本:Ayala市是莫雷洛斯州的一部分,人口密度为1604.0,人口为1,777,539,UTC偏移为-6。Ayala市的政府类型是议会-经理制政府,城市经理是领导人之一。 三元组:[('Ciudad_Ayala', 'populationMetro', '1777539'), ('Ciudad_Ayala', 'leaderTitle', '"City Manager"'), ('Ciudad_Ayala', 'type', 'City'), ('Ciudad_Ayala', 'populationDensity', '1604.0'), ('Ciudad_Ayala', 'governmentType', 'Council-manager_government'), ('Ciudad_Ayala', 'utcOffset', '−6'), ('Ciudad_Ayala', 'isPartOf', 'Morelos')] 从以下文本提取三元组: John Doe是新加坡国立大学的学生。 新加坡是位于马来西亚以南的城邦。 """) def main(): output = asyncio.run(foo()) logger.info(output) logger.info(f"输出类型: {type(output)}") logger.info(output.output.model_dump_json(indent=4)) if __name__ == "__main__": main()
常见问题分析与解决方法
1. 模型输出格式不稳定导致验证失败
Amazon Nova Lite作为轻量模型,处理复杂任务时可能出现格式偏差,比如漏写括号、字段名错误、列表结构不完整。解决方法:
- 强化Prompt格式约束:在系统提示中明确要求输出严格匹配JSON结构,例如添加"请以严格的JSON格式返回,不要包含任何额外文本";
- 补充JSON格式示例:在Prompt中增加正确的JSON格式示例,替代单一的元组列表示例,让模型更清晰目标输出结构;
- 启用宽松验证:对非关键字段设置
Field(..., allow_none=True),或给BaseModel添加extra='ignore'参数,忽略多余字段避免验证失败。
2. 可变长返回类型适配
当返回列表长度不固定时,模型可能出现空列表、重复项或遗漏项的情况:
- 分阶段处理:先让模型输出原始三元组文本,再通过本地代码解析转换为目标格式,降低直接生成结构化数据的压力;
- 添加重试机制:捕获ValidationException后,自动重新调用模型,或调整Prompt后重试;
- 使用工具调用能力:若模型支持工具调用,通过定义工具参数的方式强制模型输出符合结构的数据,比单纯依赖文本生成更可靠。
3. 任务复杂度拆分
如果任务涉及长文本或复杂语义提取,轻量模型可能无法准确处理:
- 拆分任务:将长文本分割为多个短片段,分别提取三元组后再合并;
- 对比验证模型能力:尝试使用Amazon Titan等能力更强的模型,验证是否是模型能力限制导致的问题。
内容的提问来源于stack exchange,提问作者DeerFreak
相关产品推荐
相关产品推荐

