工具结果与失败处理
分别处理成功结果和失败调用,避免遗漏失败日志或误改模型上下文。
onPostToolUse 只在工具成功执行后触发。失败调用使用 onPostToolUseFailure;需要完整审计时应同时注册两者,而不是只看成功回调中的结果是否包含 error 字段。
成功回调
成功 input 包含 toolName、toolArgs、toolResult、workingDirectory 和 timestamp;时间类型在官方表中写作 SDK timestamp type。invocation 提供 sessionId。
| 返回字段 | 含义 |
|---|---|
modifiedResult | 使用新结果替代原结果 |
additionalContext | 给模型补充解释或处理提示 |
suppressOutput | 不把结果显示在会话中 |
没有需要改动时返回 null 或 undefined,原样传递。适合的用途包括整理大量结果、按应用需要脱敏,或明确告诉模型结果被裁剪。仅为了提示模型如何理解结果,优先附加上下文而非替换证据。
失败回调
onPostToolUseFailure 的 input 含 sessionId、toolName、toolArgs、error、timestamp、workingDirectory;error 是从失败结果提取的字符串。该回调可返回 additionalContext,为后续处理提供指导,不必把失败伪装成成功结果。
const session = await client.createSession({
hooks: {
onPostToolUse: async (input, invocation) => {
console.log("Tool succeeded", invocation.sessionId, input.toolName);
return null;
},
onPostToolUseFailure: async (input, invocation) => {
console.error("Tool failed", invocation.sessionId, input.toolName);
return {
additionalContext: "Inspect the failed call and its inputs before trying again.",
};
},
},
});Python 和 Rust 的失败 handler 名称为 on_post_tool_use_failure,Go/.NET 为 OnPostToolUseFailure。本页不补写专门参考未列出的 Java 失败接口。
不由旧示例推翻触发条件
官方同页仍有在成功 Hook 里检查 result.error 或 shell exitCode 的示例,而页首明确区分成功和失败回调。结果内容中的业务字段与 runtime 判定调用失败不是同一个概念;不能依赖这些旧示例覆盖所有失败调用。实际失败事件应使用专门入口,错误级处理另见错误 Hook。
结果类型与脱敏边界
字段表将 toolResult/modifiedResult 写作 object,但官方示例也处理字符串,因此不要假设每个工具都返回同一固定结构。按应用真实工具的类型检查后再转换,避免截断结构化结果导致含义变化。
官方正则替换只演示脱敏流程,不能保证覆盖所有密钥格式、嵌套字段或二进制内容。日志需要脱敏时,应在写日志前完成,而不是只修改送给模型的结果却另存原文。
控制开销
成功与失败 Hook 都处在调用处理路径中。大量序列化、数据库写入或外部请求会拖慢会话;没有修改就返回空结果,需要长期保存的记录可交给应用队列。对结果大小设定的应用阈值必须明确为应用策略,不应把官方示例中的 10000 字符写成 runtime 默认限制。