gRPC结合FAISS构建AI助手语义缓存模块(一):设计

一、背景简介

原AI聊天助手项目中,每次提问(Prompt)都需要调用公有LLM API来获取大模型的回答(Answer),然而,有些时候用户会向聊天助手询问同样的问题,我们将KV存储集成到聊天助手当中,初步实现了一个Prompt对应一个Answer的缓存功能。

但是有时候,用户向聊天助手询问的问题并不是一字不差,同样的语义,由于prompt字面的不同,原先的缓存功能就失效,现在的问题是如何实现语义级别的缓存功能

二、组件依赖

2.1 高性能中间件 - 自研KV存储

Github - KVstore

支持命令

命令 语法 说明
SET SET 写入键值对,key 已存在则覆盖
GET GET 读取键值,不存在返回 $-1
DEL DEL 删除键,返回删除数量
EXISTS EXISTS 检查键是否存在,返回 0 / 1
MOD MOD 仅当键存在时更新值
SAVE SAVE 手动触发 RDB 快照保存
PING PING message 连通性探测,返回 PONG 或回显 message

2.2 高效向量搜索 - FAISS

语义级别的识别,首先想到的方案是结合FAISS来做,(Facebook AI Similarity Search),这是由 Meta(原 Facebook)开源的一个高效向量搜索库。

FAISS向量搜索具体的内部实现是一个比较复杂的问题,这里只粗浅介绍一下:

原始的prompt,比如"我饿了"、"我想吃饭",被模型编码成为高维向量:

复制代码
文本输入                    高维向量空间
"我饿了"    → 模型编码 → [0.12, -0.34, 0.56, ..., 0.78]  (768维)
"我想吃饭"  → 模型编码 → [0.11, -0.32, 0.55, ..., 0.79]  (768维)
                           ↑ 两个向量方向几乎相同 ↑

内存结构:

隐式ID 向量数据 (768个float32) 对应的文本
0 [0.0123, -0.0456, 0.0789, ...] "我饿了"
1 [0.0115, -0.0412, 0.0765, ...] "我想吃饭"
2 [-0.0891, 0.1234, -0.0056, ...] "今天天气不错"
  • FAISS 只存数字,不知道prompt的文本是什么
  • ID 自动生成(从0开始,每次调用add自增)
  • prompt文本存在KV存储里,用 ID 关联

检索时暴力遍历,通过余弦相似度衡量向量方向的相似性,给定阈值,判断是否命中。当然了,检索算法有内置的优化实现。

我们faiss模块中使用到的核心接口如下:

分类 接口 一句话作用
创建索引 IndexFlatIP 建一个用内积算相似度的索引
写入 add 把向量存进索引
检索 search 找最相似的 Top-K 个向量
保存 write_index 把内存索引存成文件
加载 read_index 从文件恢复索引到内存
取数量 ntotal 看索引里存了多少条
取维度 d 看向量是几维的

2.3 通信底座 - gRPC

gRPC(Google Remote Procedure Call)是由谷歌公司开发的远程调用框架。什么叫远程调用?

如下图所示,这是一个多语言多平台的系统,不同语言和平台之间的对象本不能直接相互调用,gRPC就是为了解决这个问题出现的:

通过Protobuf 协议(一种语言无关、平台无关且便于传输的序列化协议),server端对需要共享的对象进行序列化,接收端进行反序列化,并且client端通过stub封装从而实现直接调用 (无需关系底层实现),这篇博客介绍了你所需要的Protobuf相关内容

三、模块架构

Go后端作为gRPC的client,通过stub收发proto消息,由Python实现的faiss语义层为gRPCserver,他们之间的通信消息和服务由Proto文件给定,proto文件中定义三个接口函数:

伪代码 复制代码
GetCache(prompt)
PutCache(prompt)
DeleteCache(prompt)

prompt进faiss层被编码为相似度+ID,ID与KV中的answer绑定,faiss层通过GET ID、SET ID Answer等命令与KV存储交互。

整体模块架构总结如下:

复制代码
┌────────────────────────────────────────────────────────┐
│               业务客户端层 (Go Web 后端)               │
└───────────────────────────┬────────────────────────────┘
                            │ gRPC 通信 (50051)
┌───────────────────────────▼────────────────────────────┐
│ 1. 网关层 (main.py) - 流量拦截与服务生命周期管理        │
└───────────────────────────┬────────────────────────────┘
                            │ 本地方法调度
┌───────────────────────────▼────────────────────────────┐
│ 2. 核心算法层 (engine.py)                              │
│    ├── [模块 A] 语义编码 (SentenceTransformer)          │
│    ├── [模块 B] 几何正规化 ($L_2$ Normalization)       │
│    └── [模块 C] 容错自愈 (维度探测器)                   │
└───────────────────────────┬────────────────────────────┘
                            │ 双向读写
┌───────────────────────────▼────────────────────────────┐
│ 3. 存储与索引层 (持久化)                                │
│    ├── [模块 D] 内存阵列检索 (FAISS) ──> 负责"控门"   │
│    └── [模块 E] KV缓存 (自研KV)  ──> 负责"管账"   │
└────────────────────────────────────────────────────────┘
相关推荐
IT_陈寒34 分钟前
React的setState竟然不是立刻生效的,害我调试半天
前端·人工智能·后端
腾讯云大数据39 分钟前
腾讯云大数据计算智能:从结构化 SQL 到多模态 AI Workload 的融合范式
大数据·人工智能·腾讯云
AI职业加油站1 小时前
大数据采集工程师:技术栈全景图与实战路径
大数据·人工智能·数据分析
code 旭1 小时前
不会编程也能做AI 量化交易工具:基于 MCP 协议的自然语言交易思路不会编程也能做AI 量化交易工具:基于 MCP 协议的自然语言交易思路
人工智能·ai·量化交易·mcp
AI服务老曹1 小时前
视觉算法模型管理完整流程:多版本上线、灰度发布与回滚的落地实践
人工智能·docker·音视频
机器之心2 小时前
Anthropic发现Claude「类意识工作台」!神秘J空间藏着没说出口的想法
人工智能·openai
AI实践录2 小时前
大模型架构:理解大模型预测输出文本的底层逻辑
人工智能
Lifangyun_WD2 小时前
昇腾910B vs NVIDIA A100/H100:国产GPU算力租赁选型与迁移实践
人工智能·gpu算力·ai算力·算力租赁·gpu云主机
烟漠河洛2 小时前
线上事故复盘:Redis幂等性设计边界没覆盖跨状态请求,订单状态机直接崩了
数据库·redis·缓存
卡卡罗特AI2 小时前
GPT5.6 今晚全量开发?Codex上线史上最强Coding模型!
人工智能·ai编程