competitive-monitoring

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Competitive Monitoring

竞品监控

Track competitor websites for changes in pricing, features, positioning, and content.
跟踪竞品网站的价格、功能、定位及内容变化。

Quick Start

快速开始

bash
undefined
bash
undefined

Capture initial snapshot

捕获初始快照

/ork:competitive-monitoring capture https://competitor.com/pricing
/ork:competitive-monitoring capture https://competitor.com/pricing

Check for changes (compares to last snapshot)

检查变化(与上一次快照对比)

/ork:competitive-monitoring diff https://competitor.com/pricing
/ork:competitive-monitoring diff https://competitor.com/pricing

View change history

查看变更历史

/ork:competitive-monitoring history competitor.com
undefined
/ork:competitive-monitoring history competitor.com
undefined

Core Concepts

核心概念

Snapshot

Snapshot

A point-in-time capture of a webpage including:
  • Text content - Main body text
  • Structured data - Pricing tiers, feature lists, etc.
  • Screenshot - Visual state
  • Metadata - Timestamp, URL, capture method
某一时刻的网页捕获内容,包括:
  • 文本内容 - 页面主体文本
  • 结构化数据 - 定价套餐、功能列表等
  • 截图 - 页面视觉状态
  • 元数据 - 时间戳、URL、捕获方法

Diff

Diff

Comparison between two snapshots showing:
  • Added content - New text, features, prices
  • Removed content - Deleted sections
  • Changed content - Modified values
  • Visual changes - Layout/design shifts
对比两个快照,展示:
  • 新增内容 - 新文本、功能、价格
  • 移除内容 - 删除的板块
  • 修改内容 - 变更的值
  • 视觉变化 - 布局/设计调整

Change Classification

变更分类

SeverityExamplesAction
CriticalPrice increase/decrease, major feature changeImmediate alert
HighNew feature added, feature removedReview required
MediumCopy changes, positioning shiftNote for analysis
LowTypos, minor stylingLog only
严重程度示例操作
严重价格上涨/下调、重大功能变更立即告警
新增功能、移除功能需要审核
文案修改、定位调整记录用于分析
拼写错误、样式微调仅记录

Site Discovery with Tavily (Optional Pre-Step)

借助Tavily发现站点(可选前置步骤)

When
TAVILY_API_KEY
is available, use Tavily's crawl API to discover and extract all key pages on a competitor's site in one call. This replaces the manual map→extract two-step workflow.
当配置
TAVILY_API_KEY
后,可使用Tavily的爬取API一键发现并提取竞品站点的所有关键页面,替代手动的映射→提取两步流程。

Option A: Crawl (Recommended — Single Call)

选项A:爬取(推荐——一键操作)

bash
undefined
bash
undefined

Crawl competitor site — discovers URLs and extracts content in one step

爬取竞品站点——一步完成URL发现与内容提取

curl -s -X POST 'https://api.tavily.com/crawl'
-H 'Content-Type: application/json'
-H "Authorization: Bearer $TAVILY_API_KEY"
-d '{ "url": "https://competitor.com", "max_depth": 2, "limit": 50, "include_raw_content": "markdown", "include_paths": ["/pricing*", "/features*", "/changelog*", "/blog*"] }' | python3 -c " import json, sys data = json.load(sys.stdin) for page in data.get('results', []): fname = page['url'].replace('https://', '').replace('/', '_') with open(f'.competitive-intel/snapshots/{fname}.md', 'w') as f: f.write(page.get('raw_content', page.get('content', ''))) print(f'Captured: {page["url"]}') "
undefined
curl -s -X POST 'https://api.tavily.com/crawl'
-H 'Content-Type: application/json'
-H "Authorization: Bearer $TAVILY_API_KEY"
-d '{ "url": "https://competitor.com", "max_depth": 2, "limit": 50, "include_raw_content": "markdown", "include_paths": ["/pricing*", "/features*", "/changelog*", "/blog*"] }' | python3 -c " import json, sys data = json.load(sys.stdin) for page in data.get('results', []): fname = page['url'].replace('https://', '').replace('/', '_') with open(f'.competitive-intel/snapshots/{fname}.md', 'w') as f: f.write(page.get('raw_content', page.get('content', ''))) print(f'Captured: {page["url"]}') "
undefined

Option B: Map + Extract (Granular Control)

选项B:映射+提取(精细控制)

Use when you need to filter URLs before extracting:
bash
undefined
当需要在提取前过滤URL时使用此方式:
bash
undefined

Step 1: Discover URLs

步骤1:发现URL

curl -s -X POST 'https://api.tavily.com/map'
-H 'Content-Type: application/json'
-H "Authorization: Bearer $TAVILY_API_KEY"
-d '{"url": "https://competitor.com", "max_depth": 2, "limit": 50}'
| python3 -c " import json, sys for url in json.load(sys.stdin).get('urls', []): print(url) " > .competitive-intel/discovered-urls.txt
curl -s -X POST 'https://api.tavily.com/map'
-H 'Content-Type: application/json'
-H "Authorization: Bearer $TAVILY_API_KEY"
-d '{"url": "https://competitor.com", "max_depth": 2, "limit": 50}'
| python3 -c " import json, sys for url in json.load(sys.stdin).get('urls', []): print(url) " > .competitive-intel/discovered-urls.txt

Step 2: Filter and batch extract

步骤2:过滤并批量提取

URLS=$(grep -E '(pricing|features|changelog)' .competitive-intel/discovered-urls.txt
| head -20 | python3 -c "import json,sys; print(json.dumps([l.strip() for l in sys.stdin if l.strip()]))")
curl -s -X POST 'https://api.tavily.com/extract'
-H 'Content-Type: application/json'
-H "Authorization: Bearer $TAVILY_API_KEY"
-d "{"urls": $URLS}" | python3 -m json.tool

**Cost**: Crawl ~1 credit/5 pages. Map+Extract ~1 credit/10 mapped + 1 credit/5 extracted. Skip if `TAVILY_API_KEY` unset — proceed directly to browser-based capture below.
URLS=$(grep -E '(pricing|features|changelog)' .competitive-intel/discovered-urls.txt
| head -20 | python3 -c "import json,sys; print(json.dumps([l.strip() for l in sys.stdin if l.strip()]))")
curl -s -X POST 'https://api.tavily.com/extract'
-H 'Content-Type: application/json'
-H "Authorization: Bearer $TAVILY_API_KEY"
-d "{"urls": $URLS}" | python3 -m json.tool

**成本**:爬取约1积分/5页。映射+提取约1积分/10个映射页面 + 1积分/5个提取页面。若未设置`TAVILY_API_KEY`则跳过此步骤,直接使用下方基于浏览器的捕获方式。

Workflow

工作流

Step 1: Initial Capture

步骤1:初始捕获

bash
undefined
bash
undefined

Create snapshots directory

创建快照目录

mkdir -p .competitive-intel/snapshots
mkdir -p .competitive-intel/snapshots

Capture competitor pricing page

捕获竞品定价页面

agent-browser open https://competitor.com/pricing agent-browser wait --load networkidle
agent-browser open https://competitor.com/pricing agent-browser wait --load networkidle

Save text content

保存文本内容

agent-browser get text body > .competitive-intel/snapshots/competitor-pricing-$(date +%Y%m%d).txt
agent-browser get text body > .competitive-intel/snapshots/competitor-pricing-$(date +%Y%m%d).txt

Save screenshot

保存截图

agent-browser screenshot .competitive-intel/snapshots/competitor-pricing-$(date +%Y%m%d).png
agent-browser screenshot .competitive-intel/snapshots/competitor-pricing-$(date +%Y%m%d).png

Extract structured pricing data

提取结构化定价数据

agent-browser eval "JSON.stringify( Array.from(document.querySelectorAll('.pricing-tier')).map(tier => ({ name: tier.querySelector('h3')?.innerText, price: tier.querySelector('.price')?.innerText, features: Array.from(tier.querySelectorAll('li')).map(li => li.innerText) })) )" > .competitive-intel/snapshots/competitor-pricing-$(date +%Y%m%d).json
agent-browser close
undefined
agent-browser eval "JSON.stringify( Array.from(document.querySelectorAll('.pricing-tier')).map(tier => ({ name: tier.querySelector('h3')?.innerText, price: tier.querySelector('.price')?.innerText, features: Array.from(tier.querySelectorAll('li')).map(li => li.innerText) })) )" > .competitive-intel/snapshots/competitor-pricing-$(date +%Y%m%d).json
agent-browser close
undefined

Step 2: Diff Detection

步骤2:差异检测

bash
undefined
bash
undefined

Get latest two snapshots

获取最新两个快照

LATEST=$(ls -t .competitive-intel/snapshots/competitor-pricing-.txt | head -1) PREVIOUS=$(ls -t .competitive-intel/snapshots/competitor-pricing-.txt | head -2 | tail -1)
LATEST=$(ls -t .competitive-intel/snapshots/competitor-pricing-.txt | head -1) PREVIOUS=$(ls -t .competitive-intel/snapshots/competitor-pricing-.txt | head -2 | tail -1)

Text diff

文本差异对比

diff -u "$PREVIOUS" "$LATEST" > .competitive-intel/diffs/competitor-pricing-$(date +%Y%m%d).diff
diff -u "$PREVIOUS" "$LATEST" > .competitive-intel/diffs/competitor-pricing-$(date +%Y%m%d).diff

Check if significant changes

检查是否有重大变化

if [ -s ".competitive-intel/diffs/competitor-pricing-$(date +%Y%m%d).diff" ]; then echo "Changes detected!" cat ".competitive-intel/diffs/competitor-pricing-$(date +%Y%m%d).diff" fi
undefined
if [ -s ".competitive-intel/diffs/competitor-pricing-$(date +%Y%m%d).diff" ]; then echo "Changes detected!" cat ".competitive-intel/diffs/competitor-pricing-$(date +%Y%m%d).diff" fi
undefined

Step 3: Structured Comparison

步骤3:结构化对比

bash
undefined
bash
undefined

Compare JSON pricing data

对比JSON格式的定价数据

LATEST_JSON=$(ls -t .competitive-intel/snapshots/competitor-pricing-.json | head -1) PREVIOUS_JSON=$(ls -t .competitive-intel/snapshots/competitor-pricing-.json | head -2 | tail -1)
LATEST_JSON=$(ls -t .competitive-intel/snapshots/competitor-pricing-.json | head -1) PREVIOUS_JSON=$(ls -t .competitive-intel/snapshots/competitor-pricing-.json | head -2 | tail -1)

Use jq to compare

使用jq工具对比

jq -s ' .[0] as $old | .[1] as $new | { price_changes: [ $new[] | . as $tier | ($old[] | select(.name == $tier.name)) as $old_tier | select($old_tier.price != $tier.price) | {name: .name, old_price: $old_tier.price, new_price: .price} ], new_tiers: [$new[] | select(.name as $n | $old | map(.name) | index($n) | not)], removed_tiers: [$old[] | select(.name as $n | $new | map(.name) | index($n) | not)] } ' "$PREVIOUS_JSON" "$LATEST_JSON"
undefined
jq -s ' .[0] as $old | .[1] as $new | { price_changes: [ $new[] | . as $tier | ($old[] | select(.name == $tier.name)) as $old_tier | select($old_tier.price != $tier.price) | {name: .name, old_price: $old_tier.price, new_price: .price} ], new_tiers: [$new[] | select(.name as $n | $old | map(.name) | index($n) | not)], removed_tiers: [$old[] | select(.name as $n | $new | map(.name) | index($n) | not)] } ' "$PREVIOUS_JSON" "$LATEST_JSON"
undefined

Monitoring Targets

监控目标

Pricing Pages

定价页面

bash
undefined
bash
undefined

Extract pricing structure

提取定价结构

agent-browser eval "JSON.stringify({ tiers: Array.from(document.querySelectorAll('[class*=pricing], [class*=plan]')).map(t => ({ name: t.querySelector('h2, h3, [class*=title]')?.innerText?.trim(), price: t.querySelector('[class*=price], [class*=cost]')?.innerText?.trim(), period: t.querySelector('[class*=period], [class*=billing]')?.innerText?.trim(), cta: t.querySelector('button, [class*=cta]')?.innerText?.trim() })) })"
undefined
agent-browser eval "JSON.stringify({ tiers: Array.from(document.querySelectorAll('[class*=pricing], [class*=plan]')).map(t => ({ name: t.querySelector('h2, h3, [class*=title]')?.innerText?.trim(), price: t.querySelector('[class*=price], [class*=cost]')?.innerText?.trim(), period: t.querySelector('[class*=period], [class*=billing]')?.innerText?.trim(), cta: t.querySelector('button, [class*=cta]')?.innerText?.trim() })) })"
undefined

Feature Pages

功能页面

bash
undefined
bash
undefined

Extract feature list

提取功能列表

agent-browser eval "JSON.stringify({ features: Array.from(document.querySelectorAll('[class*=feature] h3, [class*=feature] h4')).map(f => f.innerText?.trim()), categories: Array.from(document.querySelectorAll('[class*=category]')).map(c => ({ name: c.querySelector('h2, h3')?.innerText?.trim(), items: Array.from(c.querySelectorAll('li')).map(li => li.innerText?.trim()) })) })"
undefined
agent-browser eval "JSON.stringify({ features: Array.from(document.querySelectorAll('[class*=feature] h3, [class*=feature] h4')).map(f => f.innerText?.trim()), categories: Array.from(document.querySelectorAll('[class*=category]')).map(c => ({ name: c.querySelector('h2, h3')?.innerText?.trim(), items: Array.from(c.querySelectorAll('li')).map(li => li.innerText?.trim()) })) })"
undefined

Changelog/Release Notes

更新日志/版本说明

bash
undefined
bash
undefined

Extract recent releases

提取近期版本

agent-browser eval "JSON.stringify({ releases: Array.from(document.querySelectorAll('[class*=release], [class*=changelog] > div')).slice(0, 10).map(r => ({ version: r.querySelector('[class*=version], h2, h3')?.innerText?.trim(), date: r.querySelector('[class*=date], time')?.innerText?.trim(), notes: r.querySelector('[class*=notes], [class*=description]')?.innerText?.trim()?.slice(0, 200) })) })"
undefined
agent-browser eval "JSON.stringify({ releases: Array.from(document.querySelectorAll('[class*=release], [class*=changelog] > div')).slice(0, 10).map(r => ({ version: r.querySelector('[class*=version], h2, h3')?.innerText?.trim(), date: r.querySelector('[class*=date], time')?.innerText?.trim(), notes: r.querySelector('[class*=notes], [class*=description]')?.innerText?.trim()?.slice(0, 200) })) })"
undefined

Storage Pattern

存储模式

.competitive-intel/
├── config.json           # Monitored URLs and schedules
├── snapshots/
│   ├── competitor-a/
│   │   ├── pricing-0201.txt
│   │   ├── pricing-0201.json
│   │   └── pricing-0201.png
│   └── competitor-b/
│       └── ...
├── diffs/
│   ├── competitor-a/
│   │   └── pricing-0201.diff
│   └── competitor-b/
│       └── ...
└── reports/
    └── weekly-0201.md
.competitive-intel/
├── config.json           # 监控的URL及调度配置
├── snapshots/
│   ├── competitor-a/
│   │   ├── pricing-0201.txt
│   │   ├── pricing-0201.json
│   │   └── pricing-0201.png
│   └── competitor-b/
│       └── ...
├── diffs/
│   ├── competitor-a/
│   │   └── pricing-0201.diff
│   └── competitor-b/
│       └── ...
└── reports/
    └── weekly-0201.md

Config File

配置文件

json
{
  "monitors": [
    {
      "name": "Competitor A Pricing",
      "url": "https://competitor-a.com/pricing",
      "frequency": "daily",
      "selectors": {
        "pricing": ".pricing-tier",
        "features": ".feature-list li"
      },
      "alerts": {
        "price_change": "critical",
        "new_feature": "high",
        "copy_change": "low"
      }
    }
  ],
  "storage": ".competitive-intel",
  "retention_days": 90
}
json
{
  "monitors": [
    {
      "name": "Competitor A Pricing",
      "url": "https://competitor-a.com/pricing",
      "frequency": "daily",
      "selectors": {
        "pricing": ".pricing-tier",
        "features": ".feature-list li"
      },
      "alerts": {
        "price_change": "critical",
        "new_feature": "high",
        "copy_change": "low"
      }
    }
  ],
  "storage": ".competitive-intel",
  "retention_days": 90
}

Change Report Template

变更报告模板

markdown
undefined
markdown
undefined

Competitive Change Report

竞品变更报告

Date: 2026-02-04 Competitor: Competitor A URL: https://competitor-a.com/pricing
日期: 2026-02-04 竞品: Competitor A URL: https://competitor-a.com/pricing

Summary

摘要

  • Critical Changes: 1 (price increase)
  • High Changes: 2 (new features)
  • Medium Changes: 0
  • Low Changes: 3 (copy updates)
  • 严重变更: 1项(价格上涨)
  • 高优先级变更: 2项(新增功能)
  • 中优先级变更: 0项
  • 低优先级变更: 3项(文案更新)

Critical: Price Change Detected

严重:检测到价格变更

TierPreviousCurrentChange
Pro$29/mo$39/mo+34%
套餐原价格当前价格变化幅度
Pro$29/月$39/月+34%

High: New Features Added

高优先级:新增功能

  1. AI Assistant - Added to Pro tier
  2. API Access - Now available in Team tier
  1. AI Assistant - 新增至Pro套餐
  2. API Access - 现面向Team套餐开放

Recommendation

建议

  • Update competitive positioning
  • Review our pricing strategy
  • Consider matching new AI feature
undefined
  • 更新竞品定位分析
  • 审核我方定价策略
  • 考虑匹配新增AI功能
undefined

Integration with Memory

与记忆模块集成

Store findings in knowledge graph for persistence:
bash
undefined
将发现的信息存储到知识图谱中以持久化:
bash
undefined

After detecting changes, store in memory

检测到变更后,存储到记忆模块

mcp__memory__add_node( name="Competitor A Price Increase -02", type="competitive_intelligence", content="Pro tier increased from $29 to $39 (+34%)" )
mcp__memory__add_node( name="Competitor A Price Increase -02", type="competitive_intelligence", content="Pro tier increased from $29 to $39 (+34%)" )

Query historical changes

查询历史变更

mcp__memory__search_nodes(query="competitor pricing changes ")
undefined
mcp__memory__search_nodes(query="competitor pricing changes ")
undefined

Automation Ideas

自动化思路

Scheduled Monitoring (via cron/CI)

定时监控(通过cron/CI)

yaml
undefined
yaml
undefined

.github/workflows/competitive-monitor.yml

.github/workflows/competitive-monitor.yml

name: Competitive Monitor on: schedule: - cron: '0 9 * * *' # Daily at 9 AM jobs: monitor: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm install -g agent-browser - run: agent-browser install - run: ./scripts/run-competitive-monitor.sh - uses: actions/upload-artifact@v4 with: name: competitive-intel path: .competitive-intel/
undefined
name: Competitive Monitor on: schedule: - cron: '0 9 * * *' # 每日上午9点 jobs: monitor: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm install -g agent-browser - run: agent-browser install - run: ./scripts/run-competitive-monitor.sh - uses: actions/upload-artifact@v4 with: name: competitive-intel path: .competitive-intel/
undefined

Related Skills

相关技能

  • web-research-workflow
    - Decides WebFetch vs browser
  • browser-content-capture
    - Detailed capture patterns
  • market-analysis-patterns
    - Analysis frameworks

Version: 1.1.0 (February 2026)
  • web-research-workflow
    - 决定使用WebFetch还是浏览器
  • browser-content-capture
    - 详细的捕获模式
  • market-analysis-patterns
    - 分析框架

版本: 1.1.0(2026年2月)