Qwen3.7-Max 在 OpenCode 中调用名为 unknown 的工具,通常不表示系统里存在一个隐藏工具。它表示模型或中间适配层返回的 function.name 没有匹配当前请求的 tools[]。应先保存 OpenRouter 原始响应与 OpenCode 实际发送的工具定义,确认 unknown 是上游直接生成、流式解析后产生,还是客户端名称映射失败后的占位值。
来源帖子显示,OpenCode 提示模型尝试调用不可用的 unknown 工具,并同时列出当前可用工具。这类错误发生在执行之前:调度器找不到对应工具,因此不应创建一个同名空工具来“看看会传什么”。这样做会掩盖根因,还可能把本应拒绝的参数交给意外代码执行。
OpenRouter 官方将工具调用错误分为无效 JSON、未知名称和参数不符合 schema 三类。其中 UnknownName 的定义就是返回的 function.name 不存在于请求的工具数组。这个分类能说明校验失败的位置,但不能单独判断错误来自模型、provider 模板还是 OpenCode。
unknown,而不是已提供的名称。只看终端中的最终提示无法区分这些情况。至少需要比较请求、原始响应和执行器错误三份证据。
打开脱敏调试日志,保存模型请求中的完整 tools[]。每个工具都应有唯一、稳定且清晰的函数名、用途描述和合法参数 schema。名称不能在一次会话中动态改变,也不要让多个插件注册相同名称。
{
"type": "function",
"function": {
"name": "read_file",
"description": "Read one file from the workspace",
"parameters": {
"type": "object",
"properties": {
"path": {"type": "string"}
},
"required": ["path"],
"additionalProperties": false
}
}
}
如果错误日志列出的可用工具与请求体不一致,说明工具列表在客户端内部又被过滤或覆盖。OpenCode 的全局、项目和 agent 级权限都可能影响工具可见性;agent 级设置还可能覆盖全局设置。
OpenCode 使用 permission 控制工具是允许、询问还是禁止。被禁止的工具不应继续暴露给模型。自定义工具和 MCP 工具常带有前缀,模型看到的正式名称可能与服务器内部函数名不同。
诊断时先关闭非必要插件和 MCP 服务,只保留一个内置只读工具。如果最小工具集正常,再逐个恢复扩展。每恢复一个扩展,都记录最终工具名列表;最先引入名称冲突或 unknown 的扩展就是主要调查对象。
绕过 OpenCode 的界面格式化,保存同一请求的原始响应。关注 choices[].message.tool_calls[].function.name、工具调用 ID 和 arguments。根据结果分流:
unknown:模型或实际 provider 返回未知名称。unknown:客户端转换或注册映射有问题。不要只打印最终文本,因为工具调用通常位于结构化字段中,正文内容可能为空。
流式工具调用中,ID、名称和参数可能出现在不同数据块。客户端应按 choice 索引和工具调用索引维护缓冲区,只追加非空片段,不能用后续空字符串覆盖已经收到的名称。
for event in stream:
for call in event.tool_call_deltas:
key = (event.choice_index, call.index)
if call.name_fragment:
buffers[key].name += call.name_fragment
if call.arguments_fragment:
buffers[key].arguments += call.arguments_fragment
validate_after_stream_end(buffers, advertised_tools)
若非流式请求正常、流式请求出现 unknown,证据会明显指向增量解析或协议转换。反之,两种模式都返回相同未知名称,则应继续检查模型与 provider。
OpenRouter 可以为同一模型路由到不同 provider,并允许失败时回退。不同 provider 的模型模板和工具兼容性可能不同。复现时固定一个 provider、关闭 fallback,并在模型页面查看该 endpoint 的 Tool Call Error Rate。
随后在同一提示、同一工具 schema 下更换 provider。若只有一个 provider 生成未知名称,应把请求 ID 和 provider 信息提交给 OpenRouter;若所有 provider 都一致失败,则更可能是模型行为或共享请求结构问题。
执行器必须采用白名单:只有名称完全匹配、参数 JSON 可解析且通过 schema 校验的调用才能进入权限判断。未知名称应被拒绝,并将简洁错误作为工具结果反馈给模型,允许它选择现有工具重新尝试。
对 shell、写文件、提交、部署等有副作用的工具,应默认询问或拒绝,不能把 unknown 映射到通用 shell。OpenCode 官方权限规则支持对工具设置 allow、ask 和 deny;排查期间可将编辑和 shell 保持为询问。
成功标准不是“偶尔不报错”,而是所有返回工具名都属于当前请求的白名单,参数均能通过 schema,且未知调用不会进入执行阶段。
所以,unknown 是工具名称校验失败的表现,不是需要补装的工具。先比较请求中的工具清单、OpenRouter 原始响应和 OpenCode 映射结果,再通过非流式对照与固定 provider 缩小范围;同时保持严格白名单和权限确认,才能在定位兼容问题时避免意外执行。