DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

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 转换。