Python CLI สรุปไฟล์เยอะๆ ด้วย Gemini ไม่ต้องกลัวหลุด ไม่ต้องรอนาน

สวัสดีครับเพื่อนๆ โปรแกรมเมอร์

วันนี้ผมจะพาเพื่อนๆ มาสร้างเครื่องมือ CLI แบบง่ายๆ ด้วย Python กันนะครับ เอาไว้สรุปไฟล์ข้อความเยอะๆ ที่มีอยู่ในเครื่องของเรานี่ละครับ ใช้ Gemini API มาช่วยให้งานของเรามันจบได้ไวขึ้น แถมยังทำแบบมี Resillience กับ Optimization ด้วยนะ เพื่อให้มันไม่หลุดกลางทาง แล้วก็ทำงานได้แบบไหลลื่นเลยละครับ

ปัญหาที่เราเจอบ่อยๆ คืออะไร?

เราอาจจะมีไฟล์ text หลายสิบ หลายร้อยไฟล์เลยนะครับ ที่ต้องส่งไปให้ Gemini สรุปเนื้อหาให้

  • ถ้าส่งไปทีเดียวหมด มันก็อาจจะโดน Rate Limit หรือ API มีปัญหาชั่วคราวได้
  • ส่งไปทีละไฟล์ก็ช้าอีก

แบบนี้มันไม่เวิร์คเลยนะครับ เรามาทำให้มันดีขึ้นกันดีกว่าครับ

1. เตรียม Gemini API กันก่อน

อันดับแรกเพื่อนๆ ต้องมี API Key ของ Gemini ก่อนนะครับ เข้าไปเอาได้ที่ Google AI Studio นะครับ จากนั้นก็ Install Library นี้เลยครับ

pip install google-generativeai python-dotenv

แล้วก็สร้างไฟล์ .env ไว้เก็บ API Key นะครับ ปลอดภัยกว่าเอาไป hardcode ในโค๊ดตรงๆ นะ

GOOGLE_API_KEY=\"YOUR_API_KEY_ตรงนี้\"

โค๊ดเริ่มต้นของเราก็จะประมาณนี้นะครับ

import google.generativeai as genai
import os
from dotenv import load_dotenv

load_dotenv()
genai.configure(api_key=os.getenv(\"GOOGLE_API_KEY\"))

model = genai.GenerativeModel('gemini-pro')

def summarize_text(text: str) -> str:
    try:
        response = model.generate_content(f\"กรุณาสรุปข้อความต่อไปนี้:\
{text}\")
        return response.text
    except Exception as e:
        print(f\"เกิดข้อผิดพลาดในการสรุป: {e}\")
        return \"\"

# ลองทดสอบดู
# content = \"เนื้อหาบทความยาวๆ ตรงนี้...\"
# summary = summarize_text(content)
# print(summary)

2. จัดการไฟล์เยอะๆ ด้วย File-Handling และ Context Manager

ทีนี้เรามาทำให้ CLI ของเราอ่านไฟล์ได้ทีละหลายๆ ไฟล์กันครับ แล้วก็เขียนผลลัพธ์ลงไฟล์ใหม่ด้วยนะ เพื่อให้โค๊ดมันดูดีขึ้น เราจะใช้ context-manager หรือ with open(...) นี่ละครับ มันจะช่วยให้เราไม่ต้องมานั่ง close() ไฟล์เอง ปลอดภัยกว่าเยอะเลย

import pathlib

def process_files(input_dir: str, output_dir: str):
    input_path = pathlib.Path(input_dir)
    output_path = pathlib.Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    for file_path in input_path.glob('*.txt'): # หาไฟล์ .txt ทั้งหมด
        print(f\"กำลังประมวลผลไฟล์: {file_path.name}\")
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()

        summary = summarize_text(content)

        output_file = output_path / f\"summary_{file_path.name}\"
        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(summary)
        print(f\"บันทึกสรุปแล้วที่: {output_file.name}\")

# วิธีเรียกใช้งาน
# process_files('./input_texts', './output_summaries')

3. เพิ่ม Resilience ให้ CLI ของเรา ไม่ให้ API ล่มง่ายๆ

API มันก็มีหลุดบ้างนะครับ หรือโดน Rate Limit บ้าง เราเลยต้องทำใจเย็นๆ ลองส่งใหม่ดูหน่อยครับ ถ้ามันล่ม เราจะรอซักพักแล้วลองใหม่ แบบนี้เรียกว่า Resilience นะครับ ผมจะใช้ time.sleep แบบง่ายๆ ก่อนนะ เพื่อนๆ อาจจะใช้ Library อย่าง tenacity ก็ได้นะครับ แต่เพื่อความกระชับเอาแบบนี้ไปก่อนครับ

import time

MAX_RETRIES = 3
RETRY_DELAY_SECONDS = 5

def summarize_text_with_resilience(text: str) -> str:
    for attempt in range(MAX_RETRIES):
        try:
            response = model.generate_content(f\"กรุณาสรุปข้อความต่อไปนี้:\
{text}\")
            return response.text
        except Exception as e:
            print(f\"ครั้งที่ {attempt+1}/{MAX_RETRIES} เกิดข้อผิดพลาด: {e}\")
            if attempt < MAX_RETRIES - 1:
                print(f\"รอ {RETRY_DELAY_SECONDS} วินาที แล้วลองใหม่นะครับ...\")
                time.sleep(RETRY_DELAY_SECONDS)
            else:
                print(\"ลองใหม่ครบจำนวนแล้วครับ ไม่สามารถสรุปข้อความนี้ได้\")
    return \"\"

# ทีนี้ก็เอาไปใส่ใน process_files ของเราได้เลย
# summary = summarize_text_with_resilience(content)

4. Optimization: ประมวลผลแบบเป็นชุดๆ ไม่ต้องรอนาน

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

# เพิ่มในส่วนของ process_files นะครับ

# ... โค๊ดเดิม ...

    for i, file_path in enumerate(input_path.glob('*.txt')):
        print(f\"กำลังประมวลผลไฟล์: {file_path.name}\")
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()

        summary = summarize_text_with_resilience(content) # ใช้ฟังก์ชันที่มี Resilience

        output_file = output_path / f\"summary_{file_path.name}\"
        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(summary)
        print(f\"บันทึกสรุปแล้วที่: {output_file.name}\")

        if i < len(list(input_path.glob('*.txt'))) - 1: # ไม่ต้องรอถ้าเป็นไฟล์สุดท้าย
            API_CALL_DELAY = 1 # วินาที
            print(f\"รอ {API_CALL_DELAY} วินาที ก่อนเรียก API ครั้งต่อไปนะครับ...\")
            time.sleep(API_CALL_DELAY)

# ... โค๊ดเดิม ...

สุดท้ายนี้ครับ

เพื่อนๆ ลองเอาไปปรับใช้กับงานของตัวเองดูได้นะครับ จะเห็นว่าเราสามารถสร้าง CLI ง่ายๆ ที่มีความสามารถในการจัดการไฟล์ การเชื่อมต่อกับ API และยังเพิ่มความทนทาน (Resilience) กับการเพิ่มประสิทธิภาพ (Optimization) ได้ด้วยนะ โดยไม่ต้องเขียนโค๊ดอะไรที่ซับซ้อนเลยครับ ลองดูนะครับ

อ้างอิง: * Google AI Studio Documentation * Python Pathlib Module

บทความนี้ละ "

Read more

คิวบา: มนต์เสน่ห์บนเส้นทางแห่งความท้าทาย – วิกฤตพลังงานและแรงกดดันจากสหรัฐฯ

คิวบา: มนต์เสน่ห์บนเส้นทางแห่งความท้าทาย – วิกฤตพลังงานและแรงกดดันจากสหรัฐฯ

เจาะลึกสถานการณ์ล่าสุดของคิวบา ทั้งวิกฤตไฟฟ้าดับครั้งใหญ่จากปัญหาพลังงาน และแรงกดดันจากสหรัฐฯ ภายใต้การนำของทรัมป์ อนาคตของเกาะปฏิวัติแห่งนี้จะเป็นอย่างไร?

By ทีมงาน devdog
ละครไทย: ถอดรหัสเสน่ห์ "พลอยน้ำเพชร" และปรากฏการณ์บันเทิงที่ไม่เคยจางหาย

ละครไทย: ถอดรหัสเสน่ห์ "พลอยน้ำเพชร" และปรากฏการณ์บันเทิงที่ไม่เคยจางหาย

สำรวจความเข้มข้นของละคร "พลอยน้ำเพชร" จากช่องวัน 31 พร้อมเจาะลึกตอนที่ 17-20 และเสน่ห์ของละครไทยที่ครองใจผู้ชมทั่วโลก

By ทีมงาน devdog
ชนนพัฒฐ์ นาคสั้ว: สส.สงขลา กับประเด็นร้อนคดีเว็บพนันออนไลน์ที่ DSI กำลังจับตา

ชนนพัฒฐ์ นาคสั้ว: สส.สงขลา กับประเด็นร้อนคดีเว็บพนันออนไลน์ที่ DSI กำลังจับตา

เจาะลึกประเด็นร้อน ชนนพัฒฐ์ นาคสั้ว สส.สงขลา พรรคกล้าธรรม กับกระแสข่าวพาดพิงถึงเครือข่ายเว็บพนันออนไลน์ที่ DSI กำลังสอบสวน เปิดความท้าทายต่อบทบาทผู้แทนราษฎร

By ทีมงาน devdog
เจาะลึก "ณัฐธิดา เล็กอุดากร" หลานเนวินชิดชอบ สส. อายุน้อยสุด ผู้พร้อมสร้างอนาคตใหม่ให้บุรีรัมย์

เจาะลึก "ณัฐธิดา เล็กอุดากร" หลานเนวินชิดชอบ สส. อายุน้อยสุด ผู้พร้อมสร้างอนาคตใหม่ให้บุรีรัมย์

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

By ทีมงาน devdog