Skip to content

feat(classifier): 新增 notResource flag,AI 兜底拦表情包/dev URL/裸图片#21

Merged
longsizhuo merged 2 commits into
mainfrom
fix/classifier-not-resource-flag
Apr 26, 2026
Merged

feat(classifier): 新增 notResource flag,AI 兜底拦表情包/dev URL/裸图片#21
longsizhuo merged 2 commits into
mainfrom
fix/classifier-not-resource-flag

Conversation

@longsizhuo
Copy link
Copy Markdown
Member

Summary

ChatBot listener 改了几轮黑名单(贴纸 host / 媒体扩展名 / self-org GitHub dev 子路径),把 `#5 mmbiz 图片` / `#18 klipy GIF` / `#19 自家 PR` 这种非资源链接挡掉。但黑名单永远穷举不完——backend 这层 AI 兜底必须能 catch listener 漏的。

改法

`ClassificationResult` 加第 5 个 flag `notResource`

命中场景 notResource
表情包 / 贴纸 / GIF(tenor / klipy / giphy / 微博表情) `true`
单张图片 / 截图 / 头像(孤立的纯图片页面) `true`
视频/音频文件直链(路径以 .mp4 / .mp3 / .gif 结尾) `true`
登录墙 / 错误页 / 验证码 / 404 / 维护页 `true`
内部 dev 通知页(GitHub PR/Issue/Commit、Jira、CI 报告) `true`
空白页 / 广告聚合页 / 跳转中转页 `true`
技术博客文章 / 论文 / 开源项目主页(README) / 教程 / 新闻 `false`
仓库主页(github.com/foo/bar)—— dev 子路径才算 `false`

任一 flag 命中(含 notResource)→ Worker 走 FLAGGED 进人工待审,跟 nsfw/ad/flame/illegal 同级。

改动

  • `ClassificationResult`: 加 `boolean notResource` 字段,更新 `anyFlagSet()` / `fallback()` / `blockedByContentFilter()`
  • `ClassificationService`: prompt 加详细判定规则 + JSON 模板加新字段;parseResponse 用 `.asBoolean(false)` 读,旧 cache/旧模型响应缺字段时降级 false
  • `SharedLinkEnrichmentWorker`: log 行 + flags Map 都加 `notResource`
  • `SharedLinkEnrichmentWorkerTests`: +1 场景验证 `notResource=true → FLAGGED`

兼容性

  • 旧 DeepSeek 模型若不返回 notResource 字段 → 降级 false → 不影响现有通过/拦截行为
  • 前端 admin 复核界面读 flags map 显示,多一个 key 自然展示

Test

  • `./mvnw -q test -Dtest='com.involutionhell.backend.community.**'` — 51/51 pass
  • 编译 clean

后续不在本 PR scope

  • ChatBot listener 那边的黑名单不删(双层防御)
  • 实际生效需要重启 prod backend Docker 容器(用户操作)

🤖 Generated with Claude Code

事故复盘:ChatBot listener 漏过表情包/GIF/自家 GitHub PR 链接,被 DeepSeek 走完分类后打 APPROVED 上架(#5/#18/#19)。listener 改了多轮黑名单(贴纸聚合站、媒体扩展名、self-org GitHub dev 子路径),但黑名单永远穷举不完。

改:ClassificationResult 加第 5 个 flag notResource,prompt 教模型识别'内容资源 vs 非资源':表情包/贴纸/GIF/裸图片/视频音频直链/登录墙/错误页/dev 子路径(PR/issue/commit)一律 notResource=true → 走 FLAGGED 进人工待审。仓库主页、文章、论文、项目主页等正常资源全 false 放行。

兼容性:parseResponse 用 .asBoolean(false) 读 notResource,旧模型/旧 cache 缺字段时降级为 false,不阻拦正常分享。flags map 多带一个 key,前端展示逻辑会自然 fallthrough。

测试:+1 场景 (notResource=true → FLAGGED),全 50 个 community.** 测试 pass。
Copilot AI review requested due to automatic review settings April 25, 2026 08:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 为链接分类结果新增 notResource 兜底标记,用于在 listener 黑名单覆盖不到的情况下,通过 AI 审核识别“非可分享资源”(表情包/GIF/裸图片页/登录墙/dev 通知页等)并进入人工复核队列,避免这类链接被自动上架。

Changes:

  • ClassificationResult 新增 boolean notResource,并纳入 anyFlagSet() 与降级工厂方法返回值
  • ClassificationService 更新 prompt 规则与 JSON 模板,并在解析时兼容旧响应缺字段默认 false
  • SharedLinkEnrichmentWorkerTests 增加 notResource=true → FLAGGED 的单测覆盖

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/main/java/com/involutionhell/backend/community/service/ClassificationResult.java 新增 notResource 字段并将其纳入 flag 聚合与降级返回
src/main/java/com/involutionhell/backend/community/service/ClassificationService.java prompt/模板/解析逻辑支持 notResource 且对旧模型输出保持兼容
src/test/java/com/involutionhell/backend/community/service/SharedLinkEnrichmentWorkerTests.java 新增 notResource 场景测试,验证会路由到 FLAGGED 且 flags map 包含新 key

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@longsizhuo longsizhuo merged commit 4dbf756 into main Apr 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants