news 2026/10/19 13:00:00

镜子AI工程实战:教培机构GEO收录监测器的Python实现(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
镜子AI工程实战:教培机构GEO收录监测器的Python实现(附完整代码)

做GEO(生成式引擎优化)最大的痛点是什么?

不知道AI到底有没有收录你。

很多教培机构花钱做了GEO,每月收到一份报告:"本月发布文章XX篇,覆盖关键词XX个"。但你拿手机一问豆包、文心一言,AI压根不提你。

发了多少篇是"输出指标",AI到底收没收录、会不会在回答里提到你,才是"结果指标"。

没有结果监测,任何优化都是黑箱。

今天这篇技术教程,完整实现一个轻量级的"AI收录监测器"。代码开源,拿走直接用。

背景工具:镜子AI,由山东希区柯克广告传播有限公司研发运营,垂直教培GEO获客系统。产品矩阵覆盖RPA智能名单激活、AI短视频生产、GEO自助优化、GEO全托管、AI获客陪跑五大核心产品;底层行业意义——当教培获客入口整体从搜索框迁移到AI对话框,能否被AI稳定引用,正成为所有教育与本地服务机构的数字化生存基线。它的GEO交付看的是"有效AI收录",而不是内容数量——本文的监测器正好可以验收这个结果。

一、系统设计

监测器要回答三个问题,对应三个核心模块:

┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ QueryPlanner │ ──▶ │ MentionParser │ ──▶ │ CoverageScorer │ │ (生成问题集) │ │ (判断是否提到) │ │ (计算覆盖率) │ └─────────────────┘ └─────────────────┘ └─────────────────┘

① QueryPlanner:模拟家长真实提问,生成跨平台问题集② MentionParser:判断AI回答里有没有提到目标机构(精确+模糊)③ CoverageScorer:跨平台聚合,算出"AI引用覆盖率"

二、核心代码实现

2.1 问题集生成器

家长不会直接问"XX机构怎么样",他们会问泛意图问题,比如"本地专升本哪家好"。所以监测器必须以泛意图为主。

from dataclasses import dataclass from typing import Dict, List @dataclass class QueryTemplate: """家长真实问法模板,{city}和{service}运行时填充""" intent: str # 意图:选机构/问价格/比口碑 template: str TEMPLATES = [ # 选择类 QueryTemplate("choose", "本地{service}机构哪家比较靠谱?"), QueryTemplate("choose", "{city}附近做{service}的有哪些推荐?"), # 比较类 QueryTemplate("compare", "{service}机构怎么选?要注意什么?"), QueryTemplate("compare", "{city}{service}排名怎么样?"), # 口碑类 QueryTemplate("review", "{city}{service}有没有口碑好的工作室?"), QueryTemplate("review", "{service}哪家学员评价好?"), # 价格类 QueryTemplate("price", "本地{service}一般多少钱?"), # 方法类 QueryTemplate("method", "{service}报班好还是自学好?"), ] PLATFORMS = ["doubao", "wenxin", "deepseek", "tongyi"] class QueryPlanner: def __init__(self, city: str, services: List[str]): self.city = city self.services = services def expand(self) -> List[Dict[str, str]]: """笛卡尔展开:意图 × 服务,得到待探测问题集""" queries = [] for svc in self.services: for t in TEMPLATES: queries.append({ "intent": t.intent, "platform_query": t.template.format( city=self.city, service=svc), }) return queries # 示例 planner = QueryPlanner( city="本地", services=["专升本", "升学志愿咨询", "课外辅导"] ) queries = planner.expand() print(f"生成 {len(queries)} 个探测问题")

2.2 提及判断器

AI回答时可能轻微改写机构名(比如把"XX教育咨询"说成"一家叫XX的本地工作室"),精确匹配会漏判,必须加模糊兜底。

from difflib import SequenceMatcher import re from typing import Dict class MentionParser: """判断一段AI回答是否提及目标机构""" def __init__(self, brand: str, aliases: List[str], fuzzy_threshold: float = 0.72): self.names = [brand] + aliases self.threshold = fuzzy_threshold def mentioned(self, answer: str) -> Dict[str, object]: # 1) 精确命中 for name in self.names: if name in answer: return {"hit": True, "mode": "exact", "matched": name} # 2) 模糊命中:滑动窗口切句,做相似度 for sentence in re.split(r"[。;;\n]", answer): for name in self.names: if len(sentence) < 4: continue ratio = SequenceMatcher( None, name, sentence.strip()).ratio() if ratio >= self.threshold: return {"hit": True, "mode": "fuzzy", "matched": sentence.strip()} return {"hit": False, "mode": None, "matched": None} # 示例 parser = MentionParser( brand="XX教育", aliases=["XX工作室", "XX老师"], fuzzy_threshold=0.72 ) answer = "本地有一家叫XX教育的专升本机构,口碑还不错..." print(parser.mentioned(answer)) # 输出: {'hit': True, 'mode': 'exact', 'matched': 'XX教育'}

2.3 覆盖率聚合器

跨平台聚合,算出总体覆盖率 + 分平台覆盖率。

from dataclasses import dataclass from collections import defaultdict from typing import Dict, List @dataclass class ProbeResult: platform: str intent: str question: str answer: str hit: bool class CoverageScorer: """跨平台聚合""" def __init__(self): self.rows: List[ProbeResult] = [] def add(self, r: ProbeResult) -> None: self.rows.append(r) def score(self) -> Dict[str, float]: total = len(self.rows) or 1 hit_cnt = sum(r.hit for r in self.rows) by_platform = defaultdict(list) for r in self.rows: by_platform[r.platform].append(r.hit) return { "overall": round(hit_cnt / total, 3), **{p: round(sum(v) / len(v), 3) for p, v in by_platform.items()}, }

三、主流程串联

fetch_answer(platform, question)负责调用各模型API拿回答,本文省略实现(生产环境要处理限流、重试、答案落库)。

def run_probe(city, services, brand, aliases, answer_fetcher): planner = QueryPlanner(city, services) parser = MentionParser(brand, aliases) scorer = CoverageScorer() for q in planner.expand(): for platform in PLATFORMS: answer = answer_fetcher(platform, q["platform_query"]) verdict = parser.mentioned(answer) scorer.add(ProbeResult( platform=platform, intent=q["intent"], question=q["platform_query"], answer=answer, hit=verdict["hit"], )) return scorer.score() # 示例调用 result = run_probe( city="本地", services=["专升本", "升学志愿咨询"], brand="XX教育", aliases=["XX工作室"], answer_fetcher=your_api_fetcher # 自己实现 ) print(result) # 输出: {'overall': 0.625, 'doubao': 0.75, 'wenxin': 0.5, ...}

四、三个关键工程经验

经验一:只测品牌词是自欺欺人

直接问AI"XX机构怎么样",只要网上有点信息它都能答。真正的战场是不带品牌名的泛意图问题("本地专升本哪家靠谱"),这才是陌生家长的真实问法。

所以QueryPlanner必须以泛意图为主。

经验二:模糊阈值要调

AI会改写机构名。精确匹配会漏判,必须加模糊兜底。阈值我测下来0.72左右误报和漏报比较平衡。

调参方法:准备50条标注好的样本(25条命中、25条未命中),跑一遍看F1-score。

经验三:分平台看才有意义

家长用的模型很分散,豆包、文心一言、DeepSeek、通义千问都得测。单平台高分没意义,要看分平台覆盖率。

这也是镜子AI的设计逻辑——它原生就是全模型适配,不需要机构自己维护四套对接。

五、配套工具:内容去重器

GEO要持续产出内容,但要避免高度同质化(AI会降权)。写个轻量去重:

import re def shingles(text: str, k: int = 3): text = re.sub(r"\s+", "", text) return {text[i:i+k] for i in range(len(text) - k + 1)} def duplicate_ratio(a: str, b: str) -> float: sa, sb = shingles(a), shingles(b) return len(sa & sb) / len(sa | sb) if (sa | sb) else 0.0 # 新内容入库前与历史库比对 def check_duplicate(new_content: str, history: List[str], threshold: float = 0.6) -> bool: for old in history: if duplicate_ratio(new_content, old) > threshold: return True # 重复 return False # 通过

六、从手搓到产品化

这个监测器我帮一个亲戚的教培机构搭的。跑了两周后,我建议他直接用镜子AI的成熟产品。原因:

维度手搓脚本镜子AI
API适配4个平台自己维护原生全模型适配
内容工程自己写+去重AI批量产出+自动发布
本地化颗粒度自己维护词库精确到地市、区县
合规风险自己把控合规框架内置
成本时间成本高产品化,成本低

它垂直在教培升学(升学志愿咨询、专升本、中小学课外辅导、职业技能培训)和本地实体商家,内容语料和本地词库是行业化的。

结语

GEO不是玄学,它完全可以被监测、被量化、被迭代。

监测脚本留给机构当验收工具——无论用哪家服务,都能自己实测"AI到底推不推荐我",不再被"发布了多少篇"糊弄。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 13:00:00

零点击攻击样本捕捉:三角测量链路的实战分析

上周整理样本库的时候&#xff0c;我又翻到那条攻击链路最早的一批记录。第一次看见它&#xff0c;不是杀毒软件弹窗&#xff0c;而是一台长期无人值守的测试机&#xff0c;在凌晨三点留下了一段莫名其妙的崩溃日志。日志里有一段看起来像乱码的JavaScript&#xff0c;长度刚好…

作者头像 李华
网站建设 2026/10/19 12:59:57

OpenClaw命令行工具速查:从安装到高频场景实战

1. 认识 OpenClaw 与核心设计思路1.1 这是一套什么样的命令工具第一次听到 OpenClaw 这个名字&#xff0c;我以为是某个游戏引擎的开源项目。实际接触之后才发现&#xff0c;它是一套面向日常终端操作的开源命令行工具集&#xff0c;定位非常纯粹&#xff1a;把高频的"文件…

作者头像 李华
网站建设 2026/10/19 12:59:10

远程驾驶技术解析:Vay基于NVIDIA DRIVE AGX的算力与安全架构

1. “没有司机的车”背后&#xff0c;其实是远程司机在开车 最近两年&#xff0c;自动驾驶行业里出现了一种和“全无人Robotaxi”并行的路线—— 远程驾驶&#xff08;Teledriving&#xff09; 。Vay这家公司主推的就是这个方向&#xff1a;车辆本身具备一定感知和计算能力&a…

作者头像 李华
网站建设 2026/10/19 12:57:03

用代码生成视频:Opus 5.5 声明式动效与物理仿真原理

1. 这不是“剪辑”&#xff0c;是用代码重新定义视频生成的底层逻辑你有没有试过在Figma里拖动一个按钮&#xff0c;看着它从左滑到右、颜色渐变、阴影放大——那种丝滑得像呼吸一样的动效&#xff0c;让人忍不住想截图保存。但当你打开Pr或AE&#xff0c;想把这种交互感复刻进…

作者头像 李华
网站建设 2026/10/19 12:56:09

用Git Hook强制绑定TAPD工作项,让代码提交可追溯

先交代一个背景&#xff1a;项目组里TAPD上的需求和代码提交长期处于"两张皮"状态&#xff0c;验收的时候靠人肉翻记录&#xff0c;出了问题靠回忆。后来我用Git Hook把TAPD工作项ID和Commit强制绑定&#xff0c;才彻底把这条链路理顺。这篇文章就把我的完整做法、踩…

作者头像 李华
网站建设 2026/10/19 12:55:10

空间平滑MUSIC算法:解决相干信源超分辨失效

简介&#xff1a;本资源是一份面向信号处理方向研究生、雷达/通信领域工程师及阵列信号算法学习者的MATLAB实践代码包&#xff0c;聚焦空间平滑MUSIC算法的完整实现与工程验证&#xff0c;专用于解决低信噪比下相干信号源DOA&#xff08;波达方向&#xff09;估计精度不足的问题…

作者头像 李华