Agent 的 output_type 含动态 dict,additionalProperties 错误怎样改
动态 dict 与严格输出 schema 的属性约束可能冲突。固定指标改显式字段,动态指标可改条目列表并校验重复键;必须保留对象形状时评估非 strict 输出和本地验证。
Agent 的 output_type 含动态 dict,additionalProperties 错误怎样改
想让 agent 输出一组可变指标,于是定义 metrics: dict[str, float]。Pydantic 单独校验没问题,交给 Agents SDK 后却在严格 schema 转换阶段失败:
additionalProperties should not be set for object types.
外层还可能包装成 “Strict JSON schema is enabled, but the output type is not valid”,需要往下查看异常原因。
动态字典允许任意键;严格输出 schema 需要明确对象能有哪些属性。直接把生成的 additionalProperties 改成 false,会改变原来的数据含义:你要的是任意指标名,它却不再允许那些未声明的键。
该问题有官方 issue #608 和 non_strict_output_type 示例。本文以源码快照 125efa02 为依据,公开 API 在 openai-agents 0.23.1 核对。
指标名固定,就把字段写出来
如果永远只有 latency_ms 和 error_rate,最直接的修复是显式声明字段。不要因为上游暂时返回 dict,就把开放字典一直传到输出层。
指标名确实动态时,可改成条目列表。下面的 schema 构造和 JSON 校验都在本地完成,无需模型:
from pydantic import BaseModel, ConfigDict, StrictFloat, StrictStr
from agents import AgentOutputSchema
class Metric(BaseModel):
model_config = ConfigDict(extra="forbid")
name: StrictStr
value: StrictFloat
class Report(BaseModel):
model_config = ConfigDict(extra="forbid")
metrics: list[Metric]
schema = AgentOutputSchema(Report)
report = schema.validate_json(
'{"metrics":[{"name":"latency_ms","value":12.5}]}'
)
assert report.metrics[0].name == "latency_ms"
assert report.metrics[0].value == 12.5
print(schema.json_schema())
列表允许重复 name,这和字典的键唯一语义不同。如果后续要转回字典,先校验重复键,明确报错或采用业务认可的合并策略;直接字典推导会悄悄覆盖前面的值。
下游必须接收动态对象时
如果外部协议不能改,可以使用 SDK 官方提供的非 strict 输出入口。它保留动态字典形状,但你需要接受生成端缺少严格约束,再由本地验证接住不合格结果。
from pydantic import BaseModel, StrictFloat
from agents import AgentOutputSchema, ModelBehaviorError
class DynamicReport(BaseModel):
metrics: dict[str, StrictFloat]
schema = AgentOutputSchema(DynamicReport, strict_json_schema=False)
valid = schema.validate_json('{"metrics":{"latency_ms":12.5}}')
assert valid.metrics["latency_ms"] == 12.5
try:
schema.validate_json('{"metrics":{"latency_ms":"slow"}}')
except ModelBehaviorError:
print("invalid metric rejected")
else:
raise AssertionError("wrong metric type was accepted")
将这个 schema 对象传给 Agent(..., output_type=schema) 即可选择这条路径。真实模型调用仍可能失败,业务代码要处理 ModelBehaviorError;不应该捕获后直接把原始字符串当成合格对象继续处理。
验收除了类型,还要加业务规则:数值是否在允许范围,指标名是否属于此次任务,是否遗漏必须返回的指标。语法合法、类型正确,并不能证明内容正确。严格模式也不会替你验证这些语义。
官方依据:问题 #608、官方非 strict 示例、严格 schema 转换。


