news 2026/10/1 2:50:03

Edge AI 全栈实战 ④:向量数据库 + RAG 让 IoT 诊断拥有“记忆“

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Edge AI 全栈实战 ④:向量数据库 + RAG 让 IoT 诊断拥有“记忆“

一、系列回顾与本篇定位

① 篇:ESP32 → MQTT → 云端(能通)
② 篇:ESP32 → MQTT → Flink → 实时管道 + 异常检测(生产级)
③ 篇:② + 异常时调 LLM 生成诊断(会思考)
④ 篇:③ + 向量库存历史诊断,检索增强(有记忆) ← 本篇

③ 篇的瓶颈很明显:LLM 每次都从零开始推理。

[温度漂移异常] → LLM:基于通用知识猜原因 → 诊断报告

问题是:工厂里"3 号机组温度漂移"上周刚处理过,根因是冷却泵滤网堵塞。LLM 不知道这件事。④ 篇解决的就是"让系统记住经验"。


二、整体架构

在 ③ 篇基础上加一个向量库和检索环节:

ESP32 ──MQTT──▶ Flink ──▶ 异常检测 ──▶ ┌─────────────────────┐ │ RAG 诊断算子 │ │ 1. 异常 → embedding │ │ 2. 检索 Top-K 历史 │ │ 3. 拼 prompt 调 LLM │ └─────────┬───────────┘ │ ┌────────────────────▼────────────┐ │ Milvus 向量库(历史诊断记忆) │ │ (异常向量, 根因, 处置, 时间戳) │ └─────────────────────────────────┘ │ ┌────────────────────▼────────────┐ │ LLM 诊断报告(含参考案例)→ 库/钉钉│ └─────────────────────────────────┘

关键:每次诊断完,把本次异常向量 + 最终根因写回 Milvus,形成正向循环。


三、向量库选型与建表

为什么用 Milvus(而不是简单的内存向量检索):历史诊断会累积到百万级,需要持久化 + 高效 ANN 检索 + 可按设备/时间过滤。

from pymilvus import MilvusClient ​ client = MilvusClient("http://milvus:19530") client.create_collection( collection_name="iot_diagnosis", dimension=384, # bge-small-zh 的维度 metric_type="COSINE", auto_id=True, ) ​ # 加标量字段,支持"只检索同设备型号的历史" client.alter_collection( collection_name="iot_diagnosis", properties={"enable_dynamic_field": True} )

Embedding 模型选bge-small-zh(384 维):在设备日志/告警文本上效果足够,体积小、推理快(CPU 即可 1200 句/s)。


四、Flink 侧:写入向量 + 检索增强

4.1 异常 → 向量,并检索历史

public class RAGDiagnosisFunction extends RichAsyncFunction<Alert, DiagnosisReport> { ​ private transient MilvusServiceClient milvus; private transient EmbeddingClient embed; // bge-small 本地服务 ​ @Override public void asyncInvoke(Alert a, ResultFuture<DiagnosisReport> f) { // 1. 异常文本 → 向量 float[] vec = embed.embed(buildAlertText(a)); ​ // 2. 检索同型号设备的 Top-3 历史案例 SearchParam sp = SearchParam.newBuilder() .withCollectionName("iot_diagnosis") .withVector(vec) .withTopK(3) .withExpr("device_type == \"" + a.deviceType + "\"") .build(); SearchResults res = milvus.search(sp); ​ // 3. 拼检索到的历史案例进 prompt String hist = formatHistory(res); String prompt = buildPrompt(a, hist); ​ // 4. 调 LLM 生成(同 ③ 篇的 vLLM 调用) callLLM(prompt).thenAccept(report -> { // 5. 诊断完写回向量库,形成记忆 milvus.insert(InsertParam.newBuilder() .withCollectionName("iot_diagnosis") .withFields(buildFields(a, vec, report)) .build()); f.complete(Collections.singletonList(report)); }); } ​ private String buildPrompt(Alert a, String hist) { return "你是工业设备运维助手。当前异常:" + a.type + ",数值=" + a.value + ",设备型号=" + a.deviceType + "。\n历史相似案例及根因:\n" + hist + "\n请参考历史案例判断本次根因并给处置建议,不超过 80 字。"; } }

4.2 接入主流水线

SingleOutputStreamOperator<DiagnosisReport> reports = AsyncDataStream .unorderedWait(alerts, new RAGDiagnosisFunction(), 30, TimeUnit.SECONDS, 20) .name("rag-diagnosis"); ​ reports.addSink(new DiagnosisSink());

五、Embedding 服务(轻量)

# embedding_service.py — 本地 bge-small,被 Flink 通过 HTTP 调 from sentence_transformers import SentenceTransformer from fastapi import FastAPI ​ model = SentenceTransformer("BAAI/bge-small-zh") app = FastAPI() ​ @app.post("/embed") async def embed(req: dict): v = model.encode(req["text"]).tolist() return {"vector": v}

CPU 上单条告警 embedding 约 8ms,对实时管道无感。


六、实测数据

环境:ESP32×3 + Flink(2 并行) + Milvus(单机) + vLLM(Llama-3-8B, 1×A100)。 先运行 2 周累积 1500 条历史诊断,再测新异常。

指标③ 篇(无记忆)④ 篇(RAG 增强)提升
根因命中率(人工复核)71%93%+22pt
平均诊断字数5268(更具体)—
诊断延迟 P50380 ms420 ms(+检索 40ms)可接受
峰值吞吐5 万 msg/s5 万 msg/s不变
向量库规模—1500→持续增长记忆累积

RAG 让 LLM 站在"历史经验"的肩膀上,根因命中率提升显著,且延迟仅多 40ms。


七、踩坑记录

问题现象解决
检索到不相关案例根因被带偏加device_type标量过滤,只查同型号
向量维度不匹配写入失败确认 embedding 模型维度=建表 dimension
历史太少检索无意义前期命中低冷启动先用 ③ 篇规则兜底,积累 500 条后开 RAG
写入和检索争抢延迟抖动Milvus 读写分离 + 批量插入
旧案例误导(根因已修正)错误传承加verified字段,只检索人工确认过的案例
向量库膨胀存储暴涨按时间 TTL,保留近 90 天

八、总结

本篇让 Edge AI 全栈真正"有记忆":

  • 硬件采集(ESP32)→ 大数据流处理(Flink)→ AI 推理(vLLM)+ 检索增强(Milvus/RAG)四线闭环

  • 历史诊断持续累积成"经验库",LLM 诊断根因命中率 71% → 93%

  • 标量过滤保证检索相关性,冷启动用规则兜底

  • 硬件成本仍 ¥66,云端 Milvus + vLLM 可复用

下篇预告:⑤ 篇我们做"端侧轻量化"——把诊断模型本身下沉到边缘(ESP32-S3 + TinyML),让简单异常在设备端就地判断、只把疑难杂症上云,引出"云边协同"的工程范式,给整个系列收尾。


往期回顾:

  • Edge AI 全栈1:ESP32 传感器采集到云端大模型推理的完整链路

  • Edge AI 全栈 2:ESP32 + MQTT + Flink 实时 IoT 数据管道

  • Edge AI 全栈实战 3:Flink 异常检测联动云端大模型生成诊断报告

  • RAG 架构设计 7 个关键决策:从 Chunk 策略到 Reranker 的生产级方案

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 2:49:52

SteamOS兼容安卓传闻:技术路线与掌机格局影响分析

这几天 SteamOS 兼容安卓的消息在玩家圈子里炸开了锅。我第一反应是不屑&#xff0c;Steam Deck 上那套基于 Linux 的系统&#xff0c;连 Windows 游戏都要靠 Proton 转换层来跑&#xff0c;现在还想把安卓生态也吞下来&#xff1f;但等我把 Valve 近两年的动作和这条传闻里的技…

作者头像 李华
网站建设 2026/10/1 2:48:57

Spring 声明 Bean 的注解详解

Spring 声明 Bean 的注解详解 一、概述 Spring 声明 Bean 的注解分为两大类&#xff1a;类级别注解和方法级别注解。类级别注解标注在类上&#xff0c;Spring 通过组件扫描自动注册&#xff1b;方法级别注解标注在 Configuration 类的方法上&#xff0c;手动注册返回值。类别注…

作者头像 李华
网站建设 2026/10/1 2:48:20

Zed 补上了这个快捷键,VS Code 和 IDEA 用户终于不用改肌肉记忆了

从 VS Code 或 IDEA 迁到 Zed,第一周最难受的往往不是功能缺失,而是"我那个按了好几年的键呢?" VS Code 用户大概都有这个肌肉记忆:光标停在某一行,不管在行首、行中还是行尾,按下 Ctrl+Enter,当前行保持原样不动,下面凭空多出一行空白,光标已经落在新行上…

作者头像 李华
网站建设 2026/10/1 2:48:04

多Agent智能体架构设计实战:从拆角色到协作编排的工程化落地

好的&#xff0c;直接开始。多Agent智能体架构&#xff0c;这个题目我确实有发言权。最近一年我主导了好几个从"单体Agent"往"多Agent协作"迁移的项目&#xff0c;踩过的坑、推翻重来的设计都不少。2026年业内其实已经形成一个共识&#xff1a;这是工业智能…

作者头像 李华
网站建设 2026/10/1 2:47:57

嘎嘎降AI实操指南:原理、模式选择与降AI率技巧

1. 嘎嘎降AI是什么&#xff1f;为什么你需要它先说结论&#xff1a;嘎嘎降AI是一个专门用来“去掉AI味儿”的文本处理工具。你把它当成一个过滤器就行——左边丢进去一段ChatGPT、DeepSeek、文心一言生成的稿子&#xff0c;右边出来一段读起来更像正常人写的文字&#xff0c;核…

作者头像 李华
网站建设 2026/10/1 2:47:46

搜索系列 · 第 03 篇——核心原理:倒排索引与 BM25

倒排索引 分词映射 相关性打分 段管理 目 录 一、导读 二、倒排索引原理 2.1 正排 vs 倒排 2.2 倒排索引结构 2.3 示例 三、分词器与映射 3.1 Analyzer 处理流程 3.2 常见分词器 3.3 映射&#xff1a;text vs keyword 四、BM25 相关性打分 4.1 从 TF-IDF 到 BM25 4.2 BM25 …

作者头像 李华