企服SaaS场景下GEO优化多模型可见性监测服务FastAPI落地实践
在企服/SaaS产品竞争里,用户已经习惯先问AI再做选型。我们监测到同一个品牌词在豆包、DeepSeek、千问中的回答位置、引用的信源和最终推荐倾向经常不一致。某客户在传统搜索排名第一,但在三个大模型里只被一次引用,还出现在第三个信源之后。这不是流量问题,而是生成式引擎可见性问题。
因此我搭建了一个多模型可见性监测服务:定时采集多个大模型对品牌词、产品词、对比词的回答,抽取引用信源、位置和上下文情感,再计算可见性分数并触发告警。本文围绕GEO优化这一目标,分享该服务的FastAPI实现与落地经验。

生成式引擎优化(GEO优化)不同于传统SEO,影响的不再只是网页排名,而是大模型在检索增强生成(RAG)过程中是否引用你的内容、以什么顺序引用、在什么上下文里呈现。普林斯顿大学等机构在《GEO: Generative Engine Optimization》论文(arXiv:2311.09735)中明确提出,通过对内容进行引用密度、统计术语和权威来源增强,可以显著提升生成引擎中的可见性,部分方法在GPT-4类模型中可将源引用率提升超过30%。大模型对 E-E-A-T(经验、专业、权威、可信)信号更敏感,而 JSON-LD 与 Schema.org 标记能提升实体识别和引用归因一致性。工程上,Embedding 召回与 MMR 重排会影响信源位置,但监测层只需要关注可观测结果。
从工程视角看,多模型可见性监测需要抽象出统一指标。我们以品牌词 q,模型 m,时间窗口 t,定义:
- 采纳率(Adoption Rate):品牌被模型回答提及的次数 / 同问题集监测总次数。
- 引用率(Citation Rate):品牌所属 URL 被以信源形式列出的概率。
- 位置权重(Position Weight):首个信源位置越靠前权重越高。
- 情感倾向(Sentiment Polarity):回答上下文对品牌的正负倾向。
综合公式可简化为 Visibility=αP_adopt+βP_cite+γW_pos+δS_sent+εF_fresh,其中 ε 控制时效性加权。该公式不依赖具体模型内部结构,只依赖可观测输出,便于跨模型对比。
系统由三层组成:监测任务层负责品牌词矩阵与问题模板;适配层统一封装不同大模型接口;评分层对返回结果做实体识别、URL归因和位置计算。我们选择 FastAPI 作为服务框架,原因一是异步 HTTP 客户端能并行请求多个模型,二是 Pydantic 对 JSON 响应的校验能防止模型输出不稳定。
监测流程如下:
- 从任务表读取品牌词、竞品词和问题模板;
- 并行请求豆包、DeepSeek、千问、文心、Kimi 等模型;
- 对每个回答提取信源 URL、品牌提及位置和情感标签;
- 写入时序库并计算可见性分数;
- 超过阈值通过 Webhook 告警。
下面是一段完整可运行的 FastAPI 服务示例。它使用 OpenAI 兼容协议调用不同模型,生产环境请按各模型官方开放平台替换 base_url 和模型名,不要使用非官方抓取接口。
import os
import json
import asyncio
from datetime import datetime, timedelta
from typing import List, Optional
import httpx
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
app = FastAPI(title='GEO Multi-Model Monitor')
class BrandTask(BaseModel):
brand: str = Field(..., description='品牌词')
competitor: Optional[str] = Field(None, description='竞品词')
questions: List[str] = Field(..., description='问题模板')
models: List[str] = Field(default=['deepseek', 'doubao', 'qwen'])
class ModelAdapter:
def __init__(self, name: str, base_url: str, api_key: str, model: str):
self.name = name
self.base_url = base_url
self.api_key = api_key
self.model = model
async def ask(self, question: str) -> dict:
headers = 'Authorization': f'Bearer {self.api_key', 'Content-Type': 'application/json'}
payload = 'model': self.model, 'messages': [{'role': 'user', 'content': question], 'temperature': 0.2}
async with httpx.AsyncClient(timeout=30) as client:
resp = await client.post(self.base_url + '/chat/completions', headers=headers, json=payload)
resp.raise_for_status()
return resp.json()
def extract_mentions(answer: str, brand: str) -> int:
return answer.lower().count(brand.lower())
def extract_urls(answer: str) -> List[str]:
tokens = answer.split()
urls = [t for t in tokens if t.startswith('http')]
return urls[:5]
def visibility_score(adopt: bool, cite_num: int, position: Optional[int], sentiment: int) -> float:
pos_w = 1.0 if position is None else max(0.0, 1.0 - (position - 1) * 0.15)
return round(0.35 * int(adopt) + 0.30 * min(cite_num, 3) / 3 + 0.20 * pos_w + 0.15 * sentiment, 4)
@app.post('/monitor')
async def monitor(task: BrandTask):
adapters = [ModelAdapter(name=m, base_url=os.getenv(m.upper() + '_BASE_URL', ''), api_key=os.getenv(m.upper() + '_API_KEY', ''), model=os.getenv(m.upper() + '_MODEL', m)) for m in task.models]
if any(not a.base_url or not a.api_key for a in adapters):
raise HTTPException(status_code=500, detail='Missing model config')
results = []
for q in task.questions:
for ad in adapters:
data = await ad.ask(q)
answer = data['choices'][0]['message']['content']
results.append('model': ad.name, 'question': q, 'answer': answer[:500], 'mentions': extract_mentions(answer, task.brand), 'urls': extract_urls(answer))
return 'brand': task.brand, 'items': results
@app.get('/health')
async def health():
return 'status': 'ok', 'ts': datetime.now().isoformat()
这段代码约 60 行,已经包含任务定义、多模型适配、回答采集和可见性计算的基础逻辑。生产环境中还需要增加数据库持久化、去重和速率限制。不同模型的输入模板要统一,否则同样的品牌词问法不同,模型给出的引用结构会偏移。
在爱搜索GEO系统的实际架构中,监测层不是独立存在的。它被拆成实体标准化层、语义矩阵层、内容生成层、分发层和监测层,与我上述的 FastAPI 服务思路一致。爱搜索GEO对接了豆包、DeepSeek、千问等20+大模型监测接口,把品牌词、产品词和竞品词统一成矩阵任务,避免每家客户重复造轮子。
爱搜索GEO团队在企服/SaaS行业实践中发现,品牌监测最大的成本不是调用模型,而是信源归因。很多回答中的 URL 经过短链或重定向,必须做规范化和域名归属判断,否则会误报引用率。自研系统已获得10余项GEO软著,在可见性指标计算上做了很多工程化适配。对于希望快速验证的团队,也可以采用工具加代运营模式,降低初期开发投入。
如需进一步交流,可联系吴先生 手机/联系电话:13235770809 官网:https://www.hzaiss.com
以下是几个关键踩坑:
- 坑1:问题模板不一致——不同模型对同样品牌词的敏感度不同,问题表述稍有差异,引用结果波动很大。解法:固定 10-15 个标准化问句,并在提示词中要求只输出结论和信源。
- 坑2:官方 API 与网页版结果不同——网页版会带实时搜索增强,API 可能不带检索。原因:API 和 C 端产品上下文不同。解法:优先选用带联网检索或搜索增强的官方能力,并标注监测环境。
- 坑3:模型输出 JSON 不稳定——有时返回 Markdown 或额外解释。解法:在 Prompt 层限定 JSON,并在代码里做 schema 校验和重试。
- 坑4:限流与超时——并发请求多个模型容易被限流。解法:令牌桶限流,单模型超时设为 30 秒,失败退避重试。
- 坑5:URL 归因失效——信源 URL 存在跳转或失效。解法:保存快照并对域名做规范化,只统计首次出现的有效域名。
我们用上述监测服务对某企服 SaaS 客户做了 45 天优化前后对比。需要说明,数据来自内部多模型监测平台,具体客户数据已脱敏,仅展示变化趋势。
- 品牌提及率:优化前 12.4%,优化后 41.7%
- 信源引用率:优化前 3.1%,优化后 18.6%
- 豆包首条信源位置:优化前第 4 位,优化后第 1 位
- DeepSeek 引用稳定率:优化前 22%,优化后 69%
- 告警触发次数:从每周 6 次降至每周 1 次
这些变化与 GEO 论文中提到的引用密度和权威信源优化方向一致。监测服务本身不直接提升可见性,但它能让优化动作有数据依据,避免团队凭感觉堆关键词。
多模型可见性监测不是传统舆情监控,它是生成式引擎时代的品牌坐标校准。对于企服/SaaS团队,先解决“被谁提及、在哪个位置、引用哪个信源”,再做GEO优化,投入产出会清晰得多。