浏览器 Agent 插件开发规格书 (SPEC)
版本 : v1.0.0
日期 : 2026-05-15
作者 : AI Assistant
状态: 草稿
1. 项目概述
1.1 项目名称
PageAgent-Extension - 基于 AI 的智能浏览器 Agent 插件
1.2 核心定位
本项目旨在开发一款浏览器扩展插件 ,让用户在任意网页上通过自然语言直接控制 Web 界面,实现"所想即所做"的智能交互体验。项目融合了 Page-Agent 纯前端 Agent 框架与 Chrome Extension Manifest V3 架构。
1.3 核心价值
| 维度 | 描述 |
|---|---|
| 用户体验 | 无需切换标签页,在当前页面直接与 AI 对话 |
| 功能范围 | 支持页面内容分析、表单填写、内容提取、多轮对话 |
| 部署方式 | 零后端依赖,纯前端实现,用户一键安装 |
| 安全隔离 | Shadow DOM 样式完全隔离,不污染宿主页面 |
1.4 目标用户
- 普通用户: 需要自动化网页操作的用户(如批量填写表单、信息提取)
- 内容创作者: 需要跨平台发布内容的博主、自媒体运营者
- 开发者: 需要测试网页交互逻辑的前端/测试工程师
2. 技术架构
2.1 整体架构图
┌─────────────────────────────────────────────────────────────────────────────┐
│ 用户交互层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Popup │ │ Sidebar │ │ 快捷键 │ │ 右键菜单 │ │
│ │ 弹出面板 │ │ 侧边面板 │ │ Ctrl+Shift │ │ 上下文菜单 │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
└─────────┼────────────────┼────────────────┼────────────────┼──────────────┘
│ │ │ │
└────────────────┴────────────────┴────────────────┘
│
chrome.runtime API
│
┌──────────────────────────────────┴───────────────────────────────────────┐
│ 消息通信层 │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Message Passing (异步通信) │ │
│ │ Popup ↔ Background Worker ↔ Content Script ↔ 目标网页 DOM │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────┬───────────────────────────────────────┘
│
┌──────────────────────────────────┴───────────────────────────────────────┐
│ 核心引擎层 │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ DOM 分析器 │ │ 指令解析器 │ │ 操作执行器 │ │
│ │ PageAnalyzer │ │ IntentParser │ │ ActionRunner │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ 上下文提取器 │ │ LLM 决策引擎 │ │ 状态管理器 │ │
│ │ ContextExtract │ │ LLMDecision │ │ StateManager │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
└──────────────────────────────────┬───────────────────────────────────────┘
│
┌──────────────────────────────────┴───────────────────────────────────────┐
│ AI 服务层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ OpenAI │ │ Claude │ │ 通义千问 │ │ 本地模型 │ │
│ │ GPT-4/4o │ │ Claude-3 │ │ Qwen-VL │ │ Ollama │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
2.2 Chrome Extension Manifest V3 结构
page-agent-extension/
├── manifest.json # 扩展配置文件
├── background/
│ └── service-worker.js # 后台服务线程
├── content/
│ ├── content-script.js # 注入到网页的脚本
│ ├── dom-analyzer.js # DOM 分析模块
│ ├── action-executor.js # 操作执行模块
│ └── context-extractor.js # 上下文提取模块
├── popup/
│ ├── popup.html # 弹出面板 HTML
│ ├── popup.js # 弹出面板逻辑
│ └── popup.css # 弹出面板样式
├── sidebar/
│ ├── sidebar.html # 侧边面板
│ ├── sidebar.js # 侧边面板逻辑
│ └── sidebar.css # 侧边面板样式
├── components/
│ ├── AgentDialog.svelte # AI 对话组件
│ └── ActionPanel.svelte # 操作面板组件
├── core/
│ ├── intent-parser.js # 意图解析引擎
│ ├── llm-client.js # LLM API 客户端
│ └── state-manager.js # 状态管理
├── utils/
│ ├── storage.js # 本地存储工具
│ ├── logger.js # 日志工具
│ └── constants.js # 常量定义
├── assets/
│ ├── icons/ # 插件图标
│ └── images/ # 静态资源
└── _locales/
├── zh_CN/
│ └── messages.json # 中文本地化
└── en/
└── messages.json # 英文本地化
3. 核心模块规格
3.1 DOM 分析器 (DOM Analyzer)
职责
- 扫描页面可交互元素(按钮、输入框、链接等)
- 构建元素语义树,提取可操作元素元数据
- 计算元素唯一性标识(XPath/CSS Selector)
接口规范
typescript
interface DOMAnalyzerOptions {
includeHidden?: boolean; // 是否包含隐藏元素
maxDepth?: number; // 最大遍历深度
filterSelector?: string; // 过滤选择器
}
interface AnalyzableElement {
id: string; // 唯一标识
tag: string; // HTML 标签名
type: string; // input type / button type
name: string; // name 属性
text: string; // 文本内容
placeholder: string; // 占位符
ariaLabel: string; // 无障碍标签
rect: DOMRect; // 元素位置
selector: string; // CSS 选择器
xpath: string; // XPath 路径
isVisible: boolean; // 是否可见
isEnabled: boolean; // 是否可交互
zIndex: number; // 层级
}
class DOMAnalyzer {
analyze(options?: DOMAnalyzerOptions): AnalyzableElement[];
getElementBySelector(selector: string): HTMLElement | null;
getElementByXPath(xpath: string): HTMLElement | null;
getPathTo(element: HTMLElement): string;
}
实现要点
| 要点 | 描述 |
|---|---|
| 元素过滤 | 跳过 <script>, <style>, <noscript>, display:none 等 |
| 语义标注 | 使用 ARIA 属性增强可访问性识别 |
| 批量处理 | 使用 requestIdleCallback 分批处理,避免主线程阻塞 |
| 缓存机制 | 页面变化时增量更新,而非全量重扫 |
3.2 上下文提取器 (Context Extractor)
职责
- 提取当前页面元信息(标题、URL、Meta 描述)
- 识别用户选中文本
- 智能提取页面主体内容
- 识别页面类型(电商、表单、博客、搜索结果等)
接口规范
typescript
interface PageContext {
title: string; // 页面标题
url: string; // 完整 URL
hostname: string; // 域名
pageType: PageType; // 页面类型
meta: {
description: string;
keywords: string;
author: string;
};
selectedText: string; // 用户选中文本
mainContent: string; // 主体内容(去噪后)
forms: FormInfo[]; // 表单信息
links: LinkInfo[]; // 链接信息
images: ImageInfo[]; // 图片信息
}
enum PageType {
UNKNOWN = 'unknown',
ARTICLE = 'article',
FORM = 'form',
ECOMMERCE = 'ecommerce',
SEARCH_RESULT = 'search',
SOCIAL_MEDIA = 'social',
VIDEO = 'video',
DOCUMENTATION = 'docs'
}
class ContextExtractor {
extract(): PageContext;
getSelectedText(): string;
detectPageType(): PageType;
extractMainContent(options?: ContentExtractOptions): string;
}
页面类型识别策略
| 页面类型 | 识别特征 | 提取策略 |
|---|---|---|
| Article | <article>, <main>, .post-content |
提取正文段落 |
| Form | <form>, 多个 <input> |
列出所有表单项 |
| E-commerce | .product, .price, .add-to-cart |
提取商品信息 |
| Search Result | .search-result, .list-item |
提取搜索结果列表 |
| Social Media | .post, .feed, .timeline |
提取帖子内容 |
3.3 意图解析器 (Intent Parser)
职责
- 解析用户自然语言指令
- 识别操作类型(点击、输入、提交、提取、导航等)
- 提取操作参数和目标
- 处理模糊指令和上下文继承
接口规范
typescript
interface ParsedIntent {
action: ActionType; // 操作类型
target?: string; // 目标描述
value?: string; // 操作值
constraints?: Constraint[]; // 约束条件
confidence: number; // 置信度
alternatives?: ParsedIntent[]; // 备选意图
}
enum ActionType {
CLICK = 'click',
INPUT = 'input',
SELECT = 'select',
SUBMIT = 'submit',
HOVER = 'hover',
SCROLL = 'scroll',
EXTRACT = 'extract',
NAVIGATE = 'navigate',
WAIT = 'wait',
SCREENSHOT = 'screenshot',
ANSWER = 'answer' // 仅回答问题,不操作
}
interface Constraint {
type: 'contains' | 'equals' | 'startsWith' | 'endsWith' | 'matches';
field: string; // text | ariaLabel | placeholder | value
value: string;
}
class IntentParser {
parse(userInput: string, pageContext: PageContext): ParsedIntent[];
disambiguate(intents: ParsedIntent[], elements: AnalyzableElement[]): ParsedIntent;
refine(intent: ParsedIntent, feedback: string): ParsedIntent;
}
意图识别示例
| 用户输入 | 解析结果 |
|---|---|
| "点击登录按钮" | { action: CLICK, target: "登录按钮", confidence: 0.95 } |
| "填写用户名:zhangsan" | { action: INPUT, target: "用户名", value: "zhangsan", confidence: 0.90 } |
| "提取所有商品价格" | { action: EXTRACT, target: "商品价格", confidence: 0.85 } |
| "这篇文章主要讲什么" | { action: ANSWER, confidence: 1.0 } |
3.4 操作执行器 (Action Executor)
职责
- 执行具体的 DOM 操作(点击、输入、选择等)
- 支持操作序列和回滚
- 处理操作失败和重试
- 模拟人类操作行为(延迟、随机偏移)
接口规范
typescript
interface ActionResult {
success: boolean;
message: string;
element?: AnalyzableElement;
newState?: any; // 操作后的页面状态
error?: ActionError;
}
interface ActionError {
code: ErrorCode;
message: string;
recoverable: boolean;
}
enum ErrorCode {
ELEMENT_NOT_FOUND = 'ELEMENT_NOT_FOUND',
ELEMENT_NOT_VISIBLE = 'ELEMENT_NOT_VISIBLE',
ELEMENT_DISABLED = 'ELEMENT_DISABLED',
OPERATION_TIMEOUT = 'OPERATION_TIMEOUT',
UNEXPECTED_NAVIGATION = 'UNEXPECTED_NAVIGATION',
CAPTCHA_REQUIRED = 'CAPTCHA_REQUIRED'
}
class ActionExecutor {
execute(intent: ParsedIntent, elements: AnalyzableElement[]): Promise<ActionResult>;
executeSequence(actions: ParsedIntent[]): Promise<ActionResult[]>;
canRetry(error: ActionError): boolean;
getUndoStack(): Action[];
}
操作延迟配置
typescript
const ACTION_DELAYS = {
click: { min: 100, max: 300 }, // 点击延迟 100-300ms
input: { min: 50, max: 150 }, // 输入延迟 50-150ms/字符
hover: { min: 200, max: 500 }, // 悬停延迟 200-500ms
submit: { min: 500, max: 1000 }, // 提交延迟 500-1000ms
scroll: { min: 300, max: 800 }, // 滚动延迟 300-800ms
};
3.5 LLM 决策引擎 (LLM Decision Engine)
职责
- 封装多模型支持(OpenAI、Claude、通义千问、本地 Ollama)
- 构建智能 Prompt,包含页面上下文
- 处理流式响应和非流式响应
- 管理 API 密钥和用量
接口规范
typescript
interface LLMConfig {
provider: 'openai' | 'anthropic' | 'qwen' | 'ollama';
model: string;
apiKey?: string;
baseUrl?: string;
maxTokens?: number;
temperature?: number;
}
interface LLMRequest {
systemPrompt: string;
userPrompt: string;
pageContext?: PageContext;
conversationHistory?: ChatMessage[];
stream?: boolean;
}
interface ChatMessage {
role: 'system' | 'user' | 'assistant';
content: string;
}
interface LLMResponse {
content: string;
reasoning?: string; // 思考链(部分模型支持)
usage?: {
promptTokens: number;
completionTokens: number;
totalTokens: number;
};
}
class LLMDecisionEngine {
constructor(config: LLMConfig);
chat(request: LLMRequest): Promise<LLMResponse>;
chatStream(request: LLMRequest, onChunk: (chunk: string) => void): Promise<void>;
decideAction(context: PageContext, userIntent: string): Promise<ParsedIntent>;
}
Prompt 模板
markdown
## System Prompt
你是一个专业的网页操作助手。用户将在任意网页上给出自然语言指令,
你需要理解用户意图并生成可执行的操作序列。
## 页面上下文
- 页面标题:{title}
- 页面URL:{url}
- 页面类型:{pageType}
- 可交互元素:
{elements}
## 用户指令
{userIntent}
## 输出格式
请按以下JSON格式输出操作序列:
```json
{
"reasoning": "你的推理过程",
"actions": [
{
"action": "操作类型",
"target": "目标描述",
"value": "操作值(如有)"
}
]
}
---
## 4. 用户界面规格
### 4.1 Popup 弹出面板
#### 布局设计
┌─────────────────────────────────────┐
│ 🤖 PageAgent [⚙] │ Header
├─────────────────────────────────────┤
│ │
│ 📄 页面:示例网站 │ 页面信息卡片
│ 🔗 URL: https://example.com │
│ │
├─────────────────────────────────────┤
│ │
│ 💬 "帮我填写这个表单" │ 快捷指令
│ 📋 "提取文章内容" │
│ 🔍 "总结页面要点" │
│ │
├─────────────────────────────────────┤
│ 📌 已选文字:无 │ 选中文本
│ │
├─────────────────────────────────────┤
│ 输入指令... [➤] │ 输入框
├─────────────────────────────────────┤
│ 💾 已连接 | 🔑 API密钥已设置 │ 状态栏
└─────────────────────────────────────┘
#### 规格参数
| 参数 | 值 | 说明 |
|------|-----|------|
| 宽度 | 320px | 固定宽度 |
| 高度 | 自动 | 根据内容自适应,最大 600px |
| 圆角 | 12px | 容器圆角 |
| 阴影 | 0 8px 32px rgba(0,0,0,0.15) | 悬浮阴影 |
| 主题色 | #667eea → #764ba2 | 渐变色 |
### 4.2 Sidebar 侧边面板
#### 布局设计
┌─────────────────────────────────────────┐
│ 🤖 PageAgent [−][×]│
├─────────────────────────────────────────┤
│ 💬 对话记录 │
│ ┌─────────────────────────────────────┐│
│ │ 👤 帮我提取商品价格 ││
│ └─────────────────────────────────────┘│
│ ┌─────────────────────────────────────┐│
│ │ 🤖 已为您提取到 3 个商品价格: ││
│ │ - iPhone 15: ¥5999 ││
│ │ - MacBook Pro: ¥12999 ││
│ │ - AirPods Pro: ¥1899 ││
│ └─────────────────────────────────────┘│
├─────────────────────────────────────────┤
│ 📋 操作历史 │
│ ┌─────────────────────────────────────┐│
│ │ ✓ 点击了「登录」按钮 ││
│ │ ✓ 输入了用户名 ││
│ │ ○ 等待验证码输入 ││
│ └─────────────────────────────────────┘│
├─────────────────────────────────────────┤
│ ┌─────────────────────────────────────┐│
│ │ 输入消息... [ ]││
│ └─────────────────────────────────────┘│
├─────────────────────────────────────────┤
│ 🔄 重做 | ↩️ 撤销 | ⚙️ 设置 │
└─────────────────────────────────────────┘
#### 规格参数
| 参数 | 值 | 说明 |
|------|-----|------|
| 宽度 | 400px | 可拖拽调整 |
| 高度 | 100vh | 全屏高度 |
| 位置 | 右侧固定 | always on top |
| 动画 | slide-in 0.3s ease | 展开/收起动画 |
### 4.3 Shadow DOM 样式隔离
#### CSS 变量定义
```css
:host {
/* 颜色系统 */
--pa-primary: #667eea;
--pa-primary-dark: #5a67d8;
--pa-secondary: #764ba2;
--pa-success: #48bb78;
--pa-warning: #ed8936;
--pa-error: #f56565;
/* 字体 */
--pa-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--pa-font-size-sm: 12px;
--pa-font-size-md: 14px;
--pa-font-size-lg: 16px;
/* 间距 */
--pa-spacing-xs: 4px;
--pa-spacing-sm: 8px;
--pa-spacing-md: 16px;
--pa-spacing-lg: 24px;
/* 圆角 */
--pa-radius-sm: 4px;
--pa-radius-md: 8px;
--pa-radius-lg: 12px;
/* 阴影 */
--pa-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
--pa-shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.15);
/* 过渡 */
--pa-transition: all 0.2s ease;
}
5. 消息通信协议
5.1 通信架构
┌─────────────┐ chrome.runtime ┌─────────────────────┐
│ Popup │ ────────────────────────────→ │ Background Worker │
│ │ ←──────────────────────────── │ │
└─────────────┘ sendResponse / onResponse └──────────┬──────────┘
│
┌─────────────┐ chrome.runtime ┌───────────┴──────────┐
│ Sidebar │ ────────────────────────────→ │ │
│ │ ←──────────────────────────── │ │
└─────────────┘ sendResponse │ │
│ │
┌─────────────┐ chrome.tabs.sendMessage │ │
│ Content │ ←─────────────────────────── │ │
│ Script │ ───────────────────────────→ │ │
└──────┬──────┘ injectScript └─────────────────────┘
│
│ DOM 操作
↓
┌─────────────┐
│ 目标网页 │
│ DOM │
└─────────────┘
5.2 消息类型定义
typescript
// 消息类型枚举
enum MessageType {
// 上下文相关
GET_PAGE_CONTEXT = 'GET_PAGE_CONTEXT',
PAGE_CONTEXT_RESPONSE = 'PAGE_CONTEXT_RESPONSE',
// 分析相关
ANALYZE_DOM = 'ANALYZE_DOM',
ANALYZE_RESPONSE = 'ANALYZE_RESPONSE',
// 执行相关
EXECUTE_ACTION = 'EXECUTE_ACTION',
EXECUTE_RESULT = 'EXECUTE_RESULT',
// AI 相关
CHAT = 'CHAT',
CHAT_STREAM = 'CHAT_STREAM',
CHAT_RESPONSE = 'CHAT_RESPONSE',
// 状态相关
GET_STATE = 'GET_STATE',
STATE_CHANGED = 'STATE_CHANGED',
// 设置相关
GET_SETTINGS = 'GET_SETTINGS',
SAVE_SETTINGS = 'SAVE_SETTINGS',
}
// 消息接口
interface ExtensionMessage<T = any> {
id: string; // 消息唯一 ID
type: MessageType; // 消息类型
payload: T; // 消息内容
timestamp: number; // 时间戳
source: 'popup' | 'sidebar' | 'content' | 'background';
destination: 'popup' | 'sidebar' | 'content' | 'background' | 'webpage';
}
5.3 关键通信流程
流程 1: 获取页面上下文
Popup Background Content Script Webpage
│ │ │ │
│ sendMessage(GET_CONTEXT) │ │ │
│ ─────────────────────────→│ │ │
│ │ sendMessage(GET_CONTEXT) │
│ │ ──────────────────────→│ │
│ │ │ extract() │
│ │ │ ─────────────────────→│
│ │ │ ←── PageContext ───│
│ │ sendResponse(Context) │ │
│ │ ←───────────────────── │ │
│ ←─── PageContext ────────│ │ │
流程 2: 执行 AI 操作
Sidebar Background Content Script LLM API
│ │ │ │
│ sendMessage({ │ │ │
│ type: CHAT, │ │ │
│ payload: {...} │ │ │
│ }) │ │ │
│ ─────────────────────────→│ │ │
│ │ Build Prompt │ │
│ │ ──────────────────────→│ │
│ │ │ POST /chat/completions
│ │ │ ──────────────────────→│
│ │ │ ←─── Stream ───────│
│ │ sendMessage(STREAM) │ │
│ ←─── Stream chunks ──────│←────────────────────── │ │
│ │ │ │
│ │ executeSequence() │ │
│ │ ──────────────────────→│ │
│ │ │ DOM Manipulation │
│ │ │ ─────────────────────→│
6. 数据存储规格
6.1 chrome.storage 使用策略
| 存储类型 | 用途 | 数据量限制 |
|---|---|---|
| local | 用户设置、API 密钥缓存 | 10MB |
| session | 当前会话临时数据 | 10MB |
| managed | 企业策略配置(只读) | - |
| sync | 跨设备同步设置 | 100KB |
6.2 数据模型
typescript
// 用户设置
interface UserSettings {
// API 配置
apiProvider: 'openai' | 'anthropic' | 'qwen' | 'ollama';
apiKey: string; // 加密存储
apiBaseUrl?: string;
defaultModel: string;
// 界面偏好
theme: 'light' | 'dark' | 'auto';
language: 'zh-CN' | 'en-US';
showInToolbar: boolean;
sidebarPosition: 'left' | 'right';
// 功能开关
enableShortcut: boolean;
enableContextMenu: boolean;
enableNotifications: boolean;
autoAnalyze: boolean; // 自动分析页面
// 高级设置
maxTokens: number;
temperature: number;
streamResponse: boolean;
// 快捷指令
quickCommands: QuickCommand[];
}
// 快捷指令
interface QuickCommand {
id: string;
label: string;
prompt: string;
icon?: string;
enabled: boolean;
}
// 会话历史
interface ChatSession {
id: string;
title: string;
createdAt: number;
updatedAt: number;
messages: ChatMessage[];
pageUrl?: string;
}
// 操作日志
interface ActionLog {
id: string;
sessionId: string;
timestamp: number;
intent: ParsedIntent;
result: ActionResult;
screenshot?: string; // Base64 截图
}
6.3 加密方案
API 密钥使用 crypto.subtle 进行加密存储:
typescript
// 加密
async function encryptApiKey(key: string, password: string): Promise<string> {
const encoder = new TextEncoder();
const data = encoder.encode(key);
const salt = crypto.getRandomValues(new Uint8Array(16));
const keyMaterial = await crypto.subtle.importKey(
'raw',
encoder.encode(password),
'PBKDF2',
false,
['deriveBits', 'deriveKey']
);
const cryptoKey = await crypto.subtle.deriveKey(
{ name: 'PBKDF2', salt, iterations: 100000, hash: 'SHA-256' },
keyMaterial,
{ name: 'AES-GCM', length: 256 },
false,
['encrypt']
);
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv },
cryptoKey,
data
);
// 返回 salt + iv + encrypted
return btoa(String.fromCharCode(...salt, ...iv, ...new Uint8Array(encrypted)));
}
7. 权限清单
7.1 manifest.json 权限配置
json
{
"manifest_version": 3,
"permissions": [
"storage",
"activeTab",
"scripting",
"contextMenus",
"notifications",
"commands"
],
"host_permissions": [
"<all_urls>"
],
"optional_host_permissions": [
"https://api.openai.com/*",
"https://api.anthropic.com/*",
"https://dashscope.aliyuncs.com/*"
]
}
7.2 权限用途说明
| 权限 | 用途 | 必要性 |
|---|---|---|
| storage | 存储用户设置和会话历史 | 必须 |
| activeTab | 访问当前激活标签页 | 必须 |
| scripting | 向页面注入脚本执行操作 | 必须 |
| contextMenus | 右键菜单集成 | 可选 |
| notifications | 操作完成通知 | 可选 |
| commands | 全局快捷键 | 可选 |
| host_permissions | 访问所有网站页面内容 | 必须 |
8. 开发流程
8.1 环境准备
bash
# 1. 克隆项目
git clone https://github.com/your-org/page-agent-extension.git
cd page-agent-extension
# 2. 安装依赖
pnpm install
# 3. 安装开发依赖
pnpm add -D @types/chrome typescript
# 4. 启动开发服务器
pnpm dev
# 5. 在 Chrome 加载扩展
# - 打开 chrome://extensions/
# - 开启「开发者模式」
# - 点击「加载已解压的扩展程序」
# - 选择 dist 目录
8.2 构建配置
json
// package.json
{
"scripts": {
"dev": "vite build --watch",
"build": "vite build",
"lint": "eslint src --ext .ts,.tsx",
"test": "vitest",
"zip": "zip -r dist.zip dist/"
}
}
8.3 开发调试
| 调试目标 | 方法 |
|---|---|
| Content Script | 在目标页面上右键 → 检查 → Console |
| Background Worker | chrome://extensions/ → Service Worker 链接 |
| Popup | 右键插件图标 → 检查弹出内容 |
| Sidebar | 点击插件图标 → 切换到侧边面板模式 |
8.4 测试策略
| 测试类型 | 工具 | 覆盖目标 |
|---|---|---|
| 单元测试 | Vitest + jsdom | DOM 分析器、意图解析器 |
| 集成测试 | Playwright | Content Script 注入 |
| E2E 测试 | Playwright + pytest | 完整用户流程 |
| 视觉回归 | Percy | UI 组件样式 |
9. 验收标准
9.1 功能验收
| 功能点 | 验收条件 | 测试方法 |
|---|---|---|
| 页面上下文提取 | 能正确提取标题、URL、选中文字 | 打开各类网站验证 |
| 元素分析 | 能识别按钮、输入框并生成选择器 | 自动遍历测试页面 |
| 意图解析 | 能正确解析常见指令 | 输入 20+ 条指令测试 |
| 操作执行 | 能完成点击、输入、提交操作 | 执行预设操作序列 |
| AI 对话 | 能流式返回 AI 回复 | 发送问题验证响应 |
| 多模型支持 | 能切换 OpenAI/Claude/Qwen | 切换 API 测试 |
9.2 性能验收
| 指标 | 目标值 | 测试方法 |
|---|---|---|
| 页面加载时间 | < 500ms | 打开页面到插件可用 |
| DOM 分析耗时 | < 2s(1000元素) | 大型页面测试 |
| 意图解析延迟 | < 1s | 本地模型测试 |
| 内存占用 | < 100MB | Chrome Task Manager |
9.3 兼容性验收
| 浏览器 | 最低版本 | 测试状态 |
|---|---|---|
| Chrome | 120+ | 待测试 |
| Edge | 120+ | 待测试 |
| Firefox | 120+ | 待测试 |
| Arc | 最新版 | 待测试 |
10. 未来规划
10.1 短期计划 (v1.1)
- 支持更多 AI 模型(Claude API)
- 添加操作回放和撤销功能
- 支持多标签页协同操作
10.2 中期计划 (v2.0)
- 集成屏幕阅读(多模态输入)
- 支持本地 LLM (Ollama)
- 工作流编排器(串联多个操作)
10.3 长期计划 (v3.0)
- 企业级管理后台
- 团队协作功能
- 自定义 Agent 训练
附录
A. 参考资料
| 资料 | 链接 |
|---|---|
| Page-Agent GitHub | alibaba/page-agent |
| Chrome Extension 文档 | developer.chrome.com/docs/extensions |
| Manifest V3 迁移指南 | developer.chrome.com/docs/extensions/develop/migrate |
| Shadow DOM 教程 | developer.mozilla.org/docs/Web/Web_Components/Using_shadow_DOM |
B. 术语表
| 术语 | 定义 |
|---|---|
| Content Script | 注入到网页中运行的 JavaScript,可访问页面 DOM |
| Service Worker | 后台脚本,处理扩展与页面的通信 |
| Popup | 点击扩展图标弹出的 UI 面板 |
| Shadow DOM | Web Component 的样式隔离机制 |
| Intent | 用户意图,即用户想表达的目标 |
文档版本:v1.0.0 | 最后更新:2026-05-15