在做内容聚合/审核类项目时,经常遇到“文本是否重复/相似”的判断需求。自己实现一套相似度算法(分词、向量化、编辑距离等)成本不低,维护也麻烦。最近接入了一个现成接口,整体响应快、数据维度也够用,这里做个简单复盘。
一、接口能做什么?
核心能力:对两段文本进行相似度分析,并返回多维度算法指标
先看返回结构(已做精简):
{ "code": 200, "msg": "success", "data": { "text1_length": 10, "text2_length": 13, "overall_score": 0.3566, "similarity_level": "slightly_similar", "level_name": "轻度相似", "metrics": { "cosine": 0.4129, "jaccard": 0.2571, "edit_similarity": 0.3846, "lcs_similarity": 0.5217, "prefix_similarity": 0, "edit_distance": 8 } }, "time": 1777298792 }字段说明(挑重点):
overall_score:综合相似度(0-1),可以直接作为业务判断依据similarity_level:英文分级标识(如:slightly_similar)level_name:中文分级(适合前端直接展示)text1_length / text2_length:文本长度,方便做归一化分析metrics
:算法细节指标(这个比较关键)
cosine:余弦相似度(偏语义)jaccard:集合相似度(偏词集合)edit_similarity:编辑相似度(字符级)lcs_similarity:最长公共子序列prefix_similarity:公共前缀edit_distance:编辑距离(差异程度)
👉 结论:不仅给结果,还给“过程指标”,方便做二次策略判断。
二、使用体验与技术评估
1. 多算法聚合,省去重复造轮子
常见的几种文本相似度算法都内置了,不需要自己做分词、建模、调权重。
2. 返回结构适合直接落业务
overall_score可以直接做阈值判断level_name可以直接给前端展示metrics可用于精细化策略(比如区分“抄袭 vs 改写”)
3. 响应性能可用
平均耗时:9ms 左右
对在线接口来说,可以直接同步调用
4. 调用门槛低
无 Key 也能调用(按 IP 限制)
有 Key 后额度提升,适合逐步接入
三、一些实际用法思路(架构延伸)
思路1:作为内容去重服务的核心判定层
典型流程:
用户提交内容 → 提取文本 → 调用相似度接口 → 判断阈值 → 入库/拦截
示例策略:
overall_score > 0.8→ 判定为重复0.5 ~ 0.8→ 进入人工审核< 0.5→ 正常通过
思路2:结合 Redis 做结果缓存(避免重复请求)
很多场景下,相同文本组合会反复出现。
可以做一层缓存:
key = hash(text1 + text2) value = 相似度结果(JSON) TTL = 1小时
收益:
降低接口调用次数
提升整体响应速度
避免触发 QPS 限制
思路3:异步化处理(适合批量任务)
如果是批量检测(比如历史数据清洗):
写入消息队列(Kafka / RabbitMQ)
Worker 异步调用接口
结果写回数据库
这样可以避免同步接口阻塞主流程。
思路4:多指标融合(二次建模)
接口已经提供了多个算法指标,可以自己做一层加权:
final_score = 0.5*cosine + 0.3*jaccard + 0.2*edit_similarity
适用于:
特定领域文本(如评论、标题党、短文本)
对“语义 vs 字面”的权重有特殊要求
四、多语言调用示例
Python(推荐,带异常处理)
import requests API_ENDPOINT = "https://v1.apizero.cn/textsim" def check_similarity(text1, text2, api_key=None): headers = { "Content-Type": "application/json" } # 可选:携带 Key if api_key: headers["X-Api-Key"] = api_key payload = { "text1": text1, "text2": text2 } try: response = requests.post(API_ENDPOINT, json=payload, headers=headers, timeout=5) response.raise_for_status() data = response.json() if data.get("code") != 200: print("接口返回异常:", data.get("msg")) return None result = data["data"] print("综合相似度:", result["overall_score"]) print("相似等级:", result["level_name"]) print("余弦相似度:", result["metrics"]["cosine"]) return result except requests.exceptions.Timeout: print("请求超时") except requests.exceptions.RequestException as e: print("请求异常:", e) except ValueError: print("JSON 解析失败") return None if __name__ == "__main__": t1 = "今天天气很好,适合出去散步" t2 = "天气不错,今天很适合外出走走" check_similarity(t1, t2)JavaScript(Fetch 版本)
const API_ENDPOINT = "https://v1.apizero.cn/textsim"; async function checkSimilarity(text1, text2) { try { const res = await fetch(API_ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text1, text2 }) }); const data = await res.json(); if (data.code !== 200) { console.error("接口错误:", data.msg); return; } console.log("相似度:", data.data.overall_score); console.log("等级:", data.data.level_name); } catch (err) { console.error("请求失败:", err); } } checkSimilarity("文本A", "文本B");五、简单总结
在内容审核、去重、相似推荐这类场景中,文本相似度是一个绕不开的基础能力。这类接口的价值在于:直接提供多算法结果,省去底层实现成本,同时又保留了足够的可扩展空间。
对于有文本比对需求的项目,可以作为一个基础能力模块接入,再结合缓存、队列等手段做工程化优化。
接口地址(技术资料)
https://www.apizero.cn/marketplace/textsim有时候,少写几百行代码,比什么优化都更实在。