คุณเคยสังเกตไหมว่าเวลาถาม ChatGPT หรือ AI ตัวอื่น ตัวอักษรมันพิมพ์ทีละตัวแทนที่จะรอจนเสร็จทั้งหมด? นั่นคือเทคโนโลยีที่เรียกว่า Server-Sent Events (SSE) หรือ Streaming นั่นเอง วันนี้ผมจะสอนคุณตั้งแต่เริ่มต้นจนสามารถนำไปใช้งานจริงได้

Streaming SSE คืออะไร? อธิบายแบบเข้าใจง่าย

ลองนึกภาพว่าคุณสั่งอาหารที่ร้าน แทนที่จะรอจนทำเสร็จทั้งหมดก่อนค่อยยกมาให้ พนักงานก็จะทยอยส่งจานเดียวไปเรื่อยๆ จนครบ นี่คือหลักการเดียวกันกับ Streaming

ข้อดีหลักๆ ของการใช้ Streaming SSE:

เตรียมพร้อมก่อนเริ่มต้น

สิ่งที่ต้องมี

ก่อนจะเริ่มเขียนโค้ด คุณต้องเตรียมอะไรบ้าง:

ทำความรู้จักกับ API Endpoint ของ HolySheep

ตามปกติแล้ว API ที่ใช้ Streaming จะมีลักษณะแบบนี้:

เริ่มเขียนโค้ดแบบ Step by Step

ขั้นตอนที่ 1: สร้างโครงสร้าง HTML พื้นฐาน

ก่อนอื่นให้สร้างไฟล์ชื่อ index.html สำหรับหน้าเว็บของเรา:

<!DOCTYPE html>
<html lang="th">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Streaming SSE Demo - HolySheep AI</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
            background: #f5f5f5;
        }
        #chat-container {
            background: white;
            border-radius: 12px;
            padding: 20px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        #messages {
            height: 400px;
            overflow-y: auto;
            border: 1px solid #ddd;
            border-radius: 8px;
            padding: 15px;
            margin-bottom: 15px;
        }
        #user-input {
            width: 100%;
            padding: 12px;
            border-radius: 8px;
            border: 1px solid #ddd;
            font-size: 16px;
            box-sizing: border-box;
        }
        button {
            background: #4CAF50;
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 16px;
            margin-top: 10px;
        }
        button:hover {
            background: #45a049;
        }
        .message {
            margin-bottom: 15px;
            padding: 10px;
            border-radius: 8px;
        }
        .user-message {
            background: #e3f2fd;
            text-align: right;
        }
        .ai-message {
            background: #f1f8e9;
        }
    </style>
</head>
<body>
    <div id="chat-container">
        <h2>💬 Chat กับ AI แบบ Streaming</h2>
        <div id="messages"></div>
        <input type="text" id="user-input" placeholder="พิมพ์ข้อความของคุณ...">
        <button onclick="sendMessage()">ส่งข้อความ</button>
    </div>

    <script>
        // โค้ด JavaScript จะอยู่ตรงนี้
    </script>
</body>
</html>

จากโค้ดด้านบน เราได้สร้าง:

ขั้นตอนที่ 2: เขียนโค้ด JavaScript สำหรับเชื่อมต่อ Streaming

ต่อไปจะเป็นหัวใจหลักของบทความนี้ ให้แทนที่ส่วน <script> ด้วยโค้ดนี้:

const API_KEY = 'YOUR_HOLYSHEEP_API_KEY'; // ใส่ API Key ของคุณตรงนี้
const BASE_URL = 'https://api.holysheep.ai/v1';

// ฟังก์ชันสำหรับส่งข้อความไปยัง AI
async function sendMessage() {
    const input = document.getElementById('user-input');
    const messagesDiv = document.getElementById('messages');
    const userMessage = input.value.trim();
    
    if (!userMessage) return;
    
    // เพิ่มข้อความของผู้ใช้ลงในกล่องแชท
    addMessage(userMessage, 'user');
    input.value = '';
    
    // สร้างกล่องสำหรับข้อความ AI (จะอัพเดททีหลัง)
    const aiMessageDiv = document.createElement('div');
    aiMessageDiv.className = 'message ai-message';
    const aiTextSpan = document.createElement('span');
    aiMessageDiv.appendChild(aiTextSpan);
    messagesDiv.appendChild(aiMessageDiv);
    
    try {
        // ส่งคำขอแบบ Streaming
        const response = await fetch(${BASE_URL}/chat/completions, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': Bearer ${API_KEY}
            },
            body: JSON.stringify({
                model: 'gpt-4.1',
                messages: [
                    { role: 'user', content: userMessage }
                ],
                stream: true  // เปิดโหมด Streaming
            })
        });
        
        // อ่านข้อมูลทีละส่วน
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        let aiResponse = '';
        
        while (true) {
            const { done, value } = await reader.read();
            if (done) break;
            
            // แปลงข้อมูลที่ได้รับเป็นข้อความ
            const chunk = decoder.decode(value);
            
            // แยกวิเคราะห์ข้อมูล SSE
            const lines = chunk.split('\n');
            
            for (const line of lines) {
                if (line.startsWith('data: ')) {
                    const data = line.slice(6); // ตัด 'data: ' ออก
                    
                    // ข้อมูลสิ้นสุด
                    if (data === '[DONE]') {
                        continue;
                    }
                    
                    try {
                        const json = JSON.parse(data);
                        const content = json.choices?.[0]?.delta?.content;
                        
                        if (content) {
                            aiResponse += content;
                            aiTextSpan.textContent = aiResponse;
                            
                            // เลื่อนหน้าจอให้ตามข้อความ
                            messagesDiv.scrollTop = messagesDiv.scrollHeight;
                        }
                    } catch (e) {
                        // ข้ามข้อมูลที่ parse ไม่ได้
                    }
                }
            }
        }
        
        // หลังจากได้รับข้อมูลครบ เลื่อนหน้าจอลงมาด้านล่าง
        messagesDiv.scrollTop = messagesDiv.scrollHeight;
        
    } catch (error) {
        console.error('เกิดข้อผิดพลาด:', error);
        aiTextSpan.textContent = '❌ เกิดข้อผิดพลาด: ' + error.message;
    }
}

// ฟังก์ชันเพิ่มข้อความลงในกล่องแชท
function addMessage(text, type) {
    const messagesDiv = document.getElementById('messages');
    const messageDiv = document.createElement('div');
    messageDiv.className = message ${type}-message;
    messageDiv.textContent = text;
    messagesDiv.appendChild(messageDiv);
    messagesDiv.scrollTop = messagesDiv.scrollHeight;
}

ขั้นตอนที่ 3: ทดสอบการทำงาน

หลังจากเขียนโค้ดเสร็จแล้ว ให้ทดสอบตามขั้นตอนนี้:

รู้จักกับข้อมูลที่ได้รับจาก Streaming

เมื่อคุณใช้งาน Streaming แต่ละครั้ง ข้อมูลที่ได้รับจะมีรูปแบบดังนี้:

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1234567890,"model":"gpt-4.1","choices":[{"index":0,"delta":{"content":"ส"},"finish_reason":null}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1234567890,"model":"gpt-4.1","choices":[{"index":0,"delta":{"content":"วัส"},"finish_reason":null}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1234567890,"model":"gpt-4.1","choices":[{"index":0,"delta":{"content":"ดี"},"finish_reason":null}]}

data: [DONE]

จากตัวอย่างข้างบน:

เพิ่มเติม: รองรับ Webhook และการแจ้งเตือน

สำหรับระบบที่ต้องการแจ้งเตือนเมื่อ AI ตอบเสร็จ หรือต้องการบันทึกข้อมูลการสนทนา สามารถใช้ Webhook ได้ แต่ต้องระวังเรื่องความปลอดภัยด้วย

ประสิทธิภาพและการปรับปรุง

ทำไมต้องใช้ HolySheep AI?

จากประสบการณ์ที่ใช้งาน API หลายตัว พบว่า HolySheep AI มีข้อดีหลายอย่างที่เหมาะกับการใช้งานจริง:

เคล็ดลับเพิ่มประสิทธิภาพ

จากการทดสอบและใช้งานจริง มีเคล็ดลับที่ช่วยให้การใช้ Streaming มีประสิทธิภาพดีขึ้น:

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

กรณีที่ 1: ได้รับข้อผิดพลาด "401 Unauthorized"

อาการ: เมื่อกดส่งข้อความแล้วขึ้นข้อผิดพลาด 401 พร้อมข้อความว่า "Invalid authentication credentials"

// ❌ วิธีที่ผิด - ลืมใส่ API Key
const response = await fetch(${BASE_URL}/chat/completions, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
        // ลืม Authorization header!
    },
    body: JSON.stringify({...})
});

// ✅ วิธีที่ถูกต้อง
const response = await fetch(${BASE_URL}/chat/completions, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': Bearer ${API_KEY}  // อย่าลืมส่วนนี้!
    },
    body: JSON.stringify({...})
});

// หรือตรวจสอบว่า API Key ถูกต้อง
if (!API_KEY || API_KEY === 'YOUR_HOLYSHEEP_API_KEY') {
    alert('กรุณาใส่ API Key ของคุณก่อน!');
    return;
}

วิธีแก้ไข: ตรวจสอบว่าได้ใส่ API Key ที่ถูกต้อง โดยเข้าไปที่หน้า Dashboard ของ HolySheep AI แล้วคัดลอก Key มาใส่ให้ถูกต้อง ระวังอย่าให้มีช่องว่างเพิ่มเข้ามา

กรณีที่ 2: ข้อความไม่แสดงทีละตัวอักษร แต่แสดงพร้อมกันทีเดียว

อาการ: รอจน AI ตอบเสร็จก่อนแล้วค่อยแสดงทั้งหมด ไม่เห็นผลของ Streaming

// ❌ วิธีที่ผิด - รอจนได้ข้อมูลครบก่อนแล้วค่อยแสดง
const response = await fetch(${BASE_URL}/chat/completions, {...});
const data = await response.json();  // รอจนเสร็จ!
aiTextSpan.textContent = data.choices[0].message.content;  // แสดงทีเดียว

// ✅ วิธีที่ถูกต้อง - อัพเดททุกครั้งที่ได้รับข้อมูลใหม่
const response = await fetch(${BASE_URL}/chat/completions, {
    method: 'POST',
    headers: {...},
    body: JSON.stringify({
        ...
        stream: true  // ต้องมีส่วนนี้ด้วย!
    })
});

const reader = response.body.getReader();
// อ่านและแสดงทีละส่วน
while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    
    // ประมวลผลแต่ละส่วนที่ได้รับ
    const chunk = decoder.decode(value);
    const content = parseChunk(chunk);  // ฟังก์ชันแยกข้อมูล
    
    if (content) {
        aiResponse += content;
        aiTextSpan.textContent = aiResponse;  // อัพเดททุกครั้ง
    }
}

วิธีแก้ไข: ตรวจสอบว่าในส่วน body ของคำขอมี stream: true อยู่ด้วย ถ้าไม่มี AI จะส่งข้อมูลกลับมาทีเดียวแทนที่จะส่งทีละส่วน และต้องใช้ response.body.getReader() ในการอ่านข้อมูลแบบ Streaming

กรณีที่ 3: เว็บไซต์แสดงข้อผิดพลาด CORS

อาการ: เมื่อรันโค้ดในเบราว์เซอร์จริง ขึ้นข้อผิดพลาด "Access-Control-Allow-Origin"

// ❌ วิธีที่ผิด - เรียกใช้โดยตรงจาก Frontend (เบราว์เซอร์)
fetch('https://api.holysheep.ai/v1/chat/completions', {...})

// ✅ วิธีที่ถูกต้อง - สร้าง Backend Proxy
// ไฟล์ server.js (Node.js)
const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors());  // อนุญาต CORS

app.post('/api/chat', async (req, res) => {
    // เรียก API ผ่าน Server แทน
    const response = await fetch('https://api.holysheep.ai/v1/chat/completions', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': Bearer ${process.env.HOLYSHEEP_API_KEY}
        },
        body: JSON.stringify(req.body)
    });
    
    // ส่งข้อมูลกลับไปให้ Frontend
    res.json(await response.json());
});

app.listen(3000);

// ✅ อีกวิธี - หรือใช้ Streaming ผ่าน Backend
app.post('/api/chat/stream', async (req, res) => {
    const response = await fetch('https://api.holysheep.ai/v1/chat/completions', {
        method: 'POST',
        headers: {...},
        body: JSON.stringify({...})
    });
    
    // ส่งต่อข้อมูล Streaming ไปให้ Frontend
    response.body.pipe(res);
});

วิธีแก้ไข: เนื่องจากปัญหา CORS เบราว์เซอร์จะบล็อกการเรียก API โดยตรง วิธีแก้คือสร้าง Backend Server เพื่อเป็นตัวกลาง หรือถ้าต้องการเรียกใช้โดยตรงจาก Frontend ให้ใช้วิธีอื่นแทน เช่น ใช้ Backend ของ HolySheep ที่มี CORS Headers ตั้งค่าไว้แล้ว

สรุปและขั้นตอนถัดไป

ในบทความนี้คุณได้เรียนรู้วิธีการเชื่อมต่อ Streaming SSE กับ API ของ AI ตั้งแต่พื้นฐานจนสามารถนำไปใช้งาน