1. ภาพรวม
ยุคของ "แชทบอทที่อ่านได้" กำลังจะสิ้นสุดลง เรากำลังก้าวเข้าสู่ยุคของAgentic Vision
ใน Codelab นี้ เราจะใช้วิศวกรรม AI ที่กำหนดได้ ซึ่งเป็นแนวทางปฏิบัติในการสร้างระบบ AI ที่ไม่คาดเดา โมเดล AI มาตรฐานมักจะ "หลอน" (คาดเดา) เมื่อถูกขอให้นับรายการในรูปภาพที่ซับซ้อน ในซัพพลายเชน การคาดเดาเป็นสิ่งที่อันตราย หาก AI คาดเดาว่าคุณมีสินค้า 12 รายการ แต่จริงๆ แล้วคุณมี 15 รายการ ก็จะทำให้เกิดข้อผิดพลาดที่ทำให้เสียค่าใช้จ่าย
เราจะสร้างเอเจนต์ซัพพลายเชนอัตโนมัติโดยใช้ลูปคิด ดำเนินการ สังเกตใหม่ใน Gemini 3 Flash ไม่ได้แค่ดู แต่ยังตรวจสอบด้วย
สถาปัตยกรรมที่กำหนดได้
เราจะเริ่มต้นด้วยระบบ "blind" และ "amnesiac" คุณจะต้อง "ปลุก" ประสาทสัมผัสของอุปกรณ์ทีละอย่างด้วยตนเอง

- The Eyes (Vision Agent): เราเปิดใช้ Gemini 3 Flash ด้วยการดำเนินการโค้ด โมเดลจะเขียนโค้ด Python (OpenCV) เพื่อนับพิกเซลอย่างแน่นอนแทนที่จะคาดเดาโทเค็นเพื่อเดาตัวเลข
- หน่วยความจำ (ตัวแทนซัพพลายเออร์): เราเปิดใช้ AlloyDB AI ด้วย ScaNN (Scalable Nearest Neighbors) ซึ่งจะช่วยให้ตัวแทนเรียกซัพพลายเออร์ที่แน่นอนสำหรับชิ้นส่วนจากตัวเลือกนับล้านได้ในเวลาไม่กี่มิลลิวินาที
- แฮนด์เชค (โปรโตคอล A2A): เราเปิดใช้การสื่อสารเอเจนต์ต่อเอเจนต์โดยใช้ agent_card.json ที่ได้มาตรฐาน ซึ่งช่วยให้ Vision Agent สามารถสั่งซื้อสต็อกจาก Supplier Agent ได้โดยอัตโนมัติ
สิ่งที่คุณจะสร้าง
- Vision Agent ที่ทำการ "คำนวณภาพ" ในฟีดกล้อง
- ตัวแทนซัพพลายเออร์ที่ขับเคลื่อนโดย AlloyDB ScaNN สำหรับการค้นหาเวกเตอร์ความเร็วสูง
- ส่วนหน้าของ Control Tower ที่มีการอัปเดต WebSocket แบบเรียลไทม์เพื่อแสดงภาพลูปอัตโนมัติ
สิ่งที่คุณจะได้เรียนรู้
- วิธีเปิดใช้ Agentic Vision ด้วย gemini-3-flash-preview โดยใช้ Gemini API
- วิธีติดตั้งใช้งานการค้นหาเวกเตอร์โดยใช้โอเปอเรเตอร์ <=> (ระยะทางโคไซน์) ใน AlloyDB
- วิธีเชื่อมต่อ Cloud Shell กับ AlloyDB โดยใช้พร็อกซีการตรวจสอบสิทธิ์
ข้อกำหนด
- เบราว์เซอร์ เช่น Chrome หรือ Firefox
- โปรเจ็กต์ Google Cloud ที่เปิดใช้การเรียกเก็บเงิน
- คีย์ Gemini API (ระดับฟรีพร้อมให้บริการที่ Google AI Studio) สำหรับ Vision Agent
2. ก่อนเริ่มต้น
สร้างโปรเจ็กต์
- ในคอนโซล Google Cloud ให้เลือกหรือสร้างโปรเจ็กต์ Google Cloud ในหน้าตัวเลือกโปรเจ็กต์
- ตรวจสอบว่าได้เปิดใช้การเรียกเก็บเงินสำหรับโปรเจ็กต์ Cloud แล้ว ดูวิธีตรวจสอบว่าโปรเจ็กต์เปิดใช้การเรียกเก็บเงินแล้วหรือไม่
- คุณจะใช้ Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานใน Google Cloud คลิกเปิดใช้งาน Cloud Shell ที่ด้านบนของคอนโซล Google Cloud

- เมื่อเชื่อมต่อกับ Cloud Shell แล้ว ให้ตรวจสอบว่าคุณได้รับการตรวจสอบสิทธิ์แล้วและตั้งค่าโปรเจ็กต์เป็นรหัสโปรเจ็กต์โดยใช้คำสั่งต่อไปนี้
gcloud auth list
เท่านี้ก็เรียบร้อย
ตอนนี้คุณก็พร้อมสำหรับการตั้งค่าด้วยการคลิกเพียงครั้งเดียวแล้ว ส่วนถัดไปจะอธิบายถึง
- เปิด Cloud Shell โดยอัตโนมัติ
- โคลนที่เก็บ
- แนะนำขั้นตอนการตั้งค่าทั้งหมดในบทแนะนำแบบอินเทอร์แอกทีฟ
3. การตั้งค่าใน Cloud Shell ด้วยการคลิกเพียงครั้งเดียว
เราได้ปรับปรุงการตั้งค่าให้เป็นบทแนะนำ Cloud Shell แบบมีคำแนะนำ ทุกอย่างเป็นแบบอัตโนมัติ ไม่ว่าจะเป็นการจัดสรรโครงสร้างพื้นฐาน การตั้งค่า AlloyDB การกำหนดค่า Auth Proxy และการเริ่มต้นฐานข้อมูล
เปิดบทแนะนำ Cloud Shell
⚠️ สำคัญ - ก่อนคลิก: เมื่อคลิกปุ่มด้านล่าง คุณจะเห็นกล่องโต้ตอบความปลอดภัยที่ถามว่า "เปิดใน Cloud Shell" ซึ่งจะปรากฏขึ้นก่อนที่ที่เก็บจะโคลน
คุณต้องปฏิบัติดังนี้
- ✅ เลือกช่อง "เชื่อถือที่เก็บ"
- ✅ คลิก "ยืนยัน"
หากไม่มีการดำเนินการนี้ ระบบจะไม่โคลนที่เก็บ
พร้อมไหม คลิกเพื่อเปิดโปรเจ็กต์พร้อมบทแนะนำแบบทีละขั้นตอน
จะเกิดอะไรขึ้นในลำดับต่อไป
- Cloud Shell จะเปิดขึ้นพร้อมกับที่เก็บที่โคลนไว้ล่วงหน้า
- แผงบทแนะนำจะปรากฏทางด้านขวาพร้อมวิธีการแบบทีละขั้นตอน
- คุณจะได้รับคำแนะนำเกี่ยวกับสิ่งต่อไปนี้
- รับคีย์ Gemini API (มีระดับฟรี)
- การตั้งค่าโปรเจ็กต์ GCP ในเทอร์มินัล
- เรียกใช้การตั้งค่า (ตรวจสอบ API เปิดใช้หากจำเป็น จัดสรร AlloyDB: ~15 นาที)
- ทำการเปลี่ยนแปลงรหัสคีย์ 2 รายการ (เปิดใช้การมองเห็น + ความทรงจำ)
- สร้างการ์ดตัวแทน (โปรโตคอล A2A)
- การเริ่มต้นบริการทั้งหมด
บทแนะนำนี้เป็นแบบอินเทอร์แอกทีฟ โดยแต่ละขั้นตอนจะมีหมายเลขและติดตามความคืบหน้าของคุณ
ทางเลือกอื่น: การตั้งค่าด้วยตนเอง
หากต้องการควบคุมด้วยตนเอง ให้ทำดังนี้
- เปิด Cloud Shell แล้วตรวจสอบว่าได้ตั้งค่าโปรเจ็กต์แล้ว
gcloud config get-value project
- สร้างโปรเจ็กต์ หากจำเป็น
gcloud config set project YOUR_PROJECT_ID
- โคลนที่เก็บ
git clone https://github.com/MohitBhimrajka/visual-commerce-gemini-3-alloydb.git
cd visual-commerce-gemini-3-alloydb
- เรียกใช้การตั้งค่า
sh setup.sh
ทำตามวิธีการบนหน้าจอจากสคริปต์การตั้งค่า
ขั้นตอนถัดไป: บทแนะนำจะแนะนำขั้นตอนที่เหลือให้คุณ เมื่อเสร็จแล้ว ให้ไปที่ส่วนที่ 4 เพื่อทำความเข้าใจสิ่งที่เกิดขึ้นเบื้องหลัง
4. เบื้องหลัง: พร็อกซีการตรวจสอบสิทธิ์และการเริ่มต้นฐานข้อมูล
ปัญหา: AlloyDB อยู่ภายใน VPC ส่วนตัว Cloud Shell อยู่นอกเครือข่าย การเชื่อมต่อโดยตรงเป็นไปไม่ได้
วิธีแก้ไข: AlloyDB Auth Proxy จะสร้างอุโมงค์ที่ปลอดภัยซึ่งได้รับการตรวจสอบสิทธิ์ IAM จาก 127.0.0.1:5432 ใน Cloud Shell ไปยังอินสแตนซ์ AlloyDB หากอินสแตนซ์เปิดใช้ IP สาธารณะไว้ พร็อกซีจะใช้ IP สาธารณะนั้น มิฉะนั้นจะเชื่อมต่อผ่าน IP ส่วนตัวของ VPC
สิ่งที่ setup.sh ทำ
- ตรวจพบอินสแตนซ์ AlloyDB (คลัสเตอร์ ภูมิภาค โปรเจ็กต์) โดยอัตโนมัติ
- สร้าง .env พร้อมข้อมูลเข้าสู่ระบบทั้งหมด (GEMINI_API_KEY, DB_PASS, รายละเอียด AlloyDB)
- ดาวน์โหลดและเริ่มพร็อกซีการตรวจสอบสิทธิ์ (โดยใช้ –public-ip หากมี)
- เริ่มต้นฐานข้อมูลด้วยชิ้นส่วนสินค้าคงคลังตัวอย่าง 8 รายการ + ดัชนี ScaNN
ไฟล์ .env พร้อมใช้งานแล้ว การเรียกใช้ในอนาคตทั้งหมดจะโหลดข้อมูลเข้าสู่ระบบโดยอัตโนมัติ
ยืนยันว่าใช้งานได้
ตรวจสอบว่าคุณยังอยู่ในรูทของที่เก็บ
pwd # Should end with: visual-commerce-gemini-3-alloydb
ตรวจสอบว่า Auth Proxy ทำงานอยู่
ps aux | grep alloydb-auth-proxy
สิ่งที่สร้างขึ้น
- ตารางพื้นที่โฆษณาที่มี 8 ส่วนและ Embedding แบบ 768 มิติ
- ดัชนี ScaNN (idx_inventory_scann) สำหรับการค้นหาเวกเตอร์ที่รวดเร็ว
5. ขั้นตอนที่ 1: หน่วยความจำ (ตัวแทนซัพพลายเออร์)
Supplier Agent จดจำชิ้นส่วนหลายล้านชิ้นโดยใช้ AlloyDB ScaNN เราเริ่มต้นด้วยการใช้เป็นเซิร์ฟเวอร์ A2A จากนั้นจึงแก้ไขการค้นหาเวกเตอร์
การตรวจสอบ: ผู้สูญเสียความทรงจำ
หากคุณค้นหา Supplier Agent ตอนนี้ (ด้วย SQL ตัวยึดตำแหน่ง) ระบบจะแสดงผลแถวแรกที่พบ ไม่ใช่รายการที่ตรงกันที่ใกล้เคียงที่สุด โดยไม่มีแนวคิดเรื่องความคล้ายคลึงกัน มันเป็นโรคความจำเสื่อม
เริ่มการทำงานของ Supplier Agent
เซิร์ฟเวอร์ A2A (main.py) จะมอบสิทธิ์ให้กับ agent_executor.py ซึ่งเชื่อมโยงโปรโตคอลกับตรรกะทางธุรกิจใน inventory.py
pkill -f uvicorn #Kill all uvicorn processes
ขั้นตอนที่ 1: ไปที่ไดเรกทอรีตัวแทน
cd agents/supplier-agent
ขั้นตอนที่ 2: ติดตั้งการขึ้นต่อกัน
pip install -r requirements.txt
ขั้นตอนที่ 3: เริ่มเซิร์ฟเวอร์ของ Agent
uvicorn main:app --host 0.0.0.0 --port 8082 > /dev/null 2>&1 &
> /dev/null 2>&1 & จะเรียกใช้เซิร์ฟเวอร์ในเบื้องหลังและระงับเอาต์พุตเพื่อไม่ให้ขัดจังหวะเทอร์มินัล
ขั้นตอนที่ 4: ตรวจสอบว่าเอเจนต์ทำงานอยู่ (รอ 2-3 วินาทีหลังจากเริ่มต้น)
curl http://localhost:8082/.well-known/agent-card.json
เอาต์พุตที่คาดไว้: JSON ที่มีการกำหนดค่าตัวแทน (ควรแสดงผลโดยไม่มีข้อผิดพลาด)
การฝังเชิงความหมายจริง
ในระหว่างการตั้งค่า ฐานข้อมูลได้รับการเริ่มต้นด้วยการฝังเชิงความหมายจริงที่สร้างขึ้นผ่านโมเดล text-embedding-005 ของ Gen AI SDK ของ Google วิธีนี้ช่วยให้มั่นใจได้ว่าการจับคู่ความคล้ายคลึงจะถูกต้อง ไม่ใช่เวกเตอร์แบบสุ่ม กระบวนการเริ่มต้นใช้เวลาประมาณ 10 วินาทีสำหรับรายการตัวอย่าง 13 รายการ โดยใช้การสร้างการฝังแบบขนานเพื่อสร้างเวกเตอร์ 768 มิติที่มีความหมายซึ่งบันทึกความหมายเชิงความหมายของแต่ละส่วน
AlloyDB Detour: Why ScaNN?
วิธีแก้ไข: การใช้ตัวดำเนินการ <=>
Agent จะจัดส่งพร้อมกับคำค้นหาตัวยึดตำแหน่ง เราต้องเปิดใช้การค้นหาเวกเตอร์ ScaNN
ขั้นตอนที่ 1: เปิดไฟล์สินค้าคงคลัง
cd agents/supplier-agent
ขั้นตอนที่ 2: ค้นหา TODO ใน inventory.py
มองหาฟังก์ชัน find_supplier() ที่บรรทัด 47-60 คุณจะเห็นข้อมูลดังนี้
# ============================================================
# CODELAB STEP 1: Implement ScaNN Vector Search
# ============================================================
# TODO: Replace this placeholder query with ScaNN vector search
sql = "SELECT part_name, supplier_name FROM inventory LIMIT 1;"
cursor.execute(sql)
ขั้นตอนที่ 3: แทนที่ SQL ตัวยึดตำแหน่งด้วยการค้นหาเวกเตอร์ ScaNN
ลบ 2 บรรทัดนี้
sql = "SELECT part_name, supplier_name FROM inventory LIMIT 1;"
cursor.execute(sql)
และแทนที่ด้วย
sql = """
SELECT part_name, supplier_name
FROM inventory
ORDER BY part_embedding <=> %s::vector
LIMIT 1;
"""
cursor.execute(sql, (embedding_vector,))
การดำเนินการนี้จะทำสิ่งต่อไปนี้
- <=> คือตัวดำเนินการระยะทางโคไซน์ใน PostgreSQL
- ORDER BY part_embedding <=> %s::vector จะค้นหารายการที่ตรงกันมากที่สุด (ระยะทางต่ำสุด = ความหมายเชิงความหมายที่ใกล้เคียงที่สุด)
- %s::vector จะแคสต์อาร์เรย์การฝังไปยังประเภทเวกเตอร์ของ PostgreSQL
- LIMIT 1 จะแสดงเฉพาะรายการที่ตรงกันที่ใกล้เคียงที่สุด
- ดัชนี ScaNN จะเร่งการค้นหานี้โดยอัตโนมัติ
ขั้นตอนที่ 4: บันทึกไฟล์ (Ctrl+S หรือ Cmd+S)
ตอนนี้เอเจนต์จะใช้การค้นหาเชิงความหมายแทนการแสดงผลลัพธ์แบบสุ่ม
การยืนยัน
ทดสอบการค้นพบ A2A และพื้นที่โฆษณา
curl http://localhost:8082/.well-known/agent-card.json

python3 -c "
from inventory import find_supplier
import json
vec = [0.1]*768
r = find_supplier(vec)
if r:
result = {'part': r[0], 'supplier': r[1]}
if len(r) > 2:
result['distance'] = float(r[2]) if r[2] else None
print(json.dumps(result))
else:
print('No result found')
"
คาดการณ์: agent-card.json จะแสดงการ์ดตัวแทน ข้อมูลโค้ด Python จะแสดงชิ้นส่วนและซัพพลายเออร์จากข้อมูลเริ่มต้น
6. ขั้นตอนที่ 2: ดวงตา (Vision Agent)
ในขณะที่เข้าถึงฐานข้อมูลได้ เรามาปลุกดวงตาด้วย Gemini 3 Flash กัน Vision Agent จะดำเนินการ "คณิตศาสตร์ภาพ" ผ่านการรันโค้ด เซิร์ฟเวอร์ A2A (main.py) จะมอบสิทธิ์ให้กับ agent_executor.py ซึ่งจะเรียกใช้ agent.py เพื่อการวิเคราะห์ของ Gemini
การตรวจสอบ: อาการหลอน
หากคุณถามโมเดลหลายรูปแบบมาตรฐานว่า "มีกล่องกี่กล่องในรูปภาพที่รกนี้" โมเดลจะประมวลผลรูปภาพเป็นสแนปชอตแบบคงที่และคาดเดา
- โมเดลตอบว่า "ฉันเห็นกล่องประมาณ 12 กล่อง"
- ความเป็นจริง: มีกล่อง 15 กล่อง
- ผลลัพธ์: ซัพพลายเชนล้มเหลว
วิธีแก้ไข: การปลุกวงจรการคิด-การกระทำ-การสังเกต
เราเปิดใช้การเรียกใช้โค้ดและ ThinkingConfig เพื่อให้โมเดลเขียน Python (OpenCV) เพื่อนับได้อย่างแน่นอน
- เปิด agents/vision-agent/agent.py
- ค้นหาส่วน GenerateContentConfig
- ยกเลิกการแสดงความคิดเห็นทั้งบล็อก thinking_config=types.ThinkingConfig(...) และ tools=[types.Tool(code_execution=...)]
- ไคลเอ็นต์ได้รับการกำหนดค่าให้ใช้ GEMINI_API_KEY จากสภาพแวดล้อมแล้ว
ไฟล์: agents/vision-agent/agent.py
config = types.GenerateContentConfig(
temperature=0,
# CODELAB STEP 1: Uncomment to enable reasoning
thinking_config=types.ThinkingConfig(
thinking_level="LOW", # Valid: "MINIMAL", "LOW", "MEDIUM", "HIGH"
include_thoughts=False # Set to True for debugging
),
# CODELAB STEP 2: Uncomment to enable code execution
tools=[types.Tool(code_execution=types.ToolCodeExecution)]
)
ทำไมจึงเป็น thinking_level="LOW"
สำหรับงานที่เฉพาะเจาะจงนี้ (การนับรายการผ่านการเรียกใช้โค้ด) "ต่ำ" จะให้งบประมาณการให้เหตุผลที่เพียงพอสำหรับสิ่งต่อไปนี้
- วางแผนโครงสร้างสคริปต์ Python
- ตัดสินใจว่าจะใช้แนวทางการประมวลผลรูปภาพใด
- ยืนยันว่าจำนวนตรงกับจำนวนกล่องขอบเขต
การใช้ "สูง" จะเพิ่มเวลาในการตอบสนองและต้นทุน 2-3 เท่าโดยไม่ปรับปรุงความแม่นยำสำหรับงานที่กำหนด จอง "สูง" ไว้สำหรับการให้เหตุผลหลายขั้นตอนที่ซับซ้อน (เช่น "วิเคราะห์การหยุดชะงักของซัพพลายเชนนี้และแนะนำซัพพลายเออร์ทางเลือก 3 รายพร้อมเหตุผล")
การเพิ่มประสิทธิภาพด้านต้นทุนและประสิทธิภาพเป็นทักษะสำคัญสำหรับวิศวกรรม AI ในการผลิต โดยต้องจับคู่ความลึกของการให้เหตุผลกับความซับซ้อนของงาน
เริ่ม Vision Agent
🔄 ตรวจสอบเส้นทาง: หากคุณยังอยู่ใน agents/supplier-agent/ ให้กลับไปที่รูทของที่เก็บด้วย cd ../..
ขั้นตอนที่ 1: ไปที่ไดเรกทอรีเอเจนต์ Vision
cd agents/vision-agent
ขั้นตอนที่ 2: ติดตั้งการขึ้นต่อกัน
pip install -r requirements.txt
ขั้นตอนที่ 3: เริ่มเซิร์ฟเวอร์ของ Vision Agent
uvicorn main:app --host 0.0.0.0 --port 8081 > /dev/null 2>&1 &
> /dev/null 2>&1 & จะเรียกใช้เซิร์ฟเวอร์ในเบื้องหลังและระงับเอาต์พุตเพื่อไม่ให้ขัดจังหวะเทอร์มินัล
การยืนยัน
ทดสอบการค้นพบ A2A:
curl http://localhost:8081/.well-known/agent-card.json
คาดการณ์: JSON ที่มีชื่อและทักษะของเอเจนต์ คุณจะทดสอบการนับด้วยวิชันซิสเต็มจริงด้วย UI ของ Control Tower ในขั้นตอนที่ 8

7. ขั้นตอนที่ 3: การแฮนด์เชค (บัตรตัวแทน A2A)
ตัวแทนของเราเห็นปัญหา (Vision) และรู้จักซัพพลายเออร์ (Memory) โปรโตคอล A2A ช่วยให้การค้นหาแบบไดนามิกเป็นไปได้ โดยส่วนหน้าจะเรียนรู้วิธีสื่อสารกับแต่ละเอเจนต์ด้วยการอ่านการ์ดของเอเจนต์
A2A กับ REST API แบบเดิม
มุมมอง | REST แบบดั้งเดิม | โปรโตคอล A2A |
การค้นหาอุปกรณ์ปลายทาง | URL ที่ฮาร์ดโค้ดในการกำหนดค่า | แบบไดนามิกผ่าน /.well-known/agent-card.json |
คำอธิบายความสามารถ | เอกสารประกอบ API (สำหรับมนุษย์) | ทักษะ (ที่เครื่องอ่านได้) |
การผสานรวม | รหัสที่กำหนดเองต่อบริการ | การจับคู่ความหมาย: "ฉันต้องการค้นหาสินค้าคงคลัง" → ค้นพบทักษะ |
เพิ่ม Agent ใหม่แล้ว | อัปเดตการกำหนดค่าของไคลเอ็นต์ทั้งหมด | ไม่ต้องกำหนดค่าใดๆ - ค้นพบโดยอัตโนมัติ |
ประโยชน์ในโลกแห่งความเป็นจริง: ในไมโครเซอร์วิสแบบเดิม หากคุณเพิ่ม "ตัวแทนด้านลอจิสติกส์" รายที่ 3 คุณจะต้องอัปเดตรหัสของ Control Tower ด้วย URL และสัญญา API เมื่อใช้ A2A Control Tower จะค้นพบอุปกรณ์โดยอัตโนมัติและเข้าใจความสามารถของอุปกรณ์ผ่านคำอธิบายทักษะภาษาธรรมชาติ
ด้วยเหตุนี้ A2A จึงเปิดใช้การประกอบเอเจนต์แบบพลักแอนด์เพลย์ ซึ่งเป็นรูปแบบสถาปัตยกรรมสำหรับระบบอัตโนมัติ
วิธีแก้ไข: สร้างการ์ดตัวแทน
เราต้องกำหนดสิ่งที่ตัวแทนซัพพลายเออร์ทำได้
- คัดลอก agents/supplier-agent/agent_card_skeleton.json ไปยัง agents/supplier-agent/agent_card.json
- แก้ไขไฟล์เพื่อแทนที่ตัวยึดตำแหน่ง
ก่อน (โครงร่าง):
{
"name": "___FILL: agent-name ___",
"description": "___FILL: what-this-agent-does ___"
}
หลัง (การแก้ไขของคุณ):
{
"name": "Acme Supplier Agent",
"description": "Autonomous fulfillment for industrial parts via AlloyDB ScaNN.",
"version": "1.0.0",
"skills": [{
"id": "search_inventory",
"name": "Search Inventory",
"description": "Searches the warehouse database for semantic matches using AlloyDB ScaNN vector search.",
"tags": ["inventory", "search", "alloydb"],
"examples": ["Find stock for Industrial Widget X-9", "Who supplies ball bearings?"]
}]
}
- รีสตาร์ท Supplier Agent เพื่อให้โหลดบัตรใหม่
ขั้นตอนที่ 1: หยุดตัวแทนที่กำลังทำงาน
pkill -f "uvicorn main:app.*8082"
ขั้นตอนที่ 2: ไปที่ไดเรกทอรีตัวแทน
cd agents/supplier-agent
ขั้นตอนที่ 3: เริ่ม Agent อีกครั้ง
uvicorn main:app --host 0.0.0.0 --port 8082 > /dev/null 2>&1 &
> /dev/null 2>&1 & จะเรียกใช้เซิร์ฟเวอร์ในเบื้องหลังและระงับเอาต์พุตเพื่อไม่ให้ขัดจังหวะเทอร์มินัล
ขั้นตอนที่ 4: ยืนยันบัตรตัวแทนใหม่ (รอ 2-3 วินาทีหลังจากเริ่ม)
curl http://localhost:8082/.well-known/agent-card.json
เอาต์พุตที่คาดไว้: JSON ที่มีชื่อ คำอธิบาย และทักษะที่คุณกรอก

8. ขั้นตอนที่ 4: Control Tower
เรียกใช้ส่วนหน้าของ Control Tower ด้วย FastAPI + WebSockets โดยจะค้นหาเอเจนต์ผ่าน A2A และจัดระเบียบวงจรทั้งหมดด้วยการอัปเดตแบบเรียลไทม์
เริ่มบริการทั้งหมด
วิธีที่ง่ายที่สุดในการเริ่มต้นใช้งานบริการทั้งหมด
ตรวจสอบว่าคุณอยู่ในรูทของที่เก็บ
pwd # Should end with: visual-commerce-gemini-3-alloydb
จากนั้นให้ทำดังนี้
sh run.sh
คำสั่งเดียวนี้จะเริ่ม
- พร็อกซีการตรวจสอบสิทธิ์ AlloyDB (หากไม่ได้ทำงาน)
- Vision Agent บนพอร์ต 8081
- Supplier Agent บนพอร์ต 8082
- Control Tower บนพอร์ต 8080
รอประมาณ 10 วินาทีเพื่อให้บริการทั้งหมดเริ่มต้น
ทดสอบระบบ
เข้าถึง Control Tower
- คลิกปุ่มตัวอย่างเว็บ (ไอคอนดวงตา 👁️) ในแถบเครื่องมือของ Cloud Shell
- เลือก "แสดงตัวอย่างบนพอร์ต 8080"
- แดชบอร์ด Control Tower จะเปิดขึ้นในแท็บใหม่
ลองใช้เดโม:
- ด้านขวาบน: สถานะการเชื่อมต่อ (จุดสีเขียว "สด"), สวิตช์โหมด DEMO/AUTO และตัวควบคุมเสียง
- ตรงกลาง: Canvas เวิร์กโฟลว์หลักที่มีการอัปโหลดรูปภาพและการแสดงภาพการวิเคราะห์
- แผงด้านข้าง (ปรากฏระหว่างการวิเคราะห์): ไทม์ไลน์เวิร์กโฟลว์ (ซ้าย), การติดตามความคืบหน้า และโปรแกรมดูโค้ด (ขวา)
ตัวเลือกที่ 1: เริ่มต้นอย่างรวดเร็ว (แนะนำ)
- ในหน้าแรก คุณจะเห็นส่วน "เริ่มต้นอย่างรวดเร็ว" พร้อมรูปภาพตัวอย่าง
- คลิกรูปภาพตัวอย่างเพื่อเริ่มการวิเคราะห์โดยอัตโนมัติ
- ดูเวิร์กโฟลว์อัตโนมัติ (~30-45 วินาที)
ตัวเลือกที่ 2: อัปโหลดเอง
- ลากและวางรูปภาพคลังสินค้า/ชั้นวาง (PNG, JPG, สูงสุด 10 MB) หรือคลิกเพื่อเรียกดู
- คลิก "เริ่มเวิร์กโฟลว์อัตโนมัติ"
- สังเกตไปป์ไลน์ 4 ขั้นตอน
สิ่งที่เกิดขึ้น
- การค้นพบเอเจนต์: โมดอลโปรโตคอล A2A จะแสดงการ์ด Vision Agent และ Supplier Agent พร้อมทักษะและปลายทาง
- การวิเคราะห์ภาพ: Gemini 3 Flash สร้างและเรียกใช้โค้ด Python (OpenCV) เพื่อนับรายการ แถบความคืบหน้าจะแสดงขั้นตอนย่อย กรอบล้อมรอบซ้อนทับบนรายการที่ตรวจพบ ป้ายผลลัพธ์แสดง "✓ ยืนยันโค้ดแล้ว" หรือ "~ โดยประมาณ"
- การจับคู่ซัพพลายเออร์: ภาพเคลื่อนไหวการค้นหาเวกเตอร์ ScaNN ของ AlloyDB การแสดงคำค้นหา (เช่น "กล่องโลหะอุตสาหกรรม") การ์ดผลลัพธ์แสดงชิ้นส่วนที่ตรงกัน ซัพพลายเออร์ และคะแนนความน่าเชื่อถือ
- ส่งคำสั่งซื้อแล้ว: บัตรใบเสร็จที่มีรหัสคำสั่งซื้อ จำนวน และรายละเอียด
เคล็ดลับ: เปิดโหมด DEMO ไว้ (ด้านขวาบน) เพื่อหยุดชั่วคราวในแต่ละขั้นตอนสำหรับการนำเสนอ ในโหมดอัตโนมัติ เวิร์กโฟลว์จะทำงานอย่างต่อเนื่อง

เกิดอะไรขึ้น
Control Tower ใช้โปรโตคอล A2A เพื่อค้นหาเอเจนต์ทั้ง 2 รายผ่าน /.well-known/agent-card.json จัดการการวิเคราะห์วิสัยทัศน์ (Gemini 3 Flash พร้อมการดำเนินการโค้ด) ทำการค้นหาเวกเตอร์ (AlloyDB ScaNN) และสั่งซื้อโดยอัตโนมัติ ทั้งหมดนี้มีการอัปเดต WebSocket แบบเรียลไทม์ เอเจนต์แต่ละรายจะแสดงความสามารถผ่านมาตรฐาน A2A ซึ่งช่วยให้สามารถเชื่อมต่อและใช้งานได้ทันทีโดยไม่ต้องใช้ SDK ที่กำหนดเอง ดูข้อมูลเพิ่มเติม: โปรโตคอล A2A
การแก้ปัญหา
ข้อผิดพลาดเกี่ยวกับเส้นทาง:
- "ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว" เมื่อเรียกใช้คำสั่ง: คุณไม่ได้อยู่ในรูทของที่เก็บ
# Check where you are
pwd
# If you're lost, navigate to home and back to repo
cd
cd visual-commerce-gemini-3-alloydb
ข้อผิดพลาดของบริการ:
- "มีการใช้อีเมลนี้แล้ว": กระบวนการจากการเรียกใช้ครั้งก่อนยังคงทำงานอยู่
# Kill all services and restart
pkill -f uvicorn
sh run.sh # Or manually restart individual agents
- บริการไม่เริ่มต้น: ตรวจสอบว่ามีการใช้พอร์ตอยู่หรือไม่
# Check which processes are using the ports
lsof -i :8080 # Control Tower
lsof -i :8081 # Vision Agent
lsof -i :8082 # Supplier Agent
- "ปฏิเสธการเชื่อมต่อ" กับ AlloyDB: ตรวจสอบว่า Auth Proxy ทำงานอยู่หรือไม่
ps aux | grep alloydb-auth-proxy
ปัญหาการเชื่อมต่อ AlloyDB:
หากเห็นข้อความว่า "เชื่อมต่อกับเซิร์ฟเวอร์ที่ 127.0.0.1 พอร์ต 5432 ไม่สำเร็จ" ให้ทำดังนี้
หากเห็นว่าการเชื่อมต่อกับเซิร์ฟเวอร์ที่ 127.0.0.1 พอร์ต 5432 ไม่สำเร็จ ให้ทำดังนี้
- ตรวจสอบพร็อกซีการตรวจสอบสิทธิ์: ps aux | grep alloydb-auth-proxy
- ยืนยันว่าเปิดใช้ IP สาธารณะแล้ว: gcloud alloydb instances describe INSTANCE_NAME –cluster=CLUSTER_NAME –region=us-central1 –format="value(ipAddress)"
- สำหรับการพัฒนาในเครื่อง (ไม่ใช่ Cloud Shell)
- ปัญหา: Cloud Shell ทำงานโดยอัตโนมัติ แต่เครื่องในพื้นที่ต้องใช้เครือข่ายที่ได้รับอนุญาต
- วิธีแก้ปัญหา: เรียกใช้ sh setup.sh อีกครั้ง แล้วเลือกตัวเลือกที่ 1 (ให้สิทธิ์ 0.0.0.0/0) เมื่อระบบแจ้ง
- หมายเหตุเกี่ยวกับความปลอดภัย: แม้จะใช้ 0.0.0.0/0 แต่การเชื่อมต่อก็ยังต้องมีสิ่งต่อไปนี้
- ข้อมูลเข้าสู่ระบบ GCP ที่ถูกต้อง (ข้อมูลรับรองเริ่มต้นของแอปพลิเคชัน)
- รหัสผ่านฐานข้อมูล
- การเข้ารหัส mTLS (Auth Proxy จัดการเรื่องนี้)
9. ล้างข้อมูล
หากไม่ต้องการให้มีการเรียกเก็บเงิน ให้ทำลายทรัพยากรทั้งหมดด้วยสคริปต์การล้างข้อมูลอัตโนมัติ
# From repo root
sh cleanup.sh
การดำเนินการนี้จะนำรายการต่อไปนี้ออกอย่างปลอดภัย
- คลัสเตอร์ AlloyDB (ตัวขับเคลื่อนต้นทุนหลัก)
- บริการ Cloud Run (หากมีการติดตั้งใช้งาน)
- บัญชีบริการที่เชื่อมโยง
สคริปต์จะแจ้งให้ยืนยันก่อนลบ
10. ข้อมูลอ้างอิงและข้อมูลเพิ่มเติม
การกล่าวอ้างทางเทคนิคทั้งหมดในโค้ดแล็บนี้ได้รับการยืนยันจากเอกสารประกอบอย่างเป็นทางการของ Google Cloud และ Google AI
เอกสารประกอบอย่างเป็นทางการ
Gemini 3 Flash:
- API การดำเนินการโค้ด: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-execution-api
- คู่มือนักพัฒนาซอฟต์แวร์: https://ai.google.dev/gemini-api/docs/gemini-3
- เอกสารประกอบของโมเดล: https://docs.cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-flash
- การ์ดโมเดล: https://deepmind.google/models/gemini/flash/
AlloyDB AI และ ScaNN:
- การเปรียบเทียบประสิทธิภาพของ ScaNN: https://cloud.google.com/blog/products/databases/how-scann-for-alloydb-vector-search-compares-to-pgvector-hnsw
- ทำความเข้าใจดัชนี ScaNN: https://cloud.google.com/blog/products/databases/understanding-the-scann-index-in-alloydb
- เจาะลึก AlloyDB AI: https://cloud.google.com/blog/products/databases/alloydb-ais-scann-index-improves-search-on-all-kinds-of-data
- แนวทางปฏิบัติแนะนำสำหรับการปรับแต่ง: https://docs.cloud.google.com/alloydb/docs/ai/best-practices-tuning-scann
- เอกสารประกอบของ AlloyDB: https://cloud.google.com/alloydb/docs
ข้อมูลราคา:
- ราคา Gemini API: https://ai.google.dev/gemini-api/docs/pricing
- ราคาของ AlloyDB: https://cloud.google.com/alloydb/pricing
- ราคา Vertex AI: https://cloud.google.com/vertex-ai/pricing
การกล่าวอ้างประสิทธิภาพที่ได้รับการยืนยัน
ฟีเจอร์ | อ้างสิทธิ์ | แหล่งที่มา |
ScaNN เทียบกับ HNSW (กรองแล้ว) | เร็วกว่า 10 เท่า | บล็อกของ Google Cloud (ได้รับการยืนยัน) |
ScaNN เทียบกับ HNSW (มาตรฐาน) | เร็วกว่า 4 เท่า | บล็อกของ Google Cloud (ได้รับการยืนยัน) |
หน่วยความจำที่ใช้ของ ScaNN | เล็กกว่า 3-4 เท่า | บล็อกของ Google Cloud (ได้รับการยืนยัน) |
เวลาสร้างดัชนี ScaNN | เร็วกว่า 8 เท่า | บล็อกของ Google Cloud (ได้รับการยืนยัน) |
โค้ดหมดเวลาการดำเนินการ | สูงสุด 30 วินาที | เอกสารประกอบของ Google Cloud (ได้รับการยืนยัน) |
I/O ของไฟล์การเรียกใช้โค้ด | ไม่รองรับ | เอกสารประกอบของ Google Cloud (ได้รับการยืนยัน) |
ลักษณะการทำงานเมื่ออุณหภูมิ=0 | เอาต์พุตที่แน่นอน | ยืนยันโดยชุมชน |
แหล่งข้อมูลเพิ่มเติม
โปรโตคอล Agent-to-Agent (A2A):
- A2A กำหนดมาตรฐานการค้นพบและการสื่อสารของเอเจนต์
- การ์ดตัวแทนที่แสดงใน
/.well-known/agent-card.json - มาตรฐานใหม่สำหรับการทำงานร่วมกันของเอเจนต์อัตโนมัติ
การวิจัย ScaNN:
- อิงตามการวิจัยของ Google เป็นเวลา 12 ปี
- ขับเคลื่อน Google Search และ YouTube ที่มีผู้ใช้หลายพันล้านคน
- เปิดตัวสำหรับการให้บริการทั่วไป: ตุลาคม 2024
- ดัชนีเวกเตอร์ PostgreSQL แรกที่เหมาะสำหรับเวกเตอร์ตั้งแต่ล้านถึงพันล้านรายการ
11. โหมดท้าทาย: ยกระดับทักษะการทำงานแบบเอเจนต์
คุณได้สร้างซัพพลายเชนอัตโนมัติที่ใช้งานได้ พร้อมจะก้าวไปอีกขั้นหรือยัง โดยความท้าทายเหล่านี้จะนำรูปแบบที่คุณได้เรียนรู้ไปใช้กับปัญหาใหม่ๆ
ชาเลนจ์ที่ 1: การค้นหาตามรูปภาพ (การฝังหลายรูปแบบ)
โฟลว์ปัจจุบัน: Vision Agent นับสินค้า → สร้างคำค้นหาข้อความ → Supplier Agent ฝังข้อความ → ค้นหา AlloyDB
ความท้าทาย: ข้ามข้อความทั้งหมดโดยส่งรูปภาพที่ครอบตัดไปยังตัวแทนซัพพลายเออร์โดยตรง
เคล็ดลับ:
- การดำเนินการโค้ดของ Vision Agent สามารถครอบตัดรายการแต่ละรายการจากรูปภาพชั้นวางได้
- โมเดล multimodalembedding@001 ของ Vertex AI สามารถฝังรูปภาพได้โดยตรง
- แก้ไข inventory.py เพื่อยอมรับไบต์รูปภาพแทนข้อความ
- อัปเดตคำอธิบายทักษะ A2A เพื่อระบุว่า "ยอมรับ: image/jpeg หรือ text"
เหตุผลที่เรื่องนี้สำคัญ: การค้นหาด้วยภาพมีความแม่นยำมากขึ้นสำหรับชิ้นส่วนที่มีลักษณะซับซ้อน (สีที่แตกต่างกัน ความเสียหาย ความแตกต่างของบรรจุภัณฑ์)
ความท้าทายที่ 2: การสังเกตการณ์ - ความเชื่อมั่นผ่านความโปร่งใส
สถานะปัจจุบัน: ระบบทำงานได้ แต่คุณไม่เห็น "เบื้องหลัง"
โจทย์: ตรวจสอบบันทึกการค้นหาของ AlloyDB เพื่อพิสูจน์ว่าการค้นหาเวกเตอร์กำลังดำเนินการอยู่
ขั้นตอน
- ระบบจะเปิดใช้ข้อมูลเชิงลึกของการค้นหาใน AlloyDB โดยค่าเริ่มต้น หากต้องการยืนยัน ให้เรียกใช้คำสั่งต่อไปนี้
gcloud alloydb instances describe INSTANCE_NAME \
--cluster=CLUSTER_NAME \
--region=us-central1 \
--format="value(queryInsightsConfig.queryPlansPerMinute)"
- เรียกใช้การค้นหาซัพพลายเออร์ผ่าน UI
- ดู SQL จริงที่ดำเนินการ
gcloud logging read \
'resource.type="alloydb.googleapis.com/Instance" AND textPayload:"ORDER BY part_embedding"' \
--limit 5 \
--format=json
เอาต์พุตที่คาดไว้: คุณจะเห็นคำสั่ง ORDER BY part_embedding <=> $1::vector LIMIT 1 ที่แน่นอนพร้อมเวลาในการดำเนินการ
เหตุผลที่เรื่องนี้สำคัญ: การสังเกตการณ์ช่วยสร้างความน่าเชื่อถือ เมื่อผู้มีส่วนเกี่ยวข้องถามว่า "เอเจนต์นี้ตัดสินใจอย่างไร" คุณสามารถแสดงแผนการค้นหาให้พวกเขาเห็นได้ ไม่ใช่แค่เอาต์พุต
ความท้าทายที่ 3: การจัดองค์ประกอบแบบหลายเอเจนต์
ความท้าทาย: เพิ่มเอเจนต์ที่ 3 (ตัวแทนด้านลอจิสติกส์) ที่คำนวณค่าจัดส่งตามสถานที่ตั้งของคลังสินค้าและน้ำหนักของสินค้า
สถาปัตยกรรม:
- เอาต์พุตของ Vision Agent: จำนวนรายการ
- ผลลัพธ์ของตัวแทนซัพพลายเออร์: สถานที่ตั้งของซัพพลายเออร์
- ตัวแทนด้านโลจิสติกส์ (ใหม่) ข้อมูลนำเข้า: ปลายทาง น้ำหนัก → ข้อมูลนำออก: ค่าจัดส่ง + เวลาถึงโดยประมาณ
เคล็ดลับ: โปรโตคอล A2A ทำให้การดำเนินการนี้ง่ายมาก เพียงสร้างการ์ดตัวแทนใหม่ที่มีทักษะ calculate_shipping Control Tower จะค้นพบโดยอัตโนมัติ
รูปแบบที่คุณกำลังเรียนรู้: นี่คือหัวใจสำคัญของสถาปัตยกรรมที่มุ่งเน้นเอเจนต์ ซึ่งเป็นระบบที่ซับซ้อนที่สร้างขึ้นจากผู้เชี่ยวชาญขนาดเล็กที่ประกอบกันได้
12. บทสรุป
คุณย้ายจาก Generative AI ไปยัง Agentic AI เรียบร้อยแล้ว
สิ่งที่เราสร้างขึ้น
- วิสัยทัศน์: เราแทนที่ "การคาดเดา" ด้วยการเรียกใช้โค้ด (Gemini 3 Flash ผ่านคีย์ API)
- หน่วยความจำ: เราแทนที่ "การค้นหาที่ช้า" ด้วย AlloyDB ScaNN (ผ่าน GCP)
- การดำเนินการ: เราแทนที่ "การผสานรวม API" ด้วยโปรโตคอล A2A
ข้อดีของสถาปัตยกรรมแบบไฮบริด
Codelab นี้แสดงให้เห็นแนวทางแบบผสมผสานดังนี้
- Vision Agent: ใช้ Gemini API (คีย์ API) - มีระดับฟรีแบบง่าย ไม่ต้องมีการเรียกเก็บเงินของ GCP
- เอเจนต์ซัพพลายเออร์: ใช้ GCP (Vertex AI + AlloyDB) - ระดับองค์กร พร้อมการปฏิบัติตามข้อกำหนด
นี่คือสถาปัตยกรรมของเศรษฐกิจอัตโนมัติ รหัสนี้เป็นของคุณ
ขั้นตอนถัดไป