接口概述
一句话说明
text.moderation 把文本风控前置到发布之前。 相比关键词黑名单,大模型能理解谐音、拆字、隐喻与上下文, 对「复杂、隐晦」的违规表达同样有效;接口返回的是 「结论 + 证据」——既有风险等级,也有具体命中的标签与置信度, 方便直接写进审核规则,而不是只拿到一个「通过 / 拒绝」的黑盒结果。
| 请求地址 | https://api.xujian.tech/openapi/text/moderation |
|---|---|
| 请求方式 | GET(content 放 Query)或 POST(content 放 JSON 请求体);
文本含换行、引号等特殊字符时建议用 POST |
| 鉴权方式 | 请求头 X-API-Key(不做签名与加密) |
| 接口编码 | text.moderation |
| 收费类型 | PER_CALL(按次计费,0.0100 元/次) |
| 计费特殊规则 | 结论计费:content 为空 / 超长、大模型不可用、模型返回无法解析时 返回失败且不扣费;正常给出审核结论(含「未检测出风险」)正常计费 |
| 响应格式 | JSON,Content-Type: application/json;charset=UTF-8 |
| 是否需要授权 | 否(无需授权,API Key 有效且余额充足即可调用) |
| 文本长度 | 单次审核文本不超过 1800 个字符 |
| 典型耗时 | 通常 1 ~ 5 秒 |
| 典型用途 | 社区发帖 / 评论过滤、弹幕与聊天风控、昵称签名审核、电商评价与客服质检、 内容平台机审前置 |
快速开始
curl -s -X POST "https://api.xujian.tech/openapi/text/moderation" \
-H "Content-Type: application/json" \
-H "X-API-Key: 你的APIKey" \
-d '{"content": "加我微信 xxx666,带你日入过万,内部渠道稳赚不赔"}'
curl -s -G "https://api.xujian.tech/openapi/text/moderation" \
--data-urlencode "content=今天天气不错,适合出门散步" \
-H "X-API-Key: 你的APIKey"
风险等级怎么定
- 取本次命中标签中的最高等级,不使用模型自评,保证口径稳定;
high高风险 —— 建议拦截并转人工核实;medium中风险 —— 建议人工复核后再决定是否放行;low低风险 —— 建议放行,高召回场景可抽样复核;none未检测到风险 —— 直接放行,此时labels返回一条nonLabel记录。
请求参数
| 参数名 | 是否必填 | 说明 |
|---|---|---|
X-API-Key | 是 | 开发者 API Key |
Content-Type | POST 时必填 | application/json |
业务参数
| 字段 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
content | String | 是 | 待审核的文本内容,最长 1800 个字符(超长直接返回失败,不收费)。
GET 请求放 Query String,POST 请求放 JSON 请求体的 content 字段。 |
响应参数
| 字段 | 类型 | 示例 | 说明 |
|---|---|---|---|
riskLevel | String | high | 风险等级:none 未检测到风险 / low 低风险 /
medium 中风险 / high 高风险 |
riskLevelText | String | 高风险 | 风险等级中文名 |
suggest | String | 建议拦截并转人工核实 | 处置建议,可直接用于先发后审 / 先审后发的分流转派 |
summary | String | 疑似诈骗与广告导流内容 | 审核结论说明(最多 100 个字符) |
labels | Array | […] | 命中的风险标签明细,按危险程度从高到低;未检测到风险时为一条
nonLabel 记录。最多 10 条 |
labels[].label | String | fraud | 标签编码,取值见下方「标签体系」 |
labels[].labelName | String | 诈骗欺诈 | 标签中文名 |
labels[].description | String | 疑似返利诈骗内容 | 检测结果说明 |
labels[].confidence | Number | 92.00 | 置信度,0 ~ 100,保留 2 位小数; 模型没给分值时为 null,接入方请先判空 |
apiCode | String | text.moderation | 接口编码 |
apiName | String | AI文本审核服务 | 接口名称 |
chargeType | String | PER_CALL | 计费类型 |
balance | BigDecimal | 调用完成后(已扣费)的账户余额(元) | |
costMs | Long | 2100 | 本次调用耗时(毫秒) |
标签体系(labels[].label 全部可能取值)
| 标签编码 | 中文名 | 风险等级 | 判定范围 |
|---|---|---|---|
political | 涉政敏感 | high | 危害国家安全、分裂国家、损害国家形象等言论 |
pornography | 色情低俗 | high | 淫秽描写、招嫖、性交易暗示 |
violence | 暴恐极端 | high | 暴力血腥、恐怖袭击、极端主义宣扬 |
gambling | 赌博相关 | high | 赌博平台推广、赌局邀约 |
drug | 毒品违法 | high | 毒品交易、吸食引导 |
fraud | 诈骗欺诈 | high | 刷单返利、冒充公检法、钓鱼链接 |
prohibited | 违禁品交易 | high | 枪支弹药、管制刀具、野生动物交易 |
abuse | 攻击辱骂 | medium | 人身攻击、侮辱诽谤、歧视性言论 |
ad | 广告导流 | medium | 营销推广、联系方式导流、二维码拉群 |
privacy | 隐私泄露 | medium | 身份证号、手机号、住址、银行卡号等个人信息 |
other | 其他违规 | low | 不属于以上任何一类但不宜发布的内容(模型返回约定外编码时也归入此类) |
nonLabel | 未检测出风险 | none | 未命中任何风险时的占位标签 |
响应示例
成功(命中违规内容,code = 0)
{
"code": 0,
"msg": "success",
"data": {
"riskLevel": "high",
"riskLevelText": "高风险",
"suggest": "建议拦截并转人工核实",
"summary": "疑似诈骗与广告导流内容",
"labels": [
{
"label": "fraud",
"labelName": "诈骗欺诈",
"description": "疑似返利诈骗内容",
"confidence": 92.00
},
{
"label": "ad",
"labelName": "广告导流",
"description": "疑似联系方式导流",
"confidence": 88.00
}
],
"apiCode": "text.moderation",
"apiName": "AI文本审核服务",
"chargeType": "PER_CALL",
"balance": 99.9900,
"costMs": 2100
}
}
成功(正常文本未检出风险,code = 0)
{
"code": 0,
"msg": "success",
"data": {
"riskLevel": "none",
"riskLevelText": "未检测到风险",
"suggest": "建议直接放行",
"summary": "正常文本,未检测出风险",
"labels": [
{
"label": "nonLabel",
"labelName": "未检测出风险",
"description": "未检测出风险",
"confidence": null
}
],
"apiCode": "text.moderation",
"apiName": "AI文本审核服务",
"chargeType": "PER_CALL",
"balance": 99.9800,
"costMs": 1800
}
}
失败(内容为空 / 超长)—— 不收费
{
"code": 500,
"msg": "content 长度不能超过 1800 个字符",
"data": null
}
失败(审核服务不可用)—— 不收费
{
"code": 500,
"msg": "文本审核服务暂时不可用(请求大模型超时或网络异常),本次调用不计费",
"data": null
}
错误码与常见失败原因
| code | msg(示例) | 处理建议 |
|---|---|---|
| 0 | success | 调用成功(含「未检测出风险」的结论) |
| 500 | 缺少请求头 X-API-Key | 补充 X-API-Key |
| 500 | API Key 无效 / API Key 已停用 | 检查 Key 或重新启用 |
| 500 | 客户不存在或已停用 | 联系平台(可联系微信xujian_cq) |
| 500 | 接口不存在或已停用 | 接口下线维护中,稍后再试 |
| 500 | 余额不足,请先充值。可联系微信xujian_cq | 充值后重试,余额不足不扣费 |
| 500 | content 不能为空(GET 传 Query 参数,POST 传 JSON {"content":"..."}) | 检查参数位置;不计费 |
| 500 | content 长度不能超过 1800 个字符 | 超长文本请分段后逐段调用;不计费 |
| 500 | 文本审核服务暂时不可用(……),本次调用不计费 | 大模型不可用 / 超时,稍后重试;不计费 |
多语言代码示例
Java(Hutool)
JSONObject req = JSONUtil.createObj().set("content", "加我微信 xxx666,带你日入过万");
String body = HttpRequest.post("https://api.xujian.tech/openapi/text/moderation")
.header("Content-Type", "application/json")
.header("X-API-Key", apiKey)
.timeout(30000) // 需要调用大模型,超时放宽到 30s
.body(req.toString())
.execute()
.body();
JSONObject json = JSONUtil.parseObj(body);
if (json.getInt("code") != 0) {
System.out.println("审核失败(不收费):" + json.getStr("msg"));
return;
}
JSONObject data = json.getJSONObject("data");
switch (data.getStr("riskLevel")) {
case "high" -> reject(data.getStr("summary")); // 拦截 + 人工核实
case "medium" -> review(data.getJSONArray("labels")); // 转人工复核
default -> pass(); // none / low 直接放行
}
Python
import requests
def moderate(api_key: str, content: str):
"""文本审核;服务不可用时返回 None 且不扣费"""
resp = requests.post(
"https://api.xujian.tech/openapi/text/moderation",
json={"content": content},
headers={"Content-Type": "application/json", "X-API-Key": api_key},
timeout=30,
)
result = resp.json()
if result.get("code") != 0:
print("审核失败(不收费):", result.get("msg"))
return None
data = result["data"]
labels = [f'{i["labelName"]}({i["confidence"]})' for i in data["labels"]]
print(data["riskLevelText"], data["suggest"], labels)
return data["riskLevel"]
if __name__ == "__main__":
moderate("你的APIKey", "今天天气不错,适合出门散步")
JavaScript(浏览器 / Node 18+)
const resp = await fetch("https://api.xujian.tech/openapi/text/moderation", {
method: "POST",
headers: { "Content-Type": "application/json", "X-API-Key": API_KEY },
body: JSON.stringify({ content: "加我微信 xxx666,带你日入过万" }),
});
const { code, msg, data } = await resp.json();
if (code === 0) {
const hits = data.labels.filter((i) => i.label !== "nonLabel");
console.log(`${data.riskLevelText}|${data.suggest}`, hits);
} else {
console.warn("审核失败(不收费):", msg);
}
常见问题(FAQ)
text.moderation 接口怎么收费?
text.moderation 的收费类型为 PER_CALL(按次计费),当前单价 0.0100 元/次,调用前校验余额,余额不足返回「余额不足,请先充值。可联系微信xujian_cq」且不扣费;充值可可联系微信xujian_cq。扣费金额、交易前后余额均记录于交易流水中。
「未检测出风险」会扣费吗?
会。给出「未检测出风险」本身就是一次完整的审核结论(大模型已经完成了推理), 与其他结论一样按次计费。只有 content 为空 / 超长、大模型不可用、 模型返回无法解析这几种情况才返回失败且不扣费。
和关键词过滤有什么区别?
关键词黑名单容易漏掉谐音、拆字、拼音缩写与隐喻表达(如「薇 ❤」「+v 看pyq」), 误杀率也高。本接口用大模型做语义级判定,能结合上下文给出标签与置信度, 并返回具体理由,便于写规则、也便于向用户解释拦截原因。
一次能审核多长的文本?
单次最多 1800 个字符,超出直接返回失败(不收费)。 长文(帖子、文章)建议在业务侧按段落切分后逐段调用,或直接取标题 + 正文前 1800 字做机审。
返回速度大概多少?建议怎么接入?
需要调用一次大模型,通常 1 ~ 5 秒,远慢于数据库查询类接口,请不要放在同步发布的主链路上 (会拖慢用户发帖体验)。推荐「先发后审 + 异步复核」:内容先入待审队列, 由后台任务调用本接口,审核完成后再改可见状态。
置信度 confidence 为 null 是什么意思?
模型对该标签没有给置信度评分时用 null 表示(多数出现在判定较有把握
或不便量化的场景)。接入方务必先判空再比较,
不要用 confidence > 90 这种写法直接参与运算。
可以直接拿这个结果做封号处罚吗?
不建议。大模型存在误判可能,接口返回的是机审建议: high / medium 风险请转人工复核后再做处置,尤其涉及封禁、扣款、风控拦截等强操作时, 务必保留人工兜底与申诉通道。
调用需要签名或加密吗?
不需要。XAPI 的接口仅校验请求头 X-API-Key,不做签名、时间戳或加密。