Back to Case Studies

CLIP: anomaly alerts for every new batch of data

Index your data with CLIP, describe the images you don't want in plain words, and split each batch into clean data and anomalies — with an email when a batch loses more than it should.

Related templates

CLIP: anomaly alerts for every new batch of data

The problem

New images keep arriving — an import, a dump off a device, a nightly upload — and some of them are unusable. The catch is that “unusable” is defined by your task, not by the file. Glare, rain on the lens, the wrong subject in frame, night scenes when the model is meant for daylight: none of that is a broken file, and automatic quality metrics do not catch any of it. The only reliable judge is somebody who knows what the data is for.

Reviewing a batch by eye is expensive, and doing it for every new batch is not a plan.

This case study shows the alternative: describe the unwanted images once, in words, and use the same graph to split each batch into clean data and anomalies — with a notification when too much gets cut.

Images in1080

One batch, before the run

Flagged by the prompt19

1.8% of the batch

Clean dataset1061

25 classes, ready to use

One run of the cleanup graph: prompt night, threshold 0.23.

The data

As an example input we used a public dataset, so that anyone can repeat the run on the same images. It stands in for whatever your daily upload looks like.

Example input

nuImages — 1,080 road-scene images from Dataset Ninja. Picked because weather and lighting conditions are well represented in it, so it already contains the kind of frame worth removing: night shots, wet lenses, blown-out highlights.

Most of it is ordinary daylight, and the unusable frames are scattered through it.

A sample of the incoming batch. Most frames are ordinary daylight; the unusable ones sit in between.

A sample of the incoming batch. Most frames are ordinary daylight; the unusable ones sit in between.

A grid of road-scene frames, mostly daylight street views with a few dark night frames mixed in

This is an ordinary dataset, and you can point the same graph at your own data. In AI Search, choose the text prompt, similarity threshold, and maximum number of results. This graph uses night, 0.23, and 10,000. If the result reaches that limit, use a smaller batch before cleanup so additional matches are not moved into the clean output.

About CLIP indexing

CLIP is a model that reads both pictures and text. It turns an image into a list of numbers, and it turns a sentence into a list of numbers of the same kind, in a way that puts related pictures and words close together. So “a photo taken at night” and an actual night photo end up near each other, while the same sentence and a sunny street photo end up far apart.

Indexing simply means doing that once for every image in your data and storing the result. After that, searching the data by text is fast: your sentence is converted the same way and compared against what is already stored, and the images that come out are the ones the sentence describes.

That is what makes this graph work. No labels are needed, nothing is trained, and you never have to define “bad” in code — you write what you don’t want in a normal sentence, and the search finds it. AI Index Embeddings and AI Search both use CLIP; the optional visual embedding model is disabled.

The graph, step by step

StepWhat happens
1. UploadThe new images land in a working dataset as they are
2. Working datasetOne dataset everything downstream reads from, and the one images are pulled out of later
3. AI Index EmbeddingsScheduled indexing builds CLIP representations so the data can be searched by text
4. AI SearchStart a text search with your prompt, similarity threshold, and result limit to collect matching images
5. ReviewThat set is a dataset you can open and look through before anything is moved
6. DropStart cleanup separately to pull the matched images out of the working dataset, leaving what passed
7. Set asideThe anomalies move into their own dataset and stay there — cut out, not thrown away
8. MoveThe remainder moves into the clean output dataset
9. AlertIf the run removed more images than the threshold allows, the configured email action runs

What one run produced

The threshold was picked by trying it. AI Search runs separately from cleanup, so you can inspect its selected dataset before starting removal. Two or three attempts were enough to settle on 0.23 for the prompt night.

With that setting the run pulled 19 night frames out of the 1,080 and moved them into a separate dataset for review, leaving 1,061 images in the clean one. Further along the graph sits the notification step, configured to write only when more than 50 images are removed; 19 did not reach that, so no email was sent.

What ended up in the anomalies

Nineteen images, all of them night frames — exactly what we were looking for.

Everything the prompt night pulled out at threshold 0.23.

Everything the prompt night pulled out at threshold 0.23.

Nineteen dark night-time street frames selected by the prompt

Poor visibility also makes these frames poorer in content: only 12 of the 25 classes present in the clean dataset appear here at all.

Changing the prompt changes what gets removed

The prompt and the threshold are the whole criterion, and both are yours to set. A second pass over the same images used the prompt rain at threshold 0.19 and pulled out wet lenses and overcast scenes instead.

The same data with the prompt rain at threshold 0.19. Counts were not recorded for this pass; it illustrates what a different criterion selects.

The same data with the prompt rain at threshold 0.19. Counts were not recorded for this pass; it illustrates what a different criterion selects.

A grid of frames with rain on the lens, wet roads and overcast skies

Lower the threshold and the search takes more; raise it and the selection stays tight. Tuning it is safe, because nothing is deleted: whatever the prompt takes out lands in the anomalies dataset, where you can open it and see what was removed.

What the graph saves you

CLIP itself is a commodity; plenty of tools will index a folder of images for you. What changes the economics here is what is assembled around it into a single graph you can run.

You review 19 images instead of 1,080. Nobody looks through the whole batch anymore — you open the result of the query, decide whether those images should be deleted or sent for closer labeling, and move on. That is 1.8% of the data, and it is where the saved hours and the saved labeling budget come from.

The criterion is written once and applies to every batch. The prompt and the threshold are parameters of the graph, not a decision somebody makes again every morning. Tomorrow’s upload goes through the same criterion, so a difference between two days tells you something about the data rather than about who happened to review it.

You can repeat it for each batch. Indexing runs on a schedule; start AI Search and cleanup separately when the batch is ready. With a recipient and mail credentials configured, the graph notifies you when the removed-image count crosses your threshold. Here the threshold was 50 and AI Search found 19 night frames, so no email went out.

And nothing is deleted. The data is split into two datasets and both are kept.

Summary

The graph in this post is a small piece of automation, and it shows what AI Index Embeddings plus AI Search are enough for: state what does not belong in your data, inspect the matches, and start cleanup to separate them for a second opinion or closer labeling. The images here were an example; the useful part is that the same handful of steps can be reused for every batch.

Explore the live workflow

Inspect the actual read-only OvalBee flow behind this case study, including its nodes, configuration, and reports, or open it in OvalBee.