LangChain中如何用Pydantic定义带上下文的嵌套字段类型?
用Pydantic抽象自定义嵌套字段简化LangChain的GenAI输出Schema定义
现有基础实现
之前已用Pydantic完成基础嵌套Schema定义:
from pydantic import BaseModel, Field class Models(BaseModel): people: list[People] = Field(description="names of the people related fields mentioned in the text.") class People(BaseModel): name: str = Field(description="name of the person being discussed") title: str = Field(description="job title of the person being discussed")
能稳定生成如下格式输出:
{ "people": [ { "name": "John", "title": "black-smith" }, { "name": "Jane", "title": "deer hunter" } ] }
需求升级:每个字段包含value和context嵌套结构
现在需要将每个字段改为包含value(字段值)和context(文本来源片段)的嵌套对象,期望输出格式如下:
{ "people": [ { "name": {"value": "John", "context": "his name was John,"}, "title": {"value": "black-smith", "context": "he was a black-smith"} }, { "name": {"value": "Jane", "context": "Jane like to hunt deer in her spare time"}, "title": {"value": "deer hunter", "context": "Jane like to hunt deer in her spare time"} } ] }
当前冗余实现方式
目前只能通过重复定义dict类型并编写冗长描述实现,代码冗余度高:
class Models(BaseModel): people: list[People] = Field(description="names of the people related fields mentioned in the text.") class People(BaseModel): name: dict = Field(description="an object with 2 keys. The first being 'value' which includes the name of the person being discussed, and the second being 'context' which includes the snippet from the text where the value was taken from") title: dict = Field(description="an object with 2 keys. The first being 'value' which includes the job title of the person being discussed, and the second being 'context' which includes the snippet from the text where the value was taken from")
优化实现方案:自定义通用Pydantic嵌套模型
无需自定义Field类,直接利用Pydantic的模型嵌套特性,定义通用FieldWithContext模型复用结构:
1. 定义通用嵌套模型
from pydantic import BaseModel, Field class FieldWithContext(BaseModel): value: str = Field(description="字段的具体取值") context: str = Field(description="提取该值的原文片段")
2. 修改业务模型
将People中的字段类型替换为FieldWithContext,保留每个字段的业务描述:
class People(BaseModel): name: FieldWithContext = Field(description="讨论的人物姓名") title: FieldWithContext = Field(description="讨论的人物职位") class Models(BaseModel): people: list[People] = Field(description="文本中提到的相关人物列表")
方案优势
- 完全符合Pydantic原生语法,无需额外自定义Field逻辑,LangChain可直接解析该Schema
- 消除重复代码,通用结构只需定义一次,业务字段专注于自身含义描述
- 自动生成的Schema结构清晰,GenAI能准确理解输出要求,稳定生成符合期望的嵌套格式
内容的提问来源于stack exchange,提问作者ChrisFrankoPhD
相关产品推荐
相关产品推荐

