Skip to content

Latest commit

 

History

History
420 lines (278 loc) · 13.7 KB

File metadata and controls

420 lines (278 loc) · 13.7 KB

演示脚本

黄金主线(6 分钟):演示 1 → 2/3 → 6 → 7 → 多模态压轴(演示 19 语音深度 + 演示 8 跨模态拍照找货)→ 后台(演示 18 Dashboard + 演示 20 对话模型)。

启动

后端 必须用 Python 3.11(≥3.10)。系统 / Xcode 自带的 python3 常是 3.9,直接建 venv 会在启动时报 unsupported operand type(s) for |(代码用了 3.10+ 的 str | None 注解):

cd "/Users/xuwenyao/字节AI全栈挑战赛"          # 项目根
python3.11 -m venv server/.venv               # 一次性:务必用 3.11,别用默认 python3
source server/.venv/bin/activate
python --version                              # 确认 Python 3.11.x(≥3.10),不是 3.9
pip install -r server/requirements.txt
# 启动(路径已 CWD 无关,从项目根或 server/ 目录启动都不会找错库)
PYTHONPATH=server python -m uvicorn app.main:app --host 127.0.0.1 --port 8000

.env 里的对话 / embedding / 图像理解三把 key 会自动加载,商品向量已预热,秒开。自检:

curl -s http://127.0.0.1:8000/api/health    # 期望 llm_configured=true、embedding configured=true、商品数 321

iOS(工程已提交,直接打开即可,无需 xcodegen):

cd client-ios
open ShopGuide.xcodeproj

选 iPhone 模拟器运行「智购罗盘」(默认连 http://127.0.0.1:8000)。演示间想要干净上下文,点侧栏顶部「新对话」即可换新 session。

只有改了 project.yml 才需要 xcodegen generate。若 Run 报 Multiple commands produce '….app':git checkout -- client-ios/ShopGuide.xcodeproj/project.pbxproj 还原已提交工程,删 ~/Library/Developer/Xcode/DerivedData/ShopGuide-* 后重开 Xcode。

演示 1:模糊需求主动澄清

用户输入:

推荐手机

预期:

  • Agent 不直接乱推。
  • 先追问拍照、续航、游戏性能、性价比和预算。

继续输入:

游戏,预算9999

预期:

  • 返回手机商品卡。
  • 商品卡可点进详情页。

演示 2:反选和约束过滤

用户输入:

苹果手机不要小米

预期:

  • 返回 Apple 相关手机。
  • 不出现小米商品。

用户输入:

推荐适合油皮的防晒,200元以内,不要含酒精

预期:

  • 返回防晒商品。
  • 不受上一轮手机上下文影响。
  • 推荐商品符合 200 元以内和不含酒精约束。

演示 3:可解释推荐评分

用户输入:

推荐适合油皮的防晒,200元以内,不要含酒精

预期:

  • 商品卡右上角显示匹配分。
  • 商品卡底部显示首条命中依据。
  • 点进详情页后,“推荐决策”区块展示命中依据和注意点,例如预算、偏好、评论、来源、SKU、价格是否接近预算上限等。

演示 4:场景化推荐

用户输入:

推荐去三亚要带的东西

预期:

  • 返回防晒、轻量衣物、补能食品、充电类商品组合。
  • 不再沿用上一轮手机偏好。

演示 5:SKU 规格和真实图片

  1. 输入 17pm
  2. 点击 iPhone 商品卡的规格按钮。
  3. 在详情页切换“宇宙橙 / 冰川蓝 / 银色”和存储容量。

预期:

  • 价格随容量变化。
  • 图片随颜色变化。
  • 图片来自 Apple 官方公开 CDN,本地只缓存,不使用伪造图片。

演示 6:商品级追问问答

先输入:

推荐适合油皮的防晒,200元以内,不要含酒精

继续追问:

第一款差评主要说什么
这款适合敏感肌吗,有没有酒精

预期:

  • Agent 不重新随机推荐,而是围绕上一轮第一款商品回答。
  • 回答引用商品库里的 FAQ、评论和详情证据。
  • 差评问题会归纳 3 星及以下评论,成分问题会说明不含酒精并提醒敏感肌先测试。

再输入:

17pm

继续追问:

第一款不同规格怎么选

预期:

  • Agent 汇总可选存储、颜色、价格区间。
  • 明确说明该商品有独立真实规格图。

演示 7:购物车和下单

  1. 在详情页选一个 SKU 加入购物车。
  2. 返回聊天页,确认右上角购物车徽标。
  3. 输入:
我要下单
  1. Agent 汇总订单并要求地址,继续输入:
北京市朝阳区 Demo 路 1 号
  1. Agent 再次汇总商品、地址和金额,继续输入:
确认下单

预期:

  • 同商品不同 SKU 是独立购物车行项目。
  • 总价按 SKU 单价计算。
  • 加购、改数量和下单前会校验 mock 库存。
  • 模拟下单后聊天页出现独立订单卡,包含 SG... 订单号、地址、金额和商品数量;购物车清空。
  • 订单后推荐商品自动出现,例如配件、补充购买或复购候选。

演示 8:跨模态拍照找货(多模态向量)

  1. 点击聊天输入框左侧图片按钮(相机或相册)。
  2. 上传一张商品图,例如一副耳机或一台手机的图片。

稳定样例见 server/evaluation/cases/multimodal_demo_samples.json,可优先使用:

  • server/static/product_images/p_digital_016.jpg:手机。
  • server/static/product_images/p_anker_001_fc881685.jpg:Anker 充电设备。
  • server/static/product_images/p_beauty_001.jpg:防晒。
  • server/static/product_images/p_clothes_014.jpg:防水徒步鞋。

预期(讲解词):

  • 跨模态语义匹配:上传图用豆包多模态向量 doubao-embedding-vision 编码,与商品的文本向量落在同一图文共享空间比对——所以一张耳机图会召回耳机、一张防晒图会召回防晒,靠语义而不是关键词或颜色直方图
  • 商品卡推荐理由里会出现 语义图文匹配 X%(多模态向量,拍照找货),这是主导信号(权重最高),再融合 VLM 图像理解、轻量视觉特征和文本意图做重排。
  • 相似度呈梯度,不会全部 100%。

继续演示图文融合(图片 + 文字一起):

  1. 先在输入框输入 油皮防晒降噪耳机
  2. 不点击发送,直接上传一张商品图片。

预期:

  • Agent 会提示正在融合图片和文字需求。
  • 推荐理由同时包含:多模态向量语义匹配、VLM 图像理解词(品类/子类目/关键词/外观属性)、文本筛选词和融合排序依据。
  • 优雅降级:未配置 embedding key 时回退到轻量视觉特征,未配置 VLM 时明确显示 VLM fallback——服务不中断。

演示 9:压力测试

运行:

python3 server/scripts/stress_test_retrieval.py --sample 1000 --concurrency 16 --p95-ms 800

预期:

  • 脚本优先下载 Kaggle olistbr/brazilian-ecommerce 数据集生成压力查询。
  • 输出 QPS、p50/p95/p99/max 延迟和错误数。
  • 错误数为 0 且 p95 未超过阈值。

演示 10:长期偏好记忆

输入:

记住我以后护肤品不要含酒精,我是油皮,预算200

预期:

  • Agent 回复已记住肤质、预算和排除成分。
  • iOS 左上角“我的偏好”入口显示已保存状态。
  • 打开“我的偏好”页能看到肤质、预算偏好、排除成分,并支持清除。

继续输入:

推荐防晒

预期:

  • Agent 不再反复追问肤质,而是自动带上油皮、200 元预算和酒精排除条件。
  • 推荐结果仍然展示匹配原因和风险提示。

演示 11:预算套装方案

输入:

我1000元预算,下周去三亚,帮我配一套防晒和出行用品

预期:

  • 返回结构化 Shopping Plan 卡片。
  • 卡片包含必需项、可升级项、总价、剩余预算和每个商品的选择理由。
  • 每个方案项可点进商品详情,或直接按 SKU 逻辑加入购物车。

演示 12:平替 / 升级款 / 换品牌

先输入:

推荐适合油皮的防晒,200元以内,不要含酒精

然后继续输入:

第一款太贵了,有没有平替

预期:

  • Agent 记录 too_expensive 反馈。
  • 返回更低价候选,并解释“平替”逻辑。

继续尝试:

换个品牌

预期:

  • Agent 避开上一款品牌,返回同类替代商品。
  • 用户画像里的 last_feedback 会记录反馈链路。

演示 13:混合检索 Trace

输入:

推荐 Anker 100W 快充

预期:

  • 商品推荐理由中出现 混合检索:BM25 / 语义向量或本地向量 / 结构化 / 可信度
  • 未配置 TEXT_EMBEDDING_* 时,打开 /api/traces/{trace_id} 可看到 retrieval_stackstructured_filter + BM25 + hashing_vector + trust_reranker
  • 配置文本 embedding 并运行 server/scripts/build_text_embeddings.py 后,Trace 会显示 text_embedding(...)
  • 同时启用 VECTOR_STORE_BACKEND=chroma 且已预计算真实向量时,Trace 会显示 Chroma text_embedding(...),商品理由会出现 Chroma语义向量,用于演示标准向量数据库承载真实商品 embedding。

演示 14:售后 / 退换货政策问答

先输入:

我要看17pm

继续追问:

第一款售后和保修怎么说

预期:

  • Agent 不编造真实平台七天无理由、库存、保修期限或运费险。
  • 回答会说明这是导购 Demo,不产生真实支付、物流和售后承诺。
  • 回答会提示真实退换货规则以公开来源页面和下单平台为准。

演示 15:隐私与合规说明页

  1. 点击聊天页左上角 info.circle
  2. 查看“隐私与合规”页。

预期:

  • 页面说明商品数据来源、图片处理方式、偏好记忆内容和 API 使用边界。
  • 明确说明上传图片只用于当前检索,不作为伪造商品图保存。
  • 明确说明项目不模拟真实支付、物流、库存或平台售后承诺。

演示 16:端侧微交互和深色模式

  1. 发送任意问题,观察 assistant 思考态。
  2. 等待商品卡片出现。
  3. 点击麦克风按钮,用语音说出一个导购需求,再打开扬声器按钮让回复朗读。
  4. 重复打开同一批商品卡图片,观察二次加载速度。
  5. 切换模拟器深色模式。

预期:

  • Assistant 空消息显示三点思考动画。
  • 商品卡图片加载时有 skeleton,占位不会导致布局跳动。
  • 图片走内存缓存和 URLCache 磁盘缓存,重复展示不会反复拉取同一张图。
  • 发送、加购、切换语音开关时有轻量触觉反馈;TTS 只朗读简短导购回答,不朗读商品卡 JSON。
  • 商品卡进入有轻量 scale/opacity 动效。
  • 深色模式下背景、卡片、徽标描边和文字对比保持清晰。

演示 17:自动化评测报告

运行:

PYTHONPATH=server python3 server/evaluation/run_eval.py

预期:

  • 输出意图、约束、反选、多轮、购物车、图片找货和来源 grounding 的通过率。
  • 生成 server/evaluation/output/evaluation_report.html,可直接打开作为答辩材料。
  • 报告中展示 Top-3 命中率、反选过滤准确率、主动澄清准确率、购物车成功率、图片 Top-K 命中率、预算套装成功率、订单后推荐成功率和 p95 延迟。

演示 18:Agent Trace / Dashboard

  1. 启动后端并完成一次聊天推荐,例如 推荐适合油皮的防晒,200元以内,不要含酒精
  2. 打开 http://127.0.0.1:8000/admin/metrics

预期:

  • Dashboard 显示商品总数、公开来源覆盖、评论覆盖、SKU 覆盖和规格图覆盖。
  • 能看到 Agent 调用次数、Grounding Guard 通过/拦截次数、图片检索延迟、SSE 首 token 延迟和最近 Trace。
  • 第二次发送完全相同的推荐问题时,retrieval_cache_hit_raterecommendation_cache_hit_rate 应上升,可现场展示缓存命中带来的延迟下降。
  • 点击 Trace ID 或访问 /api/traces/{trace_id},可以看到意图识别、约束解析、候选过滤、检索 Top 商品、Grounding Guard 和 SSE 输出链路。

演示 19:语音深度(流式识别 + 可调 TTS + 语音连续对话)

  1. 点击聊天页底部的麦克风按钮,对着说一句导购需求,例如“推荐拍照好的手机四千以内”。
  2. 观察输入区上方弹出的聆听浮层:波形动效 + 实时转写文字随说随出。 3.(可选)开启语音连续对话后再说一句。
  3. 长按顶部喇叭按钮,打开语音设置面板,拖动语速滑杆、切换中文音色,点“试听”。

预期:

  • 流式 ASR:SFSpeechRecognizer(zh-CN)开启 partial results,聆听浮层实时展示转写,不是说完才出。
  • 语音连续对话:开启后,识别一停顿就自动发送并把回复朗读出来,全程免手动——可演示一问一答的语音闭环。
  • 可调 TTS:语速(0.5×–1.5×)和中文音色可调并本地持久化(@AppStorage);只朗读简短导购回答,不朗读商品卡 JSON。
  • 讲解点:语音输入用系统级 ASR,语音播报用系统 TTS,商品事实仍只来自后端工具——多模态入口扩展但不破坏 grounding。

演示 20:对话模型可插拔 / 优雅降级(架构杀手锏)

  1. 打开侧栏 →「对话模型」,可见当前状态(默认就用后端 .env 的 key,演示时无需手填)。
  2. 讲解:这里只切换最外层对话/规划模型;商品检索、跨模态图搜、RAG 工具调用、Grounding Guard 都由后端统一控制,不受影响。 3.(进阶演示)切换到另一个 OpenAI-compatible 模型并保存,或直接清空配置退回本地确定性逻辑。

预期:

  • 可插拔:换对话模型后,商品、价格、SKU 依然准确,Guard 依然拦截编造的促销/库存/价格——证明“事实来自工具,不来自模型”。
  • 保存有护栏:保存前先做连通性校验,校验失败不写入会话覆盖、自动回退到后端默认 key,现场不会因填错 Key 把会话弄挂。
  • 优雅降级:把 key 清空 / 用错模型时,Agent 退回本地确定性文案,服务不中断,仍能出商品卡。