GEMINI LABJP
VIDEO — Agentic video understanding reached 3.7 Flash, 3.6 Flash, and 3.5 Flash-Lite on September 1. The model navigates the timeline itself rather than sampling frames at a fixed rateTOKENS — Because it pulls transcripts, frames, or audio only when it needs them, Google measures up to 88% fewer tokens on long-form contentSCOPE — It works across both the Interactions and GenerateContent APIs. If you have costed out long-video work before, the assumptions have movedMUSIC — Lyria 3.5 entered public preview on September 3, generating full-length songs at 44.1 kHz stereoCONTROL — Lyria 3.5 accepts text and image inputs, with better musical coherence, more natural vocals, and finer control over duration and structureROBOTICS — gemini-robotics-er-2-streaming-preview is tuned for real-time streaming over the Live API, with function calling that blocks on physical robot actionsVIDEO — Agentic video understanding reached 3.7 Flash, 3.6 Flash, and 3.5 Flash-Lite on September 1. The model navigates the timeline itself rather than sampling frames at a fixed rateTOKENS — Because it pulls transcripts, frames, or audio only when it needs them, Google measures up to 88% fewer tokens on long-form contentSCOPE — It works across both the Interactions and GenerateContent APIs. If you have costed out long-video work before, the assumptions have movedMUSIC — Lyria 3.5 entered public preview on September 3, generating full-length songs at 44.1 kHz stereoCONTROL — Lyria 3.5 accepts text and image inputs, with better musical coherence, more natural vocals, and finer control over duration and structureROBOTICS — gemini-robotics-er-2-streaming-preview is tuned for real-time streaming over the Live API, with function calling that blocks on physical robot actions
Articles/Advanced
Advanced/2026-08-31Advanced

Define What Counts as a Duplicate Before Adding Embedding Search to Your Image Pipeline

My dedup check flagged two prints with identical composition but different colors as one image. Here is how I split duplicate detection into three layers, measured where perceptual hashing ends, and decided what embedding search is actually for.

Gemini API234File Search7embeddings12image processing2indie development22

Premium Article

The wallpaper apps I run as an indie developer include a curated ukiyo-e collection, and every new asset passes through a duplicate check before it ships. One day I tried to register two prints in a row: the same composition, pulled from the same woodblock, but printed in completely different color palettes. The check declared them identical.

To me, they are two different works. Same block, different printing — I want both in the collection. That disagreement between the machine's answer and mine is what forced me to rethink how the check was built.

The timing was interesting, because File Search had just gained multimodal search, and gemini-embedding-2 can now embed images directly. Should I throw away hash matching and move the whole check to embedding search? I went back and forth for a while. The short answer: I adopted embeddings, but refused to make them the gatekeeper. This is the reasoning, with the actual distance numbers that shaped it.

The Conclusion First: Hashes Guard the Gate, Embeddings Only Suggest

Here is the structure I landed on.

StageMethodWhat the machine may do
At registration, first gateSHA-256 (byte identity)Reject automatically
At registration, second gatedHash (64-bit perceptual hash)Hold and queue for review. Never delete
After registration, asyncEmbedding nearest-neighbor searchDisplay similar existing works. Nothing else

Notice that I did adopt embedding search — I just never granted it the power to reject. The reason is the direction of each method's errors. A hash fails by missing a transformed copy. An embedding fails by calling a distinct work a duplicate. The first failure leaves one redundant pair in your collection. The second one deletes an asset you can never get back. Deletion is irreversible, so the method whose errors point in the dangerous direction does not get to stand at the gate. That is the whole principle.

"Duplicate" Is Not One Thing: Three Layers

Midway through the redesign I realized the real problem: I had never written down what I meant by duplicate. When I finally did, it split cleanly into three layers.

LayerMeaningExampleWho can answer
Layer 1Identical fileThe same file registered twiceSHA-256, instantly
Layer 2Transformed copies of one imageRe-encodes, resizes, light cropsPerceptual hash, almost instantly
Layer 3Distinct works that look alikeAlternate printings, series pieces, similar compositionsNo algorithm. This is an editorial decision

My two prints lived in layer 3, and layer 3 is not a detection-accuracy problem at all. Whether an alternate printing of the same woodblock counts as one work or two is a question about how you want to present your collection. I had been trying to solve a curation question with a similarity metric, and that mismatch was the entire source of my confusion.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
You will be able to define what counts as a duplicate in three distinct layers, and match each layer to perceptual hashing, embedding search, or human judgment before writing any code
You will be able to reproduce the boundary where a 64-bit hash stops working — the gap between distance 8 and distance 29 — and set thresholds for your own collection with evidence behind them
You will be able to prevent the irreversible mistake of auto-deleting distinct works that merely look similar, by deciding in advance which layer machines are allowed to act on
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

Related Articles

Advanced2026-07-08
One File Search Store for Many Apps: Splitting Retrieval With customMetadata and Chunk Config
Put several apps' FAQs in a single Gemini File Search store and metadataFilter can silently return empty grounding, or answers get split across chunk boundaries. Here is the customMetadata design, the AIP-160 filter-syntax trap, and measured chunkingConfig tuning.
Advanced2026-09-05
Two Kinds of Video Questions: Why I Send "Find It" and "Prove It Isn't There" Down Separate Paths
Agentic video understanding lets the model decide which parts of a video to watch. That works beautifully for finding things, and it quietly breaks when you need to prove something never appears. Here is how I split my questions, and the coverage check I now run first.
Advanced2026-07-08
When Your Knowledge Base Shifts Mid-Run: Pinning File Search to an Execution Epoch for Consistent Agent Grounding
When a File Search store is updated while a Managed Agent is running, a single execution can mix old and new grounding. Borrowing MVCC ideas, pinning an execution epoch keeps one agent run's evidence consistent. Here is the design and implementation.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links