สร้าง Python CLI คุย Gemini แบบไม่กลัวล่ม: เน้น Resilience

สวัสดีครับ

โปรแกรมเมอร์อย่างเราๆ เนี่ย พอต้องทำงานกับ API บ่อยๆ นะครับ โดยเฉพาะพวก External API อย่าง Gemini API ของ Google เนี่ย สิ่งหนึ่งที่สำคัญไม่แพ้การเขียนโค้ดให้มันทำงานได้ ก็คือการทำให้มัน ทนทาน (Resilience) ต่อความผิดพลาดต่างๆ นะครับ ไม่ว่าจะเน็ตล่ม หรือ API ล่ม หรือติด Rate Limit

วันนี้ผมจะพามาดูวิธีสร้าง Python CLI ง่ายๆ ที่คุยกับ Gemini API พร้อมใส่เรื่อง Resilience เข้าไปกันครับ


1. โครงสร้าง CLI แบบง่ายๆ

ขั้นแรกสุด เรามาดูโครงสร้างโปรเจกต์ CLI กันก่อนครับ ผมจะใช้ argparse มาจัดการ Argument ง่ายๆ นะครับ

# main.py
import argparse

def main():
    parser = argparse.ArgumentParser(description="CLI สำหรับคุยกับ Gemini API แบบ Resilient")
    parser.add_argument("--prompt", type=str, required=True, help="ข้อความที่คุณต้องการส่งให้ Gemini")
    args = parser.parse_args()

    print(f"กำลังส่งข้อความ: {args.prompt} ให้ Gemini...")
    # ส่วนนี้เดี๋ยวเราจะใส่โค้ดคุยกับ Gemini ครับ

if __name__ == "__main__":
    main()

เวลาเรียกใช้งานก็แบบนี้เลยครับ: python main.py --prompt "สวัสดี Gemini"


2. เชื่อมต่อ Gemini API

ก่อนอื่นนะครับ ติดตั้งไลบรารี google-generativeai ก่อนเลย pip install google-generativeai

แล้วก็เพิ่มโค้ดส่วนนี้เข้าไปใน main.py เพื่อให้ CLI เราคุยกับ Gemini ได้ครับ อย่าลืมตั้งค่า GOOGLE_API_KEY ด้วยนะครับ

# main.py (เพิ่มส่วนนี้เข้าไป)
import google.generativeai as genai
import os

genai.configure(api_key=os.environ.get("GOOGLE_API_KEY"))
model = genai.GenerativeModel('gemini-pro')

def call_gemini(prompt):
    try:
        response = model.generate_content(prompt)
        return response.text
    except Exception as e:
        print(f"เกิดข้อผิดพลาดในการเรียก Gemini: {e}")
        return None

def main(): # ในฟังก์ชัน main() แก้ไขส่วนเรียกใช้งาน
    # ... (ส่วน argparse เหมือนเดิม)

    gemini_response = call_gemini(args.prompt)
    if gemini_response:
        print("\
คำตอบจาก Gemini:")
        print(gemini_response)
    else:
        print("ไม่สามารถรับคำตอบจาก Gemini ได้ครับ")

ตอนนี้ CLI ของเราก็คุยกับ Gemini ได้แล้วครับ ลองรันดู GOOGLE_API_KEY='YOUR_API_KEY' python main.py --prompt "เล่าเรื่องสั้น 1 ย่อหน้า"


3. เพิ่มความ Resilient ด้วย Retry และ Context Manager

เพื่อให้โปรแกรมเราทนทานขึ้น เวลา API มีปัญหาชั่วคราว เราจะใช้ tenacity เข้ามาช่วยเรื่อง Retry นะครับ และใช้ context manager จัดการการบันทึก Log เวลาเกิดข้อผิดพลาด

ติดตั้ง tenacity ก่อนเลย: pip install tenacity

จากนั้นมาปรับโค้ด call_gemini กันครับ ผมจะใช้ retry decorator จาก tenacity และสร้าง Context Manager ง่ายๆ สำหรับ Log Error นะครับ

# main.py (เพิ่ม import และแก้ไขฟังก์ชัน)
from tenacity import retry, stop_after_attempt, wait_fixed, retry_if_exception_type
import contextlib
import datetime

# Context Manager สำหรับบันทึก Log (ตัวอย่างง่ายๆ)
@contextlib.contextmanager
def error_logger(log_file="error_log.txt"):
    f = open(log_file, "a", encoding="utf-8")
    try:
        yield f
    finally:
        f.close()

# Retry decorator
@retry(stop=stop_after_attempt(3), wait=wait_fixed(2),
       retry=retry_if_exception_type(Exception))
def call_gemini_resilient(prompt):
    print("--- พยายามเรียก Gemini API...")
    response = model.generate_content(prompt)
    return response.text

def main(): # ในฟังก์ชัน main() แก้ไขส่วนเรียกใช้งาน
    # ... (ส่วน argparse และ configure Gemini เหมือนเดิม)

    with error_logger() as log:
        try:
            gemini_response = call_gemini_resilient(args.prompt)
            print("\
คำตอบจาก Gemini:")
            print(gemini_response)
        except Exception as e:
            timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            log.write(f"[{timestamp}] เกิดข้อผิดพลาดหลังจากพยายามหลายครั้ง: {e}\
")
            print("ไม่สามารถรับคำตอบจาก Gemini ได้ครับ (ตรวจสอบ error_log.txt)")

คำอธิบายโค้ด: * @retry(...): จะพยายามเรียก call_gemini_resilient ซ้ำ 3 ครั้ง (หยุดเมื่อสำเร็จหรือครบ 3 ครั้ง) โดยจะรอ 2 วินาทีระหว่างการ retry ถ้าเกิด Exception ใดๆ ขึ้น * error_logger: เป็น Context Manager ง่ายๆ ที่ผมสร้างขึ้นมาเพื่อเปิดไฟล์ error_log.txt ไว้เขียนข้อผิดพลาด พอจบ Block with ไฟล์ก็จะถูกปิดอัตโนมัติครับ

ลองรันดูนะครับ ถ้า API มีปัญหาชั่วคราว มันจะลองใหม่ให้เอง GOOGLE_API_KEY='YOUR_API_KEY' python main.py --prompt "เขียนโค้ด Python สำหรับ Merge Sort"

ถ้าเกิดปัญหาแล้วมัน Retry จนครบ ก็จะบันทึก Log ลง error_log.txt ให้ด้วยครับ


สรุปนะครับ

การสร้าง CLI ที่เชื่อมต่อกับ External API อย่าง Gemini เนี่ย การใส่เรื่อง Resilience เข้าไปเป็นสิ่งสำคัญมากๆ เลยนะครับ ไม่ใช่แค่ทำให้โปรแกรมเราไม่ล่มง่ายๆ แต่ยังช่วยให้ User Experience ดีขึ้นด้วย เพราะบางทีปัญหาแค่ชั่วคราว เราก็ไม่ต้องให้ผู้ใช้ต้องมานั่งรันใหม่เอง

เพื่อนๆ ลองเอาเทคนิคนี้ไปปรับใช้กับโปรเจกต์ของตัวเองดูได้เลยนะครับ ไม่ว่าจะกับ Gemini หรือ API อื่นๆ ครับ

อ้างอิง: * Google Gemini API Docs * Tenacity Library


cii3.net

Read more

ไอลีน กู: ตำนานนักสกีฟรีสไตล์ผู้พลิกโฉมวงการและความหมายของชัยชนะ

ไอลีน กู: ตำนานนักสกีฟรีสไตล์ผู้พลิกโฉมวงการและความหมายของชัยชนะ

เจาะลึกเรื่องราวของ Eileen Gu นักสกีฟรีสไตล์ผู้สร้างประวัติศาสตร์ในโอลิมปิก 2026 สถิติที่ไม่เคยมีมาก่อน ประเด็นถกเถียง และความแข็งแกร่งส่วนตัวที่ทำให้เธอก้าวสู่ระดับโลก

By ทีมงาน devdog
วันพระ: คู่มือฉบับสมบูรณ์สำหรับพุทธศาสนิกชนและผู้สนใจยุคใหม่

วันพระ: คู่มือฉบับสมบูรณ์สำหรับพุทธศาสนิกชนและผู้สนใจยุคใหม่

เจาะลึกวันพระและความสำคัญของวันมาฆบูชา 2569 ทั้งวันหยุดราชการ ธนาคาร กิจกรรมเวียนเทียนต้นไม้ และผลกระทบต่อบริการขนส่ง เตรียมตัววางแผนทำบุญและพักผ่อน

By ทีมงาน devdog
ถอดรหัสรักแท้: "บังมัดคลองตันต้นข้าว" เรื่องราวที่สะท้อนการให้อภัยและการเริ่มต้นใหม่

ถอดรหัสรักแท้: "บังมัดคลองตันต้นข้าว" เรื่องราวที่สะท้อนการให้อภัยและการเริ่มต้นใหม่

เจาะลึกงานวิวาห์ "บังมัดคลองตัน" กับ "ต้นข้าว มิสแกรนด์" พร้อมเหตุผลจากใจเจ้าสาวที่เลือกความรักเหนือกาลเวลาและคำวิจารณ์ สู่การเริ่มต้นชีวิตคู่ที่สะท้อนการให้อภัย

By ทีมงาน devdog
ไฮไลท์บอลไทยลีก 2: มหาสารคาม เอสบีที เอฟซี กับฟอร์มร้อนแรงสู่เส้นทางเพลย์ออฟ

ไฮไลท์บอลไทยลีก 2: มหาสารคาม เอสบีที เอฟซี กับฟอร์มร้อนแรงสู่เส้นทางเพลย์ออฟ

เจาะลึกไฮไลท์บอลไทยลีก 2 ของมหาสารคาม เอสบีที เอฟซี กับฟอร์มร้อนแรง ชัยชนะสำคัญจาก ชิตชนก และบทบาทโค้ชดุสิต สู่เส้นทางเพลย์ออฟที่น่าจับตา!

By ทีมงาน devdog