我做了一个 GEO 工具,前后折腾了近半个月,1 个人,从立项到 81MB NSIS 安装包出包。
跑通之后第一次 monitor:6 个 AI 引擎 1024 次查询,86 次提到我——跨引擎 AI 提及率 8.32%。
这个数现在看不算高。但我第一次跑的时候是 0%。部署内容、优化结构、跑通 6 引擎监测这一套跑下来,从 0 到 8.32% 的过程,踩过的坑比代码多。
我把 30 天的完整过程整理成分节内容放在最后,本篇文章是骨架导览。
什么是 GEO
一句话:让 AI 在回答里提到你。
以前做 SEO,是让百度谷歌搜得到你。现在大家买东西前不打开百度了——直接问豆包、问 Kimi。AI 答完就完事,你网站连出场机会都没有。
GEO(Generative Engine Optimization)就是让 AI 引擎在回答用户问题时,愿意把你的网站 / 品牌作为引用源写进答案。
国内外都已经有人接单做这个。工具侧目前最完整的方案是 Otterly.AI / Profound 这类,但都不接国内 6 引擎(豆包、DeepSeek、通义、文心、Kimi、腾讯元宝),所以我自己写了一个。
工具的技术骨架
整个工具分四层:
下面分别讲每层做什么、怎么搭。
第一层:Tauri 桌面端壳
为什么选 Tauri 不选 Electron:Tauri 包大小只有 81MB(Electron 通常 200MB+),启动 < 1 秒,内存 30-50MB,且复用系统 WebView2(用户已经装了 Edge 就有)。
桌面端做的是sidecar 模式——Tauri 主进程启动后,自动拉起 backend (Python exe) 和 frontend (Next standalone),分别监听 :8000 和 :3001,然后 Tauri 窗口加载 http://localhost:3001。
Sidecar 启动代码大约 100 行 Rust,核心逻辑:
踩坑提示:sidecar 启动失败时 Tauri 窗口会显示"localhost 拒绝连接"——但用户不知道为什么。要给一个错误兜底 UI。
第二层:Next.js 前端
8 大模块:
关键技术决策:
output: "standalone": 让 Next.js 打包出一个 86MB 的自包含 Node 服务(不用next start全套)- 5 套主题用 CSS 变量切换:
data-theme="midnight"改一组 CSS 变量,不重载 - 客户端组件必须抽离:
useState/useEffect必须在"use client"文件里,server component 里用 hook 会编译失败 - 跨页 deep-link:
tools生成结果 →content预填表单,靠sessionStorage传值
踩坑提示:SWC 编译报错行号不可信——报 line 100,实际错在 line 50,类型不匹配引发。保持数组对象类型一致。
第三层:Python FastAPI 后端
为什么 Python:爬虫、内容改写、SEO 审计都是 Python 生态,重写不划算。
后端分 4 块:
- API 路由(
/api/clients/*、 /api/monitors/*、/api/tools/*) - 服务层(monitor_service、analytics、automation)
- LLM 适配层(每个引擎一个文件,统一接口)
- 数据库(SQLite + SQLAlchemy + Alembic)
6 引擎的接入用可插拔设计:
没配 API key 就用 ollama 本地默认(qwen3.5:4b),零成本跑通。要切换 6 引擎,只在 .env 里加 key。
数据库用 SQLite 单文件,跟用户电脑走。dogfood 阶段 42 篇文章 + 几万个 mention 完全够用,不需要 PostgreSQL。
踩坑提示:Python 的 tz-aware vs tz-naive 是经典坑——datetime.utcnow() 是 naive,datetime.now() + DB 存的是 aware,比较前必须 replace(tzinfo=None)。
第四层:6 引擎 LLM 集成
每个引擎有自己 API 格式,但做 3 件事:
-
接受关键词 + 品牌名 -
真实调用引擎搜索 -
解析回答里是否提到品牌
比如 ollama 本地:
豆包走 OpenAI 兼容 API,本质是同样的 chat completion。
判断"是否提到" 有两种策略:
-
简单匹配: if brand in response_text -
LLM 判定:让另一个 LLM 读回答 + 品牌名 + 判定结果
我用的是混合——简单匹配 + LLM 二判。LLM 输出的"判定"比较准,但慢。
6 引擎分布(我跑的真实数据):
-
minimax 内置兜底:256 次命中 -
ollama 本地:228 次 -
dashscope / deepseek / hunyuan:各 150 次左右 -
商业 4 引擎(豆包/Kimi/文心/腾讯元宝)接口 key
第五层:6 个白帽工具
/tools 页面提供 6 个工具,每个 3 秒内出可验证结果:
每个工具统一模式:
跨工具工作流:
这是 GEO 工具的"价值放大器"——单点工具 + 工作流 = 真实业务闭环。
打包:从 0 到 81MB 安装包
最后讲打包——这是最折腾的一步。
后端打包(PyInstaller frozen exe 46MB):
pyinstaller.spec 关键配置——datas 必须用绝对路径:
这里我踩过后才暴露的坑——spec 用相对路径时,PyInstaller 是相对 cwd 而不是 spec 位置解析。第一次打包跑通,30 天后重打就报
alembic.ini not found,因为 cwd 换了。。
NSIS 安装包(最终 81MB):
Tauri bundler 要下载 NSIS 工具(nsis-3.11.zip + nsis_tauri_utils.dll),GitHub Releases 在国内不稳。我的解法:
本地起一个 mirror server,所有路径都返回正确的文件,tauri-bundler 完全不知道。dll 用国内镜像 ghfast.top 下载。
junction + glob 不跟随:binaries/node 是 junction(指向真实目录),tauri 的 glob ** 不跟随 symlink——直接报 path not found。解法是 robocopy 复制真实目录 + 用目录映射代替 ** glob。
真实 dogfood 数据
跑通工具后,拿自己新建的网站当小白鼠。
绝对 +0.31pp,相对 +3.9%。
这中间有个坑值得讲——我第一次跑出 19.5% 提及率时差点拿出去吹。后来发现 19.5% 是单引擎(minimax)视角,跨 6 引擎平均只有 8.32%。
教训:跨引擎平均比单引擎数字更接近真实市场。别拿"最好看的数字"说话。
工具能跑、6 引擎全跑通、81MB 安装包出来。还在用自己的网站dogfooding, 能否变现要看后续真实数据情况,这是我现在面对的现实。
但工具是入口,不是终点。下一步:给 5 个潜在客户做GEO 体检,看谁愿意继续。
课程 9 集目录
全课程 9.4 万字,每集含:
-
我为什么这么做 -
我做错了哪些决策 -
真实代码片段(可直接复制) -
我现在会怎么改

