ผมเคยเจอปัญหาที่ทำให้หน้าผิวหน้าหนึ่ง ทุ่มเทพัฒนา Feature สำหรับ Chatbot ที่ใช้ GPT-4o จนเสร็จสิ้น แต่พอ Deploy lên Production เข้าสู่วันแรก เกิดค่าใช้จ่าย Token พุ่งสูงถึง $847 จากประมาณการเดือนละ $120 สาเหตุหลักคือ Prompt ที่ยาวเกินไป มี Context ซ้ำซ้อน และ System Message ที่ verbose เกินความจำเป็น นี่คือจุดที่ผมเริ่มศึกษา Prompt Compression อย่างจริงจัง

บทความนี้จะสอนเทคนิคการลด Token โดยรักษาคุณภาพ Output ให้เท่าเดิม พร้อมโค้ดที่พร้อมใช้งานจริงบน HolySheep AI ซึ่งมีอัตราที่ ¥1=$1 ประหยัดได้มากกว่า 85% เมื่อเทียบกับ OpenAI โดยตรง

ทำไมต้อง Prompt Compression

เมื่อใช้ Large Language Model ผ่าน API ทุก Token มีค่าใช้จ่าย โดยเฉพาะ Model ระดับสูงอย่าง GPT-4.1 ราคา $8 ต่อล้าน Token หรือ Claude Sonnet 4.5 ที่ $15 ต่อล้าน Token การลดจำนวน Token ใน Input โดยตรงหมายถึงการประหยัดค่าใช้จ่ายทันที นอกจากนี้ Response Time ก็เร็วขึ้นด้วย เพราะ Model ต้องประมวลผลข้อมูลน้อยลง

ผมทดสอบบน HolySheep AI ที่รองรับ Model หลากหลาย ตั้งแต่ DeepSeek V3.2 ($0.42/MTok) จนถึง Claude Sonnet 4.5 ($15/MTok) และวัดความหน่วงได้ต่ำกว่า 50ms ทำให้เห็นชัดว่า Prompt ที่กระชับให้ผลลัพธ์เร็วกว่าอย่างเห็นได้ชัด

เทคนิค Prompt Compression ที่ใช้ได้จริง

1. ใช้ Short-hand Notation แทนประโยคเต็ม

แทนที่จะเขียน "Please provide a detailed summary of the following text" ซึ่งใช้ Token ถึง 10 ตัว เปลี่ยนเป็น "TL;DR:" ที่ใช้แค่ 2 Token เทคนิคนี้ลด Token ได้ถึง 80% ในบางกรณี

2. รวม System Prompt ที่ซ้ำซ้อน

หลายครั้งที่ System Message มีคำสั่งซ้ำกัน เช่น "You are a helpful assistant" แล้วตามด้วย "You should answer questions helpfully" รวมเป็นประโยคเดียว "You are a helpful, concise assistant" จะลด Token ได้โดยไม่สูญเสียความหมาย

3. ใช้ Delimiter ที่กระชับ

แทนที่จะใช้ ```json ซึ่งใช้ 4 Token ใช้แค่ :: หรือ ### ก็เพียงพอสำหรับการแบ่งส่วนข้อมูล

4. Context Compression ก่อนส่งให้ Model

เมื่อต้องส่ง Conversation History ที่ยาวมาก ให้บีบอัด Context ก่อนด้วย Prompt สั้นๆ เพื่อให้ Model สรุปและจำข้อมูลสำคัญ ก่อนจะถามคำถามใหม่

import openai
import tiktoken

ตั้งค่า HolySheep API

openai.api_base = "https://api.holysheep.ai/v1" openai.api_key = "YOUR_HOLYSHEEP_API_KEY" def count_tokens(text, model="gpt-4"): """นับจำนวน Token ในข้อความ""" encoding = tiktoken.encoding_for_model(model) return len(encoding.encode(text)) def compress_prompt(original_prompt, max_tokens=2000): """บีบอัด Prompt โดยใช้ LLM สรุปเนื้อหาสำคัญ""" compression_instruction = f"""Compress this prompt to maximum {max_tokens} tokens. Keep only: task, constraints, output format. Remove: examples (if obvious), redundant explanations. Original: {original_prompt}""" response = openai.ChatCompletion.create( model="gpt-4.1", messages=[ {"role": "system", "content": "You are a prompt compression assistant. Output ONLY the compressed prompt, no explanations."}, {"role": "user", "content": compression_instruction} ], temperature=0.3 ) return response.choices[0].message.content

ทดสอบ

original = """You are an expert code reviewer working at a software company. Your task is to review code for potential bugs, security issues, and performance problems. Please provide detailed feedback including: 1. Specific line numbers with issues 2. Severity level (critical/high/medium/low) 3. Suggested fix for each issue Make sure to check for SQL injection, XSS, and memory leaks." """ compressed = compress_prompt(original) print(f"Original tokens: {count_tokens(original)}") print(f"Compressed tokens: {count_tokens(compressed)}") print(f"Reduction: {(1 - count_tokens(compressed)/count_tokens(original))*100:.1f}%")

5. ใช้ Few-shot Example อย่างมีประสิทธิภาพ

แทนที่จะให้ตัวอย่าง (Example) หลายชุด ให้ตัวอย่างแค่ชุดเดียวที่ครอบคลุมกรณี Edge Case สำคัญ แล้วเขียน Task ให้ชัดเจนว่าต้องการอะไร

import json
import re

class PromptCompressor:
    """คลาสสำหรับบีบอัด Prompt หลายรูปแบบ"""
    
    # พจนานุกรมคำย่อที่ใช้บ่อย
    SHORTHAND_MAP = {
        "please provide": "give",
        "in order to": "to",
        "at this point in time": "now",
        "due to the fact that": "because",
        "in the event that": "if",
        "for the purpose of": "to",
        "with regard to": "about",
        "as a consequence of": "due to",
    }
    
    @staticmethod
    def basic_compress(text):
        """บีบอัดพื้นฐานด้วยการแทนที่คำ"""
        compressed = text
        for full, short in PromptCompressor.SHORTHAND_MAP.items():
            compressed = re.sub(full, short, compressed, flags=re.IGNORECASE)
        # ลบช่องว่างซ้ำ
        compressed = re.sub(r'\s+', ' ', compressed)
        return compressed.strip()
    
    @staticmethod
    def remove_redundant(text):
        """ลบส่วนที่ซ้ำซ้อนโดยไม่สูญเสียความหมาย"""
        lines = text.split('\n')
        seen = set()
        unique_lines = []
        
        for line in lines:
            # ลบ Comment และช่องว่าง
            clean_line = ' '.join(line.split()).lower()
            if clean_line and clean_line not in seen:
                seen.add(clean_line)
                unique_lines.append(line)
        
        return '\n'.join(unique_lines)
    
    @staticmethod
    def smart_truncate(text, max_chars=4000):
        """ตัด Prompt ให้กระชับโดยรักษาส่วนสำคัญ"""
        # รักษา System/Role และ Task หลัก
        parts = {
            'system': '',
            'task': '',
            'constraints': '',
            'context': ''
        }
        
        current_section = 'context'
        for line in text.split('\n'):
            lower = line.lower()
            if 'role' in lower or 'you are' in lower:
                current_section = 'system'
            elif 'task' in lower or 'please' in lower:
                current_section = 'task'
            elif 'constraint' in lower or 'rule' in lower or 'must' in lower:
                current_section = 'constraints'
            
            parts[current_section] += line + '\n'
        
        # รวมโดยเรียงลำดับความสำคัญ
        result = parts['system']
        result += parts['task']
        result += parts['constraints']
        
        if len(result) < max_chars:
            result += parts['context']
        
        return result[:max_chars]

ทดสอบ

test_prompt = """You are an expert software engineer. You must please provide code reviews in a helpful manner. Please check for bugs and security issues. The code is written in Python. The context is a web application. Please provide feedback as soon as possible. You should be thorough in your analysis. You are an expert software engineer.""" compressor = PromptCompressor() print("Original:", len(test_prompt), "chars") print("Basic:", len(compressor.basic_compress(test_prompt)), "chars") print("Unique:", len(compressor.remove_redundant(test_prompt)), "chars")

6. Streaming กับ Batch Processing

สำหรับงานที่ต้องประมวลผลหลาย Prompt คล้ายกัน ให้รวมเป็น Batch แล้วใช้ Context Window ร่วมกัน แทนที่จะเรียก API แยกทีละ Prompt

import openai
from concurrent.futures import ThreadPoolExecutor

openai.api_base = "https://api.holysheep.ai/v1"
openai.api_key = "YOUR_HOLYSHEEP_API_KEY"

def process_single_request(prompt_data):
    """ประมวลผล Prompt เดียว"""
    prompt, model, task_id = prompt_data
    
    response = openai.ChatCompletion.create(
        model=model,
        messages=[
            {"role": "system", "content": "Extract key information from user input. Be concise."},
            {"role": "user", "content": prompt}
        ],
        temperature=0.1,
        max_tokens=150
    )
    
    return task_id, response.choices[0].message.content

def batch_process_optimized(prompts, model="gpt-4.1", max_workers=5):
    """ประมวลผลหลาย Prompt พร้อมกันแบบ Optimize"""
    
    # ใช้ ThreadPoolExecutor เพื่อเรียก API หลายเส้น
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        tasks = [(p, model, i) for i, p in enumerate(prompts)]
        results = list(executor.map(process_single_request, tasks))
    
    # เรียงลำดับตาม Task ID
    results.sort(key=lambda x: x[0])
    return [r[1] for r in results]

ตัวอย่าง: ประมวลผลรีวิวสินค้า 100 รายการ

sample_reviews = [ "สินค้าดีมาก จัดส่งเร็ว บรรจุภัณฑ์ไม่เสียหาย แต่ราคาสูงไปนิด", "ใช้งานง่าย คุ้มค่า ควรซื้อ", "ไม่ตรงปก สีผิดไปจากในรูป เสียใจมาก", # ... รีวิวอื่นๆ ] * 25 # ทำให้เป็น 100 รายการ results = batch_process_optimized(sample_reviews[:100]) print(f"ประมวลผล {len(results)} รายการเรียบร้อย")

ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข

กรณีที่ 1: ConnectionError: timeout หลังจากส่ง Prompt ยาว

สาเหตุ: เมื่อ Prompt มีขนาดใหญ่เกินไป ทำให้เวลาในการประมวลผลนานเกิน Timeout ที่กำหนด โดยเฉพาะเมื่อใช้ Model ระดับสูงอย่าง GPT-4.1 ที่มี Context Window จำกัด

วิธีแก้ไข:

import openai
from openai.error import Timeout, APIError
import time

openai.api_base = "https://api.holysheep.ai/v1"
openai.api_key = "YOUR_HOLYSHEEP_API_KEY"

def safe_completion(messages, model="gpt-4.1", max_retries=3):
    """เรียก API อย่างปลอดภัยพร้อม Retry Logic"""
    
    for attempt in range(max_retries):
        try:
            response = openai.ChatCompletion.create(
                model=model,
                messages=messages,
                timeout=60,  # ตั้ง Timeout 60 วินาที
                max_tokens=2000
            )
            return response
            
        except Timeout:
            print(f"Attempt {attempt + 1}: Timeout occurred")
            # ลดขนาด Prompt โดยตัด Context เก่าออก
            if len(messages) > 2:
                # เก็บ System และ Message ล่าสุด 2 รายการ
                messages = [messages[0]] + messages[-2:]
                # ลด Model ลงชั่วคราว
                model = "gpt-4.1"
            else:
                # ถ้ายัง Timeout อีก ให้ลด max_tokens
                messages[1]["content"] = messages[1]["content"][:1000]
                
        except APIError as e:
            print(f"