
Effect 4.0 工具调用参数校验失败处理failureMode路由与ToolParameterValidationError.toolParams移除【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect导读本文聚焦 Effect 4.0当前仓库GitHub_Trending/ef/effect主分支中 AI 工具调用Tool Calling的一个关键行为变更工具调用参数校验失败tool call parameter validation failures现在统一路由到工具自身的failureMode策略处理同时删除了ToolParameterValidationError上的toolParams字段。读完本文你将理解FailureMode error | return两种策略在参数校验失败场景下的完整语义、ToolParameterValidationError的新数据结构以及这一变更对基于 Effect AIeffect/ai-openai、effect/ai-anthropic、effect/ai-openai-compat、effect/ai-openrouter构建 Agent 应用的迁移影响。背景changeset 声明了什么本次变更记录于仓库的 changeset 文件 .changeset/pre/eff-1008-tool-param-failure-mode.md其内容非常精炼但信息量集中在一处行为契约上Route tool call parameter validation failures through the toolsfailureModeand dropToolParameterValidationError.toolParams.逐字拆解包含两个语义点路由参数校验失败到failureMode当 LLM 发起一次工具调用、但参数无法通过工具的参数 Schema 校验时失败不再以单一固定方式上报而是跟随该工具声明的failureModeerror或return决定走错误通道还是结果通道。移除toolParams字段ToolParameterValidationError不再携带原始工具参数快照错误体更加精简。该 changeset 同时声明了对多个包的影响级别包changeset 版本声明说明effectpatch核心实现所在包unstable/ai模块effect/ai-anthropicpatchAnthropic 提供方集成effect/ai-openaipatchOpenAI 提供方集成effect/ai-openai-compatpatchOpenAI 兼容端点集成effect/ai-openrouterpatchOpenRouter 提供方集成从包清单可以看出这次行为统一发生在 Effect AI 的核心层各提供方Provider只需跟随核心语义无需各自特判。failureMode是什么工具错误处理的两种策略在理解本次变更前需要先明确failureMode的定位。它定义于 packages/effect/src/unstable/ai/Tool.ts是一个字符串联合类型export type FailureMode error | return其 JSDoc 语义为error默认值工具调用处理器tool call handler执行期间发生的错误将通过调用 Effect 的错误通道error channel抛出调用方需要显式catch/flip处理。return工具调用处理器执行期间发生的错误会被捕获并作为工具调用结果tool call result的一部分返回不会中断整个生成流程。该字段被写入Tool接口的Config类型约束中Tool.ts所有工具用户自定义工具Tool.make、提供方内建工具Tool.providerDefined、动态工具Tool.dynamic的配置都必须包含failureMode成员Tool.ts。默认值可通过Tool.make的示例确认——创建工具时不传failureMode即默认为error见 Tool.ts 中的const result [GetWeather.name, GetWeather.failureMode] // [GetWeather, error]。同时failureMode还参与类型层面的推导工具的错误结果类型FailureResultT会根据failureMode是否为return来扩展联合分支Tool.tserror模式FailureResultT FailureT | ExecutionFailurereturn模式FailureResultT FailureT | ExecutionFailure | AiError也就是说在return模式下AiError包括本变更主角ToolParameterValidationError会成为工具结果的合法成员从而可以被编码回传给模型。参数校验失败的新路由逻辑核心实现Toolkit 处理器本次变更的核心逻辑位于Toolkit的handle处理器中packages/effect/src/unstable/ai/Toolkit.ts。简化后的关键路径如下const decodedParamsResult yield* Effect.result(schemas.decodeParameters(params)) if (Result.isFailure(decodedParamsResult)) { const error AiError.make({ module: Toolkit, method: ${name}.handle, reason: new AiError.ToolParameterValidationError({ toolName: name, description: decodedParamsResult.failure.message }) }) if (tool.failureMode error) { return yield* error // ① 错误通道 } return Stream.fromEffect( // ② 结果通道 Effect.map(encodeResult(error, true), (encodedResult) ({ result: error, isFailure: true, preliminary: false, encodedResult })) ) }流程拆解schemas.decodeParameters(params)使用工具的parametersSchema对模型传入的参数做解码校验对应 Toolkit.tsSchema.decodeUnknownEffect(tool.parametersSchema)。通过Effect.result(...)将解码结果捕获为Exit不直接抛出从而在同一位置获得“成功/失败”两分支。失败时构造AiError其reason为ToolParameterValidationErrortoolName取工具名description取 Schema 校验失败消息。依据tool.failureMode分流error直接return yield* error错误进入 Effect 错误通道return将错误作为一条失败的工具结果isFailure: true编码后放入Stream随工具结果流返回给上层最终可编码回传给 LLM让模型有机会修正参数。这一逻辑与工具处理器执行失败时的分流完全对称——Toolkit.ts 中处理器失败同样依据tool.failureMode error ? Stream.fail(normalizedError) : Stream.succeed({ result: normalizedError, isFailure: true, preliminary: false })。换言之本次变更把参数校验失败纳入了与处理器失败完全一致的统一策略框架。需要注意的细节在return模式下编码错误结果使用的是encodeResult(error, true)即走失败 SchemaTool.failureResultSchema(tool)见 Toolkit.ts编码AiError确保结果可以 JSON 序列化后回传给模型。参数解码使用的 Schema 缓存schemasCache会为每个工具缓存decodeParameters因此校验开销只发生在首次调用Toolkit.ts。ToolParameterValidationError的结构变化ToolParameterValidationError定义于 packages/effect/src/unstable/ai/AiError.ts作为Schema.Error的子类其 Schema 仅包含两个字段export class ToolParameterValidationError extends Schema.ErrorToolParameterValidationError( effect/ai/AiError/ToolParameterValidationError )({ _tag: Schema.tag(ToolParameterValidationError), toolName: Schema.String, description: Schema.String }) { get isRetryable(): boolean { return true // 模型可能在下一次尝试中修正参数 } }结构要点_tagToolParameterValidationError用于运行时判别。toolName触发校验失败的工具名。descriptionSchema 校验失败的原始消息例如缺失字段时形如Missing key\n at [testParam]。isRetryable恒为true因为参数错误来自模型输出模型可能在下一次尝试中自我修正——这是与InvalidToolResultError处理器返回非法结果、不可重试见 AiError.ts的关键区别。message拼接为Invalid parameters for tool toolName: description。本次变更前该错误还带有一个toolParams字段保存模型传入的原始参数快照变更后该字段已被移除错误体保持最小化。这对下游的影响在于序列化后的错误更紧凑网络传输与日志体积更小若你的代码此前依赖error.reason.toolParams读取原始参数升级后需要改用其他途径例如从请求侧的 span annotation 获取参数——handle在入口处通过Effect.annotateCurrentSpan({ tool: name, parameters: params })记录了原始参数见 Toolkit.ts。同时ToolParameterValidationError仍是AiErrorReason联合成员之一AiError.ts并随AiError.make暴露AiError.ts因此所有既有的AiError判别、isRetryable检查与AiErrorReason类型守卫依旧适用。测试验证两种模式下的行为对照仓库测试 packages/effect/test/unstable/ai/Tool.test.ts 对这一行为提供了直接证据。测试中的两个工具分别以两种模式注册Tool.test.ts 的failureMode: return与另一处failureMode: error并围绕无效参数缺字段与NaN 参数两类场景验证路由结果。场景一failureMode: return 缺失字段模拟 LLM 返回params: {}缺少必需的testParam最终response.toolResults为单条失败结果Tool.test.tsResponse.toolResultPart({ id: toolCallId, name: toolName, isFailure: true, providerExecuted: false, preliminary: false, result: AiError.make({ module: Toolkit, method: FailureModeReturn.handle, reason: new AiError.ToolParameterValidationError({ toolName, description // Missing key\n at [\testParam\] }) }), encodedResult: { // 可回传给模型的 JSON 形式 _tag: AiError, module: Toolkit, method: FailureModeReturn.handle, reason: { _tag: ToolParameterValidationError, toolName, description } } })注意encodedResult中不再包含toolParams这正是“droptoolParams”的直接验证。场景二failureMode: error NaN 参数模型传入params: { testParam: NaN }由于FailureModeError使用error模式整个生成 Effect 被翻转Effect.flip后拿到的错误即为AiError其reason._tag ToolParameterValidationErrorTool.test.ts。两种模式的行为对照可总结为维度failureMode: errorfailureMode: return校验失败去向Effect 错误通道Effect.flip可见工具结果流toolResults中的失败条目isFailure不适用走错误true是否回传给模型否是encodedResult为AiErrorJSON对生成流程的影响中断继续模型可依据错误修正参数此外处理器级失败handler failure的return模式同样经过 OpenAI transformer 测试验证Tool.test.ts说明参数校验失败与处理器失败共享同一策略出口。对使用各 AI 提供方的迁移影响本次变更触及effect/ai-openai、effect/ai-anthropic、effect/ai-openai-compat、effect/ai-openrouter四个提供方包。由于核心逻辑集中在Toolkit.handle提供方集成只需将AiError含ToolParameterValidationError正确地编码进各自的工具结果协议即可获得一致的失败语义。以effect/ai-openai为例其语言模型实现 packages/ai/openai/src/OpenAiLanguageModel.ts 处理AiError的编码与回传effect/ai-openai-compat的 packages/ai/openai-compat/src/OpenAiLanguageModel.ts 与effect/ai-openrouter的 packages/ai/openrouter/src/OpenRouterLanguageModel.ts 亦复用同一AiError结构。四包连同effect一起被打上patch版本声明意味着这是行为修正而非破坏性大版本但对依赖toolParams的代码属于 breaking 变更升级时应排查。迁移检查清单搜索toolParams使用点若代码中读取了ToolParameterValidationError的toolParams字段需移除相关逻辑原始参数可通过 span annotationEffect.annotateCurrentSpan({ tool, parameters })或自行记录。确认failureMode设置符合预期Tool.make默认error若希望 Agent 在参数出错时继续对话并自我修正应显式设置failureMode: return。调整错误处理分支error模式下校验失败会出现在错误通道需用Effect.catchTag/match处理ToolParameterValidationErrorreturn模式下则检查response.toolResults中isFailure: true且reason._tag ToolParameterValidationError的条目。利用isRetryableToolParameterValidationError.isRetryable true可放心纳入自动重试/重生成逻辑。总结本次 changeset.changeset/pre/eff-1008-tool-param-failure-mode.md将工具参数校验失败统一纳入failureMode策略框架error模式抛入错误通道、return模式作为可回传模型的失败工具结果同时精简了ToolParameterValidationError的数据结构移除toolParams。实现层面核心分流位于 Toolkit.ts错误定义位于 AiError.ts行为由 Tool.test.ts 覆盖验证并同步影响四个 AI 提供方包。对于构建可自我纠错的 Agent 应用理解并正确配置failureMode是驾驭本次变更的关键。【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考