塔罗牌:AI塔罗牌解读服务的缓存
在优化OpenAI API费用和响应速度的同时,设计每次都提供新体验的塔罗服务缓存方案
问题意识
AI生成的内容每次都是新的,这是一大优势,但如果每次对相同的输入调用API,费用会迅速累积。塔罗牌服务也是一样。虽然使用OpenAI API进行牌面解读,但由于费用和响应速度问题,不可能对每个请求都调用API。
然而,仅仅将牌面和方向作为键的缓存是不够的。用户即使抽到相同的牌面,也期待每次有不同的解读。为缩小这一差距,我们引入了利用桶系统的缓存策略。
桶:多样性与效率的平衡
核心思想很简单。通过组合78张卡牌、正反方向以及10个桶,1560个唯一缓存键,并在每个键下存储AI生成的解读。
78张 × 2方向 × 10桶 = 1560个唯一组合每当用户请求时,会随机选择这一组合中的一个。缓存键是tarot:read:{card}:{direction}:{bucket}形式,使用相同键的后续请求立即从Valkey返回结果。只有在缓存中无结果时才调用OpenAI API。
此外,还有一个附加装置。服务器每次请求会随机选择4个关键词,与上下文一起传递给AI。因此,即使牌面、方向、桶相同,根据关键词的不同,解读也可能不同。
flowchart LR
subgraph RandomSelect["随机选择"]
Card[78张卡牌]
Dir[正反方向]
Bucket[桶 1~10]
Keywords[4个关键词]
end
subgraph CacheKey["缓存键"]
Key["tarot:read:{card}:{dir}:{bucket}"]
end
Card --> Key
Dir --> Key
Bucket --> Key
Key --> Valkey[(Valkey)]
Key -.->|缓存未命中| OpenAI[OpenAI API]
Keywords -.->|解读方向| OpenAI
整体流程用序列图表示如下。
sequenceDiagram
autonumber
actor Client as 客户端
participant Service as TarotService
participant Cache as Valkey
participant AI as OpenAI
Client->>Service: 塔罗解读请求
Note over Service: 随机选择牌面/方向/桶
Service->>Cache: 缓存查询 (`GET`)
alt 缓存命中
Cache-->>Service: 返回存储的结果
else 缓存未命中
Service->>AI: 调用OpenAI API
AI-->>Service: 返回解读结果 ({advice})
Note over Service: 数据组合<br/>(card.name / card.nameKR / keywords)
Service->>Cache: 保存结果 (`SET`)
end
Service-->>Client: 最终解读结果响应部署
前端通过Vercel,后端在本地Kubernetes集群上运行。
flowchart TD
subgraph Front["Vercel"]
Vercel[塔罗牌 Next.js 应用]
end
subgraph CICD["CI / CD"]
GH[GitHub]
Actions[GitHub Actions]
Harbor[(Harbor)]
ArgoCD[ArgoCD]
S3[(S3)]
end
subgraph K8s["本地 K8s 集群"]
GW[Gateway API]
Service[塔罗牌服务]
HPA[HPA: 2~10 副本]
end
%% 部署流水线流程
GH -->|Git 版本标签推送 v*.*.*| Actions
Actions -->|镜像构建/推送| Harbor
Harbor -->|镜像存储| S3
Harbor -->|镜像引用| ArgoCD
ArgoCD -->|GitOps 部署| Service
%% 前端流水线流程
Actions -->|前端构建/部署| Vercel
%% 流量流向
Vercel --> |外部流量| GW
GW -->|路由| Service
Service -->|自动扩展| HPA部署流水线在GitHub上新版本标签(v*.*.*)推送时立即自动启动。GitHub Actions基于该标签构建镜像并推送到内部容器仓库Harbor,ArgoCD通过GitOps配置检测变更并自动同步集群状态。此外,前端通过GitHub Actions直接进行Vercel的构建和部署。
后端通过HPA根据流量自动扩展为2至10个副本,外部用户的请求安全地路由到内部Gateway API。
改进空间
目前是一个不用登录即可使用的简单服务,但我们计划添加登录功能,以允许保存用户的解读历史和提供个性化的体验。
结语
塔罗牌服务虽然是一个小项目,但它包含了解决AI生成和缓存平衡的实际问题。利用桶系统的缓存策略在费用和多样性之间提供了实际的妥协方案,并有足够的改进空间。