Repository navigation
【改善建议】Provider-side invalid_tool_call 被归类为 PI_AI_ERROR,缺少有界纠错恢复(0.2.0-rc.2) #8729
Replies: 1 comment
|
补充一个 2026-10-07 的真实任务案例:同一类 provider-side 参数校验错误也会在长任务的最终文件交付阶段触发。 环境与影响
同次会话中的工具定义与错误参数会话持久化的 request/header 中, {
"name": "present",
"parameters": {
"type": "object",
"properties": {
"files": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": { "type": "string" },
"description": { "type": "string" }
},
"required": ["path"]
}
}
},
"required": ["files"]
}
}失败响应的 {
"path": "<workspace>/deliverables.xlsx",
"status": "completed"
}这里已替换实际路径和文件名。前两项使用 path 与 description;第三项多出的 status 被 items.additionalProperties=false 禁止。这个字段与前一个 todo_write 的字段相同,可能是模型混用了工具参数,但这只是推测;可以确定的是 present 参数违反了本次会话实际声明的 schema。 注意:上面只是数组中的一个对象摘录。持久化参数流在 files 数组闭合后停止,没有发出最外层对象的结束括号;它不是一次成功、完整、可执行的工具调用。 对应终止记录{
"type": "finish",
"reason": {
"kind": "error",
"failure": {
"message": "Invalid tool arguments at \"$.files[].status\": value is forbidden",
"code": "PI_AI_ERROR"
}
}
}随后是相同错误的 turn/end,没有自动纠错的下一步。该会话中,第 55 步没有持久化的 tool/call 或 tool/result 执行记录,包括这一响应内先返回的 todo_write,因此界面仍保留之前的待办进度。 后端相邻日志如下,省略请求标识: 推理正常以 stop 结束,然后 API 参数校验拒绝 present。日志中的 calls=1 是后端解析器已接受的调用数量,不代表 Harness 已执行一次工具。这组记录没有显示超时、OOM 或输出长度截断。 此案例希望补充的回归场景在一个响应中,模型先输出合法的 todo_write,再输出带禁止字段的 present;兼容后端随后以输出校验错误终止流。建议验证:
这是对原帖恢复诉求的第二个实测案例。模型多传字段是直接触发原因,本地后端拒绝也符合 schema;这里没有将错误参数归因于 Harness。后端先以 API/SSE 错误结束响应的路径,与 Harness 内部工具执行阶段的参数验证是两个不同层次,恢复责任及错误信息传递可能需要后端和适配器协同。 证据来自本次会话的工具定义、参数流、执行记录与本地后端日志;没有完整网络抓包,也没有在最新上游源码构建上重跑该任务。未上传原始会话、截图或文档内容。 |
Uh oh!
There was an error while loading. Please reload this page.
问题与改进诉求
在 DeepSeek Harness Desktop
0.2.0-rc.2中,通过llm-pi-ai使用非官方本地 OpenAI Chat Completions 兼容后端时,模型生成了不符合工具定义的参数。后端正确拒绝该调用,但错误到达 Harness 后被归类为PI_AI_ERROR,本轮直接结束,没有出现让模型修正参数并继续原任务的恢复步骤。希望讨论是否能为这类 provider-side model-output validation failure 提供可选、有界的纠错恢复。这里反馈的是后端以 API/SSE 错误终止生成的路径,不是声称 Harness 内部所有工具参数校验失败都无法恢复,也不是说错误参数由 Harness 生成。
环境
0.2.0-rc.2@deepseek-ai/dsh-llm-pi-ai@0.2.0-rc.2@earendil-works/pi-ai@0.87.1mediumweb_search以下来自 2026-10-03 的一次真实任务记录。版本通过已安装包的
package.json核实;工具定义、参数流和终止状态来自同一次会话。实际发生了什么
todo_write和两次subagent调用已成功。web_search。queries为字符串数组:{ "name": "web_search", "parameters": { "type": "object", "properties": { "queries": { "type": "array", "description": "1–4 search queries; their results are merged.", "items": { "type": "string" } } }, "required": ["queries"] } }queries值是对象数组。下面仅摘录数组的前两项,未附完整任务或会话内容:[ { "OWASP": "agentic AI security top 10 2025 ASI" }, { "NIST": "agentic AI security guidance 2025 2026 publication" } ]{ "type": "finish", "reason": { "kind": "error", "failure": { "message": "Invalid tool arguments at \"$.queries[]\": type does not match the tool schema", "code": "PI_AI_ERROR" } } }随后出现
turn/end,原因仍是同一错误。该失败步骤没有web_search的tool/call执行记录,也没有参数纠正后的下一次尝试。用户界面显示“本轮运行失败”。补充一个流式细节:
tool-call-chunks已记录参数数组,但参数 JSON 的最后一个外层}尚未发出;后端在校验失败时没有完成该工具调用。上面的数组摘录不是一次成功、完整的工具调用,不应将其恢复成可执行调用直接运行。源码核对与证据边界
queries.items.type是string,实际元素是object,拒绝是合理的。http::fail(502, parser.error(), "model_output_error", "invalid_tool_call")。其 HTTP/SSE handler 在 SSE 已开始时发送流内错误,而不会把已发送的 HTTP 200 改成 502。这部分是本地源码核对,不是该次请求的完整网络抓包;部署 API 二进制与核对的本地构建 SHA-256 一致。该本地构建提交未在公开仓库中找到,因此没有提供不可访问的源码链接。mapStopReason将错误文本传给classifyPiAiError,这条文本进入PI_AI_ERROR兜底分支。提交前也静态核对了上游master的固定提交da00f7f,其 error mapping 仍采用这一路径;没有宣称已在最新源码构建上重跑完整任务。invalid_tool_call/model_output_error是本后端使用的错误分类,不能假设所有 OpenAI 兼容服务都支持相同语义。原始结构化错误如何穿过 pi-ai 到达 Harness,可能需要双方协同;目前的会话证据不足以断定信息具体在哪一层丢失。建议的恢复行为
如果维护者认为这类恢复应由 Harness 承担,建议考虑:
PI_AI_ERROR一律加入普通网络重试,也不要无限原样重发请求。一个值得增加的回归场景是:模拟兼容后端先发出不合规工具参数片段,再以明确的输出校验错误终止 SSE,检查未完成调用不会被执行、错误类型可辨识、可选纠错流程次数有限且不会重复先前成功的工具。这个模拟场景是测试建议,尚未作为独立最小复现脚本运行;已观察到的是上述真实会话。
如果该恢复更适合由后端自行修正后重试,或以插件实现,也希望了解推荐的扩展点。
相关但不同的反馈:#4361 涉及网络错误被归类为
PI_AI_ERROR;本帖涉及模型输出参数错误,需要纠正参数,而非单纯退避重试。All reactions