如何使用 Dify 快速构建 LLM 应用 API 并自定义前端来实现门店智能导购
背景
最近做了一个门店智能导购项目——在门店触屏终端上部署 AI 顾问,顾客可以打字或语音提问,系统给出专业建议并同步播放语音,虚拟角色还会根据对话状态切换动作视频。
这套系统已经在多家门店落地运行。这篇文章把整个技术方案整理出来,包括后端怎么用 Dify 快速搭建、前端怎么处理流式对话和语音交互,以及踩过的一些坑。
解决的核心痛点
| 痛点 | 解决方式 |
|---|---|
| 店员无法全天候待命 | AI 助手 7×24 在线,秒级响应 |
| 新店员知识不足,培训成本高 | AI 预置行业知识库,开箱即用 |
| 高峰期顾客排队等候 | 顾客自助交互,无需等候 |
| 不同门店回答质量不一致 | 统一 AI 工作流,服务标准化 |
| 线下门店缺乏科技感 | 虚拟角色 + 语音交互,提升门店形象 |
技术方案:两大板块
整个系统的核心技术分两块:后端用 Dify 搭建 LLM 应用,前端用 React 构建自定义交互页面。
板块一:用 Dify 搭建后端
为什么选 Dify
Dify 是一个开源的 LLM 应用开发平台,核心能力是通过可视化拖拽编排 AI 工作流。不需要写后端代码,就能定义复杂的 AI 对话逻辑,并将整个流水线作为 API 服务对外提供。
对于门店导购这个场景,Dify 的优势在于:
- 工作流编排:可视化拖拽节点,编排"条件分支→大模型→语音合成"等完整流水线
- 知识库(RAG):上传行业文档,AI 回复时自动检索相关知识
- 多轮对话:平台自动管理对话上下文
- 语音合成(TTS):内置文字转语音,回复文字与语音同步返回
- API 服务化:编排好的工作流一键暴露为 REST API
工作流水线设计
我们没有用"一步大模型直接回答"的简单方案,而是设计了意图理解 → 分流处理 → 知识库精准检索的多节点流水线:
用户提问
│
▼
┌──────────────────────┐
│ 意图理解节点(小LLM)│
│ · 识别用户意图方向 │
│ · 提取结构化字段 │
│ (物种/品种/年龄等) │
└──────────┬───────────┘
│
┌──────┼──────┐──────┐
▼ ▼ ▼ ▼
养护咨询 商品导购 品种科普 其他方向
知识库 知识库 知识库 通用回复
│ │ │ │
▼ ▼ ▼ ▼
各方向对应的 LLM 节点
(调用对应知识库,带元数据过滤)
│
▼
语音合成节点(文字转语音)
│
▼
输出回复 + 语音(流式推送)
第一阶段:意图理解。 用户提问后,首先经过一个轻量级 LLM 节点,完成两件事:识别用户意图方向(养护知识、商品导购、品种科普等),以及从用户输入中提取结构化字段(宠物物种、品种、年龄、体重等)。
第二阶段:意图分流。 根据意图方向,路由到不同的 LLM 处理节点,每个方向接入对应的知识库。
第三阶段:知识库精准检索。 这是最关键的一环。提取出的结构化字段直接作为知识库元数据过滤条件。例如用户养的是"幼年猫咪",系统会过滤出仅适用于幼猫的商品,排除不匹配的结果。
前端通过一个 POST 请求调用该 API,即可获得流式的文字 + 语音回复。整个后端无需编写任何代码,全部在 Dify 控制台完成编排。
知识库与元数据过滤
Dify 的知识库支持 RAG 检索增强,而元数据过滤是让它真正好用的关键特性。
可以为每条知识文档打上自定义标签字段(如"适用物种""适用年龄段""商品品类""门店区域"等),检索时对这些字段进行标量过滤,实现精准的范围限定。
在本项目中,元数据过滤发挥了两层作用:
- 商品精准推荐:用户填写的宠物信息经意图节点提取后,直接指导商品知识库的标量过滤。例如"2岁金毛犬"的查询,只会返回适用于成年犬、大型犬的商品
- 多门店知识隔离:不同门店可能有不同的商品库存和促销政策,通过门店字段过滤,让 AI 只检索当前门店相关知识
搭建步骤
| 步骤 | 操作 |
|---|---|
| 1. 部署 Dify | Docker Compose 一键部署,浏览器访问控制台 |
| 2. 创建应用 | 创建「聊天助手」应用,获取 API Key |
| 3. 定义输入变量 | 配置业务字段(如宠物信息),部分字段兼做条件路由开关 |
| 4. 编排工作流 | 拖拽节点搭建条件分支 → 大模型 → 语音合成的流水线 |
| 5. 配置提示词 | 定义 AI 角色、职责、回答边界与语言风格 |
| 6. 上传知识库 | 上传行业文档,设置元数据标签 |
| 7. 开启语音合成 | 在应用设置中开启 TTS,流式响应自动穿插语音 |
| 8. 获取 API | 前端配置 API Key,通过 Nginx 代理访问 |
踩坑提醒:Nginx 反向代理必须关闭响应缓冲(
proxy_buffering off),否则流式通信会变成一次性返回,逐字输出效果失效。
板块二:用 React 构建前端交互
有了 Dify 提供的后端 API,前端的工作就是围绕这套 API 构建实际业务场景中的交互页面。
流式对话:文字逐字 + 语音同步
后端 API 以 SSE(Server-Sent Events)方式持续推送事件流,前端逐行解析,实现两个通道同步消费:
- 文字通道:每收到一个文字片段,立即拼接到界面,用户看到逐字打出的效果
- 语音通道:每收到一段音频分片,立即送入播放器播放,与文字同步
为什么不用 WebSocket?SSE 是单向推送,对于"后端持续推送、前端只接收"的场景更简单高效。为什么不用浏览器自带的 EventSource?它只支持 GET,而对话接口需要 POST 携带请求体,所以用 fetch 手动处理 SSE 流。
语音流式播放:音频分片边收边播
后端返回的语音是一段段音频分片,不能等全部收完再播。前端使用浏览器原生的 MediaSource API,每收到一段分片就追加到音频缓冲区,浏览器自动播放,实现「边收边播」。
核心技术难点:音频缓冲区的追加是异步操作,必须等上一段追加完成后才能追加下一段,否则报错。通过「队列 + 状态标志」机制实现可靠的串行追加,确保多段语音无缝衔接。
虚拟角色视频状态机
为增强沉浸感,AI 顾问配有虚拟角色视频,按对话状态切换:
| 触发条件 | 切换到 | 视频表现 |
|---|---|---|
| 用户正在输入/说话 | 等待 | 角色安静待机 |
| 用户发送消息 | 思考 | 角色做思考动作 |
| 语音开始播放 | 回答 | 角色嘴巴动作,模拟说话 |
| 语音播放结束 | 等待 | 回到待机 |
三组视频同时挂在页面上,通过透明度切换。关键优化:视频地址等媒体属性直接操作 DOM,绕过框架的属性对比机制,避免每次界面更新都重新请求视频文件,网络请求量降低 90% 以上。
其他交互能力
- 语音输入:浏览器录音 → 上传到语音识别服务(开源模型私有化部署,数据不出服务器)→ 识别结果自动填入输入框
- 多轮对话:每轮对话后获得对话标识,下次携带即可关联上下文
- 扫码查询:扫码枪输入条形码,系统转为查询问题发给 AI
- 热门问题推荐:触屏上轮播常见问题,降低用户输入门槛
- 门店标识与数据隔离:通过用户标识区分不同门店,后台可按门店筛选对话记录
踩过的坑
Q1:流式数据解析中,数据块可能包含半行内容,如何处理?
使用缓冲区模式逐行切分。每次读取后追加到缓冲区,按换行符切分出完整行处理,不完整的部分保留到下次。文本解码时标记「流模式」,避免多字节中文字符被截断。
Q2:浏览器禁止自动播放音频,第一段语音被拦截怎么办?
在用户首次点击发送时,播放一个静音音频「解锁」播放权限,后续语音即可自动播放。
Q3:触屏终端有哪些特殊的交互适配?
| 问题 | 方案 |
|---|---|
| 虚拟键盘遮挡输入框 | 监听视口变化 API,动态调整布局 |
| 点击区域太小 | CSS 全局增大触摸目标(最小 48px) |
| 长按触发右键菜单 | 全局禁用 |
| 双指缩放导致页面错位 | 禁用页面缩放 |
Q4:门店终端到服务器的通信安全怎么解决?
Nginx 作为反向代理,终端只与 Nginx 通信(HTTPS),Nginx 到后端走内网 HTTP。使用自签证书,证书配置包含服务器 IP 的域名扩展信息,终端设备预先安装信任。
可扩展性
这套方案的架构是通用的,替换知识库就能适配其他行业:
- 多行业适配:知识库替换为美妆、母婴、数码、医药等领域
- 多门店知识隔离:利用元数据过滤,同一套系统服务多门店
- 多语言:工作流平台支持多语言提示词,前端增加国际化即可出海
- 数据分析后台:对话记录 + 数据看板,分析高频问题、门店服务质量
- 微信小程序 / H5:前端逻辑可迁移到小程序端,实现线上到线下的导购打通
- 数字人直播:虚拟角色视频可升级为实时驱动的数字人,接入直播间
总结
整个项目的核心思路是:用 Dify 快速搞定后端 AI 能力,把精力集中在前端交互体验上。
Dify 解决了最复杂的部分——工作流编排、知识库管理、多轮对话、语音合成——全部可视化完成,不需要写后端代码。前端则专注于让交互更贴合实际业务场景:流式对话、语音同步、虚拟角色、触屏适配。
对于类似场景(门店导购、行业知识问答、AI 虚拟顾问),这套方案可以作为参考蓝本快速复用。