最开始我只是想做一个很直接的工具:用户上传一张图片,系统告诉他这张图是不是 AI 生成的。
这个想法听起来很简单。现在 AI 生图这么多,网上到处都是 Midjourney、Stable Diffusion、DALL·E、Flux、豆包、通义万相之类模型生成的图,尤其是最近出的GPT-image-2,有点让社媒陷入黑暗森林的感觉了。很多图看起来已经足够真实,有时候仅靠人眼很难判断。我原本以为,这个项目的核心就是找一个检测算法,或者接一个 API,然后把结果展示出来。
但真正开始做之后,我很快发现:AI 图片鉴别不是一个简单的二分类问题。
它不是:
输入图片 → 输出 AI / 真人txt更接近:
输入图片 → 收集多种证据 → 判断每种证据的强弱和可靠性 → 给出风险分析txt也就是说,这个项目真正困难的地方,不是”怎么给一个分数”,而是”这个分数凭什么可信”。
一、项目背景#
一开始,我给这个项目设想的定位比较直接:做一个检测图片是否为 AI 生成的工具。用户上传图片,系统显示检测结果,最好能给出一个百分比,比如”AI 生成概率 87%”。
但后来我越来越觉得,这种产品表述其实有问题。
因为”87% AI 生成”这句话本身就很危险。它会让用户以为这个系统真的知道图片的真实来源。但实际上,大多数检测方法都只是风险信号,不是证明。
比如:
- 没有 EXIF,不代表图片是 AI;
- 没有 C2PA,不代表图片是真的;
- 检测到某种频率模式,不代表一定有水印;
- 视觉上没有异常,不代表不是 AI;
- 内容是假的,也不代表图片一定是 AI 生成;
- 搜不到外部来源,也不能说明图片就是假的;
- 某个 detector 给出高分,也不等于那就是客观概率。
我在做这个项目的过程中,逐渐意识到一个更准确的定位应该是:
BemoLens 不是一个”AI 鉴定器”,而是一个”图片真实性分析框架”。
它不是为了给出一个绝对结论,而是为了把一张图片拆开,从多个角度分析它有哪些证据、哪些风险、哪些不确定性。
所以后来我把项目思路改成了:
图片真实性分析
AI 生成风险分析
内容真实性风险分析
多证据 Gate 架构
可解释报告txt这个转变很重要。它让我不再纠结”怎么一锤定音”,而是开始思考”怎么把证据组织清楚”。
二、为什么不适合商业化#
开发过程中,我也认真想过:这个项目能不能做成一个产品赚钱?
后来我的判断是:现在不适合直接商业化,更适合先开源。
原因有几个。
首先,没有训练集,权重计算不客观。现在很多 gate 的权重,比如 3、4、8,以及 aiRisk = 0.75、0.45 这类分数,本质上都是启发式规则,也就是说,我们目前的权重、分数、算法是未经过任何数据集检验的,所以它并不准确。它们可以作为产品原型的初始逻辑,但不能宣称具有统计意义。
如果要真正说”这个系统准确率多少”,就必须有标注数据集,有不同图片类型的测试,有真实照片、AI 图、局部 AI 编辑图、压缩图、截图图、社交平台转存图、二次元图、游戏截图、新闻截图、伪造推文截图等等。没有这些数据,就不能把一个风险分数包装成客观事实。
其次,检测工具链本身还不成熟。C2PA 是一个很有价值的方向,但覆盖率不高。SynthID、Stable Diffusion invisible watermark、各家平台的隐式水印,也不是一个统一、稳定、公开可查的体系。很多水印检测不是”检测到就一定是真的”,而是”有些频率模式像水印”。
我自己就遇到一个很典型的例子:我截图了一张推特贴文,通过微信转发后再上传检测,结果系统提示检测到了 Stable Diffusion watermark。这个链路明显不太可能真的保留一个稳定的 SD 水印,更合理的解释是:截图、微信压缩、重编码产生的频率特征让 detector 误检了。
这让我更明确地意识到:
水印相似信号不等于已验证水印。
第三,商业化会带来责任风险。如果一个用户拿你的报告去判断别人是不是造假、是不是 AI 图、是不是散布谣言,那这个结果就会变得很敏感。只要误判,产品信任就会出问题。
所以,现在更适合的路线不是把它包装成一个收费鉴定器,而是把它开源成一个:
多证据图片真实性分析框架txt这更诚实,也更有长期价值。
三、整体架构#
为了避免”一个模型说了算”,我把整个检测流程设计成 gate-based architecture,也就是多道检测门。
每一道门负责一种证据。每一道门都输出自己的结果、风险、可靠性和解释。最终由 aggregator 综合这些信号,而不是让某一个 gate 独断最终结论。
目前设计了八道门:
Gate 0:输入质量 / 文件可用性
Gate 1:C2PA / Metadata
Gate 2:像素级隐式水印
Gate 3:压缩痕迹 / ELA / 噪声
Gate 4:视觉语义异常
Gate 5:物理与场景一致性
Gate 6:统计模型检测
Gate 7:跨来源 / 内容事实核查txt这个架构最重要的好处是:它把一个模糊问题拆成了多个可讨论的问题。
不是直接问:
这张图是不是 AI?txt而是分别问:
这张图有没有可信来源声明?
有没有 C2PA?
有没有官方或平台水印?
有没有压缩和编辑痕迹?
视觉内容有没有明显异常?
物理关系是否自洽?
统计检测模型是否认为它像 AI?
图片里的内容能不能被外部来源验证?txt这样做之后,系统就不再是一个黑盒。用户可以看到每一步的依据,也可以看到每一步的局限。这里仍然有一些缺陷:比如,对于一些特定的图片如二次元图片,Gate 3、4、5就不太适用,所以怎么去动态判断门的开关也是一个比较复杂的问题。又比如,对于一些误判效果,怎么去做处理等等。
四、Gate 0:输入质量#
Gate 0 看起来不起眼,但实际上很重要。
很多检测工具一上来就开始分析图片,但不先判断输入本身是否适合分析。这会导致很多误判。
比如用户上传的是:
- 极低清图片;
- 纯 UI 截图;
- 二维码;
- 图标;
- 纯文字截图;
- 表情包;
- 游戏截图;
- 二次元插画;
- 海报;
- 被微信压缩过很多次的图片。
这些图片并不适合所有检测方式。比如 Gate 5 的物理一致性分析,对 UI 截图和二次元图就很容易误伤。Gate 3 的压缩痕迹分析,对微信转发图也容易把平台压缩当成异常。
所以 Gate 0 应该做输入检查和图片类型路由。
它至少要判断:
文件格式
文件大小
图片尺寸
是否过小
是否严重压缩
是否截图
是否可能是 UI / 海报 / 二次元 / 游戏 / 新闻截图txt这一步的意义不是判断 AI,而是告诉后面的 gate:
哪些检测适合运行
哪些检测应该降权
哪些检测应该跳过txt我后来意识到,一个好系统不是”所有检测都跑一遍”,而是要知道”哪些检测对当前图片不适用”。
五、Gate 1:来源元数据#
C2PA 是目前比较严肃的图片来源声明标准。简单说,它可以记录图片的来源、编辑历史和签名信息。如果一张图片有可信的 C2PA Content Credentials,并且签名验证通过,那它就是一个很强的来源证据。
但这里也有很多细节。
比如我问过一个问题:如果 C2PA 查出来 signed by Google LLC,这代表什么?
一开始容易误解成:
Google 签了,所以是 AI 生成。txt但其实不是。signed by Google LLC 只代表这份 C2PA manifest 是由 Google 的签名凭证签的。真正要看的是里面的 action、digitalSourceType、claimType。
如果里面写的是 camera capture,那可能反而说明它来自 Pixel Camera 或 Google Photos 的可信拍摄链路。
如果里面写的是 AI generated、trainedAlgorithmicMedia、created by Gemini 或 Imagen,那才更接近 AI 生成证据。
所以 Gate 1 的原则是:
签名者是谁 ≠ 最终结论
签名是否 verified 很重要
claim 内容是什么更重要txtC2PA 的强度很高,但覆盖率不高。很多图片没有 C2PA,很多平台转存之后 C2PA 也可能丢失。所以:
有 verified C2PA 是强证据;
没有 C2PA 不是反证。txt这个边界非常重要。
不过C2PA的确是个大杀器,测试 GPT-image-2 原图可以直接测出来。
六、Gate 2:隐式水印#
Gate 2 关注的是图片里是否存在隐式水印,比如某些 Stable Diffusion 生态工具曾经使用的 invisible watermark,或者 Google SynthID 这类平台水印。
这个方向听起来很强,因为如果真的解码出官方水印,那它可以成为很直接的证据。
但现实问题是:很多水印检测并不稳定。
比如 SD invisible watermark,如果只是检测到”某些频率模式像水印”,那不应该直接显示:
SD Invisible Watermark: Detectedtxt而应该显示:
疑似 Stable Diffusion 水印相似信号
置信度较低
不能作为决定性证据txt我在项目里逐渐把 Gate 2 的结果从简单的 detected / not_detected 改成更细的状态:
verified
probable
suspected
not_detected
unsupported
errortxt只有当它明确解码出已知水印信息,并且置信度足够高,图片也没有经过明显截图、压缩、转存、裁剪时,才可以作为强证据。
如果只是低置信度频域信号,就只能作为弱证据。
这件事给我的一个重要启发是:
检测器的输出不能直接等于产品结论。中间必须有信任分层。
七、Gate 3:压缩与编辑痕迹#
Gate 3 主要看图片是否有编辑或重编码痕迹,比如:
- 局部重压缩;
- ELA 异常;
- 噪声模式不一致;
- 不同区域压缩质量不一致;
- 局部边缘异常;
- 拼接或修图留下的痕迹。
这类检测可以发现一些编辑痕迹,但它的问题也很明显:它不直接证明 AI。
比如微信压缩、截图、平台重编码、裁剪、转格式,都会制造压缩异常。真实照片被社交平台转发几次后,也可能出现很复杂的噪声和压缩痕迹。
所以 Gate 3 的定位应该是:
处理痕迹辅助证据txt不是:
AI 生成证据txt比如报告里应该写:
Moderate compression inconsistencies found — may indicate editing or compositing.txt翻译成中文就是:
发现中等程度的压缩不一致,可能表示图片经过编辑或合成。txt注意这里是”可能表示编辑或合成”,不是”证明 AI 生成”。
这个 gate 对局部 AI 编辑也有帮助。比如真实照片经过 AI 扩图、AI 去物体、AI 替换背景,可能会留下区域噪声和压缩不一致。但最终仍然要保守解释。
八、Gate 4:视觉异常#
Gate 4 是我讨论得比较多的一道门。它主要使用视觉大模型检查图片内容中是否存在 AI 生成图常见的视觉异常。
比如:
- 手指数量或结构异常;
- 文字乱码;
- 脸部细节异常;
- 眼睛、牙齿、耳朵、眼镜、首饰异常;
- 物体边缘融合;
- 重复纹理;
- 反射不一致;
- 背景细节不自然。
最开始我试过 Gemini 2.5 Flash,但效果不太好。它有时候太保守,什么都说没问题;有时候又会幻觉式地找一些不可靠异常。后来换到 5.4 nano,效果明显更好。这个体验让我意识到:Gate 4 很吃模型质量。
但更关键的不是模型名字,而是 prompt 的设计。
不能问:
这张图片是不是 AI 生成?txt应该问:
不要判断这张图是不是 AI。
不要输出概率。
只检查图片中是否存在具体可见异常。
如果没有明确异常,就返回空 findings。
不要猜测。
不要把低清、压缩、风格化本身当成 AI 证据。txt也就是说,视觉模型在 Gate 4 里不是最终裁判,而是一个”视觉异常检查员”。
它输出的是 findings,比如:
hand_anomaly
text_gibberish
reflection_inconsistency
object_fusion
texture_repetitiontxt然后系统再根据 finding 的数量、严重程度、置信度和图片类型,计算一个 anomalyScore。
这里我学到一个很重要的 AI 使用原则:
不要让大模型直接替你做最终判断,要让它输出结构化中间证据。
这比”让模型给概率”可靠得多。
九、Gate 5:物理一致性#
Gate 5 和 Gate 4 有些相似,但它关注的不是局部视觉异常,而是全局物理逻辑。
比如:
- 光源和阴影是否一致;
- 镜子反射是否合理;
- 水面倒影是否正确;
- 透视线是否冲突;
- 物体是否合理接触地面或桌面;
- 人是否悬浮;
- 物体尺度是否合理;
- 遮挡关系是否成立;
- 运动模糊方向是否一致。
Gate 4 看的是:
这里有没有 AI 常见破绽?txtGate 5 看的是:
这个世界是否符合基本物理规律?txt举个例子:
一个人手指有 6 根 → Gate 4
一个人脚没接触地面却像站着 → Gate 5
背景文字乱码 → Gate 4
镜子里没有应该出现的人 → Gate 5txt但 Gate 5 也容易误判。特殊拍摄角度、广角镜头、复杂光源、舞台灯光、低清图片,都可能让模型误以为物理关系有问题。
所以 Gate 5 的权重不能太高,也不能 fast path。它适合作为中等强度辅助证据,和 Gate 4 互补。
如果 Gate 4 和 Gate 5 都发现明显异常,同时 Gate 6 统计模型也给高风险,那么最终 AI Risk 可以升高。但如果只有 Gate 5 一个 warn,就不能直接说这图是 AI。
十、Gate 6:统计模型#
Gate 6 是我一开始以为最像”AI detector”的部分。它接入专门的 AI image detector,比如 Hugging Face 上的一些 ViT / CLIP 二分类模型,或者第三方 API,例如 Sightengine 这类服务。
但讨论下来,我反而觉得 Gate 6 要更谨慎。
统计模型的问题是:
- 黑盒;
- 训练集偏差;
- 对新生成模型泛化不一定好;
- 容易受压缩、截图、转格式影响;
- 对二次元、游戏、UI、海报等非摄影图可能误伤;
- API 成本不低;
- 本地部署可能有内存和工程复杂度。
所以 Gate 6 的定位应该是:
统计模型辅助证据txt不是:
最终 AI 概率txt如果某个 detector 输出 0.92,也不应该展示成”92% AI-generated”。更好的文案是:
统计模型发现了较强的 AI-like 特征。
该信号不能单独证明图片为 AI 生成。txt我也思考过本地跑 detector 会不会内存爆炸。结论是:如果是轻量 CLIP / ViT detector,单张图、固定尺寸推理,一般还可以。但不要在前端浏览器或 Next.js 主进程里直接跑大模型。更合理的是单独做一个 detector service:
Next.js App
↓
Gate Orchestrator
↓
Python / FastAPI Detector Service
↓
ONNX Runtime / PyTorchtxt并且:
模型启动时加载一次
图片 resize 到 224 / 384 / 512
单张图推理
失败就 skiptxt这个 gate 更像未来扩展点,不应该是 MVP 的唯一核心。
十一、Gate 7:跨来源核查#
Gate 7 是我后来觉得特别有价值的一道门。
前面几个 gate 都在看图片本身,但 Gate 7 看的是图片在外部世界里是否站得住。
一开始我只想到反向搜图,也就是查这张图有没有在网上出现过。比如用 Google Lens、TinEye、Yandex、百度识图,看它是不是来自 AI 作品站、新闻网站、摄影图库、社交媒体、事实核查网站。
但后来我意识到,Gate 7 不应该只做反向搜图,还应该做内容事实核查。
因为现在很多假图不是单纯”图片像 AI”,而是图片里传达了一个假的事实。
比如一张伪造的推文截图,上面写着:
Trump announces acquisition of Xtxt这张图可能是 AI 生成的,也可能是 PS 的,也可能是网页模板伪造的。此时反向搜图不一定有结果,但我们可以提取图片里的 claim,然后去查:
有没有原始 X 帖子?
有没有官方账号发布?
有没有可信新闻报道?
有没有事实核查网站辟谣?txt这就是 Gate 7B:Content Claim Verification。
它的核心流程是:
输入图片
→ OCR / 视觉模型提取文字和 claim
→ 识别涉及人物、机构、平台、时间
→ 生成搜索 query
→ 搜索官方来源、新闻源、事实核查源
→ 判断 claim 是 verified、contradicted、not_found 还是 inconclusivetxt这里有一个很重要的产品区分:
内容真实性风险 ≠ AI 生成风险txt一张图片内容是假的,不代表图片一定是 AI。它可能是:
- PS 改图;
- 网页截图伪造;
- 手动编辑;
- 模板生成;
- AI 生成;
- 真实照片配了错误文字。
所以最终报告应该分成两个指标:
AI Generation Risk
Content Authenticity Risktxt比如:
真实照片 + 假配文 → AI Risk 低/中,Content Risk 高
AI 生成风景图,无虚假 claim → AI Risk 高,Content Risk 低
伪造推文截图 → AI Risk 中,Content Risk 高
AI 生成假新闻图 → AI Risk 高,Content Risk 高txt这个分离让我觉得项目成熟了很多,因为它不再把所有问题都塞进”是不是 AI”这个筐里。
十二、评分系统#
项目里不可避免会有分数。每个 gate 需要输出 aiRisk、reliability、weight,最后 aggregator 计算最终风险。
但我越来越觉得,要非常小心地对待这些数字。
比如 Gate 4 的异常分数、Gate 5 的物理一致性分数、Gate 6 的 modelScore,都不应该被直接当成最终概率。它们只是内部风险信号。
一个比较合理的思路是:
effectiveWeight = weight * reliability
weightedRisk = aiRisk * effectiveWeight
finalScore =
sum(aiRisk * weight * reliability) /
sum(weight * reliability)txt但这里的 weight 和阈值都应该写清楚:
这是启发式参数
不是统计学真理
后续需要通过标注数据集校准txt现在可以先用经验权重:
Gate 1 C2PA:强证据,可 fast path
Gate 2 可信水印:条件强证据
Gate 3 压缩痕迹:weight 3
Gate 4 视觉语义:weight 4
Gate 5 物理一致性:weight 4
Gate 6 统计模型:weight 3
Gate 7 跨来源核查:weight 8txt但这些只是初始方案。真正要客观,必须有评估集。
所以这个项目如果开源,就应该明确:
我们提供 scoring framework
但不声称默认权重已经经过充分校准txt这比闭源产品直接给一个神秘分数更诚实。
十三、报告导出#
我还设计了 Report 详情页导出 PDF 的功能。
一开始我以为就是把页面导出成 PDF。后来想清楚了,这不应该是页面截图,而应该是一份正式的图片真实性分析报告。
报告应该包含:
封面
总结论
AI Risk
Content Risk
Confidence
图片信息
文件 hash
八道 gate 结果
证据摘要
隐私说明
局限性说明txt尤其要有局限性说明:
本报告提供的是风险信号,并非绝对鉴定结论。
缺少 metadata 或水印,并不能证明图片一定为真人拍摄。
类似水印的信号可能受到截图、压缩、缩放、重编码影响。
视觉和物理一致性检查对插画、UI 截图、游戏图、海报、表情包、低清图可靠性较低。
统计检测模型可能受到训练集偏差、压缩处理和新生成模型影响。
跨来源核查受搜索覆盖、语言、地区和时间敏感性影响。txt这份报告的目的不是吓唬用户,而是让用户知道:
系统发现了什么
哪些是强证据
哪些是弱信号
哪些 gate 没有执行
为什么不能直接下绝对结论txt这也和开源定位一致:证据导向,而不是结论导向。
十四、开发反思与后续#
这次开发让我对 AI 辅助编程有了更具体的感受。AI 最有用的地方不是替我写几行代码,而是帮我把混乱的问题结构化——先写 spec,再拆 task,再生成文档,再指导实现。这其实是一种 spec-driven development。这次的搭配是使用雷总送的 xiaomi mimo 2.5 pro,接入 hermes 来写代码,使用 gpt-5.5 来写task、plan 等文档。不过 mimo 的 credits 烧得有点快,7亿给我嚯嚯得只剩2亿了
另外几个比较重要的原则:
不要问 AI “这张图是不是 AI”,要让它输出结构化中间证据。 让模型做”结构化观察”而不是”最终裁判”,这比让它直接给概率可靠得多。
追问数字的来源。 AI 给的权重、阈值、分数如果没有数据支撑,就只是启发式参数。追问”凭什么”,才能防止项目变成空心参数堆砌。
让 AI 做反方提醒。 当我想把某个信号作为强证据时,AI 会提醒可能误检、不能 fast path、需要降权。不一定全对,但很适合当讨论对象。
关于项目方向,我没有选择把它包装成收费鉴定器,而是决定开源。因为这个项目最有价值的地方不是某个检测算法,而是它的框架——多证据 gate 架构、可解释输出、AI Risk / Content Risk 分离、报告导出、免责声明和局限性。这些东西适合开源共建,而非闭源包装。另外它的功能不支持它作为一个付费的 Saas,权重算法不准确、gate动态化未实现、未经过数据集检测、detecter工具较少等等都是比较大的问题。
下一步的重点不是盲目增加检测功能,而是整理仓库结构、稳定 gate 接口、标注实验性功能、定义评估数据格式,以及完善 UI 和报告(便于未来继续开发
面对不确定性很强的问题,不要急着给答案,要先建立证据系统。BemoLens 不试图证明一张图一定真假——它试图告诉你:我们看到了哪些证据,这些证据有多强、有多可靠,又有哪些地方不能下结论。在 AI 内容越来越多的时代,承认不确定性,也许比给出一个漂亮但虚假的百分比更重要。