分类目录归档:插件

OpenClaw插件开发与使用

OpenClaw 新增 TinyFish 浏览器自动化插件:5 分钟实现复杂网页工作流

一句话总结

OpenClaw 最新版本(#58645)正式将 TinyFish 作为内置浏览器自动化插件捆绑发布,让 AI Agent 能够安全、可靠地执行复杂的公共网页自动化任务,无需额外安装即可通过配置快速启用。

为什么需要 TinyFish?

在 AI Agent 的实际应用中,简单的 HTTP 请求web_fetch)和 搜索引擎调用web_search)往往无法满足需求——现代网站大量使用 JavaScript 渲染、需要用户登录态、或包含复杂的交互流程。传统方案需要开发者自行搭建浏览器集群,而 TinyFish 提供了托管式的浏览器自动化能力,直接集成到 OpenClaw 的插件架构中。

本文将详细介绍 TinyFish 的功能特性、配置方法,以及如何在实际工作流中正确使用。

TinyFish 核心功能解析

1. 托管式浏览器自动化

TinyFish 提供云端托管的浏览器环境,支持执行复杂的网页操作:

| 能力 | 说明 |
|:—|:—|
| JavaScript 渲染 | 完整执行页面脚本,获取动态内容 |
| 登录态保持 | 支持 Cookie 和凭证注入 |
| 多步骤交互 | 点击、表单填写、滚动等操作链 |
| 流式响应 | 通过 SSE 实时返回执行进度 |

与本地 PlaywrightSelenium 相比,TinyFish 免去了基础设施维护成本,且与 OpenClaw 的权限系统深度集成。

2. 四层安全防护机制

TinyFish 内置了严格的安全策略,防止恶意利用:

安全配置示例(config.yaml)

tinyfish: enabled: true # SSRF 防护:限制内网地址访问 ssrf_guard: true # 凭证拒绝:防止敏感信息泄露到日志 credential_rejection: true # 仅允许特定域名(可选) allowed_domains: - "example.com" - "api.service.org"

关键安全特性:

  • SSRF 防护:阻止访问私有 IP 段和元数据服务
  • 凭证隔离:自动过滤请求/响应中的敏感字段
  • COMPLETE 终端校验:SSE 流必须正常结束,防止数据截断攻击
  • SecretRef 支持:API 密钥通过引用注入,不硬编码

3. 智能技能升级路径

TinyFish 被设计为 OpenClaw 技能体系的”最终手段”,遵循明确的升级路径:

web_fetch(简单静态页面)
    ↓ 失败或需要 JS
web_search(获取相关链接)
    ↓ 需要深度交互
tinyfish_automation(复杂工作流)
    ↓ 需要精确控制
browser(本地浏览器直连)

这种分层设计确保资源高效利用——仅在必要时才调用成本较高的浏览器自动化。

快速配置指南

步骤一:启用插件

TinyFish 默认为关闭状态,需显式启用:

编辑 OpenClaw 配置文件

$ openclaw config edit

添加以下配置

plugins: tinyfish: enabled: true api_key: $secretRef: "tinyfish-api-key" # 使用 SecretRef 引用

步骤二:配置 API 凭证

添加 API 密钥到密钥管理

$ openclaw secret set tinyfish-api-key "tf_live_xxxxxxxxxxxx"

验证配置

$ openclaw plugin verify tinyfish ✓ Plugin manifest valid ✓ API connectivity check passed ✓ SSE parser test passed

步骤三:在工作流中使用

// 示例:自动化获取电商产品价格
{
  "tool": "tinyfish_automation",
  "params": {
    "url": "https://example-shop.com/products/12345",
    "workflow": [
      { "action": "waitForSelector", "selector": ".price-display" },
      { "action": "click", "selector": "#currency-selector" },
      { "action": "select", "selector": "#currency-usd" },
      { "action": "extract", "selector": ".final-price", "as": "price_usd" }
    ],
    "timeout": 30000
  }
}

技术实现亮点

SSE 流解析与错误处理

TinyFish 采用 Server-Sent Events (SSE) 实现实时进度反馈,解析器经过专门加固:

// 核心解析逻辑(简化示意)
async function* parseEventBlock(stream: ReadableStream) {
  try {
    for await (const event of stream) {
      yield validateAndParse(event);
      
      if (event.type === 'COMPLETE') {
        return; // 正常终止
      }
    }
    // 流结束但未收到 COMPLETE — 异常
    throw new StreamTerminatedError('Stream ended before COMPLETE');
  } catch (err) {
    // 关键修复:后置 finally 中的解析错误不会掩盖主错误
    try {
      await cleanupParseState();
    } catch (cleanupErr) {
      logger.warn('Cleanup error suppressed', cleanupErr);
    }
    throw err;
  }
}

语义化的集成类型

代码审查中,将模糊的 API_INTEGRATION 拆分为更精确的类型:

| 类型 | 用途 |
|:—|:—|
| TINYFISH_API_INTEGRATION | TinyFish 服务端的 API 调用 |
| CLIENT_SOURCE | 客户端来源标识(用于审计和限流) |

这种区分提升了日志可读性和问题排查效率。

实际应用场景

场景一:竞品价格监控

// 定时任务配置
{
  "schedule": "0 /6   ",
  "workflow": {
    "tool": "tinyfish_automation",
    "params": {
      "url": "{{competitor_url}}",
      "workflow": [
        { "action": "bypassCloudflare", "mode": "stealth" },
        { "action": "extract", "selector": "[data-testid='price']" }
      ]
    }
  }
}

场景二:政府公开数据抓取

需要处理复杂的表单提交和分页:

{
  "tool": "tinyfish_automation",
  "params": {
    "url": "https://data.gov.cn/search",
    "workflow": [
      { "action": "fill", "selector": "#keyword", "value": "{{query}}" },
      { "action": "click", "selector": "#search-btn" },
      { "action": "waitForNavigation" },
      { "action": "extractAll", "selector": ".result-item", "pagination": ".next-page" }
    ],
    "maxPages": 5
  }
}

场景三:SaaS 平台数据导出

处理需要登录的私有数据(配合 SecretRef):

{
  "tool": "tinyfish_automation",
  "params": {
    "url": "https://crm.internal.com/reports",
    "cookies": {
      $secretRef: "crm-session-cookies"
    },
    "workflow": [
      { "action": "click", "selector": "#export-csv" },
      { "action": "waitForDownload", "timeout": 60000 }
    ]
  }
}

FAQ

Q1: TinyFish 与 OpenClaw 原有的 browser 工具有什么区别?

browser 工具需要本地安装浏览器驱动(如 Chrome + ChromeDriver),适合开发环境和对延迟敏感的场景。TinyFish 是托管服务,无需本地基础设施,更适合生产环境的弹性扩展和团队协作。两者在 OpenClaw 的技能体系中属于同一层级,可根据需求选择。

Q2: 启用 TinyFish 会产生额外费用吗?

TinyFish 作为捆绑插件本身免费,但实际调用 TinyFish 云服务时,会根据使用时长和并发量计费。建议先在 TinyFish 定价页面 了解费率,并在 OpenClaw 配置中设置 maxConcurrentSessionsmonthlyBudgetLimit 进行成本控制。

Q3: 如何处理需要二次验证的网站?

对于 MFA/2FA 场景,TinyFish 支持两种模式:
1. 预置凭证模式:提前获取并注入长期有效的 session cookie(推荐)
2. 人工介入模式:工作流暂停,通过 webhook 通知人工完成验证后继续

具体配置参考 OpenClaw 文档 – 高级认证流程

Q4: SSE 流解析失败如何排查?

常见原因及解决方法:

| 错误信息 | 原因 | 解决 |
|:—|:—|:—|
| Stream ended before COMPLETE | 服务端异常终止 | 检查 TinyFish 服务状态,增大 timeout |
| Malformed event data | 网络中断导致数据截断 | 启用重试机制 retry: { maxAttempts: 3 } |
| SSRF guard triggered | 目标地址被安全策略拦截 | 确认目标域名在 allowed_domains 列表中 |

Q5: 如何为 TinyFish 编写自定义工作流?

OpenClaw 提供了工作流 DSL 验证工具:

验证工作流语法

$ openclaw tinyfish validate-workflow workflow.json

本地调试(模拟执行,不消耗配额)

$ openclaw tinyfish simulate --workflow workflow.json --mock-url https://httpbin.org

详细 DSL 规范见 TinyFish 工作流文档

总结与下一步

TinyFish 的集成标志着 OpenClaw 在浏览器自动化领域的重大进展——开发者现在可以在统一的插件架构中,根据任务复杂度灵活选择 web_fetchweb_searchtinyfish_automationbrowser,实现成本与能力的最佳平衡。

建议行动:
1. 升级至 OpenClaw 最新版本(≥ #58645)
2. 在 TinyFish 官网 注册获取 API 密钥
3. 参考本文配置启用插件,从简单的价格监控任务开始尝试
4. 关注后续版本对 Playwright 脚本导入 的支持(路线图 #42100)

相关阅读

参考来源

| 来源 | 链接 |
|:—|:—|
| 本次功能更新 Commit | https://github.com/openclaw/openclaw/commit/b880118d2dd64f45d768228d9e917d10ab99f92a |
| 关联 Issue #41300 | https://github.com/openclaw/openclaw/issues/41300 |
| OpenClaw 官方文档 | https://docs.openclaw.dev |
| TinyFish 官方网站 | https://tinyfish.dev |

OpenClaw 插件系统升级:5个关键修复提升运行时稳定性

一句话总结

本次更新通过引入运行时门面激活保护机制,彻底解决了 OpenClaw 插件系统中因重复激活导致的崩溃与资源泄漏问题,显著提升了浏览器插件和 Discord 集成的稳定性。

背景:插件系统的核心痛点

OpenClaw 的插件架构中,门面模式(Facade Pattern) 是连接核心系统与插件功能的关键桥梁。然而,在实际生产环境中,开发团队发现多个插件存在重复激活门面的隐患:

  • 浏览器插件:页面刷新时可能触发多次激活,导致内存泄漏
  • Discord 插件:线程清理与激活逻辑耦合,引发竞态条件
  • 插件 SDK:缺乏统一的加载策略控制,各插件自行其是

这些问题在 #59412 提交中得到了系统性修复。

核心改进详解

1. 运行时门面激活保护机制

最基础的修复是为门面激活添加幂等性保护

// plugin-sdk/src/facade.rs
impl PluginFacade {
    /// 带保护的激活方法,防止重复初始化
    pub fn activate_guarded(&mut self) -> Result<(), FacadeError> {
        // 检查是否已激活,避免重复操作
        if self.state == FacadeState::Active {
            log::debug!("Facade already active, skipping activation");
            return Ok(());
        }
        
        self.do_activate()?;
        self.state = FacadeState::Active;
        Ok(())
    }
}

关键设计:将状态检查与业务逻辑分离,确保任何路径下都不会出现双重激活。

2. 本地化门面加载策略

此前,门面加载策略分散在各插件实现中。本次重构将其内聚到 SDK 层

// plugin-sdk/src/policy.rs
pub struct FacadeLoadPolicy {
    /// 是否允许延迟加载
    pub lazy_loading: bool,
    /// 激活超时时间(毫秒)
    pub activation_timeout_ms: u32,
    /// 失败重试策略
    pub retry_policy: RetryPolicy,
}

impl Default for FacadeLoadPolicy { fn default() -> Self { Self { lazy_loading: true, activation_timeout_ms: 5000, retry_policy: RetryPolicy::ExponentialBackoff { max_retries: 3, base_ms: 100, }, } } }

收益:插件开发者只需配置策略,无需关心底层实现细节。

3. 浏览器插件:分离清理与激活逻辑

浏览器插件的复杂性在于页面生命周期与插件生命周期的交错。修复方案将清理辅助函数移出激活保护范围:

// browser/src/plugin.rs
impl BrowserPlugin {
    pub fn on_page_reload(&mut self) {
        // ✅ 清理操作不受激活保护限制
        self.cleanup_helpers();
        
        // ✅ 激活操作带保护,可安全重复调用
        if let Err(e) = self.facade.activate_guarded() {
            log::warn!("Facade activation skipped: {}", e);
        }
    }
    
    fn cleanup_helpers(&mut self) {
        // 释放页面相关的临时资源
        self.page_context.clear();
        self.event_listeners.drain(..).for_each(|h| h.unbind());
    }
}

设计原则:清理操作应当始终执行,而激活操作应当幂等可控

4. Discord 插件:解绑线程清理操作

Discord 插件的特殊性在于其多线程消息处理模型。修复确保线程解绑在激活保护之外:

// discord/src/plugin.rs
impl DiscordPlugin {
    fn shutdown(&mut self) {
        // 无论门面状态如何,都必须解绑线程
        // 防止线程泄漏导致的进程挂起
        if let Some(thread) = self.cleanup_thread.take() {
            thread.unbind();
        }
        
        // 门面停用带保护
        let _ = self.facade.deactivate_guarded();
    }
}

5. 健壮性增强:非零退出码处理

浏览器插件新增了对清理命令异常退出的容错:

当 trash 命令以非零状态退出时的处理逻辑

修复前:直接 panic,导致插件崩溃

修复后:记录警告并尝试备用清理方案

示例:手动触发清理的调试命令

openclaw-cli browser cleanup --force --fallback
// browser/src/cleanup.rs
fn safe_trash_remove(path: &Path) -> Result<(), CleanupError> {
    match Command::new("trash").arg(path).status() {
        Ok(status) if status.success() => Ok(()),
        Ok(status) => {
            // 非零退出码处理:降级到标准删除
            log::warn!("trash exited with {}, falling back to fs::remove", status);
            fs::remove_dir_all(path).map_err(CleanupError::from)
        }
        Err(e) => {
            // 命令未找到:同样降级
            log::warn!("trash not available: {}", e);
            fs::remove_dir_all(path).map_err(CleanupError::from)
        }
    }
}

迁移指南:如何适配新机制

对于插件开发者

1. 更新 SDK 依赖Cargo.toml):

   [dependencies]
   openclaw-plugin-sdk = "^0.24.0"  # 包含激活保护机制
   

2. 替换激活调用

   // 旧代码(存在风险)
   self.facade.activate()?;
   
   // 新代码(受保护)
   self.facade.activate_guarded()?;
   

3. 审查清理逻辑:确保 Drop 实现和清理函数不依赖门面激活状态

对于运维人员

监控以下指标以验证修复效果:

查看插件激活相关日志

openclaw-cli logs --filter "facade" --level warn

检查重复激活事件(应当为零)

openclaw-cli metrics get plugin.facade.double_activation_attempts

FAQ

Q1: 什么是”门面激活保护”,为什么需要它?

门面激活保护是一种幂等性控制机制,确保插件的门面对象在生命周期内只被激活一次。需要它的原因是:OpenClaw 支持热重载和动态页面切换,这些场景可能触发多次初始化调用,若无保护会导致资源重复分配、状态冲突甚至崩溃。

Q2: 这次更新会影响现有插件的兼容性吗?

不会破坏兼容性activate_guarded() 是新增方法,旧的 activate() 仍然可用(但已标记为 #[deprecated])。建议开发者在新版本中迁移,旧插件可继续运行,只是无法享受保护机制带来的稳定性提升。

Q3: 如何检测我的插件是否存在重复激活问题?

启用调试日志并监控以下模式:

openclaw-cli run --plugin your-plugin --verbose

查找包含 "double activation" 或 "facade state conflict" 的日志

也可使用内置的诊断工具:

openclaw-cli plugin diagnose --check-facade-lifecycle

Q4: 浏览器插件的”trash 回退”机制在什么场景下会触发?

当系统未安装 trash-cli 工具,或该工具返回非零退出码时(如文件被占用、权限不足),会自动降级到标准文件系统删除。这确保了清理操作的最终可靠性,即使外部依赖异常也能完成核心功能。

Q5: 这次更新与 OpenClaw 的 AI Agent 功能有关联吗?

间接相关。AI Agent 插件同样基于这套插件 SDK 构建,本次修复为其提供了更稳定的运行时基础。特别是 Agent 的多会话管理场景,频繁的面激活/停用操作现在有了更可靠的保护。

总结

#59412 提交代表了 OpenClaw 插件系统向生产级稳定性迈出的关键一步。通过引入运行时门面激活保护、本地化加载策略、以及细粒度的清理逻辑分离,开发团队解决了长期存在的架构隐患。

关键行动点
1. 升级至 OpenClaw 0.24.0+ 版本
2. 审查自定义插件的门面使用模式
3. 启用新指标监控以验证修复效果

相关阅读

参考来源

| 来源 | 链接 |
|:—|:—|
| 本次提交的完整变更 | https://github.com/openclaw/openclaw/commit/52a018680da0fd8ac8e234fa594bc0b245fbc772 |
| OpenClaw 官方文档 | https://docs.openclaw.dev |
| 插件 SDK API 参考 | https://docs.rs/openclaw-plugin-sdk |
| 相关 Issue 讨论 | https://github.com/openclaw/openclaw/issues?q=label%3Aplugin-stability |

OpenClaw 新功能:TinyFish 浏览器自动化插件使用指南

OpenClaw 新功能:TinyFish 浏览器自动化插件使用指南

OpenClaw 现在内置 TinyFish 浏览器自动化插件,让你能够自动化复杂的网页工作流程,无需手动编写 Selenium 或 Puppeteer 代码。

本文将详细介绍 TinyFish 的功能、配置方法和实际应用场景。

目录

什么是 TinyFish

TinyFish 是一个托管式浏览器自动化插件,专为 OpenClaw 设计。它提供了一个简单的工具 tinyfish_automation,让你能够:

  • 自动化复杂的公共网页工作流程
  • 执行需要浏览器交互的任务
  • 处理动态加载的网页内容
  • 与现有的 web_fetch 和 web_search 工具形成能力升级链

能力升级链

OpenClaw 提供了一系列网页工具,按复杂度递增:

web_fetch → web_search → tinyfish → browser
  • web_fetch — 简单静态页面获取
  • web_search — 网页搜索
  • tinyfish — 托管浏览器自动化
  • browser — 本地浏览器控制

核心功能

1. 托管浏览器自动化

TinyFish 在托管环境中运行浏览器,无需本地安装 Chrome 或 Firefox:

config.yaml

plugins: tinyfish: enabled: true api_key: ${TINYFISH_API_KEY} # 可选,高级功能需要

2. SSE 流式响应

支持 Server-Sent Events (SSE) 流式响应,实时获取自动化进度:

  • COMPLETE 终端标记 — 明确知道何时完成
  • SSRF 防护 — 防止服务器端请求伪造攻击
  • 凭据拒绝 — 自动检测和拒绝敏感信息

3. 工具调用升级指导

当简单工具无法满足需求时,OpenClaw 会自动建议升级到 TinyFish:

用户:帮我从京东抓取商品价格
AI:这个页面需要 JavaScript 渲染,建议使用 tinyfish 自动化工具...

安装与配置

步骤 1: 启用插件

编辑 config.yaml

plugins:
  allow:
    - tinyfish  # 显式允许 TinyFish 插件
  
  tinyfish:
    enabled: true
    # 可选:配置 API 密钥以使用高级功能
    api_key:
      value: ${TINYFISH_API_KEY}  # 从环境变量读取

步骤 2: 配置安全策略

plugins:
  tinyfish:
    security:
      ssrf_guard: true        # 启用 SSRF 防护
      credential_rejection: true  # 拒绝包含凭据的请求
      max_execution_time: 300000  # 最大执行时间(毫秒)

步骤 3: 重启 OpenClaw

openclaw restart

使用示例

示例 1: 自动化登录流程

使用 tinyfish_automation 工具

  • tool: tinyfish_automation
params: url: "https://example.com/login" steps: - action: "fill" selector: "#username" value: "myusername" - action: "fill" selector: "#password" value: "${PASSWORD}" # 使用环境变量 - action: "click" selector: "#login-button" - action: "wait" duration: 2000 # 等待 2 秒 - action: "extract" selector: ".dashboard-title" as: "page_title"

示例 2: 抓取动态内容

- tool: tinyfish_automation
  params:
    url: "https://spa-app.example.com"
    steps:
      - action: "wait_for"
        selector: "#data-loaded"  # 等待数据加载完成
        timeout: 10000
      - action: "extract_all"
        selector: ".product-item"
        properties:
          - name: "title"
            selector: ".product-title"
          - name: "price"
            selector: ".product-price"

示例 3: 表单提交自动化

- tool: tinyfish_automation
  params:
    url: "https://forms.example.com/apply"
    steps:
      - action: "select"
        selector: "#country"
        value: "China"
      - action: "fill"
        selector: "#email"
        value: "user@example.com"
      - action: "upload"
        selector: "#resume-upload"
        file: "/path/to/resume.pdf"
      - action: "click"
        selector: "#submit-button"
      - action: "wait_for_navigation"
        timeout: 5000

安全特性

1. SSRF 防护

TinyFish 内置 SSRF (Server-Side Request Forgery) 防护:

security:
  ssrf_guard: true
  blocked_hosts:
    - "localhost"
    - "127.0.0.1"
    - "10.0.0.0/8"
    - "192.168.0.0/16"

2. 凭据自动检测

自动检测请求中是否包含敏感信息(密码、API 密钥等):

警告:检测到请求包含可能的凭据信息
建议:使用 SecretRef 方式安全存储凭据

3. 执行超时控制

防止自动化任务无限期运行:

max_execution_time: 300000  # 5 分钟

4. 请求审计日志

所有自动化操作都会被记录:

查看 TinyFish 审计日志

tail -f ~/.openclaw/logs/tinyfish-audit.log

最佳实践

1. 错误处理

为自动化任务添加错误处理:

- tool: tinyfish_automation
  params:
    url: "https://example.com"
    steps: [...]
  on_error:
    action: "retry"
    max_retries: 3
    fallback: "notify_admin"

2. 速率限制

避免对目标网站造成过大压力:

plugins:
  tinyfish:
    rate_limit:
      requests_per_minute: 10
      delay_between_requests: 2000  # 毫秒

3. 选择器优化

使用稳定的选择器:

推荐:使用 data-testid 或 id

selector: "[data-testid='submit-button']"

避免:过于依赖 DOM 结构

selector: "div.container > div.row > button"

总结

TinyFish 为 OpenClaw 带来了强大的浏览器自动化能力:

1. 托管运行 — 无需本地浏览器环境
2. 安全可靠 — SSRF 防护、凭据检测
3. 易于使用 — 声明式步骤配置
4. 能力升级 — 与现有工具无缝集成

下一步行动:
1. 在 config.yaml 中启用 TinyFish 插件
2. 尝试自动化一个简单的网页任务
3. 根据需要配置安全策略

常见问题

Q: TinyFish 和本地 browser 工具有什么区别?

A:

  • TinyFish — 托管浏览器,适合云端自动化,无需本地环境
  • browser — 本地浏览器控制,适合需要本地交互的场景

Q: TinyFish 需要 API Key 吗?

A: 基础功能免费,高级功能(如更多并发、更长执行时间)需要 API Key。

Q: 如何处理验证码?

A: TinyFish 不自动处理验证码。建议:

  • 使用支持验证码识别的第三方服务
  • 在测试环境中禁用验证码
  • 使用 API 替代网页自动化

Q: 自动化任务失败如何调试?

A:
1. 查看审计日志:~/.openclaw/logs/tinyfish-audit.log
2. 启用调试模式:debug: true
3. 使用 screenshot 步骤捕获页面状态

Q: TinyFish 支持哪些浏览器?

A: 目前支持 Chromium 内核的浏览器(Chrome、Edge 等),Firefox 支持即将推出。

Q: 可以同时运行多个自动化任务吗?

A: 可以,但受限于:

  • 配置的最大并发数
  • TinyFish API 的速率限制
  • 目标网站的承受能力

参考来源

相关阅读: