工具前后 Hooks 与结果路由
修改工具参数、拦截结果和追加工具调用,理解执行后不能回滚。
BeforeTool 在执行前触发,AfterTool 在执行后触发。两者都提供 tool_name、tool_input,MCP 调用可有 mcp_context,tail 调用可带 original_request_name。
BeforeTool
拒绝时返回 decision deny 和 reason;工具不会执行,原因作为工具错误交给 Agent,它可以调整或继续其他工作。hookSpecificOutput.tool_input 与原参数合并并覆盖对应键,适合校验后规范化参数。
{
"decision": "deny",
"reason": "This path is outside the approved project scope."
}此示例只展示协议,并没有实现路径判断。实际校验要读取工具 schema,处理相对路径、允许范围与缺失字段。
AfterTool
额外输入 tool_response 包含 llmContent、returnDisplay 和可选 error。decision deny 会将真实结果从给模型的内容中隐藏,以 reason 替换;它不会撤销已发生的文件写入、进程或外部请求。
hookSpecificOutput.additionalContext 把文字追加到工具结果,适合提供后处理说明。检查结果失败与工具本身失败应区分记录。
Tail tool call
AfterTool 可返回 hookSpecificOutput.tailToolCallRequest,对象包含 name 与 args,请求立刻执行另一工具,其结果替换原工具响应。这适合程序化路由,不是单纯给模型写一条建议。
original_request_name 用于识别这种后续调用的原始工具身份。路由 Hook 应避免无条件请求同一工具导致重复调用,并检查新工具所需参数。
匹配工具身份
内置工具按 read_file、run_shell_command 等实际名称匹配;MCP 名称形如 mcp_<server_name>_<tool_name>。matcher 是正则,需考虑工具名中的字符和预期范围。
停止与拒绝
BeforeTool 的 exit 2 阻止本次工具,AfterTool 的 exit 2 隐藏结果,两者都让本轮 Agent 继续。真正需要停止整个循环时使用 continue false;不能把工具拒绝当作整个任务已结束。