语义缓存 (Semantic Cache)
一、什么是语义缓存?
语义缓存利用向量相似性搜索,对 AI 响应进行智能缓存。即使两次请求的文字表述不完全相同,只要语义相似,就能直接返回缓存结果,从而大幅降低重复调用大模型的成本和延迟。
四大核心优势
- 降低成本:避免为相似请求重复调用昂贵的 LLM API
- 性能提升:亚毫秒级缓存读取 vs. 秒级 API 调用
- 智能匹配:超越精确文本匹配,实现语义相似识别
- 流式支持:完整支持流式响应的缓存与顺序还原
二、核心机制:双层缓存 (Dual-Layer Caching)
语义缓存包含两种匹配策略:
| 模式 | 机制 | 说明 |
|---|---|---|
| 直接哈希模式 (Exact Hash) | 对请求内容计算确定性哈希 | 完全相同请求 → 立即命中,最快速度,无需嵌入模型 |
| 语义相似模式 (Semantic) | 生成向量嵌入进行相似度搜索 | 文字不同但语义相近 → 命中缓存,需配置嵌入模型 |
默认行为:先尝试直接哈希匹配,若未命中则回退到语义相似搜索。
三、必须的组件:向量数据库 (Vector Store)
语义缓存必须配置向量数据库作为存储后端。支持的类型包括:
- Weaviate (生产级 gRPC 支持)
- Redis / Valkey (高性能内存存储,推荐用于纯哈希模式)
- Qdrant (Rust 编写,支持高级过滤)
- Pinecone (托管服务,支持 Serverless)
关键代码:初始化向量存储 (以 Weaviate 为例)
go
import (
"context"
"github.com/maximhq/bifrost/framework/vectorstore"
)
vectorConfig := &vectorstore.Config{
Enabled: true,
Type: vectorstore.VectorStoreTypeWeaviate,
Config: vectorstore.WeaviateConfig{
Scheme: "http",
Host: "localhost:8080",
},
}
store, err := vectorstore.NewVectorStore(context.Background(), vectorConfig, logger)
if err != nil {
log.Fatal("Failed to create vector store:", err)
}四、核心配置:启用语义缓存
关键代码:创建并配置语义缓存插件 (Go SDK)
go
import (
"time"
"github.com/maximhq/bifrost/plugins/semanticcache"
"github.com/maximhq/bifrost/core/schemas"
)
cacheConfig := &semanticcache.Config{
// 【必填】嵌入模型配置 (若启用语义匹配)
Provider: schemas.OpenAI,
Keys: []schemas.Key{{Value: "sk-..."}},
EmbeddingModel: "text-embedding-3-small",
Dimension: 1536,
// 缓存行为配置
TTL: 5 * time.Minute, // 缓存有效期
Threshold: 0.8, // 相似度阈值 (默认 0.8)
CleanUpOnShutdown: true, // 关闭时是否清空缓存
// 对话处理配置
ConversationHistoryThreshold: 5, // 对话消息数超过该值则不缓存 (防误判)
ExcludeSystemPrompt: bifrost.Ptr(false), // 是否排除系统提示词参与计算
// 高级隔离选项
CacheByModel: bifrost.Ptr(true), // 按模型隔离缓存
CacheByProvider: bifrost.Ptr(true), // 按提供商隔离缓存
}
plugin, err := semanticcache.Init(context.Background(), cacheConfig, logger, store)
if err != nil {
log.Fatal("Failed to create semantic cache plugin:", err)
}
// 将插件加入 Bifrost 总配置
bifrostConfig := schemas.BifrostConfig{
LLMPlugins: []schemas.LLMPlugin{plugin},
// ... 其他配置
}五、纯直接哈希模式 (无嵌入模型)
若不想调用任何嵌入 API(例如仅需精确去重、无外部网络环境),可启用纯哈希模式。
关键代码:纯直接哈希模式配置
go
cacheConfig := &semanticcache.Config{
// 不提供 Provider、Keys、EmbeddingModel
Dimension: 1, // 占位值,实际存储无向量,仅元数据
TTL: 5 * time.Minute,
CleanUpOnShutdown: true,
CacheByModel: bifrost.Ptr(true),
CacheByProvider: bifrost.Ptr(true),
}
plugin, err := semanticcache.Init(ctx, cacheConfig, logger, store)注意
纯哈希模式下仍需要向量数据库,推荐使用 Redis / Valkey(无需真实向量字段)。
六、必须触发的条件:设置缓存键 (Cache Key)
语义缓存仅在请求上下文中提供了缓存键时才会生效。无缓存键的请求将完全绕过缓存。
关键代码:在请求中注入缓存键
go
import "github.com/maximhq/bifrost/plugins/semanticcache"
// 在上下文中设置缓存键,此请求将被缓存
ctx = context.WithValue(ctx, semanticcache.CacheKey, "session-123")
response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), request)
// 未设置缓存键的上下文 → 此请求不会触发缓存
response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(context.Background(), schemas.NoDeadline), request)七、高级控制选项
1. 单次请求动态覆盖 TTL 和阈值
go
ctx = context.WithValue(ctx, semanticcache.CacheKey, "session-123")
ctx = context.WithValue(ctx, semanticcache.CacheTTLKey, 30*time.Second)
ctx = context.WithValue(ctx, semanticcache.CacheThresholdKey, 0.9)2. 强制指定缓存类型 (仅双模式有效)
go
// 强制仅用直接哈希匹配
ctx = context.WithValue(ctx, semanticcache.CacheTypeKey, semanticcache.CacheTypeDirect)
// 强制仅用语义相似匹配
ctx = context.WithValue(ctx, semanticcache.CacheTypeKey, semanticcache.CacheTypeSemantic)3. 禁止存储本次响应 (只读不写)
go
ctx = context.WithValue(ctx, semanticcache.CacheNoStoreKey, true)4. 手动清理缓存条目
go
// 按请求 ID 删除特定条目
err := plugin.ClearCacheForRequestID("550e8400-e29b-41d4-a716-446655440000")
// 按缓存键删除全部相关条目
err := plugin.ClearCacheForKey("support-session-456")八、缓存命中后的调试信息
缓存命中后,响应对象的 ExtraFields.CacheDebug 字段会包含一个 JSON 对象,其中关键字段如下:
直接哈希命中
json
{
"cache_hit": true,
"hit_type": "direct",
"cache_id": "550e8500-e29b-41d4-a725-446655440001"
}语义相似命中
json
{
"cache_hit": true,
"hit_type": "semantic",
"cache_id": "550e8500-e29b-41d4-a725-446655440001",
"threshold": 0.8,
"similarity": 0.95,
"provider_used": "openai",
"model_used": "gpt-4o-mini",
"input_tokens": 100
}提示
利用 cache_id 可实现精确的缓存条目管理。