feat: implement t-604 keyword prompt moderation

This commit is contained in:
QiuSW
2026-07-06 14:57:25 +08:00
parent c89cb4cf28
commit ca0ffb8dbe
24 changed files with 787 additions and 10 deletions
+27
View File
@@ -1241,3 +1241,30 @@
- 单独复跑失败起点 `apps.billing.tests.BillingServiceTests apps.billing.tests.BillingAdminTests apps.billing.tests.ConcurrentDebitTests`:17 条业务用例 OK;并发扣点用例本体打印 `ok` 后在测试库 flush 阶段再次因 MySQL 连接超时 / WinError 10060 记 ERROR。
- 结论:T-605 相关测试已通过,全量单次绿受远程 MySQL 长跑稳定性阻塞,不是本任务断言失败。
- 下一步:回到 T-603,在更稳定的 MySQL 测试库或网络条件下补跑完整验证,再决定是否标 `DONE`。
## 2026-07-06 T-604:中文敏感词本地过滤
- 状态:DONE。
- 目标:按 `docs/moderation.md` 落地本地 keyword provider,只审核输入 prompt;命中必须在下载 `image_url`、解析别名、计费、预扣点和上游调用前返回 `400 content_blocked`。
- 依赖确认:编码前已验证 `ahocorapy==1.6.2` 可安装,API 使用 `KeywordTree.add()` / `finalize()` / `search_all()`,`search_all()` 返回 `(matched_keyword, index)`。
- 代码变更:
- `config/settings.py` / `.env.example` / `requirements.txt`:接入 `apps.moderation`、`MODERATION_*` 配置和 `ahocorapy` 依赖。
- `apps/moderation`:新增 `SensitiveWord` 模型/admin/迁移、归一化管线、共享 cache 版本号、signal 失效、keyword provider 与 prompt 审核 service;清理早期 Tencent stub 和输出审核骨架。
- `apps/api/generation.py`:生成 title/image 的入口改为 serializer 后先 `moderate_prompt()`;命中直接 `content_blocked`,未命中才读取图片并继续别名、计费、扣点、上游调用。
- `apps/api/tests.py` / `apps/moderation/tests.py`:覆盖 no-op、归一化、防绕过、词库版本重建、命中不下载图片/不扣点/不建记录/不调上游。
- 文档变更:
- `docs/moderation.md`:从设计口径更新为实现态,明确 T-604 已清理输出审核和云厂商 stub。
- `docs/06-tasks.md`:T-604 标为 DONE。
- `docs/current-state.md`:同步依赖、当前状态、配置基线、验证证据和任务看板。
- 验证:
- `py -3.12 -m py_compile config\settings.py apps\api\generation.py apps\api\tests.py apps\moderation\apps.py apps\moderation\models.py apps\moderation\normalization.py apps\moderation\policy.py apps\moderation\services.py apps\moderation\signals.py apps\moderation\versioning.py apps\moderation\providers\base.py apps\moderation\providers\keyword.py apps\moderation\tests.py`:通过。
- `py -3.12 manage.py check`:通过,0 issues。
- `py -3.12 manage.py makemigrations --check --dry-run`:通过,No changes detected。
- `py -3.12 manage.py test apps.moderation --keepdb --noinput --verbosity 2`:通过,7 tests OK。
- `py -3.12 manage.py test apps.api.tests.GenerateApiTests.test_blocked_prompt_returns_content_blocked_before_image_download_or_charge apps.api.tests.GenerateApiTests.test_disabled_moderation_does_not_block_matching_prompt --keepdb --noinput --verbosity 2`:通过,2 tests OK。
- `py -3.12 manage.py test apps.api.tests.GenerateApiTests --keepdb --noinput --verbosity 2`:通过,16 tests OK。
- 测试期仅保留 allauth 在 MySQL 条件唯一约束上的既有 `models.W036` 警告,本项目邮箱唯一性由 `user.email` 承担。
- 注意:
- 真实敏感词库数据不入仓库,需要运营在 admin 中维护或后续另做导入命令。
- 生产多 worker 必须使用共享 cache(DatabaseCache/Redis/Memcached)承载 `MODERATION_CACHE_VERSION_KEY`,不能依赖 `LocMemCache` 做跨进程刷新。
- 下一个看板任务仍是 T-603:在稳定 MySQL 测试库上补跑完整验证并收尾。