跳到正文
FunCoding

搜索

搜索文档、Skill 和 MCP

工具结果与失败处理

分别处理成功结果和失败调用,避免遗漏失败日志或误改模型上下文。

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 默认限制。