Multi-Modal Fraud & Quality Detection with Vision LLMs
For curators, product discovery, and listing validation platforms: detecting fake products, scams, and inflated claims is a precision game. A false reject (wrongly blocking a legitimate EU product) damages a seller and erodes curator trust. A false negative (a phishing site or fraudulent listing shipping) damages users and violates platform integrity. This guide shows how to balance both using multi-modal analysis — screenshot + text signals + claims — with Qwen3 Vision LLMs and structured JSON verdicts.
Start building: Get a free JuiceFactory API key — no credit card required.
The Threat Model
Curation workflows process hundreds of product submissions. Adversaries exploit this scale:
- Fake product sites: Parked domains, login walls with no content, error pages, placeholder copy — noise that pollutes a high-trust directory.
- Phishing & brand impersonation: A page masquerading as Slack or Notion, asking users to "log in" to a malicious auth endpoint.
- Inflated claims: A tool claims "EU data residency" and "GDPR-native," but the privacy policy is missing or states data flows to US cloud providers. Claims and reality diverge.
- Scam/deception: Crypto yield schemes, "get rich quick" overlays, fake testimonials, or obfuscated payment models.
- Bot pages & detritus: Automatically generated content farms, promotional spam, or machine-translated garbage.
The defender's dilemma: catching fakes requires skepticism, but excessive skepticism (high false-positive rate) blocks real products and kills curator velocity.
The Detection Architecture: Screenshot + Text + Claims
Multi-modal fraud detection combines three signal streams into a single, structured verdict:
- Screenshot (visual): What the page looks like — layout, branding, UI cues, visual artifacts of automation.
- Text signals (structured metadata): Page title, meta description, headings, body text, presence of privacy policy & company imprint.
- Submitter claims (ground truth to verify): What the product claims to be — name, category, pricing model, data location, sovereignty assertions.
The model fuses these three into a binary or ternary decision:
pass: Legitimate product, claims match reality, no red flags.review: Uncertain; claims don't align perfectly with page, or missing evidence for sovereignty claims. Escalate to human curation.reject: Fraud, phishing, scam, or irrelevant page. Block listing.
Real Implementation: LaunchRadar + Qwen3-VL
Here's how it works in practice (from LaunchRadar, a curated directory of sovereign, GDPR-native EU software):
System Prompt (Trust & Safety Frame)
You are a trust & safety and product reviewer for LaunchRadar, a curated directory
of sovereign, GDPR-native European software. You are given a SCREENSHOT of a submitted
product's homepage, extracted page TEXT/signals, and the submitter's CLAIMED listing fields.
Assess strictly and skeptically:
1. Is this a REAL, legitimate software product — not a scam, phishing page,
crypto/"you won" scheme, brand impersonation, malware/deceptive page,
login wall with no info, or a parked/empty/error page?
2. Do the submitter's claims (name, what it does, category, pricing) match
what the site actually shows?
3. Are the sovereignty claims plausibly supported? gdprEvidence/euOwnedEvidence
= is there a privacy policy, imprint/impressum, EU company info, or
European language/market signals backing GDPR-native / EU-owned /
EU data residency?
Notice the framing: strict and skeptical, naming the specific threats (scam, phishing, brand impersonation, parked pages), and requiring evidence for claims, not assertions.
Input Schema
export type Claims = {
name: string;
url: string;
tagline?: string | null;
description?: string | null;
category?: string | null;
pricing?: string | null;
dataLocation?: string | null;
gdprNative?: boolean;
euOwned?: boolean;
selfHostable?: boolean;
openSource?: boolean;
};
const signals = {
finalUrl: scrape.finalUrl,
blocked: scrape.blocked,
title: scrape.title,
metaDescription: scrape.metaDescription,
ogDescription: scrape.ogDescription,
headings: scrape.headings,
hasPrivacyPolicy: scrape.hasPrivacyPolicy,
hasImprint: scrape.hasImprint,
bodyText: scrape.bodyText,
};
The submitter provides claims (what they say their product is). The scraper provides signals (what the page actually contains). The vision LLM's job is to spot mismatches and verify sovereignty assertions.
The API Call
const res = await fetch(`${api()}/v1/chat/completions`, {
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${KEY}`
},
body: JSON.stringify({
model: "qwen3-vl", // Qwen 3 Vision LLM
temperature: 0.2, // Low temp for deterministic, precise output
max_tokens: 1600,
response_format: { type: "json_object" }, // Force JSON-mode (no prose)
messages: [
{ role: "system", content: SYSTEM },
{ role: "user", content: [
{ type: "text", text: `SUBMITTER CLAIMS:\n${JSON.stringify(claims)}\n\nPAGE SIGNALS:\n${JSON.stringify(signals)}\n\nReview the screenshot and the above...` },
{ type: "image_url", image_url: { url: `data:image/jpeg;base64,${screenshotBase64}` } }
]}
],
}),
});
Key tuning decisions:
- Temperature 0.2: General research on LLM phishing detectors tends to report better precision at lower temperatures (~0.2–0.3); higher entropy introduces hallucination and false rejections. Treat this as a starting point and A/B-test it on your own labelled set.
- JSON-mode: Structured output eliminates parsing ambiguity and ensures consistent schema across verdicts.
- Qwen3-VL: multimodal VLMs are reported in general research (not measured on this task) to reach roughly ~90%+ on document-fraud and phishing benchmarks with screenshot input — treat that as a directional prior, not a promise for your workload, and A/B-test it on your own labelled set. Open-source and EU-hosted on JuiceFactory.
The Verdict Schema
export type Verification = {
verdict: "pass" | "review" | "reject";
scamScore: number; // 0–100 confidence in fraud
isRealProduct: boolean; // Legitimate site vs. scam/parked
claimsMatch: boolean; // Do submitter claims align with page?
sovereignty: { // For GDPR/EU-native claims
dataLocationPlausible: boolean;
gdprEvidence: boolean; // Privacy policy present?
euOwnedEvidence: boolean; // Company info/imprint/EU signals?
notes: string; // Detailed explanation
};
redFlags: string[]; // Specific threats detected
summary: string; // One-paragraph human-readable verdict
suggested: { // Clean listing fields from actual site
tagline?: string;
description?: string;
category?: string;
pricing?: string; // "Free", "Freemium", "Paid", "Contact"
dataLocation?: string; // "EU", "Nordic", "Self-hosted", etc.
features?: string[];
useCases?: string[];
};
};
Real-World Red Flags
The system catches these threats:
| Threat | Signal | Example |
|---|---|---|
| Parked/empty domain | bodyText empty or boilerplate; no headings | Domain registered, no content deployed. |
| Phishing page | Logo present but URL mismatches claimed brand; call-to-action is "log in" with no product description | Screenshot shows Slack UI; URL is "slack-verify.herokuapp.com". |
| Fake sovereignty claims | gdprNative: true but no privacy policy found; or privacy policy redirects outside EU | Submitter claims "EU data residency" but Terms link to AWS-US region notice. |
| Inflated pricing claim | Submitter says "Free" but page shows "$99/month" or has aggressive upsell | Real pricing contradicts submission. |
| Crypto scam overlay | bodyText contains "yield", "APY", "guaranteed returns" | Real product is a note-taking app; page mentions DeFi yields. |
| Login wall, no product | Screenshot shows login form; no public product information visible | User cannot evaluate product without credentials. |
| Brand impersonation | Logo and name closely mimic established brand; different domain | Page looks like Notion but URL is "n0tion.ai". |
False Positives vs. False Negatives: A Value Choice
Research in content moderation (Automated Content Moderation: A Primer) identifies a fundamental tradeoff:
- False positive (wrongly reject): A legitimate EU tool gets blocked, costing the vendor time to appeal and harming curator reputation.
- False negative (wrongly pass): A scam or phishing page ships in the directory, harming users and regulators' trust in curation.
The threshold that separates these is not technical — it's a policy choice. The review verdict exists precisely to defer this choice to humans.
Setting Strategy by Context
For high-trust directories (LaunchRadar):
- Err toward higher precision (fewer false positives):
passonly if evidence strongly supports legitimacy and claims. reviewfor uncertain cases (missing privacy policy, weak imprint, but otherwise plausible).rejectonly for clear fraud (phishing, parked, crypto overlay).- Why? A false positive damages a small vendor; a false negative damages the directory's reputation equally, but vendors can appeal.
For user-facing moderation (e.g., product reviews on a marketplace):
- Err toward higher recall (fewer false negatives): Catch scams aggressively, escalate borderline cases to human review.
- Accept more false positives (a seller's review gets hidden temporarily) to protect buyers.
- Why? The cost of a scam reaching users exceeds the cost of a wrongly-hidden review.
Calibration in Practice
Use the scamScore and redFlags to tune the threshold:
if (verdict === "reject" && scamScore >= 85) {
// High confidence fraud: auto-reject
listing.status = "rejected";
} else if (verdict === "reject" && scamScore >= 60) {
// Moderate confidence: escalate to human
listing.status = "review";
} else if (verdict === "review") {
// Uncertain: human decision
listing.status = "review";
} else {
// Pass or low-confidence reject
listing.status = "approved";
}
The model outputs scamScore and redFlags so curators can reason about borderline cases. A score of 65 with a note "missing privacy policy" is different from a score of 65 with "phishing URL pattern" — the latter is higher-stakes. Where you set these numeric cutoffs is a policy choice, not a fixed rule — calibrate them against your own labelled decisions.
Human Curation: Keeping the Loop Closed
Automated detection must not be the final decision. Curators should:
- Review all
reviewverdicts before approving or rejecting. - Spot-check
passverdicts (especially early in deployment) to calibrate the model. - Document appeals when vendors dispute rejections. Feedback loops improve the model.
How often you spot-check, how you run appeals, and how frequently you retrain all depend on your volume — a directory taking a handful of submissions a day will sample very differently from one taking hundreds. Start conservative (sample more early on), then relax the cadence as your labelled agreement with the model stabilises.
The summary field in the verdict is designed for curators:
"summary": "Page has privacy policy and EU company imprint (GmbH).
Screenshots match described features. No immediate red flags.
Recommend approval — pricing claim 'Freemium' matches web copy."
This narrative, paired with the structured fields, lets a human curator decide in seconds, not hours of manual review.
Feedback Loop
Track curator decisions against model predictions:
- Curator approved a
reviewverdict: Model was too conservative. Retrain with this as a signal. - Curator rejected a
passverdict: Model hallucinated or missed a signal. Debug the input (was the screenshot corrupt? was the text signal incomplete?).
Over time — at a retrain cadence that fits your volume — this feedback tightens the review threshold and reduces false positives without increasing false negatives.
Where JuiceFactory Fits
JuiceFactory is the EU-sovereign, GDPR-compliant AI gateway that hosts Qwen3-VL and other open-source models. If you're still choosing infrastructure, compare EU-hosted vision and LLM providers before you commit. For this workflow:
- Sovereignty & statelessness: Your detection pipeline runs on EU infrastructure, with no data flowing to US cloud providers. The API is stateless — no server-side retention of your prompts, screenshots, or verdicts.
- Vision LLM: Qwen3-VL handles multi-modal inputs (screenshot + text); benchmark it on your own fraud set rather than trusting a generic accuracy figure.
- JSON-mode: Structured, deterministic output (no parsing errors, consistent schema).
- BYOK (Bring Your Own Key): You control the API key; JuiceFactory doesn't see your listings or verdicts.
- Scalability: Handle hundreds of submissions per day without rate-limiting; billing per token.
Quick Start
JuiceFactory is OpenAI-compatible — point any OpenAI SDK or fetch at https://api.juicefactory.ai/v1 and swap in your key:
export JUICEFACTORY_API="https://api.juicefactory.ai"
export JUICEFACTORY_API_KEY="your-key-here"
curl -X POST "${JUICEFACTORY_API}/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${JUICEFACTORY_API_KEY}" \
-d '{
"model": "qwen3-vl",
"temperature": 0.2,
"max_tokens": 1600,
"response_format": { "type": "json_object" },
"messages": [
{ "role": "system", "content": "<SYSTEM_PROMPT_HERE>" },
{ "role": "user", "content": [
{ "type": "text", "text": "SUBMITTER CLAIMS:\n..." },
{ "type": "image_url", "image_url": { "url": "data:image/jpeg;base64,..." } }
]}
]
}'
See Structured Extraction with Vision LLMs and Adversarial Validation for deeper guides on handling edge cases.
Key Takeaways
-
Multi-modal wins: Screenshot + text + metadata catch fraud that text-only LLMs miss — that's the durable point, independent of any specific accuracy number.
-
Temperature matters: Low temperature (0.2–0.3) tends to reduce hallucination and improve precision — verify the exact setting on your own set. Use JSON-mode to eliminate parsing ambiguity.
-
False positives and false negatives are different costs: A wrong reject blocks a vendor; a wrong pass harms users. Choose your threshold based on your curator's risk tolerance, not a generic default.
-
Humans decide, not the model: The
reviewverdict is your ally. Use it liberally. Feedback from curators on borderline cases trains the next iteration. -
Evidence, not assertions: Look for privacy policies, company imprints, European language/market signals. Require proof of sovereignty claims — don't trust a checkbox.
-
Keep it deterministic: JSON-mode, structured output, and low temperature ensure that the same listing produces the same verdict twice. Curators need consistency to reason about appeals.
-
EU infrastructure matters: GDPR compliance, no US cloud vendor lock-in, and BYOK mean your listings and verdicts never leave the EU data space.
References & Further Reading
- ThinkDeception: A Progressive Reinforcement Learning Framework for Interpretable Multimodal Deception Detection — Structured multimodal fraud detection.
- Making MLLMs Blind: Adversarial Smuggling Attacks in MLLM Content Moderation — How to stress-test your vision-LLM pipeline.
- How Can We Effectively Use LLMs for Phishing Detection? — Temperature, screenshot inputs, and zero-shot accuracy on phishing.
- Multimodal LLMs for Phishing Detection — Global Anti-Scam Alliance best practices.
- FlexGuard: Continuous Risk Scoring for Strictness-Adaptive LLM Content Moderation — Adaptive thresholding for false-positive/negative tuning.
- Automated Content Moderation: A Primer — Foundational framing of the false-positive/negative tradeoff.
- LLM Content Moderation: Implementation Guide for Trust & Safety Teams — Practical deployment strategies.
About JuiceFactory: Sovereign EU LLM gateway. Qwen models (text + vision), JSON-mode, BYOK, no US cloud lock-in. juicefactory.ai
Start building: Get a free JuiceFactory API key — no credit card required.
Related guides: EU LLM API Comparison · Multi-Modal AI Assistant · Structured Data Extraction · Vision-LLM Cost Optimization