Ir al contenido principal

Visión agéntica en Gemini 3: tutorial práctico

Aprende a usar la visión agéntica en Gemini 3 Flash con Python. Cuatro ejemplos muestran cómo el bucle Think, Act, Observe recorta, anota y extrae datos de imágenes.
Actualizado 23 sept 2026  · 11 min leer

Explorar con IA

ChatGPTClaudePerplexity

Envías una imagen a una API de visión para que lea una etiqueta de precio diminuta. La respuesta llega con mucha seguridad… y está mal. Lo mismo al contar objetos en una foto llena de cosas: el modelo mira la imagen completa una vez y suelta un número que no se acerca.

Gemini 3 Flash lo aborda de otra manera. Con la ejecución de código activada, puede escribir y ejecutar Python a mitad de respuesta para recortar, ampliar y anotar imágenes antes de comprometerse con una respuesta. Google llama a esto visión agéntica y reporta una mejora de calidad del 5-10% en benchmarks de visión.

Este tutorial recorre cuatro ejemplos de dificultad creciente: leer la letra pequeña en una estantería de supermercado, extraer nombres de bebidas de una carta con poca luz, contar monedas dispersas y extraer los datos de una tabla para crear un gráfico.

¿Qué es la visión agéntica? El bucle "Think, Act, Observe"

La idea es sencilla. Con la ejecución de código activa, Gemini 3 puede parar a mitad de respuesta, escribir y ejecutar Python en un entorno aislado, revisar lo que produjo el código y decidir el siguiente paso. 

En tareas de visión, esto suele significar recortar zonas de la imagen, ampliarlas, dibujar cajas delimitadoras o ajustar el contraste para sacar detalles que no se ven a la resolución original.

Esto se materializa como un bucle de tres fases.

Durante Think, el modelo evalúa lo que tiene (la imagen original o una versión ya recortada o anotada) y planifica su siguiente movimiento. Puede decidir que una etiqueta de precio es demasiado pequeña para leerla y que necesita recortarse y ampliarse.

Act convierte ese plan en Python. El entorno aislado trae 43 librerías preinstaladas (PIL, OpenCV, matplotlib y más), así que el modelo puede escribir el código de procesado de imagen que necesite.

Tras ejecutar el código, Observe cierra el bucle. La salida (nuevas imágenes, texto impreso, valores calculados) vuelve al contexto. A partir de ahí, el modelo responde o repite el ciclo.

Una sola llamada a la API puede recorrer este bucle varias veces. En los ejemplos siguientes verás cómo recorta siete zonas de la estantería en una sola petición. En otro, extrae datos de una tabla a un DataFrame de pandas y genera un gráfico de barras, todo dentro de la misma llamada. 

Si este concepto de bucle agéntico te suena nuevo, el itinerario de aprendizaje AI Agent Fundamentals de DataCamp lo explica a fondo.

Limitaciones y consideraciones

  • La ejecución de código y las llamadas a funciones personalizadas no pueden usarse en la misma petición.
  • La documentación de Google advierte que la ejecución de código puede empeorar el rendimiento en tareas no visuales. Actívala solo cuando la tarea se beneficie de manipular imágenes.
  • La segmentación a nivel de píxel (máscaras, contornos) no forma parte de la visión agéntica y permanece en Gemini 2.5.
  • A veces el modelo omite ejecutar código si con una sola pasada le basta. Es intencional, no un fallo.

Configura tu entorno para visión agéntica

Consigue una clave de API en ai.google.dev y guárdala como GOOGLE_API_KEY en tu entorno o en un archivo .env. Luego instala el SDK y las librerías de imagen:

pip install google-genai python-dotenv Pillow matplotlib opencv-python

Empieza creando el cliente:

from google import genai
from google.genai import types
from dotenv import load_dotenv
 
load_dotenv()
 
client = genai.Client(
    http_options=types.HttpOptions(timeout=600_000)
)
MODEL = "gemini-3-flash-preview"

Ese timeout=600_000 es importante. Las llamadas con visión agéntica implican varias rondas de generación y ejecución de código dentro del entorno aislado, y una sola petición puede tardar alrededor de cuatro minutos. 

El timeout por defecto de httpx cerrará la conexión mucho antes, dejándote con un ReadTimeout silencioso y sin pistas de lo ocurrido.

A continuación, configura el modo agéntico:

agentic_config = types.GenerateContentConfig(
    tools=[types.Tool(code_execution=types.ToolCodeExecution())],
	thinking_config=types.ThinkingConfig(
    	thinking_level="HIGH",
    	include_thoughts=True
	),
    media_resolution=types.MediaResolution.MEDIA_RESOLUTION_HIGH,
)

tools es el interruptor que activa la ejecución de código. Le da al modelo un entorno Python aislado con 43 librerías (numpy, pandas, PIL, matplotlib, OpenCV y más). Cada bloque de código tiene 30 segundos para ejecutarse y el entorno reintenta hasta 5 veces si hay errores.

thinking_level="HIGH" deja más margen al modelo para planificar antes de escribir código. Para trabajos de visión en varios pasos, se nota. Con include_thoughts=True expones ese razonamiento en la respuesta, útil para depurar.

media_resolution define cuántos tokens recibe la imagen de entrada antes incluso de empezar el bucle. MEDIA_RESOLUTION_HIGH es un buen valor por defecto. Puedes subirlo a MEDIA_RESOLUTION_ULTRA_HIGH para imágenes muy densas o bajarlo a MEDIA_RESOLUTION_LOW cuando priorices la velocidad sobre el detalle.

Esta misma configuración funciona en Vertex AI con cambios mínimos. Para una guía más amplia de la Gemini 3 API más allá de visión, echa un vistazo al tutorial complementario.

Visión agéntica en Gemini 3: leer detalle fino con recortes y zoom

La imagen de abajo es una estantería de supermercado alemana con tres filas de productos. Las etiquetas de precio recorren el borde de cada estante y un aviso de "Liebe Kunden" (Queridos clientes) aparece cerca de la parte inferior. Si haces zoom tú mismo se pueden leer, pero son lo bastante pequeñas como para que un modelo que mira toda la imagen tenga que decidir qué puede y qué no puede distinguir.

Cómo interpretar la respuesta multiparte

Las respuestas agénticas no son bloques de texto único. Llegan como una lista de partes: razonamiento, código que escribió el modelo, resultados de ejecución, imágenes generadas y la respuesta final. Este auxiliar las recorre:

def print_response(response, show_thoughts=False):
	for part in response.candidates[0].content.parts:
    	if part.thought and show_thoughts:
        	print("[THINK]", part.text[:500])
    	elif part.executable_code:
        	print("[CODE]")
        	print(part.executable_code.code)
    	elif part.code_execution_result:
        	print(f"[RESULT] ({part.code_execution_result.outcome})")
            print(part.code_execution_result.output)
    	elif part.inline_data:
        	print(f"[IMAGE] {part.inline_data.mime_type}, "
                  f"{len(part.inline_data.data):,} bytes")
    	elif part.text:
        	print("[ANSWER]", part.text)

Todos los ejemplos de este tutorial usan la misma función, así que defínela una vez y reutilízala.

Ahora carga la imagen de la estantería y escribe un prompt que pida al modelo leer el cartel y listar cada producto con su precio.

from pathlib import Path
 
image_path = Path("images/grocery_shelf.jpg")
image_part = types.Part.from_bytes(
	data=image_path.read_bytes(), mime_type="image/jpeg"
)
 
prompt = (
	"Read the 'Liebe Kunden' sign at the bottom of the shelf. "
	"What does it say? Also list all visible product names "
	"and their prices from the shelf labels."
)

Primero ejecútalo sin ejecución de código:

standard_config = types.GenerateContentConfig(
    media_resolution=types.MediaResolution.MEDIA_RESOLUTION_HIGH,
)
 
standard_response = client.models.generate_content(
	model=MODEL,
	contents=[image_part, prompt],
	config=standard_config,
)
print_response(standard_response)

Aquí tienes una versión recortada de la salida:

[ANSWER] Based on the image provided, here is the information requested:
 
### The 'Liebe Kunden' Sign
> "Dear Customers, unfortunately, we must inform you that due to
> increased demand, we cannot currently offer all products..."
 
### Product Names and Prices (from shelf labels)
 
**Top Row Labels:**
*   Uncle Ben's Express Reis Mexi-Scharf 250g: 1,69
*   Uncle Ben's Express Reis Griechisch 250g: 1,69
*   Uncle Ben's Express Reis Curry 250g: 1,69
*   Channa Masala 300g (partially obscured): 2,49
*   (Label obscured): 2,49
*   (Label obscured): 1,29
*   (Label obscured): 0,99
...
 
**Second Row Labels:**
*   Uncle Ben's Express Reis Chili con Carne 250g: 2,49
*   Uncle Ben's Spitzen-Langkorn Reis 10 Min 500g: 1,79
*   (Label obscured): 2,99
*   (Label obscured): 2,79
...

La traducción del cartel es correcta y el modelo lee las etiquetas de Uncle Ben's que reconoce. Pero aproximadamente un tercio de las entradas quedan como "(Label obscured)" y marcas como Oryza, Reis-fit y Reiskugeln ni aparecen.

Ahora el mismo prompt con la configuración agéntica:

agentic_response = client.models.generate_content(
	model=MODEL,
	contents=[image_part, prompt],
	config=agentic_config,
)
print_response(agentic_response, show_thoughts=True)

La estructura de salida es distinta. En lugar de un único [ANSWER], recorre todo el bucle Think/Act/Observe:

[THINK] Okay, so the primary goal here is twofold: First, I need to
decipher that "Liebe Kunden" sign down there. Then, I need to build a
comprehensive list of what's on this shelf...
 
[CODE]
import PIL.Image
 
img = PIL.Image.open('input_file_0.jpeg')
width, height = img.size
 
crops = [
	{'box_2d': [630, 447, 887, 559], 'label': 'liebe_kunden_sign'},
	{'box_2d': [80, 40, 240, 560], 'label': 'shelf1_left'},
	{'box_2d': [190, 550, 310, 980], 'label': 'shelf1_right'},
	{'box_2d': [400, 0, 480, 450], 'label': 'shelf2_left'},
	{'box_2d': [410, 450, 480, 1000], 'label': 'shelf2_right'},
	{'box_2d': [630, 130, 760, 460], 'label': 'shelf3_left'},
	{'box_2d': [550, 600, 660, 990], 'label': 'shelf3_right'},
]
# ... crops and saves each region
 
[IMAGE] image/png, 135,953 bytes
[IMAGE] image/png, 90,395 bytes
[IMAGE] image/png, 125,816 bytes
[IMAGE] image/png, 102,288 bytes
[IMAGE] image/png, 173,606 bytes
[IMAGE] image/png, 283,263 bytes
[IMAGE] image/png, 100,522 bytes

Los siete recortes que generó el modelo:

Title: Gemini 3 agentic vision crop of Liebe Kunden customer notice on grocery shelf - Description: Gemini 3 agentic vision crop of Liebe Kunden customer notice on grocery shelf

Title: Agentic vision crop of top shelf left section showing Uncle Ben's rice products - Description: Agentic vision crop of top shelf left section showing Uncle Ben's rice products

Title: Agentic vision crop of top shelf right section showing Reiskugeln and curry products - Description: Agentic vision crop of top shelf right section showing Reiskugeln and curry products

Title: Agentic vision crop of middle shelf left section with rice products and price labels - Description: Agentic vision crop of middle shelf left section with rice products and price labels

Title: Agentic vision crop of middle shelf right section showing Oryza rice products - Description: Agentic vision crop of middle shelf right section showing Oryza rice products

Title: Agentic vision crop of bottom shelf left section with Uncle Ben's 1kg bags - Description: Agentic vision crop of bottom shelf left section with Uncle Ben's 1kg bags

Title: Agentic vision crop of bottom shelf right section showing Reis-fit products - Description: Agentic vision crop of bottom shelf right section showing Reis-fit products

Tras observar esos recortes, el modelo produce una respuesta completa:

[ANSWER]
**Top Shelf (Left to Right):**
*   Uncle Ben's Express Reis Mexi. Scharf 250g: 1,69 €
*   Channa Masala 285g: 2,49 €
*   Madras Curry 285g: 2,49 €
*   Steam Basmati Reis Kochbeutel 250g: 1,99 €
*   Reiskugeln Pur 4x2 St: 1,99 €
...
 
**Middle Shelf (Left to Right):**
*   Uncle Ben's Express Reis Chili con Carne 250g: 2,49 €
*   Oryza Langkorn & Wildreis 500g Kochbeutel: 2,99 €
*   Oryza Basmati & Wildreis 500g Kochbeutel: 2,79 €
*   Oryza Jasmin Reis 500g Kochbeutel: 2,79 €
...
 
**Bottom Shelf (Left to Right):**
*   Uncle Ben's Natur Reis 10-Min. Kochbeutel 1kg: 3,69 €
*   Reis-fit 10 Minuten Natur-Reis 500g: 1,89 €
*   Reis-fit Langkorn & Wildreis 500g: 1,89 €
...

La salida completa, sin recortes, de ambas llamadas está disponible en este gist.

La respuesta agéntica lee más de 30 productos en los tres estantes. Los artículos de Oryza, Reis-fit, Madras Curry, Reiskugeln y Steam Basmati que la visión estándar marcó como "(obscured)" aparecen con nombre y precio.

La diferencia no va de alucinaciones frente a exactitud; la visión estándar es sincera con lo que no puede leer. La visión agéntica simplemente no acepta ese límite y hace zoom hasta que puede.

El prompt importa. Pedir al modelo que "liste todos los nombres de producto visibles y sus precios" marca un listón de exhaustividad que lo empuja a recortar. 

Un prompt más vago como "describe esta imagen" probablemente produciría una respuesta de una sola pasada incluso con ejecución de código activa, porque el modelo no vería motivos para ir más allá.

Lectura con poca luz y obstrucciones

Esta imagen es una carta de bar en Brasil fotografiada con poca iluminación. Tres paneles de cristal listan bebidas en texto dorado, pero lámparas colgantes tapan partes del panel izquierdo, el derecho apenas se ve en el borde del encuadre y los reflejos se esparcen por el vidrio.

El prompt no menciona brillo, recortes ni ninguna técnica concreta. Solo pide el contenido:

image_path = Path("images/bar_menu.jpg")
image_part = types.Part.from_bytes(
	data=image_path.read_bytes(), mime_type="image/jpeg"
)
 
prompt = (
	"Read every drink listed on this menu board, including the ones "
	"partially hidden behind the lamps and on the side panels. For "
	"each drink, give me the name and beer style."
)

La visión estándar lee sin problemas el panel central bien iluminado, sacando ocho cervezas de la sección "FRUTADAS" y cuatro de "CHOPP". Pero el panel izquierdo queda así:

[ANSWER]
### Left Panel (Partially visible)
*   **[Unreadable] LAGER** | [Style unreadable]
*   **RED LAGER** | [Style unreadable]
*   **[Unreadable] LAGER** | [Style unreadable]
*   **[Unreadable]GER** | [Style unreadable]
*   **HONKERS ALE** | [Style unreadable]
*   **[Unreadable]SELLE** | [Style unreadable]

Seis entradas, la mayoría con nombres ilegibles y todas sin estilo. El modelo ve que hay texto, pero no logra descifrarlo.

La llamada agéntica realiza dos rondas de código. Primero, recorta los tres paneles:

[CODE]
middle_panel = [200, 320, 950, 780]
left_panel = [200, 0, 950, 260]
right_panel = [200, 840, 700, 1000]
# ... crops and saves each region

image10.png

Tras observar esos recortes, el modelo decide que los paneles izquierdo y derecho necesitan más zoom. Ejecuta una segunda ronda:

[CODE]
left_panel_top = [100, 0, 500, 250]
left_panel_bottom = [500, 0, 980, 250]
right_panel_top = [100, 800, 600, 1000]

image1.png

Con ese zoom extra, el modelo recupera nombres que la visión estándar marcó como ilegibles: Amber Lager, Honkers Ale (Goose Island) y Demoiselle (Colorado) del panel izquierdo, además de Wals Dubbel, Tripel, Quadrupel y Petroleum del derecho. También identifica el encabezado del panel izquierdo como "MISTURAS" y el del derecho como "ALCOÓLICAS".

El prompt nunca dijo "recorta los paneles" ni "haz zoom en las zonas oscuras". Pidió las bebidas y sus estilos, y el modelo trabajó hacia atrás desde ese objetivo. 

Lo que diferencia este ejemplo del de la estantería es la segunda pasada. Tras la primera ronda de recortes, el modelo miró lo que tenía, decidió que los paneles izquierdo y derecho seguían siendo difíciles de leer y ejecutó otra ronda de zooms más ajustados sin que se lo indicaran. 

El bucle se autocorrigió. 

Esa es la ventaja de dejar el método abierto: el modelo no solo preprocesa una vez, itera hasta que los resultados cumplan el listón marcado por el prompt.

Conteo y anotación con visión agéntica en Gemini 3

La carta del bar funcionó porque el prompt dejó el método abierto y el modelo supo qué hacer. No siempre es así. A veces necesita instrucciones explícitas sobre qué herramienta usar, y el siguiente ejemplo muestra dónde está ese límite.

La imagen de abajo muestra monedas esparcidas sobre un escritorio y una carpeta negra. Algunas se superponen, otras están parcialmente ocultas y la mezcla de cobre y plata hace fácil perder la cuenta.

image18.png

Un primer enfoque razonable es pedir al modelo que anote cada moneda para poder contar a partir de sus propias marcas. La documentación de Google confirma que la visión agéntica puede dibujar cajas delimitadoras y etiquetas directamente sobre imágenes usando PIL y OpenCV en el entorno aislado. Así que:

image_path = Path("images/coins.jpg")
image_part = types.Part.from_bytes(
	data=image_path.read_bytes(), mime_type="image/jpeg"
)
 
prompt_v1 = (
	"Count every coin in this image. Draw a bounding box or circle "
	"around each one and number them. Check for overlapping or "
	"partially hidden coins. Give me the final count."
)
 
response_v1 = client.models.generate_content(
	model=MODEL,
	contents=[image_part, prompt_v1],
	config=agentic_config,
)
print_response(response_v1, show_thoughts=True)

El modelo recorta cinco zonas, analiza cada una y devuelve un conteo de 34. Pero fíjate en el formato de la respuesta:

[ANSWER] Final Count: 34 coins in total.
 
[
  {"box_2d": [387, 175, 451, 236], "label": "1"},
  {"box_2d": [356, 196, 407, 248], "label": "2"},
  {"box_2d": [319, 231, 375, 274], "label": "3"},
  ...
]

Devolvió coordenadas de cajas como JSON en lugar de dibujar nada sobre la imagen. El prompt decía "draw", pero el modelo lo trató como una tarea de descripción y entregó texto estructurado.

La documentación de ejecución de código da una pista: "Aunque el modelo maneja automáticamente el zoom para detalles pequeños, debes indicarle explícitamente que use código para otras tareas". La palabra "draw" es lo bastante ambigua como para que el modelo eligiera la vía solo-texto. 

Describir la tarea en términos del código que quieres que ejecute elimina esa ambigüedad:

prompt_v2 = (
	"Count every coin in this image. Use Python to draw a numbered "
	"bounding box on the image around each coin you find. Check for "
	"overlapping or partially hidden coins. After annotating, give "
	"me the final count."
)
 
response_v2 = client.models.generate_content(
	model=MODEL,
	contents=[image_part, prompt_v2],
	config=agentic_config,
)
print_response(response_v2, show_thoughts=True)

Esta vez, el modelo escribe código de dibujo real:

[CODE]
import PIL.Image
import PIL.ImageDraw
 
img = PIL.Image.open('input_file_0.jpeg')
width, height = img.size
 
coins = [
	[383, 175, 452, 227], [352, 196, 411, 255], ...  # 34 total
]
 
draw = PIL.ImageDraw.Draw(img)
for i, coin in enumerate(coins):
	ymin, xmin, ymax, xmax = coin
	left, top, right, bottom = (xmin*width/1000, ymin*height/1000,
                                 xmax*width/1000, ymax*height/1000)
	draw.rectangle([left, top, right, bottom], outline='red', width=3)
	draw.text((left, top), str(i + 1), fill='red')
 
[RESULT] (Outcome.OUTCOME_OK)
Total coins detected: 34
 
[IMAGE] image/png, 3,685,043 bytes
 
[ANSWER] I have identified and counted a total of 34 coins.

image13.png

Cada moneda recibe un recuadro rojo y un número. El conteo real es 35 o 36, según cómo juzgues dos monedas que se superponen cerca de la parte inferior. 

El modelo dio 34, fallando una o dos en ese grupo. Pero la anotación actúa como una libreta visual: en lugar de un número que debas aceptar sin más, obtienes un artefacto verificable que puedes revisar caja a caja.

La salida completa, sin recortes, de ambas llamadas está disponible en este gist.

Extracción y visualización en varios pasos

Los ejemplos anteriores implicaban una tarea principal cada uno (leer texto, contar objetos). Este encadena varias: recortar una tabla de una foto, extraer los números a un DataFrame y generar un gráfico. La imagen es una tabla de impuestos al estilo del IRS fotografiada sobre un escritorio con una calculadora.

image5.png

El prompt describe toda la tubería de una vez:

image_path = Path("images/data_table.jpg")
image_part = types.Part.from_bytes(
	data=image_path.read_bytes(), mime_type="image/jpeg"
)
 
prompt = (
	"Crop and zoom into the table in this image. Extract the first "
	"10 rows of data into a structured format. Identify the column "
	"headers. Then create a bar chart comparing the values in the "
	"numeric columns for those 10 rows. Summarize which row has the "
	"highest and lowest values."
)
 
response = client.models.generate_content(
	model=MODEL,
	contents=[image_part, prompt],
	config=agentic_config,
)
print_response(response, show_thoughts=True)

El modelo realiza cuatro rondas de código para pasar de la foto completa a un gráfico terminado. Las tres primeras son zooms progresivos: recorta la tabla de "Single or Married Filing Separately", luego los encabezados de columna y después las primeras 10 filas de datos, generando cinco imágenes intermedias por el camino. Este es el primer recorte en el que aísla la tabla:

Title: Gemini 3 agentic vision first crop isolating the Single Filing tax table region - Description: Gemini 3 agentic vision first crop isolating the Single Filing tax table region

En la cuarta ronda ya lee suficiente detalle para extraer los números. Construye un DataFrame de pandas, imprime la tabla y genera un gráfico de barras agrupadas en un único bloque de código:

[CODE]
import matplotlib.pyplot as plt
import pandas as pd
 
data = [
	{"Higher Paying Job Wage": "$0 - 9,999",
 	"$0 - 9,999": 0, "$10,000 - 19,999": 940,
 	"$20,000 - 29,999": 1020, "$30,000 - 39,999": 1020},
	...  # 10 rows total
]
 
df = pd.DataFrame(data)
df.set_index("Higher Paying Job Wage").plot(kind='bar', figsize=(12, 6))
plt.title('Tax Table: Single or Married Filing Separately')
plt.ylabel('Tax Amount')
plt.savefig('tax_bar_chart.png')

La tabla extraída:

Higher Paying Job Wage

$0 - 9,999

$10,000 - 19,999

$20,000 - 29,999

$30,000 - 39,999

$0 - 9,999

$0

$940

$1,020

$1,020

$10,000 - 19,999

$940

$1,540

$1,620

$2,020

$20,000 - 29,999

$1,020

$1,620

$2,100

$3,100

$30,000 - 39,999

$1,020

$2,020

$3,100

$4,100

$40,000 - 59,999

$1,870

$3,470

$4,550

$5,550

$60,000 - 79,999

$1,870

$3,470

$4,690

$5,890

$80,000 - 99,999

$2,000

$3,810

$5,090

$6,290

$100,000 - 124,999

$2,040

$3,840

$5,120

$6,320

$125,000 - 149,999

$2,040

$3,840

$5,120

$6,910

$150,000 - 174,999

$2,220

$4,830

$6,910

$8,910

Y el gráfico de barras generado:

Title: Bar chart generated by Gemini 3 agentic vision comparing tax amounts across wage brackets - Description: Bar chart generated by Gemini 3 agentic vision comparing tax amounts across wage brackets

La salida completa, sin recortes, está disponible en este gist.

Una única llamada a la API produjo un DataFrame estructurado, un resumen con las filas de valor máximo y mínimo identificadas, y un gráfico de barras listo para publicar. El prompt listaba cuatro cosas (recortar, extraer, graficar, resumir) y el modelo trató cada una como una etapa de una tubería donde la salida de un paso alimentaba al siguiente. 

Los ejemplos anteriores usaban el bucle para refinar una sola operación (mejores recortes, mejores anotaciones). Aquí el bucle encadena operaciones distintas, cada una apoyándose en lo que produjo la ronda anterior.

Conclusión

La visión agéntica convierte una sola llamada a la API en un bucle de feedback donde el modelo escribe código, mira lo que produjo y decide qué hacer después. 

El ejemplo de la estantería mostró el patrón básico: recortar zonas demasiado pequeñas para leer y responder a partir de las versiones ampliadas. La carta del bar añadió una segunda dimensión: el modelo hizo una ronda de recortes, decidió que no bastaba y se acercó más por su cuenta a las áreas problemáticas. 

En las monedas, la anotación convirtió una estimación en un artefacto comprobable. La tabla de impuestos encadenó cuatro operaciones distintas (recortar, extraer, calcular, graficar) dentro de una sola petición.

Cada ejemplo también dejó pistas sobre el prompting. Marcar un listón de exhaustividad ("listar todos los productos") empujó al modelo hacia la minuciosidad. Dejar el método abierto le permitió elegir su propio preprocesado. 

Pero verbos ambiguos como "draw" a veces lo desviaron, y cambiar a "Use Python to draw" lo corrigió. 

La pauta: describe qué quieres obtener, sé específico con la herramienta cuando la tarea sea ambigua y deja que el bucle se encargue del resto.

Todo el código de este tutorial funciona con gemini-3-flash-preview y el SDK google-genai. Si quieres profundizar, el curso de DataCamp Introduction to AI Agents cubre el patrón de bucle detrás de todo esto.

Preguntas frecuentes sobre la visión agéntica en Gemini 3

¿Qué es la visión agéntica en Gemini 3 Flash?

La visión agéntica es una función por la que Gemini 3 Flash puede escribir y ejecutar código Python a mitad de respuesta para manipular imágenes antes de contestar. Usa un bucle Think, Act, Observe para recortar, ampliar, anotar y mejorar imágenes dentro de un entorno aislado, todo dentro de una única llamada a la API.

¿Cómo activo la visión agéntica en la API de Gemini?

Añade una herramienta de ejecución de código a tu GenerateContentConfig: tools=[types.Tool(code_execution=types.ToolCodeExecution())]. Esto da al modelo acceso a un entorno Python aislado con 43 librerías preinstaladas, incluidas PIL, OpenCV y matplotlib.

¿Por qué el modelo se salta la ejecución de código aunque esté activada?

El modelo solo escribe código cuando decide que una sola mirada a la imagen no basta. Si puede responder con confianza desde la resolución original, salta la ruta de ejecución de código. Es intencional y está documentado por Google.

¿Cuál es la diferencia entre "draw" y "Use Python to draw" en los prompts?

Decir "draw" es ambiguo y el modelo puede devolver descripciones en texto o coordenadas JSON en lugar de una imagen real. Añadir "Use Python to draw" le indica que escriba código ejecutable que produzca una salida visual, lo que activa de forma fiable la ruta de ejecución de código.

¿Puedo combinar visión agéntica con llamadas a funciones personalizadas?

No. La ejecución de código y las llamadas a funciones personalizadas no se pueden usar en la misma petición a la API. Si tu flujo necesita ambas, tendrás que hacer llamadas separadas.


Bexruz (Bex) Tuychiev's photo
Author
Bexruz (Bex) Tuychiev
LinkedIn

Soy creador de contenidos sobre ciencia de datos con más de 2 años de experiencia y uno de los mayores seguimientos en Medium. Me gusta escribir artículos detallados sobre IA y ML con un toque sarcástico, porque hay que darle algo de vidilla al tema. He publicado más de 130 artículos y un curso en DataCamp, y tengo otro en marcha. Mis contenidos han sido vistos por más de 5 millones de personas; 20.000 de ellas se convirtieron en seguidores tanto en Medium como en LinkedIn. 

Temas
Inteligencia Artificial
Agentes de IA

Los mejores cursos de DataCamp

programa

Fundamentos de agentes de IA

6 h
¡Descubre cómo los agentes de IA pueden transformar tu forma de trabajar y aportar valor a tu organización!
Ver detallesRight Arrow
Iniciar Curso
Ver másRight Arrow
Relacionado
An AI juggles tasks

blog

Cinco proyectos que puedes crear con modelos de IA generativa (con ejemplos)

Aprende a utilizar modelos de IA generativa para crear un editor de imágenes, un chatbot similar a ChatGPT con pocos recursos y una aplicación clasificadora de aprobación de préstamos y a automatizar interacciones PDF y un asistente de voz con GPT.
Abid Ali Awan's photo

Abid Ali Awan

10 min

Tutorial

Visión GPT-4: Guía completa para principiantes

Este tutorial le presentará todo lo que necesita saber sobre GPT-4 Vision, desde cómo acceder a él hasta ejemplos prácticos del mundo real y sus limitaciones.
Arunn Thevapalan's photo

Arunn Thevapalan

12 min

Tutorial

Tutorial del Optimizador Adam: Intuición e implementación en Python

Comprender y aplicar el optimizador Adam en Python. Aprende la intuición, las matemáticas y las aplicaciones prácticas del aprendizaje automático con PyTorch

Tutorial

Ajuste fino de GPT-3 mediante la API OpenAI y Python

Libere todo el potencial de GPT-3 mediante el ajuste fino. Aprenda a utilizar la API de OpenAI y Python para mejorar este modelo de red neuronal avanzado para su caso de uso específico.
Zoumana Keita 's photo

Zoumana Keita

12 min

Tutorial

Construir agentes LangChain para automatizar tareas en Python

Un tutorial completo sobre la construcción de agentes LangChain multiherramienta para automatizar tareas en Python utilizando LLMs y modelos de chat utilizando OpenAI.
cursor ai code editor

Tutorial

Cursor AI: Una guía con 10 ejemplos prácticos

Aprende a instalar Cursor AI en Windows, macOS y Linux, y descubre cómo utilizarlo a través de 10 casos de uso diferentes.
Ver MásVer Más