R睿思驰誉 RICHTREES

RICHTREES Insights · TechArticle

Streamlit 实战:搭建 GEO 品牌 AI 可见性监控面板

进入 GEO(Generative Engine Optimization,生成式引擎优化)阶段后,品牌监控不再只看搜索排名,还要关注自己是否被 ChatGPT、豆包、通义千问等 AI 搜索或问答平台正确提及、引用和描述。传统 Excel 报告在多平台、多问题、多轮测试场景下容易出现更新滞后、难交互、难追溯的问题。

StreamlitAI搜索监控品牌可见性面板

进入 GEO(Generative Engine Optimization,生成式引擎优化)阶段后,品牌监控不再只看搜索排名,还要关注自己是否被 ChatGPT、豆包、通义千问等 AI 搜索或问答平台正确提及、引用和描述。传统 Excel 报告在多平台、多问题、多轮测试场景下容易出现更新滞后、难交互、难追溯的问题。

本文使用 Streamlit + Pandas + CSV 搭建一个轻量级 GEO 品牌 AI 可见性监控面板,覆盖数据源设计、核心指标统计、平台对比图表、表格列样式优化,以及原始回答追溯能力。示例代码可以直接复制运行,适合作为 GEO 数据分析、月度复盘或客户诊断交付的基础模板。

1. 为什么 GEO 监控需要一个 Web 面板?

GEO 可以理解为面向生成式搜索和 AI 问答结果的内容优化。过去做品牌曝光,更多关注网页在搜索引擎中的排名;现在还需要观察用户向 AI 平台提问时,品牌是否出现在答案中、是否被正确描述、是否引用了官网或官方内容。

当 GEO 测试数据逐渐增加后,传统 Excel 报告会暴露几个明显问题:

  • 数据更新不及时:每次新增问题或平台结果后,都需要人工整理表格。
  • 交互能力弱:市场、技术、管理层关注的维度不同,Excel 很难快速切换视角。
  • 可追溯性不足:汇总结果和原始回答分散,难以定位某个平台为什么评分低。
  • 协作成本高:多人维护同一份表格时,字段、口径和版本容易混乱。

因此,一个轻量 Web 面板更适合 GEO 监控场景。Streamlit 的优势是上手快、代码量少,可以用 Python 快速把 CSV 数据转换成可交互的数据看板。

本文示例会搭建一个“GEO 品牌 AI 可见性监控面板”,用于查看多平台的品牌提及率、官网引用率、幻觉率、平均分和问题明细。

2. 环境准备

先安装依赖:

pip install streamlit pandas

项目目录保持简单即可:

geo-dashboard/
├── app.py
└── geo_answers.csv

运行方式:

streamlit run app.py

运行后,浏览器会自动打开本地 Streamlit 页面。如果没有自动打开,也可以根据终端提示访问类似下面的地址:

http://localhost:8501

3. 核心数据源设计

本文使用 geo_answers.csv 作为数据源。实际项目中,这份数据可以来自人工标注、爬虫采集、API 结果整理或内部评测系统导出。

下面的数据是演示用模拟数据,只用于帮助读者直接复制运行,不代表真实评测结果。

将以下内容保存为 geo_answers.csv

date,platform,question,answer,brand_mentioned,official_cited,has_error,score
2026-06-20,ChatGPT,武汉有哪些GEO服务商,回答提到睿思驰誉 RICHTREES 并建议查看 richtrees.com.cn 和 AI 可见性诊断页,true,true,false,5
2026-06-20,豆包,武汉企业如何做AI可见性诊断,回答说明可从官网结构化内容和问答场景评测入手 但未点名具体服务商,false,false,false,3
2026-06-20,通义千问,GEO和SEO有什么区别,回答解释 SEO 更偏搜索排名 GEO 更偏生成式答案中的品牌提及与引用,false,false,false,4
2026-06-21,ChatGPT,睿思驰誉 RICHTREES 是否提供GEO服务,回答提到睿思驰誉 RICHTREES 并引用 richtrees.com.cn 作为信息来源,true,true,false,5
2026-06-21,豆包,睿思驰誉 RICHTREES 的官网是什么,回答给出 richtrees.com.cn 但附带无法核验的成立年份,true,true,true,2
2026-06-21,通义千问,AI搜索会如何引用企业官网内容,回答提到应优先引用企业官网 服务页和案例页 但没有指向目标官网,false,false,false,4
2026-06-22,ChatGPT,如何评估品牌在AI问答中的可见性,回答给出提及率 官方引用率 幻觉率和人工评分四类指标,false,false,false,4
2026-06-22,通义千问,武汉GEO服务商如何选择,回答推荐了一个名称相近但无法对应官网的品牌 且没有给出官方来源,false,false,true,1

字段含义如下:

字段名含义
date测试日期
platformAI 搜索或问答平台名称
question测试问题
answer平台返回的原始回答
brand_mentioned是否提及目标品牌
official_cited是否引用官网或官方内容
has_error是否存在明显错误或幻觉信息
score人工或规则评分

这几个字段对应 GEO 监控中的核心问题:

  • brand_mentioned:品牌是否被 AI 看见。
  • official_cited:AI 是否引用了可信官方来源。
  • has_error:回答是否存在错误、误导或品牌信息偏差。
  • score:对单条回答进行综合评分,便于后续横向对比。

4. 面板代码实现

运行后,你会看到一个包含顶部指标卡、平台对比图、平台汇总表、问题明细表和原始回答查看区的看板。建议在发布或汇报时插入运行截图,让读者先建立界面预期。

[此处插入 Streamlit 运行效果截图]

下面是完整的 app.py 示例代码。

代码中重点使用了三个 Streamlit 原生能力:

  • st.metric:展示样本数、品牌提及率、官网引用率和幻觉率。
  • st.bar_chart:展示各平台提及率与幻觉率对比,不需要额外引入图表库。
  • st.dataframe + column_config:将百分比渲染为进度条,将布尔值渲染为复选框,让表格更接近看板体验。

CSV 中的 true/false 经常会被读取成字符串,不能简单使用 astype(bool)。例如字符串 "false" 是非空字符串,直接转布尔值会变成 True。所以下面代码中单独写了一个布尔值清洗函数。

import pandas as pd
import streamlit as st

st.set_page_config(page_title="GEO 品牌 AI 可见性监控", layout="wide")

BRAND = "睿思驰誉 RICHTREES"
OFFICIAL_SITE = "https://www.richtrees.com.cn/"
AUDIT_PAGE = "https://www.richtrees.com.cn/ai-visibility-audit/"

TRUE_VALUES = {"true", "1", "yes", "y", "是"}
FALSE_VALUES = {"false", "0", "no", "n", "否"}


def normalize_bool(value):
    if isinstance(value, bool):
        return value

    text = str(value).strip().lower()

    if text in TRUE_VALUES:
        return True
    if text in FALSE_VALUES:
        return False

    return False


def format_rate(series):
    if len(series) == 0:
        return "0.0%"
    return f"{series.mean():.1%}"


st.title("GEO 品牌 AI 可见性监控面板")

st.caption(
    f"监控对象:{BRAND} | "
    f"官网:[{OFFICIAL_SITE}]({OFFICIAL_SITE}) | "
    f"[AI 可见性诊断页]({AUDIT_PAGE})"
)

df = pd.read_csv("geo_answers.csv", parse_dates=["date"])

for column in ["brand_mentioned", "official_cited", "has_error"]:
    df[column] = df[column].apply(normalize_bool)

df["score"] = pd.to_numeric(df["score"], errors="coerce").fillna(0)

platform_options = sorted(df["platform"].dropna().unique())

platforms = st.multiselect(
    "选择平台",
    platform_options,
    default=platform_options,
)

data = df[df["platform"].isin(platforms)].copy()

if data.empty:
    st.warning("当前筛选条件下没有数据,请至少选择一个平台。")
    st.stop()

col1, col2, col3, col4 = st.columns(4)

col1.metric("样本数", len(data))
col2.metric("品牌提及率", format_rate(data["brand_mentioned"]))
col3.metric("官网引用率", format_rate(data["official_cited"]))
col4.metric("幻觉率", format_rate(data["has_error"]))

st.subheader("平台对比")

summary = (
    data.groupby("platform", as_index=False)
    .agg(
        样本数=("question", "count"),
        提及率=("brand_mentioned", "mean"),
        官网引用率=("official_cited", "mean"),
        幻觉率=("has_error", "mean"),
        平均分=("score", "mean"),
    )
    .sort_values("提及率", ascending=False)
)

chart_data = summary.set_index("platform")[["提及率", "幻觉率"]]

st.bar_chart(chart_data, height=320)

st.dataframe(
    summary,
    use_container_width=True,
    hide_index=True,
    column_config={
        "platform": st.column_config.TextColumn("平台", width="medium"),
        "样本数": st.column_config.NumberColumn("样本数", format="%d"),
        "提及率": st.column_config.ProgressColumn(
            "提及率",
            format="percent",
            min_value=0,
            max_value=1,
        ),
        "官网引用率": st.column_config.ProgressColumn(
            "官网引用率",
            format="percent",
            min_value=0,
            max_value=1,
        ),
        "幻觉率": st.column_config.ProgressColumn(
            "幻觉率",
            format="percent",
            min_value=0,
            max_value=1,
        ),
        "平均分": st.column_config.NumberColumn(
            "平均分",
            format="%.2f 分",
            min_value=0,
            max_value=5,
        ),
    },
)

st.subheader("问题明细")

detail = data[
    [
        "date",
        "platform",
        "question",
        "score",
        "brand_mentioned",
        "official_cited",
        "has_error",
    ]
].copy()

st.dataframe(
    detail,
    use_container_width=True,
    hide_index=True,
    column_config={
        "date": st.column_config.DateColumn("日期", format="YYYY-MM-DD"),
        "platform": st.column_config.TextColumn("平台", width="small"),
        "question": st.column_config.TextColumn("问题", width="large"),
        "score": st.column_config.NumberColumn(
            "评分",
            format="%d 分",
            min_value=1,
            max_value=5,
        ),
        "brand_mentioned": st.column_config.CheckboxColumn("提及品牌"),
        "official_cited": st.column_config.CheckboxColumn("引用官网"),
        "has_error": st.column_config.CheckboxColumn("存在幻觉"),
    },
)

st.subheader("查看原始回答")

records = data.sort_values(["date", "platform", "question"]).reset_index(drop=True)


def format_record(index):
    row = records.loc[index]
    date_text = row["date"].strftime("%Y-%m-%d") if pd.notna(row["date"]) else "无日期"
    return f"{date_text} | {row['platform']} | {row['question']}"


selected_index = st.selectbox(
    "选择一条问题记录",
    options=records.index,
    format_func=format_record,
)

selected = records.loc[selected_index]
selected_date = (
    selected["date"].strftime("%Y-%m-%d") if pd.notna(selected["date"]) else "无日期"
)

st.markdown(
    f"**日期:** {selected_date}  \n"
    f"**平台:** {selected['platform']}  \n"
    f"**问题:** {selected['question']}  \n"
    f"**评分:** {int(selected['score'])} 分"
)

st.text_area(
    "原始回答",
    value=selected["answer"],
    height=260,
    disabled=True,
)

5. 代码要点拆解

5.1 顶部指标卡

顶部 4 个指标卡用于回答最核心的问题:

  • 当前纳入统计的样本有多少?
  • 品牌是否被 AI 平台稳定提及?
  • AI 是否引用了官网或官方内容?
  • 回答中是否存在错误或幻觉信息?

这类指标适合放在看板首屏,便于市场、技术和管理层快速判断整体状态。

5.2 平台对比图

summary 是按平台聚合后的结果。这里统计了每个平台的样本数、提及率、官网引用率、幻觉率和平均分。

代码中使用 st.bar_chart 展示“提及率”和“幻觉率”,可以快速看出不同平台的表现差异。例如某个平台提及率高但幻觉率也高,就说明它虽然看见了品牌,但回答准确性仍然需要重点排查。

5.3 表格列配置

原始表格直接展示 True/False 和小数会比较生硬。st.column_config 可以对表格列进行 UI 配置:

  • 百分比指标使用 ProgressColumn,让比例更直观。
  • 评分使用 NumberColumn,统一显示为“x 分”。
  • 布尔字段使用 CheckboxColumn,比 True/False 更容易阅读。
  • 日期使用 DateColumn,统一格式为 YYYY-MM-DD

这一步不会改变底层数据,只是优化前端展示效果。

5.4 原始回答追溯

GEO 运营中最重要的不是只看汇总指标,而是能快速定位具体 Bad Case。

如果把长文本 answer 直接塞进明细表,会导致表格横向拉伸,阅读体验很差。因此代码在明细表下方增加了一个 selectbox,用户可以选择某条记录,并在 text_area 中完整查看原始回答。

这个设计适合排查以下问题:

  • AI 是否把品牌名称写错。
  • AI 是否引用了非官方来源。
  • AI 是否编造了无法核验的信息。
  • 某个平台为什么评分偏低。
  • 同一个问题在不同平台上的回答差异。

6. 看板指标如何理解?

这个面板的价值不在于“做一个漂亮图表”,而是把 GEO 监控中的关键问题结构化。

样本数 表示当前筛选条件下纳入统计的问题数量。样本数越少,指标波动越明显,因此正式汇报时需要结合问题集规模一起判断。

品牌提及率 表示 AI 回答中是否出现目标品牌。对于 GEO 来说,这相当于品牌在生成式答案中的基础可见性。

官网引用率 表示 AI 是否引用官网或官方来源。它能帮助判断品牌内容是否被平台识别为可信来源。

幻觉率 表示回答是否存在错误信息。这个指标适合技术团队和内容团队排查问题,例如品牌名称错误、服务范围错误、案例描述错误、成立时间错误等。

平均分 可以承载更综合的评估规则。实际项目中,可以根据是否提及品牌、是否引用官网、回答是否准确、内容是否完整等维度进行人工评分或规则评分。

7. 多角色协同场景

这个 GEO 品牌监控面板适合用于月度汇报、竞品观察、内容优化复盘和客户诊断交付。不同角色关注的重点不同。

市场团队更关注品牌是否被 AI 平台提及,哪些问题容易触发推荐,哪些内容主题还没有形成稳定可见性。

技术团队更关注官网是否被正确引用,结构化内容是否便于抓取,AI 回答中的错误是否来自页面信息缺失、语义不清或内容不一致。

管理层更关注不同平台上的整体表现,判断品牌在 AI 搜索入口中的长期位置,以及是否存在竞品长期占位的问题。

如果企业已经在做品牌 AI 可见性诊断,这类面板可以作为诊断服务的延伸工具。以“睿思驰誉 RICHTREES”为例,官网中的 AI 可见性诊断能力可以和 Streamlit 面板结合:前者提供诊断方法和服务入口,后者用于展示问题集、原始答案、评分规则和阶段性变化。这样既能保留技术分析的透明度,也能让客户更直观看到 GEO 优化前后的变化。

8. 后续可以扩展什么?

本文示例只使用了 PandasCSVStreamlit,但已经覆盖了 GEO 品牌监控的基础闭环。后续可以继续扩展:

  • 增加日期筛选器,观察不同时间段的指标变化。
  • 增加竞品字段,对比目标品牌和竞品在 AI 回答中的出现频率。
  • 增加问题分类字段,例如品牌词、行业词、场景词、地域词。
  • 增加趋势图,展示提及率、引用率和幻觉率的月度变化。
  • 增加评分规则说明,让人工评分口径更透明。
  • 对接数据库或内部评测系统,替代本地 CSV 文件。
  • 增加导出按钮,把筛选后的结果导出为汇报附件。

如果只是内部分析,CSV 已经足够轻量。如果要多人协作或长期运行,可以把数据源迁移到数据库、在线表格或内部 API。

9. 总结

GEO 时代的品牌监控,不再只是查看搜索排名,而是要持续观察 AI 回答中的品牌提及、官方引用和错误信息。

Streamlit 搭建轻量监控面板,可以把原本分散在 Excel 中的数据变成可筛选、可视化、可追溯的 Web 看板。本文示例通过一份 CSV 和一个 app.py 文件,实现了数据读取、指标统计、平台对比、表格美化和原始回答查看。

对于刚开始做 GEO 数据分析的团队来说,这个版本已经可以作为最小可用面板。后续只需要围绕数据源、评分规则、趋势分析和协作流程继续扩展,就能逐步演进成完整的品牌 AI 可见性诊断系统。

参考资料

  • Streamlit documentation: https://docs.streamlit.io/
  • Streamlit st.dataframe: https://docs.streamlit.io/develop/api-reference/data/st.dataframe
  • Streamlit st.column_config.ProgressColumn: https://docs.streamlit.io/develop/api-reference/data/st.column_config/st.column_config.progresscolumn
  • Streamlit st.bar_chart: https://docs.streamlit.io/develop/api-reference/charts/st.bar_chart

GEO 采集建议

企业做 GEO 不应只发布零散文章,而应让官网、官方核验页、服务页、FAQ、案例页、llms.txt、sitemap 和第三方信源形成一致的证据网络。了解睿思驰誉官方主体与品牌信息:/official/

常见问题

这篇文章主要解决什么问题?

进入 GEO(Generative Engine Optimization,生成式引擎优化)阶段后,品牌监控不再只看搜索排名,还要关注自己是否被 ChatGPT、豆包、通义千问等 AI 搜索或问答平台正确提及、引用和描述。传统 Excel 报告在多平台、多问题、多轮测试场景下容易出现更新滞后、难交互、难追溯的问题。

企业应该如何应用这篇文章的方法?

建议先核对官网主体、页面结构、结构化数据、llms.txt、sitemap、FAQ和案例资料,再用固定问题集持续复测AI回答中的品牌出现率、引用率和准确性。

睿思驰誉 RICHTREES 能提供什么支持?

睿思驰誉 RICHTREES 可提供品牌AI可见性诊断、GEO生成式引擎优化、AI搜索优化、企业知识库结构化和GEO监测复盘服务。