fix: json_parser 不再要求模型输出 compute_provider — Gemini 有效响应被误杀

根因: validate_schema 把 compute_provider 列为必填并校验非空数组,
但提示词模板从不要求模型输出该字段(它是 orchestrator 在解析成功后
自行填充的内部记账字段)。Gemini 返回完整合法 JSON 时被误判解析失败,
100% 复现。NVIDIA 走单帧轻量解析绕过了该校验,故此前仅 Gemini 受影响。

修复: compute_provider 从必填清单移除,缺失/非法时归一为空数组,
由 format_cloud_result 用实际成功的 provider 覆盖填充。

验证: 单元测试模拟 Gemini 真实输出(无 compute_provider + markdown
fence 包裹)解析通过。
This commit is contained in:
ericwyuan
2026-08-20 16:14:27 +08:00
parent a2554c9df0
commit f4e742481d

View File

@@ -46,8 +46,12 @@ def parse_vlm_json(raw: str) -> dict:
def validate_schema(data: dict) -> dict: def validate_schema(data: dict) -> dict:
"""Schema 校验 + 脏数据清洗""" """Schema 校验 + 脏数据清洗
required = ["global_summary", "entities_json", "frame_details", "compute_provider"]
注意: compute_provider 是内部记账字段orchestrator 在解析成功后填充),
提示词从不要求模型输出它,故不做必填校验。
"""
required = ["global_summary", "entities_json", "frame_details"]
for k in required: for k in required:
if k not in data: if k not in data:
raise VLMOutputInvalidError(f"缺失字段: {k}") raise VLMOutputInvalidError(f"缺失字段: {k}")
@@ -94,11 +98,11 @@ def validate_schema(data: dict) -> dict:
}) })
data["frame_details"] = cleaned_frames data["frame_details"] = cleaned_frames
# compute_provider 校验为数组 # compute_provider: 模型通常不输出(提示词不要求),缺失/非法时归一为空数组
if not isinstance(data["compute_provider"], list): # 由 orchestrator.format_cloud_result 用实际成功的 provider 覆盖填充
raise VLMOutputInvalidError("compute_provider 必须为数组") cp = data.get("compute_provider")
if len(data["compute_provider"]) == 0: if not isinstance(cp, list):
raise VLMOutputInvalidError("compute_provider 不能为空数组") cp = []
data["compute_provider"] = [str(p) for p in data["compute_provider"]] data["compute_provider"] = [str(p) for p in cp]
return data return data