GORAGOD.com

สร้างระบบถาม-ตอบอัจฉริยะด้วย Gemini API และ Embeddings จากฐานข้อมูลของคุณ

บทความนี้จะนำคุณไปสู่ขั้นตอนการสร้างระบบถาม-ตอบอัจฉริยะ โดยใช้ประโยชน์จากพลังของ Gemini API ในการทำความเข้าใจภาษา และ Embeddings ในการค้นหาข้อมูลที่เกี่ยวข้องจากฐานข้อมูลของคุณ เพื่อให้ได้คำตอบที่อิงกับข้อมูลของคุณเอง

ขั้นตอนการทำงานหลัก

  1. สร้าง Embeddings จากข้อมูลในฐานข้อมูล แปลงเนื้อหาของบทความหรือเอกสารในฐานข้อมูลของคุณให้เป็น Vector Embeddings
  2. จัดเก็บ Embeddings บันทึก Embeddings เหล่านี้กลับเข้าไปในฐานข้อมูล (หรือ Vector Database)
  3. ค้นหาบทความที่เกี่ยวข้อง เมื่อผู้ใช้ถามคำถาม ให้สร้าง Embedding ของคำถามนั้น และค้นหา Embeddings ของบทความที่ใกล้เคียงที่สุดในฐานข้อมูล
  4. ใช้ Gemini API สร้างคำตอบ นำบทความที่เกี่ยวข้องมาเป็น Context พร้อมกับคำถามของผู้ใช้ แล้วส่งให้ Gemini API สร้างคำตอบที่อิงกับข้อมูลเหล่านั้น

ขั้นตอนที่ 1 สร้าง Embeddings

ขั้นตอนนี้เราจะดึงข้อมูลจากฐานข้อมูล สร้าง Embeddings โดยใช้ Gemini Embedding API และอัปเดต Embeddings กลับเข้าไปในฐานข้อมูล

โค้ดตัวอย่าง (PHP)

<?php

// --- ฟังก์ชันสำหรับสร้าง Embedding ---
function getEmbedding($text) {
    $api_key = 'YOUR_GEMINI_API_KEY';
    $url = 'https://generativelanguage.googleapis.com/v1beta/models/embedding-001:embedContent?key=' . $api_key;
    $data = [
        'model' => 'embedding-001',
        'content' => ['parts' => [['text' => $text]]]
    ];
    $payload = json_encode($data);
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    $response = curl_exec($ch);
    curl_close($ch);
    $result = json_decode($response, true);
    return $result['embedding']['values'] ?? null;
}

// --- เชื่อมต่อฐานข้อมูล MySQL ---
$host = 'localhost';
$dbname = 'your_database';
$user = 'your_username';
$password = 'your_password';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("ไม่สามารถเชื่อมต่อฐานข้อมูลได้: " . $e->getMessage());
}

// --- ดึงข้อมูลและสร้าง Embeddings ---
$sql_select = "SELECT id, detail FROM your_table WHERE embedding IS NULL"; // ดึงเฉพาะรายการที่ยังไม่มี Embedding
$stmt_select = $pdo->query($sql_select);

while ($row = $stmt_select->fetch(PDO::FETCH_ASSOC)) {
    $id = $row['id'];
    $detail = $row['detail'];
    $embedding = getEmbedding($detail);

    if ($embedding) {
        $embedding_json = json_encode($embedding);
        $sql_update = "UPDATE your_table SET embedding = :embedding WHERE id = :id";
        $stmt_update = $pdo->prepare($sql_update);
        $stmt_update->bindParam(':embedding', $embedding_json);
        $stmt_update->bindParam(':id', $id, PDO::PARAM_INT);

        if ($stmt_update->execute()) {
            echo "อัปเดต Embedding สำหรับ ID: " . $id . " สำเร็จ\n";
        } else {
            echo "ไม่สามารถอัปเดต Embedding สำหรับ ID: " . $id . "\n";
            print_r($stmt_update->errorInfo());
        }
        sleep(1); // ป้องกัน Rate Limiting
    } else {
        echo "ไม่สามารถสร้าง Embedding สำหรับ ID: " . $id . "\n";
    }
}

echo "กระบวนการสร้างและจัดเก็บ Embeddings เสร็จสิ้น\n";

คำแนะนำ

  • ตรวจสอบให้แน่ใจว่าตารางของคุณ (your_table) มีคอลัมน์สำหรับจัดเก็บ Embedding (เช่น embedding เป็น JSON หรือ VECTOR ใน MySQL 9.0+)
  • แทนที่ 'YOUR_GEMINI_API_KEY', ข้อมูลการเชื่อมต่อฐานข้อมูล, และชื่อตารางให้ถูกต้อง

ขั้นตอนที่ 2 ค้นหาบทความที่เกี่ยวข้อง

เมื่อผู้ใช้ถามคำถาม เราจะสร้าง Embedding ของคำถามนั้นและเปรียบเทียบกับ Embeddings ที่จัดเก็บไว้เพื่อหาบทความที่เกี่ยวข้อง

โค้ดตัวอย่าง (PHP)

<?php

// --- ฟังก์ชัน getEmbedding() จากขั้นตอนที่ 1 ---

// --- ฟังก์ชันคำนวณ Cosine Similarity ---
function cosineSimilarity($vecA, $vecB) {
    $dotProduct = 0;
    $normA = 0;
    $normB = 0;
    for ($i = 0; $i < count($vecA); $i++) {
        $dotProduct += $vecA[$i] * $vecB[$i];
        $normA += pow($vecA[$i], 2);
        $normB += pow($vecB[$i], 2);
    }
    if ($normA == 0 || $normB == 0) {
        return 0;
    }
    return $dotProduct / (sqrt($normA) * sqrt($normB));
}

// --- เชื่อมต่อฐานข้อมูล MySQL (เหมือนขั้นตอนที่ 1) ---
$host = 'localhost';
$dbname = 'your_database';
$user = 'your_username';
$password = 'your_password';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("ไม่สามารถเชื่อมต่อฐานข้อมูลได้: " . $e->getMessage());
}

// --- ฟังก์ชันค้นหาบทความที่เกี่ยวข้อง ---
function findRelatedDocuments($question, $pdo, $tableName = 'your_table', $limit = 3) {
    $questionEmbedding = getEmbedding($question);
    if (!$questionEmbedding) {
        return "ไม่สามารถสร้าง Embedding สำหรับคำถามได้";
    }

    $sql_select = "SELECT id, topic, detail, embedding FROM $tableName WHERE embedding IS NOT NULL";
    $stmt_select = $pdo->query($sql_select);
    $results = [];

    while ($row = $stmt_select->fetch(PDO::FETCH_ASSOC)) {
        $documentEmbedding = json_decode($row['embedding'], true);
        if ($documentEmbedding) {
            $similarity = cosineSimilarity($questionEmbedding, $documentEmbedding);
            $results[] = [
                'id' => $row['id'],
                'topic' => $row['topic'],
                'detail' => $row['detail'],
                'similarity' => $similarity
            ];
        }
    }

    usort($results, function($a, $b) {
        return $b['similarity'] <=> $a['similarity'];
    });

    return array_slice($results, 0, $limit);
}

// --- ตัวอย่างการใช้งาน ---
$question = "วิธีติดตั้ง Widget บนเว็บไซต์";
$relatedDocuments = findRelatedDocuments($question, $pdo);

echo "คำถาม: " . $question . "\n\n";
echo "บทความที่เกี่ยวข้อง:\n";
if (is_array($relatedDocuments)) {
    foreach ($relatedDocuments as $doc) {
        echo "ID: " . $doc['id'] . ", หัวข้อ: " . $doc['topic'] . ", ความคล้ายคลึง: " . $doc['similarity'] . "\n";
        echo "เนื้อหาบางส่วน: " . mb_substr($doc['detail'], 0, 200) . "...\n\n";
    }
} else {
    echo $relatedDocuments . "\n";
}

ขั้นตอนที่ 3 ใช้ Gemini API สร้างคำตอบ

นำบทความที่เกี่ยวข้องจากขั้นตอนที่ 2 มาใช้เป็น Context ให้กับ Gemini API เพื่อสร้างคำตอบที่อิงกับข้อมูลของคุณ

โค้ดตัวอย่าง (PHP)

<?php

// --- ฟังก์ชัน getEmbedding(), cosineSimilarity(), findRelatedDocuments() จากขั้นตอนก่อนหน้า ---

// --- ฟังก์ชันสำหรับส่งคำถามและบทความที่เกี่ยวข้องไปยัง Gemini Pro ---
function askGeminiPro($question, $relatedDocuments) {
    $gemini_api_key = 'YOUR_GEMINI_API_KEY';
    $url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=' . $gemini_api_key;

    $context = "อ้างอิงจากข้อมูลต่อไปนี้เพื่อตอบคำถาม: ";
    foreach ($relatedDocuments as $doc) {
        $context .= "\n\nหัวข้อ: " . $doc['topic'] . "\nเนื้อหา: " . mb_substr($doc['detail'], 0, 500) . "..."; // ใช้เนื้อหาบางส่วน
    }
    $prompt = $context . "\n\nคำถาม: " . $question . "\n\nโปรดให้คำตอบที่กระชับและตรงประเด็น";

    $data = [
        'contents' => [
            [
                'parts' => [['text' => $prompt]]
            ]
        ]
    ];
    $payload = json_encode($data);

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    $response = curl_exec($ch);
    curl_close($ch);
    $result = json_decode($response, true);

    return $result['candidates'][0]['content']['parts'][0]['text'] ?? "ไม่สามารถสร้างคำตอบได้";
}

// --- ขั้นตอนการทำงานหลัก ---
$userQuestion = "วิธีติดตั้ง Widget บนเว็บไซต์ทำอย่างไร";
$relevantDocs = findRelatedDocuments($userQuestion, $pdo);

echo "คำถาม: " . $userQuestion . "\n\n";
echo "บทความที่เกี่ยวข้อง:\n";
if (is_array($relevantDocs)) {
    foreach ($relevantDocs as $doc) {
        echo "ID: " . $doc['id'] . ", หัวข้อ: " . $doc['topic'] . ", ความคล้ายคลึง: " . $doc['similarity'] . "\n";
        echo "เนื้อหาบางส่วน: " . mb_substr($doc['detail'], 0, 200) . "...\n\n";
    }

    $answer = askGeminiPro($userQuestion, $relevantDocs);
    echo "\nคำตอบจาก AI:\n" . $answer . "\n";

} else {
    echo $relevantDocs . "\n";
}

การนำไปใช้งาน

  1. รัน Script แรกเพื่อสร้างและจัดเก็บ Embeddings ในฐานข้อมูลของคุณ (ทำเพียงครั้งแรก หรือเมื่อมีการอัปเดตข้อมูล)
  2. เมื่อผู้ใช้ถามคำถาม ให้รัน Script ที่สอง (ส่วนของการค้นหาและตอบคำถาม) เพื่อดึงบทความที่เกี่ยวข้องและใช้ Gemini API สร้างคำตอบ

บทความนี้ นำเสนอตัวอย่างแนวคิดเบื้องต้น ในการสร้างระบบถาม-ตอบอัจฉริยะ โดยใช้ประโยชน์จากพลังของ Gemini API (ฟรี) ในการทำความเข้าใจภาษา และ Embeddings ในการค้นหาข้อมูลที่เกี่ยวข้องจากฐานข้อมูลของคุณ เพื่อให้ได้คำตอบที่อิงกับข้อมูลของคุณเอง

โปรดทราบว่าโค้ดและขั้นตอนที่นำเสนอเป็นเพียงตัวอย่างพื้นฐานเพื่อแสดงให้เห็นหลักการทำงานเท่านั้น

หากต้องการนำไปใช้งานจริง ควรมีอะไรต้องเพิ่มเติม หรือต้องทำอะไร ใช้เครื่องมืออะไรบ้าง

การนำระบบถาม-ตอบอัจฉริยะนี้ไปใช้งานจริงในสภาพแวดล้อม Production จำเป็นต้องมีการพัฒนาและพิจารณาในหลายด้านเพิ่มเติม เพื่อให้ระบบมีความเสถียร, ประสิทธิภาพสูง, และใช้งานได้ง่าย

สิ่งที่ต้องเพิ่มเติม/พัฒนา

  1. การจัดการฐานข้อมูล Embeddings ที่มีประสิทธิภาพ

    • Vector Database พิจารณาใช้ Vector Database โดยเฉพาะ เช่น Pinecone, Weaviate, ChromaDB เพื่อการจัดเก็บและค้นหา Embeddings ที่รวดเร็วและมีประสิทธิภาพสูงกว่าการใช้ MySQL เพียงอย่างเดียว (โดยเฉพาะกับข้อมูลขนาดใหญ่)
    • Indexing หากยังคงใช้ MySQL ควรมีการพิจารณาการสร้าง Index ที่เหมาะสมเพื่อเพิ่มประสิทธิภาพในการค้นหา
  2. การปรับปรุงประสิทธิภาพการค้นหา

    • Algorithm การค้นหา Nearest Neighbors ใน Vector Database จะมี Algorithm ที่ optimized สำหรับการค้นหา Nearest Neighbors (ANN) ซึ่งเร็วกว่าการวนลูปคำนวณในตัวอย่าง
    • การกรอง (Filtering) หากข้อมูลมี Metadata (เช่น หมวดหมู่, วันที่) ควรมีกลไกในการกรองผลการค้นหา Embeddings
  3. การจัดการ Context และ Prompt ที่ซับซ้อน

    • การเลือกส่วนของเนื้อหาที่เกี่ยวข้องที่สุด หากบทความที่เกี่ยวข้องมีขนาดยาว อาจต้องมีกลไกในการเลือกเฉพาะส่วนที่เกี่ยวข้องกับคำถามมากที่สุดเพื่อใส่ใน Context ของ Prompt
    • การจัดการจำนวน Token ระมัดระวังเรื่องจำนวน Token สูงสุดที่ LLM รองรับ อาจต้องมีการสรุปเนื้อหาก่อนส่ง หรือใช้เทคนิคอื่นๆ ในการจัดการ Context
    • การออกแบบ Prompt ที่มีประสิทธิภาพ ปรับปรุง Prompt ให้ LLM เข้าใจบริบทและให้คำตอบในรูปแบบที่ต้องการ
  4. ระบบ User Interface (UI) และ User Experience (UX)

    • สร้าง UI ที่ใช้งานง่ายสำหรับผู้ใช้ในการป้อนคำถามและดูคำตอบ
    • พิจารณาการแสดงแหล่งที่มาของข้อมูลที่ใช้ในการตอบคำถาม
  5. การจัดการ Error และ Logging

    • มีระบบจัดการ Error ที่ดี เพื่อให้ระบบทำงานได้อย่างราบรื่นแม้เกิดข้อผิดพลาด
    • มีระบบ Logging เพื่อติดตามการทำงานของระบบและวิเคราะห์ปัญหา
  6. ความปลอดภัย

    • ตรวจสอบและป้องกันการโจมตีต่างๆ ที่อาจเกิดขึ้นผ่าน Input ของผู้ใช้

เครื่องมือและเทคโนโลยีที่ควรพิจารณา

  • Vector Databases Pinecone, Weaviate, ChromaDB, Milvus
  • Framework สำหรับ LLM LangChain, LlamaIndex (ช่วยในการจัดการ Data Loading, Indexing, Retrieval, และ Generation)
  • Web Framework (สำหรับ UI) เช่น Flask (Python), Laravel (PHP), React, Vue.js

สรุป

ตัวอย่างที่เราได้ทำไปเป็นเพียงจุดเริ่มต้นที่ดีในการทำความเข้าใจหลักการทำงานของการใช้ AI ตอบคำถามจากข้อมูลของเรา หากต้องการนำไปใช้งานจริง จะต้องมีการพัฒนาในหลายส่วนเพิ่มเติม โดยเฉพาะในเรื่องของประสิทธิภาพการจัดการข้อมูล, ความแม่นยำในการค้นหา, และประสบการณ์ผู้ใช้งาน