Files
violation-detector/README.md
3218485270 b413104587 feat: 结构化输出按官方规范 + 两段式重试 + DeepSeek 复检开关
- 豆包: response_format.json_schema(strict);DeepSeek: 切 Responses API text.format.json_schema
  (官方 chat/completions 通道不支持 json_schema),不支持时自动降级 json_object([output] schema)
- 重试两段式:传输错误 cfg.retries 次;解析失败/空正文有独立 3 次专用重试,仍失败落 parse_fail
- 移除三票复核(decide_final/_verify_clean/verify_clean),DeepSeek 单次判定即终稿
- 新增 [run] deepseek_recheck 开关(默认 no=仅豆包初筛;yes=追加 DeepSeek 复检)
- GUI 不再覆盖 config 提示词;prompt 相对/前导斜杠路径按 exe 目录解析
- 报表去「票型/复核」列并同步说明;README/config.example.ini 同步
- 测试新增输出格式、重试、开关与提示词路径用例(50 passed)
2026-09-03 11:44:10 +08:00

6.2 KiB
Raw Permalink Blame History

商品图合规检测工具

同一份 17 类违规检测提示词,两级级联调用视觉模型,在控制成本的同时从严检测:

全部图片 ──▶ 豆包(火山方舟 Ark)初筛 ──┬─ 判为违规 ──▶ 直接定稿(便宜,拦下大头)
                                        └─ 无违规/违规不明/异常 ──▶ DeepSeek 复检(可开关)
                                                                     (单次判定即终稿,已移除三票复核)

DeepSeek 复检默认关闭([run] deepseek_recheck=no),即默认只跑豆包初筛; 需要第二级复检时把该开关设为 yes(或 mode=deepseek 全量走 DeepSeek)。

AI 输出启用官方结构化输出:豆包走 response_format.json_schemastrict),DeepSeek 走 Responses API 的 text.format.json_schema(其 chat/completions 通道不支持 schema); 接口不支持时自动降级 json_object(见 [output] schema),保证单次判定稳定可靠。

输出结构

指定输出目录后,自动建立时间戳文件夹,按分类归档图片,Excel 放在一级目录:

<输出目录>/检测结果_20260902_151603/
├── 违规检测结果_20260902_151604.xlsx      # 检测明细 + 统计汇总
├── 12. 侵权 - 除人物外的其他侵权/  *.jpg
├── 13. 侵权 - 人物相关(…)/
├── 无违规/  ……

使用方式

exe 版(dist/ 目录)

  • 商品图合规检测工具.exe:双击打开图形界面(零配置:选图片文件夹和输出目录即可)。
  • 商品图合规检测工具CLI.exe:命令行版,用法同下方 CLI。
  • 首次运行会在 exe 同目录生成 config.ini 模板;GUI 会弹窗引导填写 豆包 API Key / 接入点、DeepSeek API Key / 模型,四项填完保存即可。
  • 内置提示词(打包进 exe);界面上也可另选 txt 覆盖。

源码运行(Python ≥3.10

uv run violation-detector-gui                 # GUI
uv run violation-detector tests -o output     # CLI
# 或免安装:
PYTHONPATH=src python -m violation_detector.gui
PYTHONPATH=src python -m violation_detector tests -o output

重新打包

uv run --with pyinstaller --with aiohttp --with openpyxl \
  pyinstaller --noconfirm --clean --onefile --windowed \
  --name 商品图合规检测工具 --add-data "prompts.txt;." --paths src app_gui.py
uv run --with pyinstaller --with aiohttp --with openpyxl \
  pyinstaller --noconfirm --clean --onefile \
  --name 商品图合规检测工具CLI --add-data "prompts.txt;." --paths src app_cli.py

CLI 用法

商品图合规检测工具CLI <图片文件夹> [选项]

  -o, --output DIR     输出目录(默认为图片文件夹)
  --mode               cascade(默认)/ doubao / deepseek
  --prompt FILE        自定义提示词(默认内置 prompts.txt
  --workers-ark/--workers-ds/--max-tokens   调优项(默认即可)

配置(config.ini,自动生成)

缺失必填项时:GUI 弹窗引导填写;CLI 打印缺哪些项后退出。也可用环境变量 ARK_API_KEY / ARK_MODEL_ID / DEEPSEEK_API_KEY / DEEPSEEK_MODEL 覆盖。

[ark]
api_key = ...
model_id = ep-xxxx
[deepseek]
api_key = sk-...
model = deepseek-v4-flash-vision-exp
max_tokens = 5000
[run]
mode = cascade          # cascade / doubao(仅豆包)/ deepseek(仅 DeepSeek
deepseek_recheck = no   # 仅 cascade 生效:no=只豆包初筛(默认)/ yes=追加 DeepSeek 复检
[output]
schema = auto    # auto(默认)/ on / off;auto=启用官方结构化输出,接口不支持自动降级 json_object

运行模式:config.ini [run] mode 全局生效(GUI 也跟随);CLI 的 --mode 参数可临时覆盖。 DeepSeek 复检开关:[run] deepseek_recheck(默认 no)。no 时 cascade 等效“仅豆包”, DeepSeek 相关的 API Key 也不再是必填项;需要 DeepSeek 复检时设 yes(或直接 mode=deepseek 全量走 DeepSeek)。

项目结构

├── src/violation_detector/
│   ├── config.py     # 配置(自动生成 ini、缺项检测、冻结环境路径)
│   ├── providers.py  # 豆包/DeepSeek 异步客户端,统一结果结构
│   ├── pipeline.py   # 级联调度、断点缓存(runs/)、成本汇总
│   ├── report.py     # 时间戳输出目录、分类归档、Excel 报表
│   ├── cli.py / gui.py
├── app_gui.py / app_cli.py   # 启动器 + PyInstaller 入口
├── prompts.txt       # 内置提示词
├── runs/             # 分阶段缓存(断点续跑;删缓存即全量重跑)
├── dist/             # 打包产物 exe
└── legacy/           # 早期脚本与实验数据

日志与排错

所有运行过程写入日志文件(exe 同目录 / 源码项目根目录下的 logs/violation_detector_日期.log):

  • 文件记录 DEBUG 级全量:运行配置、缓存命中、每次请求的重试与 HTTP 响应体、异常完整堆栈;
  • 控制台/GUI 只显示 INFO 级简洁信息,异常时同样附带完整 traceback;
  • GUI 右下角「打开日志」按钮直达日志文件;CLI 出错时会在结尾打印日志文件路径。
# 跑测试(33 个单元测试,无需网络与 API Key)
uv run --with pytest --with aiohttp --with openpyxl --no-project \
  env PYTHONPATH=src pytest tests -q

检测规则与已知特性

  • 分类按提示词 17 类标准输出唯一分类,自动归一化写法差异。
  • AI 输出:按官方启用结构化输出——豆包=response_format.json_schema(strict) DeepSeek=Responses API 的 text.format.json_schema(约束「文字/图形属性 · 侵权/违规逻辑 · 违规分类」三字段);接口不支持时自动降级 json_object[output] schema)。 DeepSeek 走 chat/completions 兜底时 temperature=0、max_tokens=5000。
  • 复检单次即终稿:DeepSeek 对豆包放行/存疑图各跑一遍即定稿,不再追加多票复核。
  • 边界图仍可能存在运行间抖动(单模型单次判定所致),成本较低可整批重跑比对,存疑图建议人工终审。
  • 级联成本:DeepSeek 只处理豆包放行的少数存疑图(单张约 1-1.6 分钱, 空闲时段半价;高峰=工作日 9-12、14-18 点)。