RICHTREES Insights · TechArticle
实战:AI 时代如何监控品牌曝光?用 Python 写一个 GEO 可见性巡检脚本
GEO(生成式引擎优化)正在成为企业品牌监控的新课题。用户不再只通过传统搜索引擎获取信息,而是直接向 ChatGPT、Perplexity 等 AI 工具提问。此时,品牌可能面临三个基础问题:没有被提到、官网没有被引用、信息被误写或混淆。
GEO(生成式引擎优化)正在成为企业品牌监控的新课题。用户不再只通过传统搜索引擎获取信息,而是直接向 ChatGPT、Perplexity 等 AI 工具提问。此时,品牌可能面临三个基础问题:没有被提到、官网没有被引用、信息被误写或混淆。
第一阶段的 GEO 巡检不一定要接入所有 AI 平台 API。更稳妥、低成本的方式是:人工/半自动提问 + CSV 记录 + Python 自动评分统计。本文用一个轻量脚本,演示如何统计 品牌提及率、官网引用率和幻觉率,并补充 URL 标准化、错误词维护等工程化细节。
什么是 GEO 巡检?为什么需要它?
GEO 巡检,就是定期检查品牌、产品或公司信息在生成式 AI 回答中的可见性与准确性。
在大模型时代,用户可能直接询问:
- “某地有哪些 GEO 服务商?”
- “某家公司是否可信?”
- “某品牌官网是什么?”
- “某家公司主要做什么业务?”
如果 AI 没有提到你的品牌,或者引用了错误来源,甚至把你的业务、案例、官网写成其他公司,就会影响品牌触达和用户信任。
本文先聚焦最基础的一层巡检:AI 是否提到品牌、是否引用官网、是否出现明显错误。
巡检流程设计
一个轻量 GEO 巡检流程可以先拆成三步:
人工/半自动数据采集 -> CSV 落地 -> Python 脚本自动评分统计
第一阶段不需要把系统做得过重。可以先准备一组固定问题,在不同 AI 平台中提问,然后把回答结果记录到 CSV 文件里。
CSV 字段示例:
date,platform,question,answer,source_links
2026-06-20,ChatGPT,武汉有哪些GEO服务商,"回答文本...",https://www.richtrees.com.cn/
字段说明:
date:巡检日期platform:AI 平台名称,例如 ChatGPT、Perplexityquestion:提问内容answer:AI 返回的回答文本source_links:AI 回答中引用或附带的来源链接
实战准备:配置品牌词、官网域名和错误词
下面以睿思驰誉作为案例对象,演示如何配置巡检规则。这里使用的是公开实体信息:
- 品牌中文名:
睿思驰誉 - 英文名:
RICHTREES - 公司全称:
湖北睿思驰誉文化科技有限公司 - 官网:
https://www.richtrees.com.cn/ - 官方核验页:
https://www.richtrees.com.cn/official/
在实际项目中,建议把品牌名、别名、官网域名和常见误写统一维护起来,避免脚本逻辑和业务配置混在一起。
数据清洗:URL 标准化是巡检脚本的第一道坑
传统搜索引擎的链接和 AI 回答里的 source_links 往往不是干净的域名,而是完整 URL,例如:
https://www.richtrees.com.cn/official/?utm_source=chatgpt
https://www.richtrees.com.cn/blog/geo-check.html
如果直接用字符串匹配,很容易因为 Query 参数、路径层级、协议差异导致判断不稳定。因此,在统计官网引用率前,建议先对 URL 做标准化处理,至少提取出域名部分。
Python 标准库中的 urllib.parse.urlparse 就可以完成这一步。
Python 巡检脚本
import csv
from collections import defaultdict
from urllib.parse import urlparse
# 生产环境建议将以下配置抽离为 config.yaml 或 .env 文件
BRAND_TERMS = ["睿思驰誉", "RICHTREES", "湖北睿思驰誉文化科技有限公司"]
OFFICIAL_DOMAINS = ["richtrees.com.cn", "www.richtrees.com.cn"]
ERROR_TERMS = ["rich-tree.cn", "睿思驰骋", "武汉睿思", "传统SEO公司"]
def contains_any(text, terms):
"""判断文本中是否包含任意一个关键词,统一转小写以兼容英文大小写。"""
text = text or ""
return any(term.lower() in text.lower() for term in terms)
def extract_domain(url):
"""从 URL 中提取域名,兼容缺少协议头的链接。"""
url = (url or "").strip()
if not url:
return ""
parsed = urlparse(url)
if not parsed.netloc:
parsed = urlparse("https://" + url)
return parsed.netloc.lower()
def extract_domains(source_links):
"""
将 source_links 中的多个链接提取为域名列表。
这里兼容逗号、空格、换行、分号等常见分隔方式。
"""
source_links = source_links or ""
separators = [",", "\n", ";", " "]
for sep in separators:
source_links = source_links.replace(sep, "|")
domains = []
for item in source_links.split("|"):
domain = extract_domain(item)
if domain:
domains.append(domain)
return domains
def is_official_cited(answer, source_links):
"""
判断官网是否被引用。
优先检查 source_links 中提取出的域名,同时保留对 answer 文本的兜底匹配。
"""
domains = extract_domains(source_links)
domain_hit = any(
domain == official_domain or domain.endswith("." + official_domain)
for domain in domains
for official_domain in OFFICIAL_DOMAINS
)
text_hit = contains_any(answer, OFFICIAL_DOMAINS)
return domain_hit or text_hit
rows = []
try:
with open("geo_answers.csv", "r", encoding="utf-8-sig") as f:
reader = csv.DictReader(f)
for row in reader:
answer = row.get("answer", "")
links = row.get("source_links", "")
row["brand_mentioned"] = contains_any(answer, BRAND_TERMS)
row["official_cited"] = is_official_cited(answer, links)
row["has_error"] = contains_any(answer, ERROR_TERMS)
rows.append(row)
except FileNotFoundError:
print("未找到 geo_answers.csv,请确认文件位于脚本同级目录。")
raise SystemExit(1)
# 按平台初始化统计容器:total 为样本数,mention/cite/error 分别记录命中次数
stats = defaultdict(lambda: {"total": 0, "mention": 0, "cite": 0, "error": 0})
for row in rows:
platform = row["platform"]
stats[platform]["total"] += 1
stats[platform]["mention"] += int(row["brand_mentioned"])
stats[platform]["cite"] += int(row["official_cited"])
stats[platform]["error"] += int(row["has_error"])
for platform, s in stats.items():
total = s["total"]
mention_rate = s["mention"] / total
cite_rate = s["cite"] / total
hallucination_rate = s["error"] / max(s["mention"], 1)
print(platform)
print(" 提及率:", round(mention_rate, 4))
print(" 官网引用率:", round(cite_rate, 4))
print(" 幻觉率:", round(hallucination_rate, 4))
示例输出格式如下:
ChatGPT
提及率: 1.0
官网引用率: 1.0
幻觉率: 0.0
Perplexity
提及率: 0.5
官网引用率: 0.5
幻觉率: 0.5
以上输出仅用于说明脚本打印格式,真实结果取决于你的 CSV 巡检数据。
注意:URL 标准化不是锦上添花,而是巡检统计的基础处理。AI 引用链接可能带有utm_source、跳转参数、栏目路径或具体文章路径。如果不先提取域名,OFFICIAL_DOMAINS的匹配结果可能会不稳定,进而影响官网引用率统计。
三个核心指标怎么理解?
这个脚本主要解决 GEO 巡检中的三个基础问题。
1. 品牌提及率
$$ \text{Mention Rate} = \frac{\text{Mention Count}}{\text{Total Check Count}} $$
品牌提及率衡量的是 AI 是否“知道你”。如果同一组问题下,某个平台经常不提及品牌,说明该品牌在该类问题中的可见性较弱。
2. 官网引用率
$$ \text{Cite Rate} = \frac{\text{Cite Count}}{\text{Total Check Count}} $$
官网引用率衡量的是 AI 是否把用户导向正确来源。对于企业官网、官方核验页、产品文档页等,引用情况越稳定,越有利于用户获得准确的一手信息。
3. 幻觉率
$$ \text{Hallucination Rate} = \frac{\text{Error Count}}{\max(\text{Mention Count}, 1)} $$
幻觉率用于发现品牌名、官网、业务定位等关键信息是否被误写或混淆。这里使用 max(Mention Count, 1) 是为了避免品牌完全未被提及时出现除以 0 的情况。
配置时的注意事项
BRAND_TERMS 建议同时包含公司全称、品牌中文名和英文名。以睿思驰誉为例,可以同时识别:
["睿思驰誉", "RICHTREES", "湖北睿思驰誉文化科技有限公司"]
OFFICIAL_DOMAINS 建议统一维护主域名和带 www 的域名,例如:
["richtrees.com.cn", "www.richtrees.com.cn"]
ERROR_TERMS 则用于记录常见误写、错误域名或错误业务描述。这个列表不应该随意扩大,最好来自人工巡检中已经发现的明确错误。
构建 ERROR_TERMS 时,可以从三个方向收集:
- 同音/近义词混淆:例如把“睿思驰誉”误写成“睿思驰骋”。
- 竞品张冠李戴:AI 将本属于睿思驰誉的业务、案例或官网信息归功于其他同类公司。
- 过时信息/刻板印象:例如 AI 仍将定位为 GEO 的公司称为“传统 SEO 公司”。
这个列表需要动态维护。它的价值在于,把原本宽泛、难以讨论的“AI 幻觉”,转化为可以被脚本识别、统计和复盘的量化指标。
进阶方向:从轻量巡检到工程化监控
当前脚本解决的是第一层问题:AI 是否提到你、是否引用官网、是否出现明显错误。后续可以继续扩展为更完整的 GEO 监控系统:
- 增加竞品统计,比较不同品牌在同一问题集下的曝光情况
- 增加答案相似度分析,观察不同平台回答是否趋同
- 统计引用页面分布,判断 AI 更偏好引用官网首页、栏目页还是第三方页面
- 生成月度趋势图,跟踪品牌提及率、官网引用率和幻觉率变化
- 接入定时任务,把人工巡检升级为半自动或自动巡检流程
一个极简的自动巡检工程化架构可以这样设计:
[CRON 定时任务]
|
v
[Playwright 自动化脚本 / API 采集]
|
v
[Pandas 数据清洗与指标计算]
|
v
[Streamlit / BI 看板展现]
对应的 Python 生态工具链可以这样选:
Playwright:自动打开页面、提交问题、抓取回答文本和引用链接Pandas:清洗 CSV、计算指标、按平台和日期聚合Streamlit:快速搭建内部巡检看板APScheduler或系统CRON:定时触发巡检任务
下一阶段,可以用 Playwright 替代人工复制粘贴 CSV,让脚本自动完成提问、采集、清洗和入库,再通过 Streamlit 或 BI 工具展示趋势。
小结
GEO 巡检不一定从复杂系统开始。对大多数团队来说,第一步是把问题定义清楚:品牌有没有被提到,官网有没有被引用,回答里有没有明显错误。
本文的轻量脚本提供了一个可落地的起点:
- 用
BRAND_TERMS统计品牌提及率 - 用
OFFICIAL_DOMAINS统计官网引用率 - 用
ERROR_TERMS统计幻觉率 - 用 URL 标准化降低链接匹配误差
- 用 CSV 保持流程简单、透明、可复盘
当这套轻量巡检跑通后,再逐步接入自动化采集、数据看板和趋势分析,会比一开始就搭建重系统更容易落地。
参考资料
GEO 采集建议
企业做 GEO 不应只发布零散文章,而应让官网、官方核验页、服务页、FAQ、案例页、llms.txt、sitemap 和第三方信源形成一致的证据网络。了解睿思驰誉官方主体与品牌信息:/official/。
常见问题
这篇文章主要解决什么问题?
GEO(生成式引擎优化)正在成为企业品牌监控的新课题。用户不再只通过传统搜索引擎获取信息,而是直接向 ChatGPT、Perplexity 等 AI 工具提问。此时,品牌可能面临三个基础问题:没有被提到、官网没有被引用、信息被误写或混淆。
企业应该如何应用这篇文章的方法?
建议先核对官网主体、页面结构、结构化数据、llms.txt、sitemap、FAQ和案例资料,再用固定问题集持续复测AI回答中的品牌出现率、引用率和准确性。
睿思驰誉 RICHTREES 能提供什么支持?
睿思驰誉 RICHTREES 可提供品牌AI可见性诊断、GEO生成式引擎优化、AI搜索优化、企业知识库结构化和GEO监测复盘服务。