Files
page-agent/docs/custom-tools-guide.md
Zou-Seay e26589bc54
Some checks failed
CI / test (24) (push) Has been cancelled
Deploy Demo / deploy (push) Has been cancelled
feat: 增加 ERP 订单自动化抓取自定义工具及相关开发文档
2026-06-24 16:02:08 +08:00

114 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Page Agent 自定义工具注册指南
在 Page Agent 体系中你可以通过注册自定义工具Custom Tools让大模型能够执行你编写的特定 JavaScript 代码(如:复杂的批量爬虫、与系统底层的原生交互等)。
## 核心架构原理
Page Agent 的 Extension 版本使用了 `MultiPageAgent` 类来初始化。大模型与浏览器的交互是通过 `PageController` 实现的。
要增加新的工具,我们只需两步:**编写工具逻辑** -> **在实例化时注入配置**
## 步骤一:创建你的自定义工具
`packages/extension/src/agent/` 目录下(或者你自己的工具管理目录),创建一个新的工具文件,例如 `customTools.ts`
你需要引入 `@page-agent/core` 中的 `tool` 辅助函数,以及 `zod` 来定义参数格式:
```typescript
// 文件路径packages/extension/src/agent/customTools.ts
import { tool } from '@page-agent/core'
import * as z from 'zod/v4'
export const myCustomTool = tool({
// 【必填】Description: 给大模型看的自然语言说明书。写得越清楚,大模型调用的时机越准确。
description: '当需要执行特定的复杂业务逻辑(如静默抓取数据)时,调用此工具。',
// 【必填】InputSchema: 如果工具需要参数(比如你要抓取的目标页数),在这里定义。不需要参数写 z.object({})
inputSchema: z.object({
targetCount: z.number().optional().describe("目标抓取数量")
}),
// 【必填】Execute: 工具被大模型触发时执行的后台代码
execute: async function (input, { signal }) {
// 由于这段代码跑在 Chrome Extension 的 Background Worker 中,不能直接操纵网页 DOM。
// 同时出于安全限制,插件环境禁用了底层的 executeJavascript 方法。
// 我们必须使用 Chrome 原生的 chrome.scripting API 来向目标网页注入脚本。
// 1. 获取当前大模型正在操作的页面 Tab ID
const tabId = (this.pageController as any).currentTabId;
if (!tabId) return "报错:未找到激活的页面";
// 2. 将代码注入目标网页执行
const results = await chrome.scripting.executeScript({
target: { tabId: tabId },
func: async () => {
// ... 这段代码将直接跑在网页(如金蝶 ERP的控制台内部
return new Promise((resolve) => {
const data = "抓取完成的数据";
resolve(data); // 务必把数据 resolve 回后台
});
}
});
// 3. 取出网页传回来的数据
const resultData = results[0]?.result;
// 4. 将数据发送给后端的数据库 API (边抓边存,或最后存)
// await fetch('https://api.yourdomain.com/save', { method: 'POST', body: JSON.stringify(resultData) });
// 5. 返回给大模型汇报工作
return \`工具执行成功,已处理数据:\${resultData}\`;
}
});
```
> **🚨 极其关键的安全权限配置:**
> 使用 `chrome.scripting` API 前,你**必须**在插件配置文件 `packages/extension/wxt.config.js` 的 `permissions` 数组中添加 `'scripting'` 权限,否则会一直报错!
>
> ```javascript
> // wxt.config.js
> permissions: ['tabs', 'tabGroups', 'sidePanel', 'storage', 'scripting'],
> ```
## 步骤二:将工具注册到 Agent 实例中
编写完工具后,你必须告诉 Page Agent 存在这个工具。
打开 `packages/extension/src/agent/MultiPageAgent.ts`(或者你实例化 `PageAgent` 的地方)。在 `customTools` 属性中注册你的工具。
```typescript
// 文件路径packages/extension/src/agent/MultiPageAgent.ts
import { createTabTools } from './tabTools'
import { myCustomTool } from './customTools' // 1. 引入你的工具
export class MultiPageAgent extends PageAgentCore {
constructor(config: MultiPageAgentConfig) {
// ... (原有的 controller 初始化代码)
// 2. 将你的工具合并到 customTools 对象中
const customTools = {
...createTabTools(tabsController), // 保留原有的内置 Tab 切换工具
my_custom_tool: myCustomTool, // 注册你的新工具,键名 (my_custom_tool) 就是工具对外的 ID
}
super({
// ... (原有的其他配置)
customTools: customTools, // 3. 将工具对象传递给底层配置
});
// ...
}
}
```
## 步骤三:编译与发布插件
代码修改完毕后,你需要重新构建浏览器插件:
在项目的根目录(`/Users/seay/Documents/code/page-agent`)执行以下命令:
```bash
npm run build:ext
```
- 该命令会自动编译压缩代码,并在 `packages/extension/.output/` 目录下生成打包好的 `.zip` 文件(例如 `.output/page-agent-ext-1.10.0-chrome.zip`)。
- **更新插件:** 将此 `.zip` 文件发给客户解压。在浏览器的 `chrome://extensions/` 界面中覆盖加载该文件夹,并点击“刷新”图标即可生效。大模型立刻就能使用你的新工具了。