GEMINI LABJP
PRO35 — July 17, the date reports had pointed to, has passed without an official Gemini 3.5 Pro announcement or model card. July 24 is being cited as the fallbackNB2LITE — Nano Banana 2 Lite, otherwise known as Gemini 3.1 Flash-Lite Image, arrives as the fastest of the family: roughly four seconds per image at $0.034 per thousandOMNI — Gemini Omni Flash enters public preview, generating video up to ten seconds long at $0.10 per second of outputEDIT — Omni Flash is built around conversational editing. Swap a character, relight a scene, or change the angle in plain language, and the original audio and video tracks stay intactSYNTHID — Both new models carry SynthID watermarking, so anything they produce can be checked for provenance from inside the Gemini appSHUTDOWN — The older image generation models are deprecated and switch off on August 17. Worth checking your migration windowPRO35 — July 17, the date reports had pointed to, has passed without an official Gemini 3.5 Pro announcement or model card. July 24 is being cited as the fallbackNB2LITE — Nano Banana 2 Lite, otherwise known as Gemini 3.1 Flash-Lite Image, arrives as the fastest of the family: roughly four seconds per image at $0.034 per thousandOMNI — Gemini Omni Flash enters public preview, generating video up to ten seconds long at $0.10 per second of outputEDIT — Omni Flash is built around conversational editing. Swap a character, relight a scene, or change the angle in plain language, and the original audio and video tracks stay intactSYNTHID — Both new models carry SynthID watermarking, so anything they produce can be checked for provenance from inside the Gemini appSHUTDOWN — The older image generation models are deprecated and switch off on August 17. Worth checking your migration window
Articles/API / SDK
API / SDK/2026-07-09Intermediate

When gemini-embedding-2 Retrieval Feels 'Almost Right,' Check task_type First

When gemini-embedding-2 search misses in a frustrating near-hit way, the cause is often a missing or mismatched task_type. Here is how to align document and query intent, plus the code and a tiny harness to prove the difference on your own data.

gemini102embedding10RAG14semantic-search4gemini-api277

Premium Article

When I rebuilt the tag search for one of my wallpaper apps on gemini-embedding-2, the results were "not wrong, just off." A search for "sunset ocean" surfaced sunset mountains and empty beaches, and the photo I actually wanted sat in seventh place. When accuracy is zero, you suspect a plain bug. When it is merely close, the cause hides.

I spent half a day poking at normalization and chunk sizes before the real culprit surfaced: task_type. I had embedded both the documents and the query without specifying it. The moment I aligned it, that seventh-place photo jumped to second.

I suspect this happens more often now, not less. Since gemini-embedding-2 went GA and can embed both text and images with one model, people swap models more freely, and the task_type setting quietly gets dropped in the process. As an indie developer running several apps at Dolice, I hit this exact trap, so let me walk through the cause and the fix, with the numbers I measured myself.

task_type tells the model what the embedding is for

An embedding model turns your text into a vector. But the same sentence has a slightly different optimal direction depending on whether it will be used as a document to be searched, or as a query doing the searching.

task_type makes that intent explicit. With gemini-embedding-2 you get embeddings optimized separately for documents and for queries. Leave it unset and you get a general-purpose embedding that is not tuned for the asymmetric task of retrieval, where a short query has to pull long documents.

This is the counterintuitive part. Since queries and documents are compared in the same space, it feels like they should be treated identically. In practice, for an asymmetric task, specifying "for query" and "for document" separately makes the cosine-similarity ranking noticeably more stable.

The common mistake: embedding both sides with no task_type

This is exactly what I was doing. At both index time and search time, I embedded through the same function without passing task_type.

from google import genai
 
client = genai.Client()  # reads GEMINI_API_KEY from the environment
 
def embed_plain(text: str) -> list[float]:
    # No task_type = a generic embedding with no stated purpose
    resp = client.models.embed_content(
        model="gemini-embedding-2",
        contents=text,
    )
    return resp.embeddings[0].values
 
# Both indexing and searching use the same function
doc_vec = embed_plain("A seaside landscape washed in sunset light")
query_vec = embed_plain("sunset ocean")

The code does not error. That is what makes it insidious. Search runs, plausible results come back, and because it is not tuned for the asymmetric case, the ranking is just blurry. That "close but off" symptom is exactly what this state produces.

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
If your search keeps missing in an almost-right way, aligning task_type alone can recover the recall you were losing
You will get copy-paste-ready code that uses RETRIEVAL_DOCUMENT and RETRIEVAL_QUERY correctly
You can adopt a habit of A/B testing task_type against a small golden set in your own project
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 $10 for lifetime access
View Membership →

Related Articles

API / SDK2026-07-04
Catch Near-Duplicate Posts Before You Publish — a Topic-Cannibalization Gate with Gemini Embeddings
Once a blog passes a few hundred posts, new articles start cannibalizing old ones in search. This walks through a pre-publish gate that embeds each post's meaning with gemini-embedding-2 and blocks drafts that sit too close to something you already wrote — with runnable code and how to pick the thresholds.
API / SDK2026-07-14
When Gemini's executed result and its prose disagree on a number — a gate that trusts only code_execution_result
Gemini Code Execution returns the value it actually computed and the sentence describing it as separate parts. Trust the prose and you can inherit a hallucinated number. Here is a verification gate, in working code, that extracts the executed result as the single source of truth and rejects prose that disagrees.
API / SDK2026-07-13
When responseSchema Can't Do $ref: Handling Recursive Schemas in Production with responseJsonSchema
Gemini's responseSchema is an OpenAPI subset with no $ref or $defs, so it can't express shared definitions or recursion. Here's how I moved to responseJsonSchema to reuse localized fields and handle a recursive category tree in production.
📚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
See all →