我在自定义工具的 Langchain 实现中使用 Pydantic v1。当我静态定义 Pydantic 类时,它将使用有关字段的元数据填充我的类的
__fields__
属性 - 这是 Langchain 所需的。
我的用例要求我根据用户的上下文在运行时创建 Pydantic 类。我尝试使用 Python 的
type
函数和 Pydantic 的 create_model
函数创建 Pydantic 类。这两种方法都无法填充__fields__
任何人都可以告诉我动态创建 Pydantic 类时如何填充
__fields__
吗?
以下代码块总结了我的预期与实际结果。
from enum import Enum
from langchain.pydantic_v1 import BaseModel, create_model
class SpecialtyEnumStatic (str, Enum):
psychiatry = "SPECIALTY:Psychiatry"
sports_medicine_internal_medicine = "SPECIALTY:Sports Medicine (Internal Medicine)"
class ProviderSearchInputStatic(BaseModel):
specialty: SpecialtyEnumStatic
print(ProviderSearchInputStatic.__fields__)
# {'specialty': ModelField(name='specialty', type=SpecialtyEnumStatic, required=True)}
specialties = {
'psychiatry': 'SPECIALTY:Psychiatry',
'sports-medicine (Internal Medicine)': 'SPECIALTY:Sports Medicine (Internal Medicine)'
}
SpecialtyEnumDynamic = Enum('SpecialtyEnumDynamic', specialties)
ProviderSearchInputDynamic = create_model(
'ProviderSearchInputDynamic',
specialty=SpecialtyEnumDynamic,
__base__=BaseModel
)
print(ProviderSearchInputDynamic.__fields__)
# {}
仅传递类型并不是定义字段的正确格式。来自
create_model
的文档字符串:
模型的字段(如果提供了基础则为额外字段),格式为
) 或<name>=(<type>, <default default>
,例如<name>=<default value>
或foobar=(str, ...)
,或者,对于复杂的用例,采用foobar=123
或<name>=<Field>
格式,例如<name>=(<type>, <FieldInfo>)
或foo=Field(datetime, default_factory=datetime.utcnow, alias='bar')
foo=(str, FieldInfo(title='Foo'))
所以正确的方法是传递一个元组
(SpecialtyEnumDynamic, ...)
:
from enum import Enum
from pydantic.v1 import BaseModel, create_model
SpecialtyEnumDynamic = Enum('SpecialtyEnumDynamic', specialties)
ProviderSearchInputDynamic = create_model(
'ProviderSearchInputDynamic',
specialty=(SpecialtyEnumDynamic, ...),
)
print(ProviderSearchInputDynamic.__fields__)
# {'specialty': ModelField(name='specialty', type=SpecialtyEnumDynamic, required=True)}