Files
zhuangang/scenarios/content-moderation.md

89 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: scenario.content-moderation
title: 内容审核:规则 + 模型的分层审核、异步流水线、人工复审、申诉和效果度量
type: scenario
domain: cross
stack: [mq, redis, postgresql, prompt-engineering, agent-ops, fastapi, react]
tags: [内容审核, 分层过滤, 敏感词, 大模型审核, 人工复审, 异步, 召回率, 误杀率]
level: intermediate
prerequisites: [backend.mq.index, ai.prompt-engineering.index]
est_hours: 2.5
related: [ai.prompt-engineering.scenario.injection-defense, ai.agent-ops.scenario.agent-quality-gate, backend.mq.reliability]
week: [13, 14]
---
# 内容审核:规则 + 模型的分层审核、异步流水线、人工复审、申诉和效果度量
## 业务背景与问题
社区产品允许用户发帖、评论,同时 AI 助手会生成回复。监管和平台要求:
1. 违规内容(色情、暴力、诈骗广告、个人信息泄露)要及时拦截;
2. 纯人工审核成本高、速度慢;纯关键词误杀多(“打击诈骗”被当成诈骗);
3. AI 生成的内容同样要审核;
4. 用户对误判可以申诉。
## 约束
- 发帖体验不能明显变慢。
- 高风险内容宁可误杀;低风险内容宁可放过后再处理。
- 审核标准会随政策变化。
## 方案设计
1. **分层审核**:
- 第一层(同步,毫秒级):敏感词(AC 自动机 / 词库服务)、黑名单 URL、正则(手机号、身份证号)→ 命中高危直接拒绝;
- 第二层(异步,秒级):大模型按审核标准分类,输出结构化结果(类别、风险等级、证据片段、理由);
- 第三层(人工):中风险和模型不确定的内容进入人工复审队列,按风险和时效排序。
2. **发布策略**:低风险先发布(“先发后审”),中风险“仅自己可见”直到审核完成,高风险拒绝。
3. **异步流水线**:发帖写库后发消息,审核服务消费(重试、死信、幂等:按内容 id + 内容哈希);结果回写并通知。
4. **AI 生成内容**:输出前过第一层;流式输出时按句缓冲检测,命中即中止并替换为提示语。
5. **审核标准即配置**:审核提示词和类别定义版本化管理;修改后用标注集回归(召回率、误杀率)通过才上线。
6. **申诉与反馈**:申诉进入人工复审;复审结论回流到标注集,用于评测和改进规则。
7. **防对抗**:谐音、拆字、图片中的文字(OCR);提示词注入(帖子内容里写“忽略审核规则”),审核提示词中把用户内容作为数据隔离。
## 关键代码
审核结果结构与决策(示意):
```python
class ModerationResult(BaseModel):
category: Literal["ok", "porn", "violence", "fraud", "pii", "other"]
risk: Literal["low", "medium", "high"]
evidence: list[str] = Field(max_length=5) # 命中的原文片段,方便复审
reason: str
def decide(rule_hit: RuleHit | None, model: ModerationResult | None) -> str:
if rule_hit and rule_hit.level == "high":
return "reject"
if model is None: # 模型超时 / 不可用:进入人工,不自动放行中高风险
return "manual_review"
if model.risk == "high":
return "reject"
if model.risk == "medium" or (rule_hit and rule_hit.level == "medium"):
return "manual_review"
return "publish"
```
审核提示词中隔离用户内容(防注入)的写法见[提示词注入防护](../topics/ai/prompt-engineering/scenarios/injection-defense.md);评测和门禁见 [Agent 质量门禁](../topics/ai/agent-ops/scenarios/agent-quality-gate.md)。
## 取舍
| 决策 | 选择 | 原因 |
| --- | --- | --- |
| 审核方式 | 规则 + 模型 + 人工分层 | 兼顾速度、成本和准确率 |
| 发布时机 | 按风险分级 | 体验和安全的平衡 |
| 模型故障 | 降级为人工 | 不能因故障放行风险内容 |
| 标准变更 | 标注集回归 | 防止改一条规则引起大量误杀 |
## 易错点
- 只看召回率(拦住多少违规),不看误杀率(误伤多少正常内容)。
- 审核结果覆盖了用户后来编辑过的新内容(用内容哈希校验版本)。
- 把用户内容直接拼进审核提示词,被注入。
- 审核日志中保存了大量个人信息,没有脱敏和保留期限。
## 面试怎么讲
> “内容审核我做了三层:同步的敏感词和正则直接拦高危;异步的大模型按审核标准输出类别、风险和证据;中风险和不确定的进人工复审。发布按风险分级,模型故障时降级到人工而不是放行。审核标准作为版本化配置,修改后用标注集回归召回率和误杀率。申诉结论回流到标注集。”