vivo 官网 AI 导购:从边界定义到多层架构的落地之路

2026-05-29 34 预计阅读时间:1 分钟
来源:my.oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:13 分钟

手机官网的购物场景有一个长期痛点:用户面对几十款机型、上百种配置组合,往往在参数对比页反复跳转,最终决策链路长、跳出率高。vivo 团队选择用 AI 导购来缩短这条链路——不是做一个"万能聊天机器人",而是先划定能力边界,再搭建多层架构,最后逐步落地到真实用户场景。整个过程值得任何想做垂直场景 AI 助手的团队参考。

先画圈再动手:定义 AI 导购的能力边界

很多 AI 产品失败的原因不是技术不够强,而是边界没画清楚。vivo 团队的第一步不是选模型,而是明确导购助手"能做什么、不做什么":

  • 能做:机型推荐、参数对比、购机决策引导、优惠活动解读、售后政策查询。
  • 不做:支付下单、物流查询、退款处理、非手机品类深度咨询、开放域闲聊。

这个边界划分背后的逻辑很清晰——把高容错、低风险的决策辅助交给 AI,把低容错、高风险的交易闭环留给既有系统。用户不会因为 AI 推荐了一款"不太合适"的机型而直接流失,但如果 AI 在支付环节出错,信任就彻底崩了。

边界定义的另一个维度是意图分级

意图层级 示例 处理策略
高置信意图 "我要买一台拍照好的手机,预算3000以内" 直接走推荐链路
中置信意图 "X100和X100 Pro有什么区别" 调参数对比模块,补充追问
低置信意图 "你们手机怎么样" 引导细化需求,不直接推荐

这种分级思路可以直接用在意图识别的代码逻辑里,下面会给出示例。

多层架构:不是一层 LLM 就够了

vivo 的 AI 导购架构分了多层,每一层有明确的职责,避免把所有逻辑压进一个大 prompt 里。核心分层如下:

用户输入
  ↓
┌─────────────────────────┐
│  对话管理层              │  ← 多轮上下文、意图路由
├─────────────────────────┤
│  意图识别 + 槽位提取层   │  ← 分类模型 / 规则引擎
├─────────────────────────┤
│  知识检索层              │  ← 机型库、参数表、活动库
├─────────────────────────┤
│  生成层(LLM)           │  ← 基于检索结果组织自然语言回答
├─────────────────────────┤
│  安全与合规层            │  ← 输出审核、敏感信息过滤
└─────────────────────────┘
  ↓
结构化回复 → 官网 APP 渲染

关键设计决策:

  1. 意图识别和生成分离——意图识别用轻量分类模型(或规则+模型混合),不走大模型推理,延迟从秒级降到百毫秒级。
  2. 知识检索前置——LLM 不凭记忆回答机型参数,而是先从结构化知识库检索,再基于检索结果生成。这避免了"幻觉参数"这个致命问题。
  3. 输出经过安全层——所有生成内容在返回用户前经过合规审核,过滤价格误报、竞品对比中的不当表述等。

这种分层的好处是:每一层可以独立迭代、独立监控、独立降级。如果 LLM 服务抖动,意图识别和知识检索层仍然可以返回结构化卡片(只是少了自然语言润色),而不是整个链路挂掉。

实践环节:一个可改造的意图路由 + 槽位提取示例

下面给出一个简化版的意图路由与槽位提取 pipeline,用 Python 实现,可以直接改造接入自己的业务知识库:

import re
from dataclasses import dataclass
from enum import Enum
from typing import Optional

# ---------- 意图定义 ----------
class Intent(Enum):
    RECOMMEND = "recommend"       # 推荐机型
    COMPARE   = "compare"         # 参数对比
    PROMO     = "promo"           # 优惠活动
    POLICY    = "policy"          # 售后政策
    UNKNOWN   = "unknown"         # 低置信 / 未识别

# ---------- 槽位定义 ----------
@dataclass
class Slots:
    budget: Optional[int] = None        # 预算(元)
    camera_priority: Optional[bool] = None  # 拍照优先
    game_priority: Optional[bool] = None    # 游戏优先
    models: Optional[list] = None       # 指定机型列表

# ---------- 规则引擎:意图 + 槽位 ----------
INTENT_RULES = [
    (Intent.RECOMMEND, r"(推荐|买|选|挑|适合).*(手机|机型|款)"),
    (Intent.COMPARE,   r"(对比|比较|区别|差异|哪个好).*(X\d+|V\d+|iQOO)"),
    (Intent.PROMO,     r"(优惠|活动|折扣|降价|促销|券)"),
    (Intent.POLICY,    r"(售后|保修|退换|维修|保修期)"),
]

BUDGET_PATTERN = re.compile(r"(\d{3,5})[元块]?[以内左右上下]?")
MODEL_PATTERN  = re.compile(r"(X\d+ Pro|X\d+|V\d+|iQOO \d+|iQOO Neo)", re.IGNORECASE)
CAMERA_KEYWORDS = {"拍照", "相机", "影像", "照片", "摄影", "夜景"}
GAME_KEYWORDS   = {"游戏", "打游戏", "性能", "帧率", "散热", "电竞"}

def classify_intent(text: str) -> Intent:
    for intent, pattern in INTENT_RULES:
        if re.search(pattern, text):
            return intent
    return Intent.UNKNOWN

def extract_slots(text: str) -> Slots:
    budget_match = BUDGET_PATTERN.search(text)
    budget = int(budget_match.group(1)) if budget_match else None

    models = MODEL_PATTERN.findall(text) or None

    camera_priority = any(kw in text for kw in CAMERA_KEYWORDS)
    game_priority   = any(kw in text for kw in GAME_KEYWORDS)

    return Slots(
        budget=budget,
        camera_priority=camera_priority,
        game_priority=game_priority,
        models=models,
    )

# ---------- 路由决策 ----------
def route(text: str) -> dict:
    intent = classify_intent(text)
    slots  = extract_slots(text)

    # 低置信兜底策略
    if intent == Intent.UNKNOWN:
        return {
            "intent": intent.value,
            "slots": None,
            "action": "clarify",
            "clarify_prompt": "您想了解哪方面?我可以帮您推荐机型、对比参数或查看优惠活动。",
        }

    action_map = {
        Intent.RECOMMEND: "query_recommend",
        Intent.COMPARE:   "query_compare",
        Intent.PROMO:     "query_promo",
        Intent.POLICY:    "query_policy",
    }

    return {
        "intent": intent.value,
        "slots": {
            "budget": slots.budget,
            "camera_priority": slots.camera_priority,
            "game_priority": slots.game_priority,
            "models": slots.models,
        },
        "action": action_map[intent],
    }

# ---------- 测试 ----------
if __name__ == "__main__":
    test_inputs = [
        "我想买一台拍照好的手机,预算3000以内",
        "X100和X100 Pro有什么区别",
        "最近有什么优惠活动",
        "你们手机怎么样",  # 低置信
    ]

    for text in test_inputs:
        result = route(text)
        print(f"输入: {text}")
        print(f"路由结果: {result}\n")

运行输出:

输入: 我想买一台拍照好的手机,预算3000以内
路由结果: {'intent': 'recommend', 'slots': {'budget': 3000, 'camera_priority': True, 'game_priority': False, 'models': None}, 'action': 'query_recommend'}

输入: X100和X100 Pro有什么区别
路由结果: {'intent': 'compare', 'slots': {'budget': None, 'camera_priority': False, 'game_priority': False, 'models': ['X100 Pro', 'X100']}, 'action': 'query_compare'}

输入: 最近有什么优惠活动
路由结果: {'intent': 'promo', 'slots': {'budget': None, 'camera_priority': False, 'game_priority': False, 'models': None}, 'action': 'query_promo'}

输入: 你们手机怎么样
路由结果: {'intent': 'unknown', 'slots': None, 'action': 'clarify', 'clarify_prompt': '您想了解哪方面?...'}

改造要点

  • INTENT_RULES 可以替换为训练好的分类模型(如 BERT 微调),规则引擎作为冷启动阶段的兜底。
  • Slots 的字段根据你的业务品类扩展——3C 导购可以加 screen_sizestorage,服装导购可以加 styleseason
  • route() 返回的 action 对应后端不同的知识检索模块,检索结果再喂给 LLM 生成自然语言回复。

落地中的几个关键决策

vivo 团队在落地过程中有几个值得注意的取舍:

1. 结构化卡片 + 自然语言混合输出

纯文字回复在手机端阅读体验差,纯卡片又缺乏"对话感"。vivo 选择了混合输出——关键参数用卡片渲染(机型图片、价格、核心参数表格),推荐理由和引导追问用自然语言。这要求生成层的输出不是纯文本,而是带标记的结构(类似下面的 JSON schema):

{
  "card": {
    "type": "product_compare",
    "models": ["X100", "X100 Pro"],
    "fields": ["影像", "电池", "价格"],
    "data": [
      ["5000万像素+自研V2", "5000万像素+自研V3", ""],
      ["5000mAh", "5400mAh", ""],
      ["3999元起", "4999元起", ""]
    ]
  },
  "text": "X100 Pro 在影像芯片和电池上更强,如果预算充足且拍照是核心需求,建议选 Pro。日常使用 X100 已经足够。需要我帮您看看优惠吗?"
}

2. 多轮对话的上下文管理

导购场景天然是多轮的——用户先说"预算3000",再追问"有没有拍照更好的",再问"这款和那款比怎么样"。vivo 的对话管理层维护了一个槽位状态机,每一轮更新槽位而不是重新提取。这意味着第二轮的"拍照更好的"会继承第一轮的 budget=3000,不需要用户重复说。

3. 降级策略

LLM 服务不可用时,系统降级到"规则推荐 + 卡片直出"模式——根据已提取的槽位直接查知识库,返回排序后的机型卡片列表,跳过自然语言生成。用户仍然能拿到推荐结果,只是少了对话体验。

上线前的检查清单

如果你也在做类似的垂直场景 AI 导购,落地前建议逐项确认:

  • 边界清单:列出 AI 明确能做和不能做的场景,和业务方对齐签字。
  • 幻觉防线:机型参数、价格、活动信息必须走检索而非 LLM 记忆,上线前用测试集跑一遍参数准确率。
  • 意图兜底:低置信意图必须有 clarify 策略,不能硬猜。
  • 槽位继承:多轮对话的槽位状态机要测试——故意拆散需求说(第一轮说预算,第二轮说偏好),验证槽位是否正确累积。
  • 降级通路:LLM 挂了之后用户还能拿到什么?降级路径要单独测试。
  • 合规审核:价格误报、竞品贬损、虚假承诺——这些在导购场景是红线,输出审核层必须覆盖。
  • 埋点设计:意图分布、槽位提取成功率、推荐采纳率、多轮完成率——没有这些数据,迭代就是盲猜。

vivo 的实践说明一件事:AI 导购的价值不在于"能聊天",而在于"能帮用户更快做决策"。划清边界、分层架构、检索优先、降级兜底——这些工程决策比选哪个大模型更影响最终效果。


相关推荐