Lewati ke konten utama

Visi Agen di Gemini 3: Tutorial Praktis

Pelajari cara menggunakan visi agen di Gemini 3 Flash dengan Python. Empat contoh menunjukkan bagaimana loop Think, Act, Observe melakukan crop, anotasi, dan mengekstrak data dari gambar.
Diperbarui 28 Sep 2026  · 11 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

Anda mengirim gambar ke API visi dan memintanya membaca label harga kecil. Respons yang kembali terdengar yakin namun salah. Hal serupa terjadi saat menghitung objek di foto yang berantakan: model melihat sekilas seluruh gambar lalu menebak angka yang meleset jauh.

Gemini 3 Flash menanganinya dengan cara berbeda. Dengan eksekusi kode diaktifkan, ia dapat menulis dan menjalankan Python di tengah respons untuk melakukan crop, pembesaran, dan anotasi gambar sebelum memberikan jawaban. Google menyebutnya visi agen (agentic vision) dan melaporkan peningkatan kualitas 5–10% pada tolok ukur visi.

Tutorial ini membahas empat contoh yang makin menantang: membaca tulisan kecil di rak bahan makanan, mengambil nama minuman dari menu bar yang remang, menghitung koin yang berserakan, dan mengekstrak data tabel ke dalam bagan.

Apa Itu Visi Agen? Loop "Think, Act, Observe"

Idenya sederhana. Dengan eksekusi kode aktif, Gemini 3 dapat berhenti di tengah respons, menulis dan menjalankan Python di sandbox, melihat apa yang dihasilkan kode, lalu memutuskan langkah berikutnya. 

Untuk tugas visi, ini biasanya berarti model memotong area gambar, memperbesarnya, menggambar bounding box, atau menyesuaikan kontras untuk menonjolkan detail yang tidak terlihat pada resolusi awal.

Ini berjalan sebagai loop tiga fase.

Selama Think, model melihat apa yang dimilikinya (gambar asli, atau versi yang sudah dipotong atau dianotasi) dan merencanakan langkah berikut. Ia mungkin memutuskan label harga terlalu kecil untuk dibaca dan perlu dipotong serta diperbesar.

Act menerjemahkan rencana itu menjadi Python. Sandbox memiliki 43 pustaka prainstal (PIL, OpenCV, matplotlib, dan lainnya), sehingga model dapat menulis kode pemrosesan gambar apa pun yang dibutuhkannya.

Setelah kode berjalan, Observe menutup loop. Output (gambar baru, teks yang dicetak, nilai yang dihitung) masuk kembali ke konteks. Dari sana, model bisa menjawab atau mengulang lagi.

Satu panggilan API dapat berputar melalui loop ini beberapa kali. Di contoh berikut, Anda akan melihatnya melakukan crop tujuh area rak dalam satu permintaan. Pada contoh lain, ia mengekstrak data tabel ke pandas DataFrame dan menghasilkan bagan batang, semuanya dalam panggilan yang sama. 

Jika konsep loop agen baru bagi Anda, alur AI Agent Fundamentals dari DataCamp membahasnya secara mendalam.

Keterbatasan dan batasan

  • Eksekusi kode dan pemanggilan fungsi kustom tidak dapat digunakan dalam permintaan yang sama.
  • Dokumentasi Google memperingatkan bahwa eksekusi kode dapat menurunkan performa pada tugas non-visual. Aktifkan hanya saat tugas diuntungkan dari manipulasi gambar.
  • Segmentasi tingkat piksel (masker, kontur) bukan bagian dari visi agen dan tetap berada di Gemini 2.5.
  • Model terkadang melewatkan eksekusi kode jika sekali lihat sudah cukup. Sesuai desain, bukan bug.

Menyiapkan Lingkungan Anda untuk Visi Agen

Ambil kunci API dari ai.google.dev dan simpan sebagai GOOGLE_API_KEY di lingkungan Anda atau berkas .env. Lalu pasang SDK dan pustaka gambar:

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

Mulailah dengan membuat klien:

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"

Parameter timeout=600_000 penting. Panggilan visi agen melibatkan beberapa putaran pembuatan dan eksekusi kode di dalam sandbox, dan satu permintaan bisa memakan waktu sekitar empat menit. 

Batas waktu default httpx akan memutus koneksi jauh sebelum itu, meninggalkan Anda dengan ReadTimeout yang sunyi tanpa petunjuk apa yang terjadi.

Selanjutnya, siapkan konfigurasi agen:

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 adalah tombol untuk menyalakan eksekusi kode. Ini memberi model lingkungan Python tersandbox dengan 43 pustaka (numpy, pandas, PIL, matplotlib, OpenCV, dan lainnya). Setiap blok kode mendapat 30 detik untuk berjalan, dan sandbox mencoba ulang hingga 5 kali saat terjadi kesalahan.

thinking_level="HIGH" memberi model ruang lebih untuk merencanakan sebelum menulis kode. Untuk pekerjaan visi multi-langkah, ini memberi perbedaan yang terasa. Menetapkan include_thoughts=True menampilkan penalaran itu di bagian respons, berguna untuk debugging.

media_resolution mengatur berapa banyak token yang didapat gambar input sebelum loop dimulai. MEDIA_RESOLUTION_HIGH adalah default yang baik. Anda dapat menaikkan ke MEDIA_RESOLUTION_ULTRA_HIGH untuk gambar yang sangat padat atau menurunkan ke MEDIA_RESOLUTION_LOW saat kecepatan lebih penting daripada detail.

Pengaturan yang sama ini berfungsi di Vertex AI dengan perubahan minimal. Untuk panduan yang lebih luas tentang Gemini 3 API di luar visi, lihat tutorial pendampingnya.

Visi Agen di Gemini 3: Membaca Detail Halus dengan Crop dan Zoom

Gambar di bawah adalah rak toko bahan makanan Jerman dengan tiga baris produk. Label harga berjajar di tepi setiap rak, dan pemberitahuan "Liebe Kunden" (Pelanggan yang Terhormat) berada di dekat bagian bawah. Label dapat dibaca jika Anda memperbesar sendiri, tetapi cukup kecil sehingga model yang melihat seluruh gambar harus memutuskan apa yang bisa dan tidak bisa dibacanya.

Mengurai respons multi-bagian

Respons agen bukan satu blok teks. Respons datang sebagai daftar bagian: pemikiran, kode yang ditulis model, hasil eksekusi, gambar yang dihasilkan, dan jawaban akhir. Pembantu ini menelusurinya:

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)

Setiap contoh dalam tutorial ini menggunakan fungsi yang sama, jadi definisikan sekali dan gunakan ulang.

Sekarang muat gambar rak dan tuliskan prompt yang meminta model membaca pengumuman dan mencantumkan setiap produk beserta harganya.

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."
)

Jalankan terlebih dahulu tanpa eksekusi kode:

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)

Berikut versi keluaran yang dipangkas:

[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
...

Terjemahan pengumuman benar, dan model membaca label Uncle Ben yang bisa dikenalinya. Namun sekitar sepertiga entri bertuliskan "(Label obscured)," dan merek seperti Oryza, Reis-fit, dan Reiskugeln sama sekali tidak muncul.

Sekarang prompt yang sama dengan konfigurasi agen:

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

Struktur keluarannya berbeda. Alih-alih satu [ANSWER], ia menelusuri penuh loop 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

Tujuh hasil crop yang dihasilkan model:

Title: Potongan visi agen Gemini 3 dari pemberitahuan pelanggan Liebe Kunden di rak bahan makanan - Description: Potongan visi agen Gemini 3 dari pemberitahuan pelanggan Liebe Kunden di rak bahan makanan

Title: Potongan visi agen bagian kiri rak atas menampilkan produk beras Uncle Ben's - Description: Potongan visi agen bagian kiri rak atas menampilkan produk beras Uncle Ben's

Title: Potongan visi agen bagian kanan rak atas menampilkan Reiskugeln dan produk kari - Description: Potongan visi agen bagian kanan rak atas menampilkan Reiskugeln dan produk kari

Title: Potongan visi agen bagian kiri rak tengah dengan produk beras dan label harga - Description: Potongan visi agen bagian kiri rak tengah dengan produk beras dan label harga

Title: Potongan visi agen bagian kanan rak tengah menampilkan produk beras Oryza - Description: Potongan visi agen bagian kanan rak tengah menampilkan produk beras Oryza

Title: Potongan visi agen bagian kiri rak bawah dengan kantong 1kg Uncle Ben's - Description: Potongan visi agen bagian kiri rak bawah dengan kantong 1kg Uncle Ben's

Title: Potongan visi agen bagian kanan rak bawah menampilkan produk Reis-fit - Description: Potongan visi agen bagian kanan rak bawah menampilkan produk Reis-fit

Setelah mengamati hasil crop tersebut, model menghasilkan jawaban lengkap:

[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 €
...

Keluaran lengkap tanpa dipangkas untuk kedua panggilan tersedia di gist ini.

Respons agen membaca 30+ produk di ketiga rak. Item Oryza, Reis-fit, Madras Curry, Reiskugeln, dan Steam Basmati yang diberi label "(obscured)" oleh visi standar semuanya muncul lengkap dengan nama dan harga.

Perbedaannya bukan soal halusinasi vs. akurasi; visi standar jujur tentang apa yang tidak bisa dibacanya. Visi agen menolak menerima batas itu dan memperbesar hingga bisa membaca.

Prompt berperan di sini. Meminta model untuk "mencantumkan semua nama produk yang terlihat beserta harganya" menetapkan standar kelengkapan yang mendorongnya untuk melakukan crop. 

Prompt yang lebih samar seperti "deskripsikan gambar ini" kemungkinan akan menghasilkan jawaban sekali lewat meskipun eksekusi kode aktif, karena model tidak melihat alasan untuk melangkah lebih jauh.

Membaca di Kondisi Redup dan Terhalang

Gambar ini adalah menu bar Brasil yang difoto dalam pencahayaan redup. Tiga panel kaca mencantumkan minuman dengan teks emas, tetapi lampu gantung menghalangi sebagian panel kiri, panel kanan nyaris tak terlihat di tepi bingkai, dan pantulan kaca tersebar di permukaan.

Prompt tidak menyebut kecerahan, crop, atau teknik spesifik apa pun. Hanya meminta isinya:

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."
)

Visi standar membaca panel tengah yang terang tanpa masalah, mengambil delapan bir dari bagian "FRUTADAS" dan empat dari "CHOPP." Namun panel kiri kembali seperti ini:

[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]

Enam entri, sebagian besar dengan nama yang tidak terbaca dan semuanya tanpa gaya. Model melihat ada teks di sana tetapi tidak dapat membacanya.

Panggilan agen menjalankan dua putaran kode. Pertama, ia melakukan crop ketiga panel:

[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

Setelah mengamati hasil crop tersebut, model memutuskan panel kiri dan kanan membutuhkan pembesaran lebih lanjut. Ia menjalankan putaran kedua:

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

image1.png

Dengan pembesaran ekstra itu, model memulihkan nama yang diberi label tak terbaca oleh visi standar: Amber Lager, Honkers Ale (Goose Island), dan Demoiselle (Colorado) dari panel kiri, plus Wals Dubbel, Tripel, Quadrupel, dan Petroleum dari panel kanan. Model juga mengidentifikasi judul panel kiri sebagai "MISTURAS" dan judul panel kanan sebagai "ALCOÓLICAS."

Prompt tidak pernah mengatakan "crop panel" atau "perbesar area gelap." Ia meminta daftar minuman dan gayanya, dan model menelusuri balik dari tujuan itu. 

Yang membuat contoh ini berbeda dari rak bahan makanan adalah pass kedua. Setelah putaran pertama crop, model melihat apa yang dimilikinya, memutuskan panel kiri dan kanan masih terlalu sulit dibaca, dan menjalankan putaran lain dengan pembesaran lebih ketat tanpa diminta. 

Loop tersebut mengoreksi diri. 

Itulah hasil dari membiarkan metodenya terbuka: model tidak hanya melakukan prapemrosesan sekali, ia beriterasi hingga hasilnya memenuhi standar yang ditetapkan oleh prompt.

Penghitungan dan Anotasi dengan Visi Agen di Gemini 3

Menu bar berhasil karena prompt membiarkan metodenya terbuka, dan model mengetahui apa yang harus dilakukan. Itu tidak selalu berlaku. Terkadang model membutuhkan instruksi eksplisit tentang alat mana yang digunakan, dan contoh berikut menunjukkan batasnya.

Gambar di bawah menampilkan koin yang berserakan di atas meja dan map hitam. Beberapa tumpang tindih, sebagian tertutup, dan campuran tembaga serta perak membuatnya mudah terlewat.

image18.png

Pendekatan awal yang masuk akal adalah meminta model menganotasi setiap koin sehingga ia dapat menghitung dari penandaannya sendiri. Dokumentasi Google menegaskan bahwa visi agen dapat menggambar bounding box dan label langsung pada gambar menggunakan PIL dan OpenCV di sandbox. Maka:

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)

Model melakukan crop lima area, menganalisis masing-masing, dan mengembalikan hitungan 34. Namun perhatikan format jawabannya:

[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"},
  ...
]

Ia mengembalikan koordinat bounding box sebagai JSON alih-alih menggambar apa pun di gambar. Prompt mengatakan "draw," tetapi model memperlakukannya sebagai tugas deskripsi dan memberikan keluaran teks terstruktur.

Dokumentasi eksekusi kode memberi petunjuk alasannya: "Meskipun model secara otomatis menangani pembesaran untuk detail kecil, Anda harus memintanya secara eksplisit untuk menggunakan kode untuk tugas lain." Kata "draw" cukup ambigu sehingga model memilih jalur hanya-teks. 

Menggambarkan tugas dalam istilah kode yang Anda ingin dijalankan menghilangkan ambiguitas itu:

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)

Kali ini, model menulis kode gambar yang sebenarnya:

[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

Setiap koin mendapat kotak merah dan nomor. Hitungan sebenarnya adalah 35 atau 36, tergantung bagaimana Anda menilai dua koin yang tumpang tindih di dekat bagian bawah bingkai. 

Model menghasilkan 34, melewatkan satu atau dua di kluster tersebut. Namun anotasi berfungsi sebagai papan coret visual: alih-alih angka yang harus Anda terima begitu saja, Anda mendapatkan artefak yang dapat diverifikasi, yang bisa diperiksa kotak demi kotak.

Keluaran lengkap tanpa dipangkas untuk kedua panggilan tersedia di gist ini.

Ekstraksi Multi-Langkah dan Pembuatan Plot

Contoh sebelumnya melibatkan satu tugas utama masing-masing (membaca teks, menghitung objek). Yang satu ini merangkai beberapa tugas: crop tabel dari foto, mengekstrak angka ke DataFrame, dan menghasilkan bagan. Gambar tersebut adalah tabel pajak gaya IRS yang difoto di atas meja dengan kalkulator.

image5.png

Prompt menjabarkan seluruh pipeline sekaligus:

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)

Model membutuhkan empat putaran kode untuk berpindah dari foto penuh ke bagan jadi. Tiga pertama adalah pembesaran progresif: ia melakukan crop tabel "Single or Married Filing Separately", lalu judul kolom, lalu 10 baris pertama data, menghasilkan lima gambar perantara sepanjang proses. Berikut crop pertama saat ia mengisolasi tabel:

Title: Potongan pertama visi agen Gemini 3 yang mengisolasi area tabel Single Filing - Description: Potongan pertama visi agen Gemini 3 yang mengisolasi area tabel Single Filing

Pada putaran keempat, ia telah membaca detail yang cukup untuk mengekstrak angka. Ia membuat pandas DataFrame, mencetak tabel, dan menghasilkan bagan batang berkelompok dalam satu blok kode:

[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')

Tabel yang diekstrak:

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

Dan bagan batang yang dihasilkan:

Title: Bagan batang yang dihasilkan oleh visi agen Gemini 3 membandingkan jumlah pajak di berbagai kelompok upah - Description: Bagan batang yang dihasilkan oleh visi agen Gemini 3 membandingkan jumlah pajak di berbagai kelompok upah

Keluaran lengkap tanpa dipangkas tersedia di gist ini.

Satu panggilan API menghasilkan DataFrame terstruktur, ringkasan dengan baris maksimum/minimum teridentifikasi, dan bagan batang yang siap terbit. Prompt mencantumkan empat hal (crop, ekstrak, bagan, ringkas), dan model memperlakukan masing-masing sebagai tahap dalam pipeline di mana keluaran satu langkah mengalir ke langkah berikutnya. 

Contoh sebelumnya menggunakan loop untuk menyempurnakan satu operasi (crop lebih baik, anotasi lebih baik). Yang ini menunjukkan loop yang merangkai operasi berbeda, masing-masing membangun di atas apa yang dihasilkan putaran sebelumnya.

Kesimpulan

Visi agen mengubah satu panggilan API menjadi loop umpan balik di mana model menulis kode, melihat apa yang dihasilkannya, lalu memutuskan langkah berikutnya. 

Contoh rak bahan makanan menunjukkan pola dasar: melakukan crop pada area yang terlalu kecil untuk dibaca, lalu menjawab dari versi yang diperbesar. Menu bar menambahkan dimensi kedua, di mana model menjalankan satu putaran crop, memutuskan itu belum cukup, dan memperbesar lebih lanjut area bermasalah secara mandiri. 

Untuk koin, anotasi mengubah tebakan menjadi artefak yang dapat diperiksa. Tabel pajak merangkai empat operasi berbeda (crop, ekstraksi, komputasi, plot) dalam satu permintaan.

Setiap contoh juga mengungkap sesuatu tentang pembuatan prompt. Menetapkan standar kelengkapan ("cantumkan semua produk") mendorong model ke arah ketelitian. Membiarkan metodenya terbuka memungkinkan model memilih jalur prapemrosesan sendiri. 

Namun verba ambigu seperti "draw" kadang membuatnya salah jalur, dan beralih ke "Use Python to draw" menyelesaikannya. 

Polanya: deskripsikan apa yang Anda ingin dihasilkan, bersikap spesifik soal alat saat tugasnya ambigu, dan biarkan loop menangani sisanya.

Semua kode dari tutorial ini berjalan dengan gemini-3-flash-preview dan SDK google-genai. Jika Anda ingin menggali lebih dalam, kursus DataCamp Introduction to AI Agents membahas pola loop di balik semuanya.

Visi Agen di Gemini 3: FAQ

Apa itu visi agen dalam Gemini 3 Flash?

Visi agen adalah fitur di mana Gemini 3 Flash dapat menulis dan menjalankan kode Python di tengah respons untuk memanipulasi gambar sebelum menjawab. Ia menggunakan loop Think, Act, Observe untuk melakukan crop, pembesaran, anotasi, dan peningkatan gambar di lingkungan sandbox, semuanya dalam satu panggilan API.

Bagaimana cara mengaktifkan visi agen di Gemini API?

Tambahkan alat eksekusi kode ke GenerateContentConfig Anda: tools=[types.Tool(code_execution=types.ToolCodeExecution())]. Ini memberi model akses ke lingkungan Python tersandbox dengan 43 pustaka prainstal termasuk PIL, OpenCV, dan matplotlib.

Mengapa model melewatkan eksekusi kode meskipun telah diaktifkan?

Model hanya menulis kode ketika ia memutuskan bahwa sekali lihat gambar tidak cukup. Jika dapat menjawab dengan yakin dari resolusi asli, ia melewati jalur eksekusi kode. Ini sesuai desain dan didokumentasikan oleh Google.

Apa perbedaan antara "draw" dan "Use Python to draw" dalam prompt?

Mengatakan "draw" bersifat ambigu dan model mungkin mengembalikan deskripsi teks atau koordinat JSON alih-alih gambar yang sebenarnya. Menambahkan "Use Python to draw" memberi tahu model untuk menulis kode yang dapat dijalankan dan menghasilkan keluaran visual, yang memicu jalur eksekusi kode secara andal.

Bisakah saya menggabungkan visi agen dengan pemanggilan fungsi kustom?

Tidak. Eksekusi kode dan pemanggilan fungsi kustom tidak dapat digunakan dalam permintaan API yang sama. Jika alur kerja Anda membutuhkan keduanya, Anda harus membuat panggilan terpisah untuk masing-masing.


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

Saya adalah kreator konten data science dengan pengalaman lebih dari 2 tahun dan salah satu dengan jumlah pengikut terbesar di Medium. Saya suka menulis artikel mendalam tentang AI dan ML dengan sedikit gaya sarkastik—karena harus ada sesuatu untuk membuatnya tidak terlalu membosankan. Saya telah menghasilkan lebih dari 130 artikel dan satu kursus di DataCamp, dengan satu lagi sedang dalam proses. Konten saya telah dilihat oleh lebih dari 5 juta pasang mata, dan 20 ribu di antaranya menjadi pengikut di Medium dan LinkedIn. 

Topik
Kecerdasan Buatan
Agen AI

Kursus Teratas di DataCamp

{count, plural, one {Program} other {Program}}

Dasar-Dasar Agen Kecerdasan Buatan

{hours} jam
Temukan bagaimana agen kecerdasan buatan (AI) dapat mengubah cara Anda bekerja dan memberikan nilai tambah bagi organisasi Anda!
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

{count, plural, one {blog} other {blogs}}

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

{count, plural, one {blog} other {blogs}}

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

{count, plural, one {blog} other {blogs}}

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

{count, plural, one {blog} other {blogs}}

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

Lihat SelengkapnyaLihat Selengkapnya