返回架构笔记
Arch Day 72

Arch Day 72: 搜索与推荐系统

Arch Day 72: 搜索与推荐系统

2026-06-10
第三阶段 - 零售域深度
电商搜索引擎推荐系统向量搜索RAGAI

日期: 2026-06-10 (Day 72) 阶段: 第三阶段 - 零售域深度 标签: #电商 #搜索引擎 #推荐系统 #向量搜索 #RAG #AI


核心概念

一句话定义

搜索系统帮用户"找到想要的"(明确意图 → 精准匹配),推荐系统帮用户"发现可能想要的"(模糊意图 → 兴趣挖掘)——两者在AI时代正在深度融合,共同构成电商的"流量分发引擎"。

为什么关注

据2025年行业数据,采用AI搜索的电商平台转化率提升最高可达43%(Netguru 2026 Report)。Elasticsearch虽然仍是电商搜索的主流选择(72%的全球POS系统使用云架构),但2025年之后,搜索需求已经进化到需要语义理解、个性化、混合检索(关键词+向量)和实时适应能力——这些都是传统Elasticsearch原生不具备的。推荐系统方面,基于RAG(Retrieval-Augmented Generation)的LLM推荐正在成为新范式。

误区与反模式

误区现实
"搜索=关键词匹配"现代搜索是语义理解+向量召回+多路融合
"推荐=协同过滤"深度学习+实时特征+多目标已成标配
"搜索和推荐是独立系统"底层架构正在融合(统一向量空间+统一排序模型)
"模型越复杂效果越好"工程优化(特征延迟/缓存/降级)往往比模型改进收益更大
"A/B测试只关注点击率"需要关注长期指标(LTV/多样性/新奇性)

知识点详解

一、搜索引擎架构

1.1 全链路架构

用户输入 "红色连衣裙 夏天"
       │
       ▼
 ┌──────────┐
 │ Query理解 │ ← NLP/LLM
 │ 意图识别   │   分词: "红色" "连衣裙" "夏天"
 │ Query改写  │   改写: +夏装 +女装
 │ 实体识别   │   实体: 颜色=红色, 品类=连衣裙, 季节=夏
 └─────┬────┘
       │
       ▼
 ┌──────────┐
 │ 召回层    │ ← 多路召回
 │ 关键词召回 │   倒排索引: ES/Solr
 │ 向量召回   │   ANN检索: HNSW/FAISS
 │ 类目召回   │   品类树检索
 │ 个性化召回 │   用户画像相似商品
 └─────┬────┘
       │ 候选集(1000-10000)
       ▼
 ┌──────────┐
 │ 粗排层    │ ← 轻量模型
 │ 双塔模型   │   快速打分,截断到Top500
 └─────┬────┘
       │ 候选集(300-500)
       ▼
 ┌──────────┐
 │ 精排层    │ ← 复杂模型
 │ Cross-Attn│   交叉注意力精细打分
 │ 多目标     │   点击率/转化率/GMV
 └─────┬────┘
       │ 排序后(50-100)
       ▼
 ┌──────────┐
 │ 重排层    │ ← 业务规则
 │ 多样性    │   类目打散
 │ 新鲜度    │   新品加权
 │ 运营干预   │   置顶/屏蔽/广告
 └─────┬────┘
       │ 最终结果(20-50)
       ▼
 搜索结果展示页

1.2 Elasticsearch在电商中的应用

// 商品索引Mapping设计
{
  "mappings": {
    "properties": {
      "product_id": {"type": "keyword"},
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",           // 中文分词
        "search_analyzer": "ik_smart",
        "fields": {
          "keyword": {"type": "keyword"},    // 精确匹配
          "pinyin": {"type": "text", "analyzer": "pinyin"}  // 拼音搜索
        }
      },
      "brand": {"type": "keyword"},
      "category_path": {"type": "keyword"},  // 品类路径: 服装>女装>连衣裙
      "price": {"type": "scaled_float", "scaling_factor": 100},
      "sales_30d": {"type": "integer"},       // 30天销量
      "rating": {"type": "float"},
      "tags": {"type": "keyword"},            // 标签: ["夏装","新品","爆款"]
      "attributes": {                         // 商品属性
        "type": "nested",
        "properties": {
          "name": {"type": "keyword"},
          "value": {"type": "keyword"}
        }
      },
      "embedding": {                          // 语义向量
        "type": "dense_vector",
        "dims": 768,
        "index": true,
        "similarity": "cosine"
      },
      "stock_status": {"type": "keyword"},
      "create_time": {"type": "date"},
      "update_time": {"type": "date"}
    }
  }
}

1.3 搜索排序策略

排序因子权重说明
文本相关性30%BM25分数 + 语义相似度
商品质量20%评分 + 好评率 + 退货率
人气热度15%30天销量 + 点击率 + 加购率
商业价值15%毛利率 + 广告出价 + 促销
个性化10%用户偏好匹配度
新鲜度5%新品加权 + 时间衰减
库存因子5%有库存加权,低库存降权

二、推荐系统架构

2.1 三层架构

┌──────────────────────────────────────────────────────────────┐
│                       离线层(Offline)                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐    │
│  │用户画像   │  │物品画像   │  │协同过滤   │  │深度模型   │    │
│  │构建      │  │构建      │  │矩阵分解   │  │训练      │    │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘    │
│  频率:T+1 / 每日                                            │
└──────────────────────────┬───────────────────────────────────┘
                           │
┌──────────────────────────▼───────────────────────────────────┐
│                       近线层(Nearline)                        │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│  │实时特征   │  │增量训练   │  │向量索引   │                  │
│  │更新      │  │模型更新   │  │更新      │                  │
│  └──────────┘  └──────────┘  └──────────┘                  │
│  频率:分钟级 / 小时级                                        │
└──────────────────────────┬───────────────────────────────────┘
                           │
┌──────────────────────────▼───────────────────────────────────┐
│                       在线层(Online)                          │
│  请求 → 用户特征获取 → 多路召回 → 粗排 → 精排 → 重排 → 展示   │
│  延迟要求:<200ms(P99)                                      │
└──────────────────────────────────────────────────────────────┘

2.2 推荐算法演进

代际算法原理优点缺点
第一代协同过滤(CF)相似用户/物品简单有效冷启动/稀疏
第二代矩阵分解(MF)SVD/ALS稀疏处理好表达力有限
第三代深度学习(DL)DNN/Wide&Deep特征交叉强训练成本高
第四代序列推荐Transformer/BERT4Rec捕捉时序推理慢
第五代多目标MMOE/PLE多目标平衡调参复杂
第六代LLM推荐RAG + 生成式理解语义延迟高/成本高

2.3 多路召回策略

class MultiChannelRecall:
    """多路召回"""

    def recall(self, user, context, top_k=500):
        # 并行执行多路召回
        channels = {
            'cf_user': self.user_cf_recall(user, k=200),        # 用户协同
            'cf_item': self.item_cf_recall(user, k=200),        # 物品协同
            'hot': self.hot_recall(context, k=100),              # 热门召回
            'new': self.new_item_recall(context, k=50),          # 新品召回
            'vector': self.vector_recall(user, k=200),           # 向量召回
            'tag': self.tag_recall(user, k=100),                 # 标签召回
            'realtime': self.realtime_recall(user, k=100),       # 实时行为召回
            'geo': self.geo_recall(user, context, k=50),         # 地理位置召回
        }

        # 合并去重
        all_candidates = self.merge_and_dedup(channels)

        # 过滤(已购/已曝光/黑名单)
        filtered = self.filter(all_candidates, user)

        return filtered[:top_k]

    def vector_recall(self, user, k):
        """向量召回:基于用户embedding在向量空间中搜索最近邻"""
        user_embedding = self.user_encoder.encode(user)
        # HNSW索引搜索,延迟<10ms
        results = self.vector_index.search(
            query=user_embedding,
            k=k,
            ef_search=200  # 搜索精度参数
        )
        return results

三、AI增强搜索推荐

3.1 向量搜索(语义搜索)

class SemanticSearch:
    """语义搜索:理解用户意图而非仅匹配关键词"""

    def __init__(self):
        # 文本编码器(如BERT/BGE/E5)
        self.text_encoder = SentenceTransformer('bge-large-zh-v1.5')
        # 商品编码器(多模态:文本+图片)
        self.item_encoder = MultiModalEncoder()

    def search(self, query, top_k=50):
        # 1. 编码查询
        query_embedding = self.text_encoder.encode(query)

        # 2. 混合搜索(Hybrid Search)
        # 关键词分数 + 向量分数 加权融合
        keyword_results = self.es_search(query, top_k=200)
        vector_results = self.vector_search(query_embedding, top_k=200)

        # 3. RRF融合(Reciprocal Rank Fusion)
        merged = self.rrf_fusion(keyword_results, vector_results)

        return merged[:top_k]

    def rrf_fusion(self, *result_lists, k=60):
        """
        RRF融合:将多路结果按排名倒数加权合并
        score = sum(1 / (k + rank_i)) for each list i
        """
        scores = defaultdict(float)
        for results in result_lists:
            for rank, item in enumerate(results):
                scores[item.id] += 1.0 / (k + rank + 1)
        return sorted(scores.items(), key=lambda x: x[1], reverse=True)

3.2 RAG增强推荐

class RAGRecommender:
    """
    RAG(Retrieval-Augmented Generation)增强推荐
    利用LLM理解用户需求 + 检索商品知识库生成推荐
    2025年最新实践: 将商品描述、评论、FAQ等构建为知识库
    """

    def recommend(self, user_query, user_profile):
        # Step 1: 检索相关商品和知识
        retrieved_items = self.vector_store.search(
            query=user_query,
            filter={"in_stock": True},
            top_k=20
        )
        retrieved_reviews = self.review_store.search(
            query=user_query,
            top_k=10
        )

        # Step 2: 构建Prompt
        context = self.build_context(retrieved_items, retrieved_reviews)
        prompt = f"""
        你是一个专业的商品推荐助手。

        用户信息:
        - 偏好: {user_profile.preferences}
        - 历史购买: {user_profile.recent_purchases}
        - 当前需求: {user_query}

        可选商品信息:
        {context}

        请根据用户需求,推荐最合适的3-5个商品,并说明推荐理由。
        输出格式: JSON数组,每项包含product_id, name, reason, match_score
        """

        # Step 3: LLM生成推荐
        response = self.llm.generate(prompt)
        recommendations = json.loads(response)

        return recommendations

3.3 LLM生成式推荐的最新进展

据2025年GenAI E-Commerce Workshop论文,RAG框架在领域特定序列生成任务中表现出色,通过利用异构知识源(商品描述、评论、用户反馈)作为额外上下文:

传统推荐流程:
  用户行为 → 特征工程 → 模型打分 → 排序 → 展示

LLM推荐流程:
  用户意图(自然语言) → Query理解(LLM) → 知识检索(RAG) → 推荐生成(LLM) → 结构化输出

优势:
  1. 理解复杂意图: "适合30岁妈妈的生日礼物,预算500内"
  2. 解释性强: 每个推荐附带理由
  3. 对话式: 支持追问和偏好调整
  4. 冷启动: 新用户可通过对话快速理解偏好

挑战:
  1. 延迟: LLM推理 100ms-2s(传统模型<50ms)
  2. 成本: Token计费,大规模调用成本高
  3. 幻觉: 可能推荐不存在的商品
  4. 时效: 训练数据截止日期之后的商品信息需要RAG补充

四、搜索推荐的A/B测试体系

4.1 指标体系

层级指标说明
效率指标点击率(CTR)曝光→点击
转化率(CVR)点击→购买
加购率点击→加入购物车
收益指标GMV/UV人均消费
笔单价平均订单金额
ARPU每用户收入
体验指标搜索满足率有结果的搜索占比
首次点击位置用户第一次点击的排名位置
翻页率需要翻页的搜索占比
长期指标留存率7日/30日留存
多样性推荐结果的品类覆盖度
新品曝光率新品获得曝光的比例

4.2 分流策略

用户请求
    │
    ▼
  Hash(userId) % 1000  →  bucket_id
    │
    ├── bucket 0-499: 实验组A (新模型)
    ├── bucket 500-799: 实验组B (新策略)
    └── bucket 800-999: 对照组 (线上基线)

注意事项:
  - 同一用户在实验期间始终分到同一组
  - 避免网络效应污染(社交场景)
  - 充分的样本量保证统计显著性
  - 负面指标监控(转化率下降>5%自动回滚)

五、数据同步与索引构建

┌──────────┐    CDC(Canal)    ┌──────────┐    ETL    ┌──────────┐
│  MySQL   │ ──────────────→ │  Kafka   │ ───────→ │ ES/向量DB │
│ (商品DB)  │                │ (变更流)  │          │ (搜索索引) │
└──────────┘                └──────────┘          └──────────┘
                                 │
                                 ├──→ Flink(实时特征更新)
                                 │
                                 └──→ Spark(离线训练数据)

索引构建频率:
  - 全量重建: 每天凌晨(处理数据漂移)
  - 增量更新: 秒级(CDC捕获变更)
  - 向量索引: 小时级更新(重新编码新商品)

对比分析

搜索 vs 推荐

维度搜索推荐
用户意图明确(主动搜索)模糊(被动接收)
输入查询词/语音/图片用户画像+行为
核心目标精准(找到想要的)发现(发现可能想要的)
排序信号相关性为主个性化为主
评估指标满足率/NDCGCTR/CVR/多样性
冷启动有query就能工作新用户缺行为数据
实时性要求极高(<200ms)高(<500ms)
流量占比30-40%50-60%

搜索引擎技术方案对比

方案优势劣势适用场景
Elasticsearch生态成熟、功能全面语义理解弱、维护成本高传统电商搜索
Meilisearch轻量、容错好规模受限中小型站内搜索
AlgoliaSaaS、开箱即用贵、数据出境快速上线
Typesense开源、速度快生态小性能敏感
Vespa混合搜索+推荐一体学习曲线高大规模搜推一体
Weaviate向量原生、AI友好传统搜索弱语义搜索为主
Qdrant向量性能最优无传统搜索纯向量召回

架构设计实操

设计目标

设计一个商品搜索推荐系统,满足:

  • 千万级SKU搜索
  • 搜索响应时间<200ms
  • 推荐响应时间<300ms
  • 支持语义搜索+关键词搜索
  • 搜索推荐融合

整体方案

┌──────────────────────────────────────────────────────────────┐
│                      统一搜推网关                              │
│  ├── /search?q=xxx       → 搜索引擎                          │
│  ├── /recommend/home     → 首页推荐                           │
│  ├── /recommend/detail   → 详情页推荐                         │
│  └── /ai-search?q=xxx   → AI对话式搜索                       │
└──────────────────────────┬───────────────────────────────────┘
                           │
┌──────────────────────────▼───────────────────────────────────┐
│                    Query理解服务                               │
│  分词 │ NER │ 意图分类 │ Query改写 │ 拼写纠错                   │
│  (LLM驱动的语义理解 + 传统NLP双路)                              │
└──────────────────────────┬───────────────────────────────────┘
                           │
┌──────────────────────────▼───────────────────────────────────┐
│                    多路召回服务                                │
│  ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐   │
│  │ES倒排   │ │向量ANN │ │类目树   │ │用户CF  │ │热点     │   │
│  │召回     │ │召回    │ │召回    │ │召回    │ │召回     │   │
│  └────────┘ └────────┘ └────────┘ └────────┘ └────────┘   │
└──────────────────────────┬───────────────────────────────────┘
                           │
┌──────────────────────────▼───────────────────────────────────┐
│                    排序服务                                    │
│  粗排(双塔, <10ms) → 精排(Cross-Encoder, <50ms) → 重排(规则)  │
└──────────────────────────┬───────────────────────────────────┘
                           │
┌──────────────────────────▼───────────────────────────────────┐
│                    数据平台                                    │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐   │
│  │ES Cluster│  │向量DB    │  │特征存储   │  │模型服务   │   │
│  │(倒排索引) │  │(Qdrant)  │  │(Redis)   │  │(TF Serving)│  │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘   │
└──────────────────────────────────────────────────────────────┘

ADR: 混合搜索(Hybrid Search)架构

背景: 纯关键词搜索无法理解语义("高性价比手机"搜不到"红米"),纯向量搜索精确性不够(搜"iPhone 15"可能返回Android手机)

决策: 采用Hybrid Search,关键词召回(ES BM25) + 向量召回(HNSW) + RRF融合

理由:

  • 关键词保证精确匹配(品牌、型号等)
  • 向量保证语义理解(同义词、概念关联)
  • RRF融合简单有效,无需训练融合模型

权衡:

  • 优势:兼顾精确性和语义理解
  • 劣势:双路召回增加系统复杂度和延迟
  • 替代方案:ES 8.x原生支持向量搜索(减少组件但灵活性低)

AI增强实践

1. 对话式购物搜索

class ConversationalSearch:
    """
    对话式购物搜索
    用户: "我想给妈妈买个生日礼物,她50岁,喜欢养花"
    AI: "根据您的需求,推荐以下礼物..."
    用户: "预算200以内的"
    AI: "好的,已筛选200元以内..."
    """

    def __init__(self):
        self.llm = ChatModel()
        self.retriever = HybridRetriever()
        self.conversation_memory = ConversationMemory()

    def search(self, user_message, session_id):
        # 1. 获取对话历史
        history = self.conversation_memory.get(session_id)

        # 2. LLM理解意图+生成搜索Query
        intent = self.llm.generate(f"""
        对话历史: {history}
        用户最新消息: {user_message}

        请分析用户意图,输出结构化搜索条件:
        {{
            "search_query": "搜索关键词",
            "filters": {{"price_max": null, "category": null, ...}},
            "intent_type": "search|refine|compare|ask",
            "clarification_needed": false
        }}
        """)

        # 3. 检索商品
        products = self.retriever.search(
            query=intent['search_query'],
            filters=intent['filters']
        )

        # 4. 生成推荐回复
        response = self.llm.generate(f"""
        用户需求: {user_message}
        候选商品: {products[:10]}
        请用自然语言推荐最合适的3个商品,说明推荐理由。
        """)

        # 5. 更新对话记忆
        self.conversation_memory.add(session_id, user_message, response)

        return response

2. 多模态搜索

模态场景技术
文本常规搜索BERT/BGE编码
图片拍照搜商品CLIP视觉编码
语音语音搜索ASR→文本→搜索
图文"帮我找类似这件但蓝色的"CLIP+LLM组合理解

与Web3/DeFi的关联

搜索推荐 × Web3

场景Web3方案价值
去中心化搜索IPFS索引+Token激励抗审查/无垄断
数据主权用户自控推荐数据隐私保护
推荐透明度链上记录推荐逻辑反操纵
激励标注Token奖励高质量评价数据质量
NFT商品搜索链上元数据索引NFT发现

DeFi中的"搜索与推荐"

DeFi Aggregator(如1inch)本质是金融产品的"搜索引擎":
  - 召回: 从多个DEX获取报价(多路召回)
  - 排序: 按最优价格/最低Gas排序
  - 路由: 拆分订单到多个DEX(类似搜索结果多样性)

DeFi的"推荐":
  - "高APY池推荐" = 个性化推荐(按用户风险偏好)
  - "相似协议推荐" = 协同过滤(投了A的人也投了B)
  - "预警推荐" = 实时推荐(风险变化时推送)

今日思考

1. 搜索推荐如何平衡"短期收益"和"长期体验"?

推荐高佣商品短期提升GMV,但用户可能因为"不精准"而流失。解决方案是多目标优化——训练时同时优化CTR、CVR和留存率,加入多样性和新奇性约束。可以用带约束的强化学习:最大化即时转化的同时,保证长期留存不低于阈值。

2. 向量搜索会完全替代关键词搜索吗?

不会。关键词搜索在精确匹配(型号、SKU编号)和可解释性上仍有优势。未来是Hybrid Search(混合搜索)——关键词保底精确性,向量增强语义理解。HNSW索引可以做到亚毫秒级检索百万级向量,性能不再是瓶颈。

3. LLM推荐如何解决"幻觉"问题——推荐不存在的商品?

通过RAG约束:LLM只能从检索到的真实商品中选择推荐,不允许"创造"商品。技术上,在prompt中明确"只从以下商品列表中推荐",输出后再校验product_id是否存在于数据库。进一步可以用结构化输出(JSON Schema约束)确保格式正确。


面试题准备

题目1:搜索和推荐有什么区别?

30秒回答: 搜索处理明确意图(用户主动查询),以相关性为核心;推荐处理模糊意图(系统主动推送),以个性化为核心。两者底层架构正在融合——共享向量空间、统一排序模型。

2分钟回答: 三个核心区别:

  1. 意图明确度:搜索=显式意图(query),推荐=隐式意图(行为推断)
  2. 排序目标:搜索重相关性(用户的query和商品的匹配度),推荐重个性化(用户和商品的偏好匹配度)
  3. 评估方式:搜索用NDCG/MAP(有ground truth),推荐用CTR/CVR(AB测试驱动)

但在AI时代两者正在融合:

  • 技术融合:共享Embedding空间,搜索也开始个性化(不同用户搜同一词看到不同结果)
  • 场景融合:搜索结果穿插推荐("猜你喜欢"在搜索结果中)
  • 架构融合:统一的召回→排序→重排Pipeline

题目2:向量搜索如何提升搜索效果?

30秒回答: 向量搜索通过语义理解弥补关键词搜索的局限——用户搜"高性价比手机"也能找到"红米Note",因为它们在语义空间中距离近。实践中采用Hybrid Search,关键词+向量双路召回再融合。

2分钟回答: 实现方式:

  1. 离线:用预训练模型(如BGE/E5)将商品标题+描述编码为向量,存入向量索引(HNSW)
  2. 在线:将用户Query编码为向量,在索引中做ANN检索(<10ms)
  3. 融合:关键词召回(ES BM25) + 向量召回 → RRF融合排序

具体收益:

  • 同义词理解:"手机壳" = "保护套"(无需手动维护同义词表)
  • 概念理解:"适合跑步的鞋" → 运动跑鞋(而非搜"跑步"关键词)
  • 跨模态:"上传一张裙子照片" → 找到类似款式

追问准备

  • Q: 向量搜索延迟怎么控制?→ HNSW索引可做到亚毫秒级(百万级),十亿级用GPU加速
  • Q: 向量模型怎么训练?→ 用电商点击数据Fine-tune,对比学习(点击=正例,展示未点击=负例)

学习资源


明日预告

Day 73: 全渠道(Omni-Channel)架构 —— 全渠道不只是"多渠道",而是统一用户体验。我们将深入统一商品/库存/会员/订单的中台架构,以及线上下单门店发货(Ship-from-Store)、门店自提(BOPIS)等O2O融合场景的技术挑战。2026年,54%的零售商将全渠道整合列为头号战略优先级。