You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Pydantic与Instructor实现LLM函数自动化:动态结果模型构建难题

解决方法

首先,你遇到的错误是因为你实例化了_ResultModel类,而Instructor需要的是Pydantic模型类本身,不是类的实例。实例属于不可哈希类型,因此会抛出TypeError: unhashable type: '_ResultModel'。

下面是两种正确的动态生成结果模型的方法:

方法一:使用Pydantic的create_model动态生成模型

Pydantic提供的create_model函数可以动态创建模型类,你可以用它生成包含所有存储工具模型列表的ResultModel:

from pydantic import create_model
from typing import List, Union

# 获取所有存储的工具模型
all_tool_models = FunctionStorage.get_all()

# 动态创建ResultModel类,results字段为所有工具模型的列表类型
ResultModel = create_model(
    "ResultModel",
    results=(List[Union[tuple(all_tool_models)]], ...)
)

方法二:提前定义模板模型并动态传入Union类型

先定义基础结果模型结构,再动态传入所有工具模型的Union类型:

from pydantic import BaseModel
from typing import List, Union

# 获取所有存储的工具模型
all_tool_models = FunctionStorage.get_all()
# 创建包含所有工具模型的Union类型
ToolUnion = Union[tuple(all_tool_models)]

# 定义结果模型
class ResultModel(BaseModel):
    results: List[ToolUnion]

顺带修正PythonCmd类的逻辑问题

你代码中PythonCmd的result计算字段存在逻辑错误:以写模式'w'打开文件后直接读取会报错,应该先写入代码片段再执行或读取。修正示例:

from pydantic import Field, computed_field
from instructor import OpenAISchema
import subprocess

@FunctionStorage.store()
class PythonCmd(OpenAISchema):
    """runs a python snippet or script"""
    snippet: str = Field(description="python snippet to run")

    @computed_field
    def result(self) -> str:
        with open('r2ai_tmp.py', 'w') as f:
            f.write(self.snippet)
        # 执行脚本并捕获输出
        run_result = subprocess.run(
            ["python", "r2ai_tmp.py"],
            capture_output=True,
            text=True
        )
        return run_result.stdout + run_result.stderr

完成以上修改后,Instructor就能正确解析OpenAI响应并使用动态生成的ResultModel了。

内容的提问来源于stack exchange,提问作者Marcel Alexandru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 13:27:03