跳到主要内容
版本:0.10(最新)

结构化输出

BoundModel.generate_structured() 从一次 LLM 调用中提取强类型、经过 校验的数据。传入一个 Pydantic 模型类,拿回一个已校验的实例——不用 解析 JSON、也不用手写 schema。

from pydantic import BaseModel
from cubepi.providers.base import TextContent, UserMessage

class Sentiment(BaseModel):
label: str
confidence: float

result = await model.generate_structured(
Sentiment,
messages=[UserMessage(content=[TextContent(text="I love this product!")])],
)
print(result) # label='positive' confidence=0.95

工作方式

底层 generate_structured() 做的事:

  1. 把 Pydantic 模型的 JSON schema 转换成一个合成的 tool 定义。
  2. tools=[synthetic_tool]tool_choice=tool_name 调用 generate(),强制模型调用这个 tool。
  3. 从响应里取出 ToolCall.arguments
  4. 通过 output_type.model_validate() 校验。

这和 pydantic-ai 默认使用的方式(ToolOutput 模式)一样。它对所有 provider 都能用,因为每个 LLM API 都支持 tool 调用。

参数

await model.generate_structured(
output_type, # Pydantic 模型类(必填)
messages, # list[Message](必填)
*,
system_prompt="", # 可选的 system prompt(永远会追加一段使用 tool 的提示)
tool_name="structured_output",
tool_description="Return the structured output",
max_output_tokens=None,
temperature=None,
max_retries=1, # Pydantic 校验失败时的重试次数(把错误回灌给模型)
)
参数默认说明
output_type必填Pydantic BaseModel 子类
messages必填对话消息
system_prompt""自定义 system prompt(永远会追加一段使用 tool 的提示)
tool_name"structured_output"合成 tool 的名称
tool_description"Return the structured output"发给模型的 tool 描述
max_retries1Pydantic 校验失败时的重试次数
max_output_tokensNone覆盖模型的默认 max tokens
temperatureNone覆盖模型的默认 temperature

错误处理

generate_structured() 在两种情况下抛 StructuredOutputError

from cubepi.providers.base import StructuredOutputError

try:
result = await model.generate_structured(MySchema, messages=[...])
except StructuredOutputError as e:
print(e) # "no tool call" 或 "validation failed after retries"
  • No tool call:模型返回了文本而不是调用 tool。
  • Validation failed:所有尝试都通不过 Pydantic 校验(首次 + 重试)。

校验失败时,错误会作为 UserMessage 回灌给模型,给它再一次机会 (最多 max_retries 次)。

tool_choice

generate_structured() 内部用 tool_choice 强制模型调用合成 tool。 你也可以在 stream()generate() 上直接用 tool_choice

reply = await model.generate(
messages=[...],
tools=[my_tool_def],
tool_choice="my_tool", # 强制使用这个 tool
)

可选值:

行为
NoneProvider 默认(模型自决)
"auto"模型自己决定是否调用 tool
"required"必须调用某个 tool
"none"不允许 tool 调用
"tool_name"强制使用指定名称的 tool

tool_choice 在所有内置 provider(Anthropic、OpenAI、OpenAI Responses) 上都能用。每个 provider 会把这个值映射到它原生的 wire 格式。