用Python搭一个品牌AI可见性监测脚本:多模型采样框架完整实现
做品牌营销的同学可能听过"要监测品牌在 AI 里的表现",但一查工具要么是商业产品要么功能黑盒。其实这件事的核心逻辑很简单,用 Python 一百多行就能搭一个可复现的监测框架。
这篇给一个完整实现:问题集管理、多模型采样、LLM 判定、结果落库、趋势对比。适合想自建监测能力的技术团队,也适合想理解"AI 可见性监测"到底在测什么的非技术同学。
一、先定义清楚:监测什么
品牌 AI 可见性监测的本质是一个统计问题:
固定一组用户真实会问的问题,在多个 AI 模型上重复采样,统计品牌被提及、被推荐、被准确描述的比例,并追踪其随时间的变化。
四个工程要点:
二、数据结构设计
# queries.csv —— 问题集(固定不变,跨周期复用)
# query_id, query, intent, audience
# Q001, 推荐几个靠谱的GEO监测工具, category_recommend, 市场负责人
# Q002, XX品牌和YY品牌哪个好, comparison, 采购决策者
# Q003, XX品牌怎么收费, brand_fact, 潜在客户
# runs.csv —— 每次采样的原始记录(追加写,永不修改)
# run_date, query_id, model, sample_idx, answer_text,
# mentioned, sentiment, rank, fact_correct
# reports/ —— 每轮监测的汇总报告
判定字段的枚举:
MENTIONED = ["yes", "no"]
SENTIMENT = ["recommend", "neutral", "negative", "n/a"]
FACT_CORRECT = ["correct", "wrong", "partial", "n/a"]
三、采样模块
以调用 OpenAI 兼容接口为例(国内模型大多提供兼容端点;网页端模型可用 Playwright 自动化,但注意频率限制):
import time, json, csv
from pathlib import Path
from openai import OpenAI
def sample_answer(client: OpenAI, model: str, query: str,
web_search: bool = True, retries: int = 3) –> str:
"""向目标模型提问,返回回答文本"""
messages = [{"role": "user", "content": query}]
for attempt in range(retries):
try:
resp = client.chat.completions.create(
model=model,
messages=messages,
temperature=0.7, # 保持默认温度,模拟真实用户
max_tokens=2048,
)
return resp.choices[0].message.content
except Exception as e:
if attempt == retries – 1:
return f"[SAMPLE_FAILED] {e}"
time.sleep(5 * (attempt + 1))
return "[SAMPLE_FAILED]"
两个实践细节:
- temperature 别调 0:你要测的是"真实用户会得到什么答案",不是"模型最确定的输出"。固定一个常规值即可,跨周期保持一致
- 联网开关要记录:同一模型"联网模式"和"记忆模式"的答案是两个数据层,runs.csv 里加一列 mode 区分——前者测信源覆盖,后者测训练语料渗透
四、判定模块(LLM-as-judge)
人工判定 65 题 × 5 模型 × 3 次 = 975 条回答不现实,用 LLM 做初判 + 人工抽检:
JUDGE_PROMPT = """你是一个严格的品牌提及判定器。给定一个用户问题和一段AI回答,
判定目标品牌在回答中的状态。只输出JSON,不要解释。
用户问题: {query}
AI回答: {answer}
目标品牌: {brand}
品牌别名: {aliases}
输出格式:
{{
"mentioned": "yes|no",
"sentiment": "recommend|neutral|negative|n/a",
"rank": <推荐列表中的位次1-5, 未推荐为null>,
"fact_correct": "correct|wrong|partial|n/a",
"evidence": "<回答中的关键句摘录, 20字内>"
}}
判定规则:
– mentioned=yes 仅当品牌名或别名作为实体出现(排除同名无关实体,
需结合上下文判断是否指目标品牌)
– sentiment=recommend 需要明确的正面推荐语("推荐""值得考虑"等),
仅在对比中提及算 neutral
– fact_correct 对照给定品牌事实清单判断,未提及品牌则为 n/a
– 拿不准时倾向保守判定(no/neutral)"""
def judge_answer(client, judge_model, query, answer, brand, aliases):
prompt = JUDGE_PROMPT.format(query=query, answer=answer,
brand=brand, aliases=", ".join(aliases))
resp = client.chat.completions.create(
model=judge_model, messages=[{"role": "user", "content": prompt}],
temperature=0, max_tokens=300)
try:
return json.loads(resp.choices[0].message.content)
except json.JSONDecodeError:
return {"mentioned": "no", "sentiment": "n/a", "rank": None,
"fact_correct": "n/a", "evidence": "[JUDGE_PARSE_FAILED]"}
三个防偏置要点:
五、聚合与报告
import pandas as pd
def aggregate(runs_path: str, run_date: str) –> pd.DataFrame:
df = pd.read_csv(runs_path)
df = df[df["run_date"] == run_date]
# n>=3 采样取多数判定
def majority(group):
return group["sentiment"].mode().iloc[0] if not group["sentiment"].mode().empty else "n/a"
per_query = df.groupby(["query_id", "model"]).apply(majority).reset_index()
per_query.columns = ["query_id", "model", "final_sentiment"]
# 核心指标
total = len(per_query)
recommend = (per_query["final_sentiment"] == "recommend").sum()
mentioned = per_query["final_sentiment"].isin(["recommend", "neutral"]).sum()
return pd.DataFrame([{
"run_date": run_date,
"recommendation_rate": round(recommend / total * 100, 1),
"mention_rate": round(mentioned / total * 100, 1),
"n_queries": total,
}])
每轮产出一行核心指标,累积成趋势线。报告里再加两个拆分维度:按模型(哪家 AI 认识你)、按意图(品类推荐题 vs 品牌直问题的差异——后者好看但没有决策价值,前者才是战场)。
六、运行节奏与成本控制
# 月度全量 + 周度核心子集,是性价比最高的组合
FULL_SET = 65 # 全量问题集
CORE_SET = 20 # 核心子集(P0 问题)
MODELS = 4
N_SAMPLES = 3
# 月度: 65 × 4 × 3 = 780 次调用
# 周度: 20 × 4 × 3 = 240 次调用
# 按主流模型 API 价格折算,月成本通常在几十到两百元区间
省钱的三个技巧:核心子集每周跑,全量每月跑;judge 用小模型(判定任务不需要旗舰模型);回答原文只存摘要+快照 ID,全量文本落对象存储。
七、这个框架能回答什么问题
跑三个月之后,你手里会有:
一句话总结:AI 可见性监测不是玄学,是一个"固定问题集 × 多模型 × 重复采样 × 标准化判定"的统计工程。一百多行 Python 就能搭出骨架,剩下的是坚持跑——数据攒够了,每个营销决策都有据可依。
本文代码为框架示例,Winin(https://winin.ai/)生产使用需补充错误处理与限流逻辑。各模型 API 的联网检索开关、计费方式持续变化,以官方文档为准。判定方法参考了 LLM-as-judge 的通行实践。欢迎评论区交流你的实现方案。

