news 2026/9/15 14:56:49

page-agent 自定义工具开发最佳实践:Zod Schema 与 AbortSignal 协作式取消

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
page-agent 自定义工具开发最佳实践:Zod Schema 与 AbortSignal 协作式取消

page-agent 自定义工具开发最佳实践:Zod Schema 与 AbortSignal 协作式取消

【免费下载链接】page-agentJavaScript in-page GUI agent. Control web interfaces with natural language.项目地址: https://gitcode.com/GitHub_Trending/pa/page-agent

page-agent 是一个运行在网页内的 JavaScript GUI Agent,用自然语言操控网页界面。本文面向新手,讲透两个核心问题:如何用 Zod Schema 定义自定义工具的输入参数,以及如何用 AbortSignal 实现协作式取消(cooperative cancellation),让你的工具在用户点击"停止"时能立即、干净地退出。

内置工具不够用?先认识 customTools

page-agent 自带一组内置工具(点击、输入文本、下拉选择、滚动、等待、执行 JS 等),定义在 tools/index.ts 中。当你的业务需要"加入购物车""查知识库""提交审批单"这类专属动作时,就通过customTools配置项扩展能力。

注册方式只需一步:在创建 Agent 时传入customTools,每个工具由tool()辅助函数包裹,包含三个要素:

要素作用关键点
description写给大模型看的"说明书",决定 AI 何时调用该工具要具体、可操作
inputSchema用 Zod 定义的输入参数结构必须从zod/v4子路径导入
execute实际业务逻辑,返回字符串结果异步工具必须响应ctx.signal

一个最小示例(完整示例见 types.ts 中的注释文档):

import { z } from 'zod/v4' import { tool } from 'page-agent' add_to_cart: tool({ description: 'Add a product to the shopping cart by its product ID.', inputSchema: z.object({ productId: z.string(), quantity: z.number().min(1).default(1), }), execute: async function (input, { signal }) { await fetch('/api/cart', { method: 'POST', body: JSON.stringify(input), signal, // 关键:把取消信号传给网络请求 }) return `Added ${input.quantity}x ${input.productId} to cart.` }, })

Zod Schema 定义的 3 个最佳实践

1. 一律从zod/v4子路径导入

page-agent 的 LLM 客户端使用 Zod 4 的z.toJSONSchema()把你的 Schema 转成大模型能理解的 OpenAPI 参数格式(见 utils.ts 中的zodToOpenAITool)。官方文档明确:支持 Zod 3(>=3.25.0)与 Zod 4,但必须import { z } from 'zod/v4',不支持 Zod Mini。

2. 用约束代替提示词

大模型传参不可靠,把"规矩"写进 Schema 比写进 description 更稳:

  • z.number().min(1).max(10)限制取值范围(内置wait工具就是min(1).max(10),见 tools/index.ts)
  • .default(1)提供缺省值,AI 少传一个参数也不会崩
  • .optional()标记可选参数
  • 字段命名用简短的 camelCase,降低模型出错率

3. description 是"AI 的行为开关"

Schema 决定"参数长什么样",description 决定"什么时候调用"。参考内置scroll工具的描述写法(tools/index.ts):先说做什么,再说明有无参数的不同行为,最后给出使用建议。模糊的 description 会导致 AI 在错误步骤调用工具。

AbortSignal 协作式取消:让任务随时可控

为什么需要"协作式"取消?

用户随时可能点击"停止"。page-agent 为每个任务创建一个AbortController,其signal会同时送达三处:大模型请求、每个工具的ctx.signal、以及异步回调(见 PageAgentCore.ts 中的设计注释)。

"协作式"的含义是:框架不会暴力杀掉你的工具,而是把signal交给你,由你的代码在合适的检查点"自愿"退出——这正是浏览器fetch取消机制的标准玩法。

工具内响应 signal 的 3 种姿势

execute: async function (input, { signal }) { // ① 网络请求:直接传给 fetch const res = await fetch(url, { signal }) // ② 长循环:每轮检查一次 for (const item of items) { signal.throwIfAborted() await process(item) } // ③ 纯等待:用内置的 waitFor(seconds, signal) await waitFor(3, signal) }

其中waitFor是项目内置的可取消等待工具(utils/index.ts):传入 signal 后,一旦取消会立刻以标准AbortError拒绝 Promise,而不是傻等到时间结束。

内置wait工具就是标准示范(tools/index.ts);实验性的execute_javascript工具甚至会把signal注入到 AI 生成的脚本作用域里,并要求生成代码遵守它(tools/index.ts)。

双保险:即使你忘了,框架也会兜底

框架在工具执行完毕后会强制再检查一次:signal.throwIfAborted()(PageAgentCore.ts)。也就是说,即使你的工具忽略了 signal 并正常返回,只要期间任务被停止,框架仍会中断任务。

AbortError被捕获时,任务状态优雅地变为stopped,历史记录里只留一条简短的 "Task aborted",不会污染 Agent 的记忆(PageAgentCore.ts)。

💡 同理:自定义onAskUser回调(询问用户)也必须响应signal,在取消时 reject,否则"停止"会卡死在等待用户回答上(见 PageAgentCore.ts 的接口注释)。

进阶:覆盖与移除内置工具

customTools的值支持两种"元操作"(types.ts):

  • 同名覆盖:用内置工具名(如ask_user)注册新工具,直接替换其行为——例如把"问用户"改成"问你的后端模型"
  • 设为null移除:如scroll: null让 Agent 永远无法滚动页面,适合做安全围栏

常见踩坑清单 ✅

后果正确做法
写成import { z } from 'zod'Schema 转换报错或行为异常统一用zod/v4子路径
异步工具不传signal点"停止"后要干等请求超时fetch必传{ signal },长循环加throwIfAborted()
execute返回 undefined步骤输出为空,AI 失去反馈永远返回字符串(可含 emoji 状态标记)
description 只写一句话AI 在不该调用的步骤乱调用说明参数语义 + 适用场景 + 注意事项
setTimeout裸等待无法被取消改用内置waitFor(seconds, signal)

获取源码与延伸阅读

克隆仓库即可本地研读:

git clone https://gitcode.com/GitHub_Trending/pa/page-agent
  • 工具定义与内置工具全集:packages/core/src/tools/index.ts
  • customTools配置说明:packages/core/src/types.ts
  • 取消机制主流程:packages/core/src/PageAgentCore.ts
  • 官方文档页(含完整示例):custom-tools 文档

小结:Zod Schema 负责"AI 能不能传对参数",AbortSignal 负责"任务能不能随时停下"。两者配合,才能写出既聪明又可控的自定义工具。

【免费下载链接】page-agentJavaScript in-page GUI agent. Control web interfaces with natural language.项目地址: https://gitcode.com/GitHub_Trending/pa/page-agent

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 14:52:33

HyperFrames 动画避坑清单:6 条让渲染不出错的运动规则

HyperFrames 动画避坑清单:6 条让渲染不出错的运动规则 【免费下载链接】hyperframes Write HTML. Render video. Built for agents. 项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes HyperFrames 是一个「写 HTML、渲染视频」(Wr…

作者头像 李华