问题现象
在 Hermes Agent 中把模型切换到 claude-opus-4-7 后,请求直接失败:
HTTP 400: custom.input_schema: JSON schema is invalid.
It must match JSON Schema draft 2020-12同一套工具 schema 在 gpt-5.5 等模型上正常,但在 Claude/Anthropic 兼容接口上报错。
初步判断
报错信息指向:
custom.input_schema也就是 tool/function 的 input schema 不被 Claude 的工具调用校验器接受。
这类问题通常不是模型本身不可用,而是某个 tool 的 JSON Schema 写法在某些后端比较宽松,在 Anthropic/Claude 兼容后端比较严格。
排查方法
1. 导出当前 Hermes 工具列表
Hermes 的工具定义会经过:
tools/registry.py
model_tools.py
schema_sanitizer.py最终生成 OpenAI 格式的 tools:
{
"type": "function",
"function": {
"name": "xxx",
"description": "...",
"parameters": {
"type": "object",
"properties": {}
}
}
}2. 单独测试每一个 tool
把当前工具逐个提交给 claude-opus-4-7,定位到底哪些 schema 会触发 400。
最终发现报错工具包括:
browser_back
browser_console
browser_get_images
browser_snapshot
delegate_task
send_message
session_search
skills_list
todo这些工具的共同点是:parameters 或嵌套对象里存在 object schema,但没有显式声明 required。
例如:
{
"type": "object",
"properties": {}
}或者:
{
"type": "object",
"properties": {
"query": {
"type": "string"
}
}
}根因
JSON Schema Draft 2020-12 中,required 字段是可以省略的。
也就是说:
{
"type": "object",
"properties": {}
}从标准 JSON Schema 角度看是合法的。
但 Anthropic/Claude 的 tool input schema 校验器更严格,实际要求 object schema 必须显式带上 required 数组。
如果没有必填字段,也要写成:
{
"type": "object",
"properties": {},
"required": []
}所以问题不是 schema 完全非法,而是 Claude 工具调用接口对 schema 有额外兼容要求。
解决方法
在 Hermes 的 schema sanitizer 里,对所有 object schema 自动补上:
"required": []前提是该 object schema 有 properties,但没有合法的 required 数组。
修改文件:
tools/schema_sanitizer.py核心逻辑:
def ensure_object_required_arrays(schema: Any) -> Any:
"""Add required: [] to every object schema missing it."""
if isinstance(schema, list):
return [ensure_object_required_arrays(item) for item in schema]
if not isinstance(schema, dict):
return schema
out = dict(schema)
if out.get("type") == "object" and isinstance(out.get("properties"), dict):
required = out.get("required")
if not isinstance(required, list) or not all(isinstance(item, str) for item in required):
out["required"] = []
for key, value in list(out.items()):
if key in {"properties", "$defs", "definitions"} and isinstance(value, dict):
out[key] = {
sub_key: ensure_object_required_arrays(sub_value)
for sub_key, sub_value in value.items()
}
elif key in {"items", "additionalProperties"}:
if not isinstance(value, bool):
out[key] = ensure_object_required_arrays(value)
elif key in {"anyOf", "oneOf", "allOf"} and isinstance(value, list):
out[key] = [ensure_object_required_arrays(item) for item in value]
return out然后在 sanitizer 流程中调用:
fn["parameters"] = ensure_object_required_arrays(fn["parameters"])验证结果
修复前,多个工具单独发送给 claude-opus-4-7 会返回 400。
修复后:
TOOL_COUNT 30
MISSING_REQUIRED_OBJECTS 0
CLAUDE_OPUS_4_7_ALL_TOOLS 200 OK也就是说,当前 30 个工具一起提交给 claude-opus-4-7 已经可以正常通过。
经验总结
- OpenAI/GPT 兼容接口能接受的 schema,不代表 Claude/Anthropic 兼容接口一定接受。
- Claude tool schema 对 object 的
required更敏感。 - 即使没有必填字段,也建议显式写:
"required": []- 最稳妥的处理方式是在统一的 schema sanitizer 层修复,而不是逐个 tool 手动改。
- 遇到 tool schema 400,优先用“逐个 tool 单独请求”的方式二分/枚举定位。
最终结论
这次 claude-opus-4-7 报错的根因是:Hermes 部分工具 schema 的 object 节点缺少显式 required 数组。
通过在 schema_sanitizer.py 中自动补齐 required: [],即可兼容 Claude/Anthropic 工具调用校验器。
