Milvus
Zilliz
  • Home
  • Blog
  • Bangun Pipeline Buku Terlaris ke Gambar untuk E-Commerce dengan Nano Banana 2 + Milvus + Qwen 3.5

Bangun Pipeline Buku Terlaris ke Gambar untuk E-Commerce dengan Nano Banana 2 + Milvus + Qwen 3.5

  • Tutorials
March 03, 2026
Lumina Wang

Jika Anda membuat alat bantu AI untuk penjual e-commerce, Anda mungkin pernah mendengar permintaan ini ribuan kali: "Saya punya produk baru. Berikan saya gambar promosi yang terlihat seperti produk tersebut masuk dalam daftar buku terlaris. Tanpa fotografer, tanpa studio, dan buatlah dengan harga yang murah."

Itulah masalahnya dalam sebuah kalimat. Penjual memiliki foto-foto datar dan katalog buku terlaris yang sudah terjual. Mereka ingin menjembatani keduanya dengan AI, baik secara cepat maupun dalam skala besar.

Ketika Google merilis Nano Banana 2 (Gemini 3.1 Flash Image) pada tanggal 26 Februari 2026, kami mengujinya pada hari yang sama dan mengintegrasikannya ke dalam pipeline pengambilan berbasis Milvus yang sudah ada. Hasilnya: total biaya pembuatan gambar turun menjadi kira-kira sepertiga dari biaya yang dihabiskan sebelumnya, dan throughput meningkat dua kali lipat. Pemotongan harga per gambar (sekitar 50% lebih murah daripada Nano Banana Pro) menyumbang sebagian dari itu, tetapi penghematan yang lebih besar berasal dari menghilangkan siklus pengerjaan ulang sepenuhnya.

Artikel ini membahas apa yang dilakukan Nano Banana 2 untuk e-commerce, di mana ia masih gagal, dan kemudian berjalan melalui tutorial langsung untuk pipa penuh: Pencarian hibrida Milvus untuk menemukan buku terlaris yang mirip secara visual, Qwen 3.5 untuk analisis gaya, dan Nano Banana 2 untuk generasi terakhir.

Apa yang Baru dengan Nano Banana 2?

Nano Banana 2 (Gemini 3.1 Flash Image) diluncurkan pada tanggal 26 Februari 2026. Ini membawa sebagian besar kemampuan Nano Banana Pro ke arsitektur Flash, yang berarti generasi yang lebih cepat dengan harga yang lebih rendah. Berikut ini adalah peningkatan utama:

  • Kualitas tingkat pro pada kecepatan Flash. Nano Banana 2 menghadirkan pengetahuan, penalaran, dan ketepatan visual kelas dunia yang sebelumnya eksklusif untuk Pro, tetapi dengan latensi dan throughput Flash.
  • Output 512px hingga 4K. Empat tingkatan resolusi (512px, 1K, 2K, 4K) dengan dukungan asli. Tingkatan 512px adalah hal yang baru dan unik untuk Nano Banana 2.
  • 14 rasio aspek. Menambahkan 4:1, 1:4, 8:1, dan 1:8 ke set yang sudah ada (1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9).
  • Hingga 14 gambar referensi. Mempertahankan kemiripan karakter hingga 5 karakter dan ketepatan objek hingga 14 objek dalam satu alur kerja.
  • Rendering teks yang lebih baik. Menghasilkan teks dalam gambar yang terbaca dan akurat dalam berbagai bahasa, dengan dukungan untuk terjemahan dan pelokalan dalam satu generasi.
  • Landasan Pencarian Gambar. Mengambil data web real-time dan gambar dari Google Penelusuran untuk menghasilkan penggambaran yang lebih akurat dari subjek dunia nyata.
  • ~50% lebih murah per gambar. Pada resolusi 1K: 0.067versusProβ€²s0.067 versus Pro's0 .134.

Kasus Penggunaan yang Menyenangkan dari Nano Banano 2: Menghasilkan Panorama Sadar Lokasi Berdasarkan Cuplikan Layar Google Map Sederhana

Dengan memberikan tangkapan layar Google Maps dan perintah gaya, model mengenali konteks geografis dan menghasilkan panorama yang mempertahankan hubungan spasial yang benar. Berguna untuk menghasilkan materi iklan yang ditargetkan berdasarkan wilayah (latar belakang kafe di Paris, pemandangan jalanan di Tokyo) tanpa menggunakan stok fotografi.

Untuk mengetahui fitur lengkapnya, lihat blog pengumuman Google dan dokumentasi pengembang.

Apa Arti Pembaruan Nano Banana Ini Bagi E-Commerce?

E-commerce adalah salah satu industri yang paling banyak menggunakan gambar. Daftar produk, iklan pasar, materi iklan sosial, kampanye spanduk, etalase yang dilokalkan: setiap saluran menuntut aliran aset visual yang konstan, masing-masing dengan spesifikasinya sendiri.

Persyaratan inti untuk pembuatan gambar AI dalam e-commerce bermuara pada:

  • Menjaga biaya tetap rendah - biaya per gambar harus sesuai dengan skala katalog.
  • Cocokkan tampilan buku terlaris yang telah terbukti - gambar baru harus selaras dengan gaya visual dari daftar yang telah terkonversi.
  • Hindari pelanggaran - tidak boleh meniru materi iklan pesaing atau menggunakan kembali aset yang dilindungi.

Selain itu, penjual lintas batas membutuhkan:

  • Dukungan format multi-platform - rasio aspek dan spesifikasi yang berbeda untuk pasar, iklan, dan etalase.
  • Rendering teks multibahasa - teks dalam gambar yang bersih dan akurat dalam berbagai bahasa.

Nano Banana 2 hampir mencentang semua kotak. Bagian di bawah ini menguraikan apa arti setiap peningkatan dalam praktiknya: di mana peningkatan tersebut secara langsung memecahkan titik masalah e-commerce, di mana peningkatan tersebut gagal, dan seperti apa dampak biaya yang sebenarnya.

Memangkas Biaya Produksi Output Hingga 60

Pada resolusi 1K, Nano Banana 2 berharga 0,067perimageversusProβ€²s0,067 per gambar dibandingkan Pro's0, ,134, yang merupakan pemotongan 50%. Tetapi, harga per gambar hanya separuh dari cerita. Apa yang biasanya membunuh anggaran pengguna adalah pengerjaan ulang. Setiap pasar memberlakukan spesifikasi gambarnya sendiri (1: 1 untuk Amazon, 3: 4 untuk etalase Shopify, ultrawide untuk iklan spanduk), dan memproduksi setiap varian berarti melewati generasi yang terpisah dengan mode kegagalannya sendiri.

Nano Banana 2 menggabungkan semua lintasan ekstra itu menjadi satu.

  • Empat tingkatan resolusi asli.

  • 512 piksel ($0,045)

  • 1K ($0.067)

  • 2K ($0.101)

  • 4K ($0.151).

Tingkatan 512px adalah hal yang baru dan unik untuk Nano Banana 2. Pengguna sekarang dapat menghasilkan draf 512px berbiaya rendah untuk iterasi dan menghasilkan aset akhir pada 2K atau 4K tanpa langkah peningkatan yang terpisah.

  • Total ada14 rasio aspek yang didukung. Berikut adalah beberapa contohnya:

  • 4:1

  • 1:4

  • 8:1

  • 1:8

Rasio ultra-lebar dan ultra-tinggi yang baru ini bergabung dengan rangkaian yang sudah ada. Satu sesi generasi dapat menghasilkan berbagai format seperti: Gambar utama Amazon (1:1), Pahlawan etalase (3:4) dan Iklan spanduk (ultra-lebar atau rasio lainnya).

Tidak ada pemotongan, tidak ada padding, tidak perlu meminta ulang untuk 4 rasio ini. Sisa 10 rasio aspek lainnya disertakan dalam set lengkap, membuat prosesnya lebih fleksibel di berbagai platform.

Penghematan ~50% per gambar saja sudah bisa mengurangi separuh tagihan. Dengan menghilangkan pengerjaan ulang di seluruh resolusi dan rasio aspek, maka total biaya yang dikeluarkan menjadi sekitar sepertiga dari biaya yang dihabiskan sebelumnya.

Mendukung Hingga 14 Gambar Referensi dengan Gaya Terlaris

Dari semua pembaruan Nano Banana 2, pencampuran multi-referensi memiliki dampak terbesar pada pipeline Milvus kami. Nano Banana 2 menerima hingga 14 gambar referensi dalam satu permintaan, dengan tetap mempertahankan:

  • Kemiripan karakter hingga 5 karakter
  • Kesesuaian objek hingga 14 objek

Dalam praktiknya, kami mengambil beberapa gambar buku terlaris dari Milvus, meneruskannya sebagai referensi, dan gambar yang dihasilkan mewarisi komposisi adegan, pencahayaan, pose, dan penempatan prop. Tidak ada rekayasa cepat yang diperlukan untuk merekonstruksi pola-pola tersebut dengan tangan.

Model terdahulu hanya mendukung satu atau dua referensi, yang memaksa pengguna untuk memilih satu buku terlaris untuk ditiru. Dengan 14 slot referensi, kami dapat memadukan karakteristik dari beberapa daftar yang berkinerja terbaik dan membiarkan model mensintesis gaya komposit. Ini adalah kemampuan yang memungkinkan pipeline berbasis pengambilan dalam tutorial di bawah ini.

Menghasilkan Visual Premium dan Siap Komersial Tanpa Biaya Produksi atau Logistik Tradisional

Untuk menghasilkan gambar yang konsisten dan dapat diandalkan, hindari membuang semua kebutuhan Anda ke dalam satu prompt. Pendekatan yang lebih dapat diandalkan adalah bekerja secara bertahap: buat latar belakang terlebih dahulu, kemudian model secara terpisah, dan akhirnya menggabungkannya bersama-sama.

Kami menguji pembuatan latar belakang pada ketiga model Nano Banana dengan prompt yang sama: cakrawala kota Shanghai pada hari hujan dengan rasio ultrawide 4:1 yang dilihat melalui jendela, dengan Oriental Pearl Tower yang terlihat. Prompt ini menguji komposisi, detail arsitektur, dan fotorealisme dalam satu kali pemotretan.

Nano Banana Asli vs Nano Banana Pro vs Nano Banana 2

  • Pisang Nano Asli. Tekstur hujan alami dengan distribusi tetesan air yang bisa dipercaya, tetapi detail bangunan terlalu diperhalus. Oriental Pearl Tower nyaris tidak dapat dikenali, dan resolusinya tidak memenuhi persyaratan produksi.
  • Nano Banana Pro. Suasana sinematik: pencahayaan interior yang hangat berpadu dengan hujan yang dingin secara meyakinkan. Namun demikian, ini menghilangkan bingkai jendela sepenuhnya, meratakan kesan kedalaman gambar. Dapat digunakan sebagai gambar pendukung, bukan pahlawan.
  • Nano Banana 2. Menyajikan pemandangan secara utuh. Bingkai jendela di latar depan menciptakan kedalaman. Menara Mutiara Oriental secara jelas terlihat detailnya. Kapal muncul di Sungai Huangpu. Pencahayaan berlapis membedakan kehangatan interior dari mendung di eksterior. Tekstur hujan dan noda air nyaris seperti fotografi, dan rasio ultrawide 4:1 mempertahankan perspektif yang benar dengan hanya sedikit distorsi di tepi jendela kiri.

Untuk sebagian besar tugas pembuatan latar belakang dalam fotografi produk, kami menemukan bahwa output Nano Banana 2 dapat digunakan tanpa pasca-pemrosesan.

Merender Teks Dalam Gambar dengan Bersih di Berbagai Bahasa

Label harga, spanduk promosi, dan teks multibahasa tidak dapat dihindari dalam gambar e-commerce, dan secara historis telah menjadi titik balik bagi generasi AI. Nano Banana 2 menanganinya dengan jauh lebih baik, mendukung rendering teks dalam gambar di berbagai bahasa dengan terjemahan dan pelokalan dalam satu generasi.

Rendering teks standar. Dalam pengujian kami, keluaran teks bebas dari kesalahan di setiap format e-commerce yang kami coba: label harga, slogan pemasaran singkat, dan deskripsi produk dalam dua bahasa.

Kelanjutan tulisan tangan. Karena e-commerce sering kali memerlukan elemen tulisan tangan seperti label harga dan kartu yang dipersonalisasi, kami menguji apakah model ini dapat mencocokkan gaya tulisan tangan yang sudah ada dan memperluasnya - khususnya, mencocokkan daftar tugas yang ditulis tangan dan menambahkan 5 item baru dengan gaya yang sama. Hasil dari tiga model:

  • Pisang Nano Asli. Nomor urut yang berulang, struktur yang disalahpahami.
  • Nano Banana Pro. Tata letak yang benar, tetapi reproduksi gaya font yang buruk.
  • Nano Banana 2. Tidak ada kesalahan. Berat goresan dan gaya bentuk huruf yang cocok cukup dekat sehingga tidak dapat dibedakan dari sumbernya.

Namun, dokumentasi Google sendiri mencatat bahwa Nano Banana 2 "masih kesulitan dengan ejaan yang akurat dan detail halus pada gambar." Hasil kami bersih di seluruh format yang kami uji, tetapi alur kerja produksi apa pun harus menyertakan langkah verifikasi teks sebelum diterbitkan.

Tutorial Langkah-demi-Langkah: Membuat Pipeline Buku Terlaris ke Gambar dengan Milvus, Qwen 3.5, dan Nano Banana 2

Sebelum kita mulai: Pengaturan Arsitektur dan Model

Untuk menghindari keacakan dari pembuatan single-prompt, kami membagi prosesnya menjadi tiga tahap yang dapat dikontrol: mengambil apa yang sudah bekerja dengan pencarian hybrid Milvus, menganalisis mengapa ia bekerja dengan Qwen 3.5, kemudian menghasilkan gambar akhir dengan batasan-batasan yang sudah dibuat dengan Nano Banana 2.

Panduan singkat untuk setiap alat jika Anda belum pernah menggunakannya:

  • Milvus: basis data vektor sumber terbuka yang paling banyak digunakan. Menyimpan katalog produk Anda sebagai vektor dan menjalankan pencarian hibrida (filter padat + jarang + skalar) untuk menemukan gambar terlaris yang paling mirip dengan produk baru.
  • Qwen 3.5: LLM multimodal yang populer. Mengambil gambar buku terlaris yang diambil dan mengekstrak pola visual di belakangnya (tata letak pemandangan, pencahayaan, pose, suasana hati) ke dalam prompt gaya terstruktur.
  • Nano Banana 2: model pembuatan gambar dari Google (Gemini 3.1 Flash Image). Mengambil tiga masukan: tata letak produk baru, referensi buku terlaris, dan style prompt Qwen 3.5. Menghasilkan foto promosi akhir.

Logika di balik arsitektur ini dimulai dengan satu pengamatan: aset visual yang paling berharga dalam katalog e-commerce mana pun adalah perpustakaan gambar buku terlaris yang telah dikonversi. Pose, komposisi, dan pencahayaan pada foto-foto tersebut disempurnakan melalui belanja iklan yang nyata. Mengambil pola-pola tersebut secara langsung adalah urutan yang jauh lebih cepat daripada merekayasa baliknya melalui penulisan yang cepat, dan langkah pengambilan tersebut adalah apa yang ditangani oleh basis data vektor.

Berikut adalah alur lengkapnya. Kami memanggil setiap model melalui API OpenRouter, jadi tidak ada persyaratan GPU lokal dan tidak ada bobot model yang harus diunduh.

New product flat-lay
β”‚
│── Embed β†’ Llama Nemotron Embed VL 1B v2
β”‚
│── Search β†’ Milvus hybrid search
β”‚   β”œβ”€β”€ Dense vectors (visual similarity)
β”‚   β”œβ”€β”€ Sparse vectors (keyword matching)
β”‚   └── Scalar filters (category + sales volume)
β”‚
│── Analyze β†’ Qwen 3.5 extracts style from retrieved bestsellers
β”‚   └── scene, lighting, pose, mood β†’ style prompt
β”‚
└── Generate β†’ Nano Banana 2
    β”œβ”€β”€ Inputs: new product + bestseller reference + style prompt
    └── Output: promotional photo

Kami mengandalkan tiga kemampuan Milvus untuk membuat tahap pengambilan bekerja:

  1. Pencarian hibrida padat + jarang. Kami menjalankan penyematan gambar dan vektor TF-IDF teks sebagai kueri paralel, lalu menggabungkan dua set hasil dengan pemeringkatan ulang RRF (Reciprocal Rank Fusion).
  2. Pemfilteran bidang skalar. Kami memfilter berdasarkan bidang metadata seperti kategori dan jumlah_penjualan sebelum perbandingan vektor, sehingga hasil hanya mencakup produk yang relevan dan berkinerja tinggi.
  3. Skema multi-bidang. Kami menyimpan vektor padat, vektor jarang, dan metadata skalar dalam satu koleksi Milvus, yang membuat seluruh logika pengambilan dalam satu kueri, bukan tersebar di beberapa sistem.

Persiapan Data

Katalog produk historis

Kami mulai dengan dua aset: gambar/folder foto produk yang sudah ada dan file products.csv yang berisi metadata.

images/
β”œβ”€β”€ SKU001.jpg
β”œβ”€β”€ SKU002.jpg
β”œβ”€β”€ ...
└── SKU040.jpg

products.csv fields: product_id, image_path, category, color, style, season, sales_count, description, price

Data produk baru

Untuk produk yang ingin kami buatkan gambar promosinya, kami menyiapkan struktur paralel: folder new_products/ dan new_products.csv.

new_products/
β”œβ”€β”€ NEW001.jpg    # Blue knit cardigan + grey tulle skirt set
β”œβ”€β”€ NEW002.jpg    # Light green floral ruffle maxi dress
β”œβ”€β”€ NEW003.jpg    # Camel turtleneck knit dress
└── NEW004.jpg    # Dark grey ethnic-style cowl neck top dress

new_products.csv fields: new_id, image_path, category, style, season, prompt_hint

Langkah 1: Instal Ketergantungan

!pip install pymilvus openai requests pillow scikit-learn tqdm

Langkah 2: Mengimpor Modul dan Konfigurasi

import os, io, base64, csv, time
import requests as req
import numpy as np
from PIL import Image
from tqdm.notebook import tqdm
from sklearn.feature_extraction.text import TfidfVectorizer
from IPython.display import display

from openai import OpenAI from pymilvus import MilvusClient, DataType, AnnSearchRequest, RRFRanker

Konfigurasikan semua model dan jalur:

# -- Config --
OPENROUTER_API_KEY = os.environ.get(
    "OPENROUTER_API_KEY",
    "<YOUR_OPENROUTER_API_KEY>",
)

# Models (all via OpenRouter, no local download needed) EMBED_MODEL = β€œnvidia/llama-nemotron-embed-vl-1b-v2” # free, image+text β†’ 2048d EMBED_DIM = 2048 LLM_MODEL = β€œqwen/qwen3.5-397b-a17b” # style analysis IMAGE_GEN_MODEL = β€œgoogle/gemini-3.1-flash-image-preview” # Nano Banana 2

# Milvus MILVUS_URI = β€œ./milvus_fashion.db” COLLECTION = β€œfashion_products” TOP_K = 3

# Paths IMAGE_DIR = β€œ./images” NEW_PRODUCT_DIR = β€œ./new_products” PRODUCT_CSV = β€œ./products.csv” NEW_PRODUCT_CSV = β€œ./new_products.csv”

# OpenRouter client (shared for LLM + image gen) llm = OpenAI(api_key=OPENROUTER_API_KEY, base_url=β€œhttps://openrouter.ai/api/v1”)

print(β€œConfig loaded. All models via OpenRouter API.”)

Fungsi utilitas

Fungsi-fungsi pembantu ini menangani pengkodean gambar, panggilan API, dan penguraian respons:

  • image_to_uri(): Mengonversi gambar PIL menjadi URI data base64 untuk transportasi API.
  • get_image_embeddings(): Menyandikan gambar secara batch menjadi vektor 2048 dimensi melalui OpenRouter Embedding API.
  • get_text_embedding (): Menyandikan teks ke dalam ruang vektor 2048 dimensi yang sama.
  • sparse_to_dict(): Mengonversi baris matriks scipy sparse ke dalam format {index: value} yang diharapkan Milvus untuk vektor jarang.
  • extract_images(): Mengekstrak gambar yang dihasilkan dari respons API Nano Banana 2.
# -- Utility functions --

def image_to_uri(img, max_size=1024): β€œ""Convert PIL Image to base64 data URI.""” img = img.copy() w, h = img.size if max(w, h) > max_size: r = max_size / max(w, h) img = img.resize((int(w * r), int(h * r)), Image.LANCZOS) buf = io.BytesIO() img.save(buf, format=β€œJPEG”, quality=85) return f"data:image/jpeg;base64,{base64.b64encode(buf.getvalue()).decode()}"

def get_image_embeddings(images, batch_size=5): β€œ""Encode images via OpenRouter embedding API.""” all_embs = [] for i in tqdm(range(0, len(images), batch_size), desc=β€œEncoding images”): batch = images[i : i + batch_size] inputs = [ {β€œcontent”: [{β€œtype”: β€œimage_url”, β€œimage_url”: {β€œurl”: image_to_uri(img, max_size=512)}}]} for img in batch ] resp = req.post( β€œhttps://openrouter.ai/api/v1/embeddings”, headers={β€œAuthorization”: f"Bearer {OPENROUTER_API_KEY}"}, json={β€œmodel”: EMBED_MODEL, β€œinput”: inputs}, timeout=120, ) data = resp.json() if β€œdata” not in data: print(f"API error: {data}") continue for item in sorted(data[β€œdata”], key=lambda x: x[β€œindex”]): all_embs.append(item[β€œembedding”]) time.sleep(0.5) # rate limit friendly return np.array(all_embs, dtype=np.float32)

def get_text_embedding(text): β€œ""Encode text via OpenRouter embedding API.""” resp = req.post( β€œhttps://openrouter.ai/api/v1/embeddings”, headers={β€œAuthorization”: f"Bearer {OPENROUTER_API_KEY}"}, json={β€œmodel”: EMBED_MODEL, β€œinput”: text}, timeout=60, ) return np.array(resp.json()[β€œdata”][0][β€œembedding”], dtype=np.float32)

def sparse_to_dict(sparse_row): β€œ""Convert scipy sparse row to Milvus sparse vector format {index: value}.""” coo = sparse_row.tocoo() return {int(i): float(v) for i, v in zip(coo.col, coo.data)}

def extract_images(response): β€œ""Extract generated images from OpenRouter response.""” images = [] raw = response.model_dump() msg = raw[β€œchoices”][0][β€œmessage”] # Method 1: images field (OpenRouter extension) if β€œimages” in msg and msg[β€œimages”]: for img_data in msg[β€œimages”]: url = img_data[β€œimage_url”][β€œurl”] b64 = url.split(β€œ,”, 1)[1] images.append(Image.open(io.BytesIO(base64.b64decode(b64)))) # Method 2: inline base64 in content parts if not images and isinstance(msg.get(β€œcontent”), list): for part in msg[β€œcontent”]: if isinstance(part, dict) and part.get(β€œtype”) == β€œimage_url”: url = part[β€œimage_url”][β€œurl”] if url.startswith(β€œdata:image”): b64 = url.split(β€œ,”, 1)[1] images.append(Image.open(io.BytesIO(base64.b64decode(b64)))) return images

print(β€œUtility functions ready.”)

Langkah 3: Memuat Katalog Produk

Baca products.csv dan muat gambar produk yang sesuai:

with open(PRODUCT_CSV, newline="", encoding="utf-8") as f:
    products = list(csv.DictReader(f))

product_images = [] for p in products: img = Image.open(os.path.join(IMAGE_DIR, p[β€œimage_path”])).convert(β€œRGB”) product_images.append(img)

print(f"Loaded {len(products)} products.") for i in range(3): p = products[i] print(f"{p[β€˜product_id’]} | {p[β€˜category’]} | {p[β€˜color’]} | {p[β€˜style’]} | sales: {p[β€˜sales_count’]}") display(product_images[i].resize((180, int(180 * product_images[i].height / product_images[i].width))))

Contoh keluaran:

Langkah 4: Hasilkan Penyematan

Pencarian hibrida memerlukan dua jenis vektor untuk setiap produk.

4.1 Vektor padat: penyematan gambar

Model nvidia/llama-nemotron-embed-vl-1b-v2 mengkodekan setiap gambar produk ke dalam vektor padat 2048 dimensi. Karena model ini mendukung input gambar dan teks dalam ruang vektor bersama, penyematan yang sama dapat digunakan untuk pengambilan gambar-ke-gambar dan teks-ke-gambar.

# Dense embeddings: image β†’ 2048-dim vector via OpenRouter API
dense_vectors = get_image_embeddings(product_images, batch_size=5)
print(f"Dense vectors: {dense_vectors.shape}  (products x {EMBED_DIM}d)")

Keluaran:

Dense vectors: (40, 2048)  (products x 2048d)

4.2 Vektor yang jarang: Penyematan teks TF-IDF

Deskripsi teks produk dikodekan ke dalam vektor jarang menggunakan vektorizer TF-IDF scikit-learn. Vektor ini menangkap pencocokan tingkat kata kunci yang dapat dilewatkan oleh vektor padat.

# Sparse embeddings: TF-IDF on product descriptions
descriptions = [p["description"] for p in products]
tfidf = TfidfVectorizer(stop_words="english", max_features=500)
tfidf_matrix = tfidf.fit_transform(descriptions)

sparse_vectors = [sparse_to_dict(tfidf_matrix[i]) for i in range(len(products))] print(f"Sparse vectors: {len(sparse_vectors)} products, vocab size: {len(tfidf.vocabulary_)}") print(f"Sample sparse vector (SKU001): {len(sparse_vectors[0])} non-zero terms")

Keluaran:

Sparse vectors: 40 products, vocab size: 179
Sample sparse vector (SKU001): 11 non-zero terms

Mengapa kedua jenis vektor tersebut? Vektor padat dan vektor jarang saling melengkapi satu sama lain. Vektor padat menangkap kemiripan visual: palet warna, siluet garmen, gaya keseluruhan. Vektor yang jarang menangkap semantik kata kunci: istilah seperti "floral", "midi", atau "sifon" yang menandakan atribut produk. Menggabungkan keduanya menghasilkan kualitas pencarian yang jauh lebih baik daripada salah satu pendekatan saja.

Langkah 5: Buat Koleksi Milvus dengan Skema Hibrida

Langkah ini membuat koleksi Milvus tunggal yang menyimpan vektor padat, vektor jarang, dan bidang metadata skalar secara bersamaan. Skema terpadu ini memungkinkan pencarian hibrida dalam satu kueri.

BidangJenisTujuan
dense_vectorFLOAT_VECTOR (2048d)Penyematan gambar, kemiripan COSINE
sparse_vectorVEKTOR JARANG_FLOATVektor jarang TF-IDF, produk dalam
kategoriVARCHARLabel kategori untuk pemfilteran
jumlah_penjualanINT64Volume penjualan historis untuk pemfilteran
warna, gaya, musimVARCHARLabel metadata tambahan
hargaFLOATHarga produk
milvus_client = MilvusClient(uri=MILVUS_URI)

if milvus_client.has_collection(COLLECTION): milvus_client.drop_collection(COLLECTION)

schema = milvus_client.create_schema(auto_id=True, enable_dynamic_field=True) schema.add_field(β€œid”, DataType.INT64, is_primary=True) schema.add_field(β€œproduct_id”, DataType.VARCHAR, max_length=20) schema.add_field(β€œcategory”, DataType.VARCHAR, max_length=50) schema.add_field(β€œcolor”, DataType.VARCHAR, max_length=50) schema.add_field(β€œstyle”, DataType.VARCHAR, max_length=50) schema.add_field(β€œseason”, DataType.VARCHAR, max_length=50) schema.add_field(β€œsales_count”, DataType.INT64) schema.add_field(β€œdescription”, DataType.VARCHAR, max_length=500) schema.add_field(β€œprice”, DataType.FLOAT) schema.add_field(β€œdense_vector”, DataType.FLOAT_VECTOR, dim=EMBED_DIM) schema.add_field(β€œsparse_vector”, DataType.SPARSE_FLOAT_VECTOR)

index_params = milvus_client.prepare_index_params() index_params.add_index(field_name=β€œdense_vector”, index_type=β€œFLAT”, metric_type=β€œCOSINE”) index_params.add_index(field_name=β€œsparse_vector”, index_type=β€œSPARSE_INVERTED_INDEX”, metric_type=β€œIP”)

milvus_client.create_collection(COLLECTION, schema=schema, index_params=index_params) print(f"Milvus collection '{COLLECTION}' created with hybrid schema.")

Masukkan data produk:

# Insert all products
rows = []
for i, p in enumerate(products):
    rows.append({
        "product_id": p["product_id"],
        "category": p["category"],
        "color": p["color"],
        "style": p["style"],
        "season": p["season"],
        "sales_count": int(p["sales_count"]),
        "description": p["description"],
        "price": float(p["price"]),
        "dense_vector": dense_vectors[i].tolist(),
        "sparse_vector": sparse_vectors[i],
    })

milvus_client.insert(COLLECTION, rows) stats = milvus_client.get_collection_stats(COLLECTION) print(f"Inserted {stats[β€˜row_count’]} products into Milvus.")

Keluaran:

Inserted 40 products into Milvus.

Langkah 6: Pencarian Hibrida untuk Menemukan Buku Terlaris yang Mirip

Ini adalah langkah pengambilan inti. Untuk setiap produk baru, pipeline menjalankan tiga operasi secara bersamaan:

  1. Pencarian padat: menemukan produk dengan penyematan gambar yang mirip secara visual.
  2. Pencarian jarang: menemukan produk dengan kata kunci teks yang cocok melalui TF-IDF.
  3. Pemfilteran skalar: membatasi hasil ke kategori dan produk yang sama dengan jumlah penjualan > 1500.
  4. Pemeringkatan ulang RRF: menggabungkan daftar hasil yang padat dan jarang menggunakan Reciprocal Rank Fusion.

Memuat produk baru:

# Load new products
with open(NEW_PRODUCT_CSV, newline="", encoding="utf-8") as f:
    new_products = list(csv.DictReader(f))

# Pick the first new product for demo new_prod = new_products[0] new_img = Image.open(os.path.join(NEW_PRODUCT_DIR, new_prod[β€œimage_path”])).convert(β€œRGB”)

print(f"New product: {new_prod[β€˜new_id’]}") print(f"Category: {new_prod[β€˜category’]} | Style: {new_prod[β€˜style’]} | Season: {new_prod[β€˜season’]}") print(f"Prompt hint: {new_prod[β€˜prompt_hint’]}") display(new_img.resize((300, int(300 * new_img.height / new_img.width))))

Keluaran:

Mengkodekan produk baru:

# Encode new product
# Dense: image embedding via API
query_dense = get_image_embeddings([new_img], batch_size=1)[0]

# Sparse: TF-IDF from text query query_text = f"{new_prod[β€˜category’]} {new_prod[β€˜style’]} {new_prod[β€˜season’]} {new_prod[β€˜prompt_hint’]}" query_sparse = sparse_to_dict(tfidf.transform([query_text])[0])

# Scalar filter filter_expr = f’category == "{new_prod[β€œcategory”]}" and sales_count > 1500’

print(f"Dense query: {query_dense.shape}") print(f"Sparse query: {len(query_sparse)} non-zero terms") print(f"Filter: {filter_expr}")

Keluaran:

Dense query: (2048,)
Sparse query: 6 non-zero terms
Filter: category == "midi_dress" and sales_count > 1500

Menjalankan pencarian hibrida

Panggilan API utama ada di sini:

  • AnnSearchRequest membuat permintaan pencarian terpisah untuk bidang vektor padat dan jarang.
  • expr = filter_expr menerapkan pemfilteran skalar dalam setiap permintaan pencarian.
  • RRFRanker(k=60) menggabungkan dua daftar hasil peringkat menggunakan algoritme Reciprocal Rank Fusion.
  • hybrid_search mengeksekusi kedua permintaan dan mengembalikan hasil yang telah digabungkan dan diperingkat ulang.
# Hybrid search: dense + sparse + scalar filter + RRF reranking
dense_req = AnnSearchRequest(
    data=[query_dense.tolist()],
    anns_field="dense_vector",
    param={"metric_type": "COSINE"},
    limit=20,
    expr=filter_expr,
)
sparse_req = AnnSearchRequest(
    data=[query_sparse],
    anns_field="sparse_vector",
    param={"metric_type": "IP"},
    limit=20,
    expr=filter_expr,
)

results = milvus_client.hybrid_search( collection_name=COLLECTION, reqs=[dense_req, sparse_req], ranker=RRFRanker(k=60), limit=TOP_K, output_fields=[β€œproduct_id”, β€œcategory”, β€œcolor”, β€œstyle”, β€œseason”, β€œsales_count”, β€œdescription”, β€œprice”], )

# Display retrieved bestsellers retrieved_products = [] retrieved_images = [] print(f"Top-{TOP_K} similar bestsellers:\n") for hit in results[0]: entity = hit[β€œentity”] pid = entity[β€œproduct_id”] img = Image.open(os.path.join(IMAGE_DIR, f"{pid}.jpg")).convert(β€œRGB”) retrieved_products.append(entity) retrieved_images.append(img) print(f"{pid} | {entity[β€˜category’]} | {entity[β€˜color’]} | {entity[β€˜style’]} " f"| sales: {entity[β€˜sales_count’]} | ${entity[β€˜price’]:.1f} | score: {hit[β€˜distance’]:.4f}") print(f" {entity[β€˜description’]}") display(img.resize((250, int(250 * img.height / img.width)))) print()

Keluaran: 3 buku terlaris yang paling mirip, diurutkan berdasarkan skor gabungan.

Langkah 7: Menganalisis Gaya Buku Terlaris dengan Qwen 3.5

Kami memasukkan gambar buku terlaris yang diambil ke dalam Qwen 3.5 dan memintanya untuk mengekstrak DNA visual yang sama: komposisi adegan, pengaturan pencahayaan, pose model, dan suasana hati secara keseluruhan. Dari analisis tersebut, kami mendapatkan kembali prompt generasi tunggal yang siap untuk diserahkan ke Nano Banana 2.

content = [
    {"type": "image_url", "image_url": {"url": image_to_uri(img)}}
    for img in retrieved_images
]
content.append({
    "type": "text",
    "text": (
        "These are our top-selling fashion product photos.\n\n"
        "Analyze their common visual style in these dimensions:\n"
        "1. Scene / background setting\n"
        "2. Lighting and color tone\n"
        "3. Model pose and framing\n"
        "4. Overall mood and aesthetic\n\n"
        "Then, based on this analysis, write ONE concise image generation prompt "
        "(under 100 words) that captures this style. The prompt should describe "
        "a scene for a model wearing a new clothing item. "
        "Output ONLY the prompt, nothing else."
    ),
})

response = llm.chat.completions.create( model=LLM_MODEL, messages=[{β€œrole”: β€œuser”, β€œcontent”: content}], max_tokens=512, temperature=0.7, ) style_prompt = response.choices[0].message.content.strip() print(β€œStyle prompt from Qwen3.5:\n”) print(style_prompt)

Contoh keluaran:

Style prompt from Qwen3.5:

Professional full-body fashion photograph of a model wearing a stylish new dress. Bright, soft high-key lighting that illuminates the subject evenly. Clean, uncluttered background, either stark white or a softly blurred bright outdoor setting. The model stands in a relaxed, natural pose to showcase the garment’s silhouette and drape. Sharp focus, vibrant colors, fresh and elegant commercial aesthetic.

Langkah 8: Hasilkan Gambar Promosi dengan Nano Banana 2

Kami memberikan tiga masukan ke Nano Banana 2: foto flat-lay produk baru, gambar buku terlaris peringkat teratas, dan prompt gaya yang kami ekstrak pada langkah sebelumnya. Model ini mengomposisikannya menjadi foto promosi yang memasangkan garmen baru dengan gaya visual yang sudah terbukti.

gen_prompt = (
    f"I have a new clothing product (Image 1: flat-lay photo) and a reference "
    f"promotional photo from our bestselling catalog (Image 2).\n\n"
    f"Generate a professional e-commerce promotional photograph of a female model "
    f"wearing the clothing from Image 1.\n\n"
    f"Style guidance: {style_prompt}\n\n"
    f"Scene hint: {new_prod['prompt_hint']}\n\n"
    f"Requirements:\n"
    f"- Full body shot, photorealistic, high quality\n"
    f"- The clothing should match Image 1 exactly\n"
    f"- The photo style and mood should match Image 2"
)

gen_content = [ {β€œtype”: β€œimage_url”, β€œimage_url”: {β€œurl”: image_to_uri(new_img)}}, {β€œtype”: β€œimage_url”, β€œimage_url”: {β€œurl”: image_to_uri(retrieved_images[0])}}, {β€œtype”: β€œtext”, β€œtext”: gen_prompt}, ]

print(β€œGenerating promotional photo with Nano Banana 2…”) gen_response = llm.chat.completions.create( model=IMAGE_GEN_MODEL, messages=[{β€œrole”: β€œuser”, β€œcontent”: gen_content}], extra_body={ β€œmodalities”: [β€œtext”, β€œimage”], β€œimage_config”: {β€œaspect_ratio”: β€œ3:4”, β€œimage_size”: β€œ2K”}, }, ) print(β€œDone!”)

Parameter kunci untuk panggilan API Nano Banana 2:

  • modalitas: ["text", "image"]: menyatakan bahwa respons harus menyertakan gambar.
  • image_config.aspect_ratio: mengontrol rasio aspek keluaran (3:4 bekerja dengan baik untuk pemotretan potret/fashion).
  • image_config.image_size: mengatur resolusi. Nano Banana 2 mendukung 512px hingga 4K.

Ekstrak gambar yang dihasilkan:

generated_images = extract_images(gen_response)

text_content = gen_response.choices[0].message.content if text_content: print(f"Model response: {text_content[:300]}\n")

if generated_images: for i, img in enumerate(generated_images): print(f"β€” Generated promo photo {i+1} β€”") display(img) img.save(f"promo_{new_prod[β€˜new_id’]}{i+1}.png") print(f"Saved: promo{new_prod[β€˜new_id’]}_{i+1}.png") else: print(β€œNo image generated. Raw response:”) print(gen_response.model_dump())

Keluaran:

Langkah 9: Perbandingan Berdampingan

Hasil foto menghasilkan goresan yang luas: pencahayaannya lembut dan merata, pose sang model terlihat wajar, dan suasana hati yang sesuai dengan referensi buku terlaris.

Yang kurang sempurna menurut kami yaitu, perpaduan pakaian. Cardigan terlihat ditempelkan pada model, bukan dikenakan, dan label garis leher berwarna putih terlihat jelas. Generasi sekali pakai kesulitan dengan integrasi pakaian ke tubuh yang halus seperti ini, jadi kami akan membahas solusinya dalam ringkasan.

Langkah 10: Pembuatan Batch untuk Semua Produk Baru

Kami membungkus seluruh pipeline ke dalam satu fungsi dan menjalankannya di seluruh produk baru yang tersisa. Kode batch dihilangkan di sini untuk mempersingkat; hubungi kami jika Anda membutuhkan implementasi lengkap.

Ada dua hal yang menonjol dari hasil batch. Petunjuk gaya yang kami dapatkan dari Qwen 3.5 menyesuaikan secara bermakna per produk: gaun musim panas dan rajutan musim dingin menerima deskripsi pemandangan yang benar-benar berbeda yang disesuaikan dengan musim, kasus penggunaan, dan aksesori. Gambar yang kami dapatkan dari Nano Banana 2, pada gilirannya, dapat bersaing dengan fotografi studio yang sesungguhnya dalam hal pencahayaan, tekstur, dan komposisi.

Kesimpulan

Dalam artikel ini, kami membahas apa yang dibawa Nano Banana 2 ke pembuatan gambar e-commerce, membandingkannya dengan Nano Banana dan Pro asli di seluruh tugas produksi yang sesungguhnya, dan membahas cara membangun pipeline buku terlaris-ke-gambar dengan Milvus, Qwen 3.5, dan Nano Banana 2.

Pipeline ini memiliki empat keuntungan praktis:

  • Biaya terkendali, anggaran yang dapat diprediksi. Model penyematan (Llama Nemotron Embed VL 1B v2) tersedia gratis di OpenRouter. Nano Banana 2 berjalan dengan biaya sekitar setengah dari biaya per-gambar Pro, dan output multi-format asli menghilangkan siklus pengerjaan ulang yang biasanya menggandakan atau melipatgandakan tagihan efektif. Untuk tim e-commerce yang mengelola ribuan SKU per musim, prediktabilitas itu berarti skala produksi gambar dengan katalog alih-alih menghabiskan anggaran.
  • Otomatisasi menyeluruh, waktu yang lebih cepat untuk membuat daftar. Alur dari foto produk flat-lay ke gambar promosi jadi berjalan tanpa intervensi manual. Produk baru dapat beralih dari foto gudang ke gambar daftar yang siap dipasarkan dalam hitungan menit, bukan hari, yang paling penting selama musim ramai saat perputaran katalog paling tinggi.
  • Tidak memerlukan GPU lokal, hambatan masuk yang lebih rendah. Setiap model berjalan melalui API OpenRouter. Sebuah tim tanpa infrastruktur ML dan tidak ada staf teknik khusus dapat menjalankan pipeline ini dari laptop. Tidak ada yang perlu disiapkan, tidak ada yang perlu dipelihara, dan tidak ada investasi perangkat keras di muka.
  • Ketepatan pengambilan yang lebih tinggi, konsistensi merek yang lebih kuat. Milvus menggabungkan pemfilteran padat, jarang, dan skalar dalam satu kueri, yang secara konsisten mengungguli pendekatan vektor tunggal untuk pencocokan produk. Dalam praktiknya, ini berarti gambar yang dihasilkan lebih andal mewarisi bahasa visual merek Anda yang sudah mapan: pencahayaan, komposisi, dan gaya yang telah terbukti berhasil membuat pelanggan beralih. Hasilnya terlihat seperti milik toko Anda, tidak seperti stok gambar AI yang umum.

Ada juga keterbatasan yang perlu diketahui:

  • Pencampuran pakaian dengan tubuh. Pembuatan single-pass dapat membuat pakaian terlihat seperti digabungkan daripada dikenakan. Detail halus seperti aksesori kecil terkadang kabur. Solusi: buatlah secara bertahap (latar belakang terlebih dahulu, kemudian pose model, lalu komposit). Pendekatan multi-pass ini memberikan setiap langkah cakupan yang lebih sempit dan secara signifikan meningkatkan kualitas pemaduan.
  • Ketepatan detail pada casing tepi. Aksesori, pola, dan tata letak yang padat teks bisa kehilangan ketajamannya. Solusi: tambahkan batasan eksplisit ke prompt pembuatan ("pakaian pas di badan, tidak ada label yang terbuka, tidak ada elemen tambahan, detail produk tajam"). Jika kualitas masih kurang pada produk tertentu, beralihlah ke Nano Banana Pro untuk hasil akhir.

Milvus adalah basis data vektor sumber terbuka yang mendukung langkah pencarian hibrida, dan jika Anda ingin melihat-lihat atau mencoba menukar foto produk Anda sendiri, hanya membutuhkan waktu sekitar sepuluh menit. Kami memiliki komunitas yang cukup aktif di Discord dan Slack, dan kami ingin sekali melihat apa yang dibuat oleh orang-orang dengan ini. Dan jika Anda akhirnya menjalankan Nano Banana 2 pada produk vertikal yang berbeda atau katalog yang lebih besar, silakan bagikan hasilnya! Kami ingin sekali mendengarnya.

Teruslah membaca

    Try Managed Milvus for Free

    Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

    Get Started

    Like the article? Spread the word

    Terus Baca