Skip to content

语义缓存 (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{
    // [Required] Embedding model config (if semantic matching is enabled)
    Provider:       schemas.OpenAI,
    Keys:          []schemas.Key{{Value: "sk-..."}},
    EmbeddingModel: "text-embedding-3-small",
    Dimension:     1536,

    // Cache behavior config
    TTL:       5 * time.Minute,  // Cache TTL (time-to-live)
    Threshold: 0.8,              // Similarity threshold (default 0.8)
    CleanUpOnShutdown: true,     // Whether to clear the cache on shutdown

    // Conversation handling config
    ConversationHistoryThreshold: 5,        // Skip caching when conversation message count exceeds this value (prevents false matches)
    ExcludeSystemPrompt: bifrost.Ptr(false), // Whether to exclude the system prompt from the computation

    // Advanced isolation options
    CacheByModel:    bifrost.Ptr(true), // Isolate cache by model
    CacheByProvider: bifrost.Ptr(true), // Isolate cache by provider
}

plugin, err := semanticcache.Init(context.Background(), cacheConfig, logger, store)
if err != nil {
    log.Fatal("Failed to create semantic cache plugin:", err)
}

// Add the plugin to the Bifrost master config
bifrostConfig := schemas.BifrostConfig{
    LLMPlugins: []schemas.LLMPlugin{plugin},
    // ... other config
}

五、纯直接哈希模式 (无嵌入模型) ​

若不想调用任何嵌入 API(例如仅需精确去重、无外部网络环境),可启用纯哈希模式。

关键代码:纯直接哈希模式配置 ​

go
cacheConfig := &semanticcache.Config{
    // Do not provide Provider, Keys, or EmbeddingModel
    Dimension: 1, // Placeholder value; no vectors are actually stored, only metadata
    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"

// Set the cache key in the context; this request will be cached
ctx = context.WithValue(ctx, semanticcache.CacheKey, "session-123")
response, err := client.ChatCompletionRequest(schemas.NewBifrostContext(ctx, schemas.NoDeadline), request)

// A context without a cache key -> this request will not trigger caching
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
// Force direct-hash matching only
ctx = context.WithValue(ctx, semanticcache.CacheTypeKey, semanticcache.CacheTypeDirect)

// Force semantic-similarity matching only
ctx = context.WithValue(ctx, semanticcache.CacheTypeKey, semanticcache.CacheTypeSemantic)

3. 禁止存储本次响应 (只读不写) ​

go
ctx = context.WithValue(ctx, semanticcache.CacheNoStoreKey, true)

4. 手动清理缓存条目 ​

go
// Delete a specific entry by request ID
err := plugin.ClearCacheForRequestID("550e8400-e29b-41d4-a716-446655440000")

// Delete all related entries by cache key
err := plugin.ClearCacheForKey("support-session-456")

八、缓存命中后的调试信息 ​

git 缓存命中后,响应对象的 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 可实现精确的缓存条目管理。