# 随机返回的毒鸡汤如何避免重复?去重缓存设计
> 接口/接入点:毒鸡汤生成(apiCode 2784,接入点 1) · 是否免费:免费 · 请求方式:POST/GET · 返回格式:JSON · 适用人群:中高级开发者、架构师 · 阅读时间:约 7 分钟
## 核心要点
- 接口**随机返回且无 ID/分类**,连发、定时推送、批量取句都容易撞句,去重必须由**调用方**自建。
- 用 Redis 存"近期句子哈希集合"做精确去重;内容池偏小时可叠加相似度(如最长公共子串)判重。
- 去重同时省额度:命中缓存直接返回,跳过一次接口调用。
## Why:为什么一定要去重
"每日推送""批量取句做素材库"这类需求,最怕连续两天同一句、或一批素材里大量重复。但接口不返回任何可用于判重的标识,也不保证不重复。所以去重逻辑只能放在调用方。
## What:接口速览
| 项目 | 说明 |
|------|------|
| 接口地址 | `https://route.showapi.com/2784-1` |
| 入参 | 无 |
| 返回关键字段 | `showapi_res_body.emposion` |
| 去重必要性 | 高(随机 + 无 ID) |
## How:Redis 精确去重(Python)
```python
import requests, hashlib, redis
API_URL = "https://route.showapi.com/2784-1"
APP_KEY = "YOUR_APPKEY"
r = redis.Redis(host="127.0.0.1", port=6379, db=0)
RECENT_KEY = "poison_soup:recent"
WINDOW = 50 # 近期 50 条内不重复
def get_unique_quote(max_try=6):
for _ in range(max_try):
body = requests.post(
API_URL, params={"appKey": APP_KEY},
headers={"content-type": "application/x-www-form-urlencoded"}, timeout=5,
).json().get("showapi_res_body", {})
if body.get("ret_code") != 0:
continue
text = body.get("emposion", "")
if not text:
continue
h = hashlib.md5(text.encode("utf-8")).hexdigest()
if not r.sismember(RECENT_KEY, h):
r.sadd(RECENT_KEY, h)
r.expire(RECENT_KEY, 60 * 60 * 24 * 30) # 30 天窗口
# 控制集合大小:保留最近 WINDOW 条
if r.scard(RECENT_KEY) > WINDOW:
# 简单策略:超量时重置窗口(生产可改用有序集合按时间裁剪)
r.expire(RECENT_KEY, 60 * 60 * 24)
return text
return "" # 兜底:极端情况返回空,由上层决定
```
### 相似度兜底(可选)
当内容池较小、精确哈希频繁碰撞导致取不到新句时,可对候选句与近期句子做"最长公共子串/编辑距离"比较,超过阈值视为近似重复。这是调用方逻辑,复杂度按需开启。
## 返回示例
```json
{ "showapi_res_body": { "ret_code": 0, "remark": "", "emposion": "上天给你关了门,顺手把窗户也焊死了。" } }
```
## 进阶/边界
- **窗口是权衡**:窗口越大越不重复,但碰撞重试越多、额度消耗越大。按你的内容池规模调 `WINDOW` 与 `max_try`。
- **多实例共享**:用 Redis 这类共享存储,避免多台机器各记各的、整体仍重复。
- **省额度**:去重放在"调用前先看缓存"能进一步省;但本接口无"按内容查重"的远端能力,缓存只能记"自己取过什么"。
- **无法按主题去重**:去重只解决"别重复",解决不了"要某主题"。主题化需返回后关键词过滤,见概览篇说明。
## FAQ
**Q1:接口有没有返回 ID 能直接去重?**
没有。返回体只有 `ret_code / remark / emposion`,无唯一 ID,只能对 `emposion` 文本做哈希去重。
**Q2:本地文件去重够用吗?**
低频单实例(如每天定时一条)够用;多实例/高并发或需要跨进程共享时,用 Redis 等共享存储。
**Q3:去重会不会把免费额度很快用完?**
避让重试本身消耗额度。把窗口与 `max_try` 控制在合理范围,并参考《免费档位下,如何控制毒鸡汤调用频次与成本?》做额度规划。
## 相关能力 / 下一步阅读
- [公众号/社群每日毒鸡汤推送:定时任务 + 去重设计](https://www.showapi.com/guides/poison-soup-daily-push-2784) —— 去重在定时场景的落地
- [毒鸡汤接口 5 秒超时下,如何做重试与容错?](https://www.showapi.com/guides/poison-soup-timeout-retry-2784) —— 重试与额度平衡
- [免费档位下,如何控制毒鸡汤调用频次与成本?](https://www.showapi.com/guides/poison-soup-free-tier-2784) —— 额度与频控
- **本系列共 14 篇**:查看[毒鸡汤生成接口官方指南总目录](https://www.showapi.com/guides/poison-soup-guides-2784)