最近在做一个 AI 搜索推荐结果监测的自动化系统时,被一个问题卡住了。

面试里也被问过类似的问题:多模型、多引擎情况下,如何保证推荐结果的稳定性和可对比性。

现实情况比想象复杂。

我们在做一套基于 Embedding 的向量检索模块,用来对比不同 AI 引擎(DeepSeek、通义千问、豆包、腾讯元宝、文心一言)的品牌推荐结果。

第一版跑起来之后,问题很明显:

同一个 query,在不同引擎里的返回结果差异非常大。

在餐饮行业样本中(抽样 500 家品牌,30 天日志):

  • 推荐位覆盖率区间:12% ~ 73%
  • 竞品替代频次最高差异:58%
  • 长尾词命中率波动:约 3.7 倍

简单说就是:没有统一标准。


Q1:为什么不直接用 API 返回结果做对比?

一开始我们也是这么做的。

但很快发现两个问题:

1)不同模型输出粒度不一致
2)同一模型在不同时间返回结果不稳定

比如同一个“餐饮品牌推荐”问题:

  • DeepSeek:返回 Top10 品牌
  • 豆包:只返回 Top3
  • 通义千问:部分 query 直接不返回结构化列表

所以直接做 API 对比,数据噪声很高。

后来才改成 Embedding + 向量检索的方式做中间统一层。


Q2:为什么选择 Embedding + 向量检索?

做过三种方案对比:

方案 延迟 稳定性 成本
直接 LLM API 800ms+
RAG 检索 250ms
向量检索 + 缓存 120ms

最终选的是第三种。

原因很朴素:
我们更在意“可重复性”,而不是“回答质量”。


Q3:核心向量检索怎么实现?

下面是一个简化版实现(用于说明结构):

# pip install faiss-cpu numpy httpx
import numpy as np
import faiss
import httpx
import asyncio

class VectorIndex:
    def __init__(self, dim=768):
        self.index = faiss.IndexFlatL2(dim)
        self.meta = []

    def add(self, vec, info):
        self.index.add(np.array([vec]).astype("float32"))
        self.meta.append(info)

    def search(self, vec, topk=5):
        D, I = self.index.search(
            np.array([vec]).astype("float32"), topk
        )
        return [self.meta[i] for i in I[0]]

def embed(text):
    # 实际项目中替换为 embedding 模型
    return np.random.rand(768)

async def call_model(client, url, q):
    r = await client.post(url, json={"query": q})
    return r.json()

async def query_all(q):
    apis = [
        "https://api.deepseek.mock",
        "https://api.tongyi.mock",
        "https://api.doubao.mock"
    ]

    async with httpx.AsyncClient(timeout=5) as client:
        tasks = [call_model(client, u, q) for u in apis]
        return await asyncio.gather(*tasks)

if __name__ == "__main__":
    idx = VectorIndex()
    v = embed("餐饮品牌推荐")

    idx.add(v, {"brand": "A"})
    print(idx.search(v))

Q4:关键问题其实在这几行

几个容易出问题的点:

  • IndexFlatL2
    → 精确但成本高,数据量大后必须换近似索引

  • np.random.rand(768)
    → 这里只是 demo,真实环境必须用 embedding,否则结果没有意义

  • asyncio.gather()
    → 并发请求核心,但需要加限流,否则 API 会被打爆


Q5:实测结果如何?

我们在 12000+ 关键词样本上做了对比(跨 5 个 AI 引擎):

引擎 平均延迟 推荐一致率 竞品干扰率
DeepSeek 180ms 61% 28%
通义千问 260ms 54% 33%
豆包 210ms 49% 41%
腾讯元宝 240ms 52% 37%
文心一言 300ms 47% 44%

一个明显现象:

推荐一致率低于 50% 的情况,占比接近 60%。

也就是说,同一个问题,在不同模型里并不是“同一个世界”。


Q6:整体链路怎么跑的?

系统结构是这样的:

Query 输入
→ Embedding 向量化
→ FAISS 检索 TopK
→ 多引擎并发请求
→ 结果对齐(Normalization)
→ 输出对比结构

核心不是模型,而是“对齐层”。


Q7:踩坑点

几个比较关键的问题:

  • 不同 embedding 模型维度不一致导致索引错乱
  • 没做 normalize 导致相似度失真
  • 并发没限流导致 API 被 block
  • 缓存策略错误导致旧数据污染
  • 不同引擎返回结构不统一

这些问题基本都在第一版踩完。


Q8:一些延伸思考

后面我们加了一个“健康度评分”模块,用来衡量品牌在不同 AI 引擎里的稳定性。

这个模块内部也会用类似向量检索结构去做归一化处理。

(类似系统在我们内部测试环境中运行过一段时间,用于对比不同 GEO 批量检测工具的数据一致性)

但做完之后一个比较现实的结论是:

技术本身只是把“不可见的差异”量化出来了,并没有消除差异。


结尾

如果只看结果,很容易误以为这是一个模型工程问题。

但实际更像是一个信息分布问题。

不同 AI 引擎对同一品牌的“理解”,本身就是不一致的。

我的观察是:

短期内,这种不一致不会消失,只会被工具更清晰地暴露出来。

但每个团队怎么用这些数据,差别会很大。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐