幂等性
幂等性是确保同一操作执行多次和执行一次效果相同的工程实践。在 AI Agent 应用中,它防止网络重试导致的重复消息、重复工具调用和重复扣款。
#type / concept
#status / evergreen
#tech / backend
#tech / architecture
[!info] related notes
- 所属 MOC: AI Agent Application MOC
- 相关: Tool Idempotency, Retry Policy
幂等性
一句话定义
幂等性是确保同一操作执行多次和执行一次效果相同的工程实践。用户点击”发送”按钮两次、网络超时重试、SSE 重连后重发,都不应该导致重复操作。
它解决什么问题
网络不可靠:
- 用户双击发送按钮 → 两条相同消息
- 网络超时重试 → 重复调用工具
- SSE 断连重连 → 重复处理事件
- 工具执行成功但返回失败 → 重试导致重复执行(如重复扣款)
核心原理
幂等性实现方式
| 方式 | 原理 | 适用场景 |
|---|---|---|
| 唯一 ID | 每个请求带唯一 ID,服务端去重 | API 请求 |
| 天然幂等 | 操作本身幂等(如 SET x=1) | 数据库操作 |
| 去重表 | 记录已执行的操作 ID | 工具调用 |
| 乐观锁 | 版本号冲突则拒绝 | 并发更新 |
幂等 Key 实现
func IdempotentMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
idempotencyKey := r.Header.Get("Idempotency-Key")
if idempotencyKey == "" {
idempotencyKey = generateUUID()
}
// 检查是否已执行
if cached, ok := cache.Get(idempotencyKey); ok {
w.Header().Set("X-Idempotent-Replayed", "true")
json.NewEncoder(w).Encode(cached)
return
}
// 执行并缓存结果
result := executeRequest(r)
cache.Set(idempotencyKey, result, 24*time.Hour)
json.NewEncoder(w).Encode(result)
})
}
常见坑
- 不做去重: 用户双击导致重复消息
- 工具不幂等: 重试导致重复扣款
- 去重 Key 不传递: 前端生成了 Key 但后端没用
- 去重窗口太短: 重试时间超过了去重窗口