从多引擎探测到优化闭环

发布时间:2026/6/29 18:40:56
从多引擎探测到优化闭环 传统 SEO 优化的是搜索引擎排名GEO 优化的是AI 大模型在回答用户问题时是否提及、如何评价你的品牌。正常用户与智能体的对话 VS GEO 监控维度对话GEO 监控目标准确回答用户问题探测第三方模型的品牌曝光模型单一可控模型通义、DeepSeek、豆包、混元、Kimi、智谱等多引擎提示词业务导向、可注入知识库中性助手避免诱导偏向输出自然语言回复结构化指标提及率、排名、态度、竞品共现后续动作会话结束诊断 → 内容草稿 → 发布向量库 → 基线对比2. 整体架构┌─────────────────────────────────────────────────────────────────┐ │ 管理端 │ │ 数据看板 │ 探测任务 │ 引擎管理 │ 品牌档案 │ 诊断报告 │ 内容草稿 │ └────────────────────────────┬────────────────────────────────────┘ │ REST /api/v1/geo/* ┌────────────────────────────▼────────────────────────────────────┐ │ GeoEngineRunner调度核心 │ │ 加载任务 → 遍历品牌×问题×引擎 → 采样探测 → 分析聚合 → 落库 │ └──┬──────────┬──────────┬──────────┬──────────┬─────────────────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ probe analyzer metrics diagnoser alert (探测) (分析) (指标) (诊断) (飞书) │ │ ▼ ▼ provider_registry content_generator create_geo_llm publisher → knowledge_document (Chroma)2.1 数据模型关系一次完整的 GEO 业务链路围绕以下核心表展开geo_engines探测引擎配置厂商、model_code、API Key 环境变量名geo_tasks探测任务品牌词、竞品、问题模板、引擎列表、采样次数、告警配置、基线 Rungeo_runs每次执行记录手动 / 定时触发geo_snapshots单次探测快照问题、回答、分析结果、提及指标geo_diagnosesLLM 生成的诊断报告geo_brand_profiles品牌档案定位、差异化、事实边界geo_content_drafts优化内容草稿geo_question_templates场景问题库3. 核心执行流程3.1 流程总览飞书 WebhookGeoDiagnoserMySQLGeoAnalyzer目标大模型probe_engineGeoEngineRunnerAPScheduler飞书 WebhookGeoDiagnoserMySQLGeoAnalyzer目标大模型probe_engineGeoEngineRunnerAPSchedulerloop[sample_count 次采样]loop[品牌 × 问题 × 引擎]run_due_geo_tasks()创建 GeoRun标记 is_runningprobe_engine(engine, prompt)中性 system 用户问题原始回答ProbeResultanalyze(brand, answer, competitors)结构化 JSONaggregate_samples() 多数投票写入 GeoSnapshot更新 Run 状态未提及/负面推荐告警schedule_diagnosis(run_id) 后台任务诊断摘要可选基线回归告警可选3.2 调度入口GEO 任务由 APScheduler 周期性触发# backend/app/core/scheduler/__init__.py scheduler.add_job(_geo_tasks_job, interval, minutes5, idgeo_tasks_runner) async def _geo_tasks_job(): from app.core.geo.engine import run_due_geo_tasks await run_due_geo_tasks()run_due_geo_tasks()会清理超过 60 分钟仍处于running的僵尸 Run查询statusactive、未在运行、且next_run_at now的任务逐个调用GeoEngineRunner.run_task(db, task_id, triggerschedule)手动执行走 APIPOST /api/v1/geo/tasks/{task_id}/run通过asyncio.create_task在后台跑同一套run_task逻辑避免阻塞 HTTP 响应。3.3 三层嵌套循环品牌 × 问题 × 引擎GeoEngineRunner.run_task是整个模块的「心脏」。其核心逻辑可以概括为# backend/app/core/geo/engine.py简化 for brand in brands: for item in prompt_items: prompt item[template].replace({keyword}, brand) for engine in engines: sample_analyses [] for sample_idx in range(sample_count): probe_result await probe_engine(engine, prompt) analysis await self.analyzer.analyze(brand, probe_result.answer, competitors) sample_analyses.append(analysis) aggregated self.analyzer.aggregate_samples(sample_analyses) snapshot GeoSnapshot(..., analysisaggregated, ...) db.add(snapshot) await db.commit() # 逐条提交支持中途取消几个设计要点问题来源任务可配置question_sourceinline内联模板或library场景问题库后者支持按recommend/compare/risk等分类统计采样次数默认 2 次通过多数投票降低 LLM 随机性逐条 commit每写入一条 snapshot 就提交配合cancel_requested标志实现优雅停止引擎可用性检查执行前过滤未配置 API Key 或已禁用的引擎默认问题模板示例DEFAULT_PROMPT_TEMPLATES [ {keyword}怎么样, {keyword}靠谱吗, 推荐几个{keyword}相关的平台, 网上对{keyword}的评价如何, ]4. 多引擎探测统一 OpenAI 兼容层4.1 厂商注册表所有支持的厂商集中在provider_registry.py统一管理base_url、环境变量名与官方文档链接PROVIDER_DEFAULTS { dashscope: { name: 通义千问, base_url: https://dashscope.aliyuncs.com/compatible-mode/v1, api_key_env: geo_dashscope_api_key, }, deepseek: { name: DeepSeek, base_url: https://api.deepseek.com, default_model: deepseek-v4-flash, }, doubao: { name: 豆包火山方舟, base_url: https://ark.cn-beijing.volces.com/api/v3, }, # hunyuan, moonshot, zhipu ... }新增厂商的 SOP查厂商 OpenAI 兼容文档确认base_url与model字段含义在PROVIDER_DEFAULTS增加预设配置.env中对应的GEO_*_API_KEY管理端「引擎管理」新增记录4.2 探测 LLMcreate_geo_llm专门为 GEO 探测创建 LangChain 实例# backend/app/core/geo/llm.py def create_geo_llm(engine: GeoEngine) - ChatOpenAI: defaults get_provider_defaults(engine.provider) or {} base_url engine.base_url or defaults.get(base_url, ) api_key resolve_api_key(settings, engine.api_key_env) kwargs { api_key: api_key, base_url: base_url, model: engine.model_code, temperature: engine.temperature, max_tokens: 2048, timeout: settings.geo_probe_timeout_seconds, } if engine.extra_body: kwargs[extra_body] engine.extra_body # 如混元搜索增强 return ChatOpenAI(**kwargs)分析器使用更便宜的模型默认qwen-turbo通过GEO_ANALYZER_PROVIDER/GEO_ANALYZER_MODEL单独配置。4.3 中性探测提示词探测时必须避免「诱导模型推荐本品牌」因此probe.py使用固定中性 system promptNEUTRAL_SYSTEM_PROMPT ( 你是一个乐于助人的助手。请根据你的知识如实回答用户问题 可以列举多个选项并说明各自特点不要刻意回避或偏向任何品牌。 ) async def probe_engine(engine: GeoEngine, prompt: str) - ProbeResult: llm create_geo_llm(engine) start time.perf_counter() response await llm.ainvoke([ SystemMessage(contentNEUTRAL_SYSTEM_PROMPT), HumanMessage(contentprompt), ]) elapsed int((time.perf_counter() - start) * 1000) return ProbeResult(promptprompt, answercontent, latency_mselapsed)这是 GEO 测量可信度的关键我们测的是模型在自然状态下的品牌认知而不是 prompt 工程后的结果。5. LLM 结构化分析器原始回答是非结构化文本需要二次 LLM 调用提取指标。GeoAnalyzer要求分析模型返回严格 JSON{ brand_mentioned: true, mention_rank: 2, recommendation: recommend, competitors_mentioned: [竞品A], citation_urls: [https://...], sentiment: {category: positive, score: 0.6}, summary: 一句话摘要, misunderstanding: false, entity_clarity: clear }5.1 多次采样聚合当sample_count 1时使用多数投票策略字段聚合规则brand_mentioned超过半数采样为 true 则 truemention_rank取有排名采样的算术平均并四舍五入recommendation票数最多的态度competitors_mentioned各采样并集misunderstanding任一为 true 则 true这种设计在成本与稳定性之间取得平衡比单次探测更可靠又比大量采样更经济。5.2 容错分析器对 JSON 解析失败、LLM 调用异常均有降级处理返回默认的not_mentioned结构避免单条失败拖垮整次 Run。6. 指标聚合与数据看板compute_run_metrics将一批 snapshot 聚合为 Run 级指标供诊断、看板、基线对比复用