我用 Node.js 搭了一套 GEO 监控系统:实时追踪品牌在 AI 搜索中的可见性

1 阅读5分钟

做 GEO 优化不能只靠感觉。我写了一套自动化监控,每天跑 Prompt 测试品牌是否被 AI 推荐,附完整架构。

问题:GEO 优化后怎么衡量效果?

做 SEO 有 Google Search Console、Ahrefs、SEMrush,数据一目了然。但做 GEO(Generative Engine Optimization)呢?

没有现成工具。

你优化了网站结构化数据、重写了内容、加了权威引用……然后呢?手动去 ChatGPT 里问一遍?这不现实,尤其当你有几十个关键词要追踪时。

我的解决方案:自己写一套 GEO 监控系统

架构设计

整体分三层:

┌─────────────────────────────────────────┐
│           Dashboard (React)              │
│   可见性趋势 │ 竞品对比 │ 告警面板       │
├─────────────────────────────────────────┤
│           Analysis Engine                │
│   引用解析 │ 情感分析 │ 排名计算          │
├─────────────────────────────────────────┤
│           Probe Layer                    │
│   ChatGPT API │ Perplexity │ DeepSeek    │
└─────────────────────────────────────────┘

Probe Layer:自动化 Prompt 测试

核心逻辑很简单 —— 定时向 AI 引擎发送预设 Prompt,解析返回结果中是否提到你的品牌。

interface ProbeConfig {
  engine: 'chatgpt' | 'perplexity' | 'deepseek';
  prompts: string[];
  brand: string;
  competitors: string[];
  schedule: string; // cron expression
}

interface ProbeResult {
  engine: string;
  prompt: string;
  response: string;
  brandMentioned: boolean;
  position: number | null;
  competitors: Record<string, boolean>;
  citations: string[];
  timestamp: Date;
}

关键实现 —— 不是简单的字符串匹配,而是要处理各种变体:

function detectBrandMention(
  response: string, 
  brand: string, 
  aliases: string[]
): BrandDetection {
  const allNames = [brand, ...aliases].map(n => n.toLowerCase());
  const lowerResponse = response.toLowerCase();
  
  const exactMatch = allNames.some(name => 
    lowerResponse.includes(name)
  );
  
  const listPattern = /(?:^|\n)\s*\d+[.)]\s*\*?\*?([^\n*]+)/g;
  const recommendations = [];
  let match;
  while ((match = listPattern.exec(response)) !== null) {
    recommendations.push(match[1].trim().toLowerCase());
  }
  
  const position = recommendations.findIndex(rec => 
    allNames.some(name => rec.includes(name))
  );
  
  const urlPattern = /https?:\/\/[^\s)]+/g;
  const citations = response.match(urlPattern) || [];
  
  return {
    mentioned: exactMatch,
    position: position >= 0 ? position + 1 : null,
    inTopN: position >= 0 && position < 3,
    citations: citations.filter(url => 
      allNames.some(name => url.includes(name))
    ),
    context: extractSurroundingText(response, brand, 200)
  };
}

Analysis Engine:数据分析

每次 Probe 的原始结果存入数据库后,需要计算几个核心指标:

1. 可见性得分 (Visibility Score)

function calculateVisibilityScore(
  results: ProbeResult[], 
  period: number = 7
): number {
  const recentResults = results.filter(r => 
    r.timestamp > new Date(Date.now() - period * 86400000)
  );
  
  if (recentResults.length === 0) return 0;
  
  const totalScore = recentResults.reduce((sum, r) => {
    let score = 0;
    if (r.brandMentioned) score += 1;
    if (r.position && r.position <= 3) score += 2;
    if (r.citations.length > 0) score += 1;
    return sum + score;
  }, 0);
  
  const maxPossible = recentResults.length * 4;
  return Math.round((totalScore / maxPossible) * 100);
}

2. 竞品对比矩阵

function buildCompetitorMatrix(
  results: ProbeResult[]
): CompetitorMatrix {
  const matrix = {};
  
  for (const result of results) {
    const engine = result.engine;
    if (!matrix[engine]) matrix[engine] = {};
    
    if (result.brandMentioned) {
      matrix[engine]['self'] = (matrix[engine]['self'] || 0) + 1;
    }
    
    for (const [comp, mentioned] of Object.entries(result.competitors)) {
      if (mentioned) {
        matrix[engine][comp] = (matrix[engine][comp] || 0) + 1;
      }
    }
  }
  
  return matrix;
}

3. 趋势告警

可见性得分连续 3 天下降 → 触发告警。这通常意味着:

  • 竞品发布了新内容,抢占了推荐位
  • AI 模型更新,引用逻辑变化
  • 你的网站出了技术问题(如 robots.txt 误配)
function checkVisibilityAlert(
  dailyScores: { date: string; score: number }[]
): Alert | null {
  const recent = dailyScores.slice(-3);
  if (recent.length < 3) return null;
  
  const declining = recent.every((day, i) => 
    i === 0 || day.score < recent[i - 1].score
  );
  
  if (declining) {
    const drop = recent[0].score - recent[2].score;
    return {
      type: 'visibility_declining',
      severity: drop > 20 ? 'critical' : 'warning',
      message: '可见性连续3天下降,累计下降 ' + drop + ' 分',
      recommendation: analyzeDeclineReason(dailyScores)
    };
  }
  
  return null;
}

实际运行数据

我用这套系统监控了自己的 SaaS 产品,跑了 30 天。一些发现:

数据 1:不同引擎的推荐稳定性差异大

引擎日均 Prompt 数品牌提及率Top3 占比波动率
ChatGPT-4o2035%12%±15%
Perplexity2052%28%±8%
DeepSeek2018%5%±22%

Perplexity 最稳定,因为它更依赖实时搜索结果(和你的 SEO 表现相关)。ChatGPT 波动较大,同一个 Prompt 不同时间问可能给出不同推荐。DeepSeek 波动最大,可能和模型版本更新频繁有关。

数据 2:Prompt 措辞对推荐结果影响巨大

同一个需求,不同问法结果完全不同:

Prompt品牌是否被提及
"推荐一个 SEO 工具"
"有哪些 AI 驱动的 SEO 工具"
"品牌在 AI 搜索中不可见怎么办"✅ Top2
"GEO optimization tools"✅ Top1
"如何提升品牌在 ChatGPT 中的可见性"✅ Top3

关键洞察:通用关键词(SEO 工具)竞争太激烈,你几乎不可能被推荐。但精准的长尾场景(GEO optimization、AI 搜索可见性)更容易获得推荐位。

这验证了 GEO 的核心策略:不要和大厂抢通用词,聚焦你的差异化场景。

数据 3:Schema Markup 效果验证

加了 SoftwareApplication + FAQ Schema 后,Perplexity 的提及率从 35% 提升到 52%。ChatGPT 变化不明显(可能不依赖结构化数据)。

成本控制

自动化监控最大的顾虑是 API 成本。我的方案:

每天 60 个 Prompt(3 引擎 × 20 个关键词)
ChatGPT API: ~$0.3/天(gpt-4o-mini)
Perplexity API: ~$0.1/天
DeepSeek API: ~$0.05/天
总计: ~$0.45/天 ≈ $13.5/月

对比请一个 SEO 顾问的费用,这个成本可以忽略。

省钱技巧

  • 用 gpt-4o-mini 而不是 gpt-4o(便宜 10x,引用检测够用)
  • 非工作日减少频率(周末每天 20 个)
  • 相似 Prompt 合并("推荐 X 工具" 类 Prompt 用模板生成)

开源替代方案

如果你不想从零搭建,有几个思路:

  1. 用 Cron + 脚本最小化版本:一个 Node.js 脚本 + SQLite,每天跑一次就行
  2. 接入现有 SEO 工具:有些工具开始支持 AI 搜索追踪(如 GEO Boost 的 AI Visibility Score)
  3. 用 n8n / Make.com 低代码方案:Webhook 触发 → API 调用 → Google Sheets 记录

我自己用的方案是方案 1 + 自建 Dashboard,因为需要更灵活的分析。

如果只是想快速看一下品牌在 AI 搜索中的表现,推荐试试 GEO Boost,一键扫描就能看到可见性得分和优化建议,不需要自己写代码。

总结

GEO 优化和 SEO 最大的区别:SEO 有成熟的监控生态,GEO 几乎是空白。

谁先建立起 GEO 监控能力,谁就能更快迭代优化策略。不管是用现成工具还是自己搭建,核心是:

  1. 定期测试:至少每天跑一次 Prompt 监控
  2. 多引擎覆盖:ChatGPT、Perplexity、DeepSeek 表现差异很大
  3. 关注趋势而非单点:单次结果波动大,看 7 天趋势更有意义
  4. 竞品对标:你的可见性上升可能是竞品下降,反之亦然

我是独立开发者,正在探索 AI 搜索优化的实践方法。以上数据来自真实测试,欢迎讨论交流。