แผนการเรียนรู้
/

การประยุกต์ใช้
Agent AI ในงานวิทยาการข้อมูล

Data Preprocessing • Automated Workflow • Chatbot for Data Query

ผลลัพธ์การเรียนรู้

1
ใช้ Agent AI เพื่อช่วยเตรียมข้อมูลอัตโนมัติได้
2
ออกแบบ chatbot สำหรับสอบถามข้อมูลได้
3
รวม Agent AI เข้ากับ pipeline วิทยาการข้อมูลได้
4
ประเมินประสิทธิภาพของ Agent ที่สร้างขึ้นได้
สัปดาห์ที่ 11

สัปดาห์ที่ 11: การประยุกต์ใช้ Agent AI ในโครงงานวิทยาการข้อมูล

  • แนวคิดของ Agentic Workflow ในงาน Data Science
  • สถาปัตยกรรม Retrieval-Augmented Generation (RAG)
  • การจัดการหน่วยความจำระยะยาวด้วย Vector Databases (pgvector)
  • การออกแบบบทบาทเอเจนต์สำหรับการจัดการเอกสาร (Document Manager)
  • ภาพรวมโปรเจกต์: AI Chatbot บน Django Framework

หัวใจของเอเจนต์: ไม่ใช่แค่ตอบ แต่คือการลงมือทำ

เอเจนต์ในโครงงานวิทยาการข้อมูลแตกต่างจาก Chatbot ทั่วไป :

  • Orchestration: สามารถวางแผนงานที่มีหลายขั้นตอนเพื่อบรรลุเป้าหมายที่ซับซ้อน .
  • Tool Use: เข้าถึงเครื่องมือภายนอก เช่น การค้นหาในฐานข้อมูลหรือประมวลผลไฟล์ .
  • Reasoning: ใช้กระบวนการคิดแบบ ReAct (Reason + Action) เพื่อประเมินผลลัพธ์ในแต่ละก้าว .

สถาปัตยกรรม RAG: พื้นฐานของ AI ที่อิงข้อมูลจริง

RAG (Retrieval-Augmented Generation) คือการดึงข้อมูลจากแหล่งภายนอกมาประกอบการตอบของ LLM

  • Retrieval: ค้นหาเนื้อหาที่เกี่ยวข้องที่สุดจากเอกสารที่ Admin อัปโหลด
  • Augmentation: นำเนื้อหานั้นไปใส่ไว้ใน Context ของ Prompt
  • Generation: ให้ LLM สร้างคำตอบโดยอ้างอิงจากข้อมูลที่ได้รับ

RAG Workflow

Ingest & Chunk
Embed into Vector DB
Semantic Search & Generate

Vector Embeddings: การค้นหาด้วยความหมาย

# การแปลงข้อความเป็นตัวเลขหลายมิติ

"Amazon" → [0.011, -0.023, 0.026, ...]

# การวัดความใกล้เคียง (Semantic Similarity)

distance(Amazon, Brazil) < distance(Amazon, Food)

เราใช้ Embeddings เพื่อให้ AI เข้าใจบริบท แม้ผู้ใช้จะใช้คำที่ต่างจากในเอกสาร (เช่น ถาม "Wide feet" แต่ระบบพบคำว่า "Extra wide")

pgvector: หน่วยความจำระยะยาวของเอเจนต์

ทำไมต้องใช้ pgvector ใน PostgreSQL?

  • Hybrid Search: รวมความสามารถของ Relational DB และ Vector Search ในที่เดียว
  • Django Integration: ใช้งานผ่าน Django ORM ได้โดยตรงด้วย VectorField
  • Scalability: รองรับการทำ Indexing แบบ HNSW เพื่อค้นหาข้อมูลมหาศาลได้อย่างรวดเร็ว

การออกแบบบทบาท (Agent Persona)

ในโปรเจกต์นี้ เอเจนต์ของเราจะสวมบทบาทเป็น "Expert Document Assistant"

Identity:

ชื่อ: doc_specialist_agent, ความสามารถ: วิเคราะห์และสรุปเนื้อหาจากเอกสารภายในองค์กร

Instructions:

"คุณคือนักจัดการความรู้ หน้าที่ของคุณคือสืบค้นข้อมูลจากเอกสารที่กำหนด และตอบคำถามอย่างถูกต้อง หากไม่มีข้อมูลให้ตอบว่าไม่ทราบ"

Django: รากฐานของระบบ Web Agent

Admin Roles

ใช้ระบบ Auth และ Admin ของ Django เพื่อจัดการสิทธิ์การอัปโหลดไฟล์ (PDF/Text)

RAG Services

เขียน Service Layer เพื่อเชื่อมต่อกับ Ollama/Gemini และ pgvector เพื่อทำ RAG

Django ช่วยจัดการ User Session และการจัดเก็บข้อมูลที่มีโครงสร้างได้อย่างปลอดภัย

การเลือก "สมอง" ของเอเจนต์ (Inference)

Ollama (Local)

  • ความเป็นส่วนตัวสูง ข้อมูลไม่ส่งออกภายนอก
  • ไม่มีค่าใช้จ่าย API
  • รันผ่าน Docker ในเครื่องได้ง่าย

Gemini (Cloud)

  • ความฉลาดและการให้เหตุผลสูง (PhD-level reasoning)
  • รองรับ Context Window ขนาดใหญ่มาก (1M+ tokens)
  • รองรับการ Input แบบมัลติโมดอล (ภาพ/เสียง)

การทำงานร่วมกันระหว่างเอเจนต์ (Multi-Agent)

ในโปรเจกต์ระดับองค์กร เราสามารถแบ่งงานให้หลายเอเจนต์ผ่านโปรโตคอล Agent2Agent (A2A)

Summarizer

สรุปเอกสารที่ Admin เพิ่งอัปโหลด

Researcher

สืบค้นข้อมูลเชิงลึกจากฐานข้อมูล Vector

Critic

ตรวจสอบความถูกต้องและ Bias ของคำตอบ

เป้าหมายของภาคปฏิบัติ (Lab Project)

"สร้างระบบจัดการเอกสารอัจฉริยะที่สามารถแชทโต้ตอบได้"

  • ตั้งค่า Django Project พร้อมเชื่อมต่อ PostgreSQL + pgvector
  • สร้างระบบอัปโหลดเอกสารสำหรับ Admin และทำ Embedding อัตโนมัติ
  • พัฒนา UI สำหรับ User เพื่อแชทโต้ตอบกับเอกสารผ่าน RAG Pipeline
  • ประยุกต์ใช้ **Ollama** หรือ **Gemini** เป็นหน่วยประมวลผลเอเจนต์

"พร้อมแล้วไปเริ่มต้นขั้นตอนแรกในสไลด์ถัดไป!"

การนำเข้าข้อมูลและการแบ่งส่วน (Chunking)

เพื่อให้ AI สามารถประมวลผลเอกสารขนาดใหญ่ได้ เราต้องแบ่งเนื้อหาเป็นส่วนย่อย:

  • Fixed-size Chunking: แบ่งตามจำนวนตัวอักษรหรือ Token ที่แน่นอน.
  • Semantic Chunking: แบ่งตามหัวข้อหรือความหมายเพื่อให้บริบทไม่ขาดหาย.
  • Overlap: การให้ส่วนท้ายของ Chunk แรกซ้อนทับกับส่วนต้นของ Chunk ถัดไป เพื่อรักษาความต่อเนื่องของข้อมูล

การเลือกโมเดล Embedding และมิติของข้อมูล

# ตัวอย่างการระบุมิติใน Django Model

embedding = VectorField(dimensions=768)

มิติ (Dimensions) ต้องตรงกับโมเดลที่ใช้เสมอ

  • Ollama (nomic-embed-text): 768 มิติ
  • OpenAI (text-embedding-3-small): 1536 มิติ
  • Google Vertex AI: รองรับได้หลายขนาดตามโมเดลที่เลือก

เพิ่มความเร็วด้วย pgvector Index (HNSW)

Hierarchical Navigable Small Worlds (HNSW):

  • ลด Latency ในการค้นหาแบบ Approximate Nearest Neighbor (ANN)
  • ประสิทธิภาพสูงกว่า IVFFlat เมื่อต้องการความแม่นยำ (Recall) ในระดับสูง
  • รองรับการรันแบบขนาน (Parallel build) ใน pgvector เวอร์ชันล่าสุด

*ช่วยให้เอเจนต์สามารถสืบค้นเอกสารนับล้านได้ในเวลาไม่กี่มิลลิวินาที *

โครงสร้างฐานข้อมูลสำหรับ RAG ใน Django

class Document(models.Model):

  title = models.CharField(max_length=255)

  content = models.TextField()

  embedding = VectorField(dimensions=768) # สำหรับ pgvector

  uploaded_by = models.ForeignKey(User, on_delete=models.CASCADE)

  created_at = models.DateTimeField(auto_now_add=True)


class Message(models.Model):

  conversation = models.ForeignKey(Conversation, ...)

  user_prompt = models.TextField()

  ai_response = models.TextField()

  embedding = VectorField(dimensions=768) # สำหรับค้นหาประวัติ

การออกแบบ Prompt สำหรับ Context Injection

"ในฐานะผู้เชี่ยวชาญ จงตอบคำถามโดยใช้บริบท (Context) ที่ให้มาเท่านั้น หากไม่มีข้อมูลในบริบทให้ตอบว่า 'ขออภัย ฉันไม่พบข้อมูลนี้ในเอกสาร' โดยไม่ต้องพยายามเดา"

Context Structure:

Context: {retrieved_chunks_from_db}
User Question: {user_input}

การจัดการหน่วยความจำ (Memory Pruning)

เมื่อประวัติการสนทนายาวเกินขีดจำกัดของโมเดล (Context Window):

  • Summarization: ให้ AI สรุปประวัติเก่าก่อนส่งต่อ
  • Sliding Window: ส่งเฉพาะข้อความ 5-10 ล่าสุด.
  • Token Pruning: ตัดข้อความเก่าออกโดยอัตโนมัติเมื่อ Token เกิน 50% ของขีดจำกัด
if current_tokens > threshold:
  keep_count = int(len(messages) * 0.2)
  return messages[-keep_count:] # Pruning!

กระบวนการฝั่งผู้ดูแลระบบ (Admin Flow)

1

Admin อัปโหลดไฟล์ (PDF/Text) ผ่าน Django Admin Interface.

2

ระบบรันฟังก์ชัน `PyMuPDFLoader` เพื่อสกัดข้อความออกจากไฟล์

3

ข้อความถูกส่งไปยัง Embedding Service เพื่อแปลงเป็น Vector และบันทึกลงฐานข้อมูล

กระบวนการฝั่งผู้ใช้ (User Chat Flow)

  1. ผู้ใช้ส่งคำถาม -> ระบบแปลงคำถามเป็น Embedding
  2. Cosine Similarity: ค้นหาเนื้อหาในฐานข้อมูลที่ "ใกล้เคียง" กับคำถามที่สุด
  3. ระบบดึง Chunk ที่เกี่ยวข้องที่สุด (เช่น Top 3-5) มาเป็น Context
  4. LLM รับ Context + คำถาม แล้วสร้างคำตอบกลับมายังหน้าจอแชท

Agentic RAG: การคิดก่อนสืบค้น

Condense Question Strategy:

เอเจนต์จะไม่ค้นหาทันที แต่จะ "เรียบเรียงคำถามใหม่" โดยพิจารณาจากประวัติการแชท (เช่น ถ้าผู้ใช้ถาม 'แล้วอันนี้ล่ะ?' เอเจนต์จะเปลี่ยนเป็น 'แล้วสวัสดิการพนักงานล่ะ?')

Generate a standalone question from chat history and user input.

การประเมินประสิทธิภาพเอเจนต์

เราวัดความสำเร็จของระบบแชทอัจฉริยะผ่านเกณฑ์มาตรฐาน

  • Retrieval Recall: เนื้อหาที่ดึงมาครอบคลุมคำตอบหรือไม่?
  • Groundedness: คำตอบอ้างอิงจากเอกสารจริงหรือ AI มโนขึ้นเอง?
  • Answer Relevance: คำตอบตรงประเด็นที่ผู้ใช้ถามหรือไม่?
  • Latency: ระยะเวลาตั้งแต่ถามจนถึงเริ่มตอบ (Streaming ช่วยให้เร็วขึ้น)

"สไลด์ถัดไป: เริ่มต้นภาคปฏิบัติสร้างแชทบอทตัวแรกของคุณ!"

Lab: RAG Chatbot Full-Stack Project

เป้าหมาย: สร้างระบบแชทอัจฉริยะที่ Admin สามารถอัปโหลด PDF และตั้งค่าโมเดลได้:

  • Backend: Django Ninja + PostgreSQL (pgvector) + Ollama
  • Frontend: Vite-React + Tailwind CSS
  • RAG Pipeline: PyMuPDF (Loader) + Ollama (Embedding & Inference)
  • Admin Control: อัปโหลดเอกสาร, เลือกโมเดล, และปรับแต่ง System Prompt

Step 1: Setting up Services with Docker

ใช้ docker-compose.yml เพื่อติดตั้ง Ollama และ Database ที่พร้อมใช้งาน pgvector

services:

  db:

    image: ankane/pgvector:latest # Postgres พร้อม pgvector

    environment: [POSTGRES_PASSWORD: 'password']

  ollama:

    image: ollama/ollama

    volumes: ['ollama_data:/root/.ollama']

$ docker compose up -d
$ docker exec ollama ollama pull llama3 scb10x/llama3.1-typhoon2-8b-instruct # โหลดโมเดลหลัก
$ docker exec ollama ollama pull nomic-embed-text # โหลด Embedding

Step 2: Django & pgvector Integration

ตั้งค่า settings.py เพื่อเชื่อมต่อฐานข้อมูลและเปิดใช้งาน Extension

DATABASES = {

  'default': {

    'ENGINE': 'django.db.backends.postgresql',

    'NAME': 'vector_db', ...

  }

}

สร้าง Migration พิเศษเพื่อเปิด Extension:

from pgvector.django import VectorExtension
operations = [VectorExtension()]

Step 3: Creating Models

# models.py

class ChatConfig(models.Model): # สำหรับ Admin ตั้งค่า

  default_model = models.CharField(max_length=100, default="llama3")

  system_prompt = models.TextField()


class Document(models.Model):

  file = models.FileField(upload_to='pdfs/')

  content = models.TextField()

  embedding = VectorField(dimensions=768) # nomic-embed มิติ=768

Step 4: PDF Loader & Chunking

ใช้ PyMuPDFLoader เพื่อสกัดข้อความจากไฟล์ที่ Admin อัปโหลด

from langchain_community.document_loaders import PyMuPDFLoader

def process_pdf(file_path):

  loader = PyMuPDFLoader(file_path)

  documents = loader.load()

  full_text = "\n".join([doc.page_content for doc in documents])

  return full_text

Personal Learning: ลองถาม AI ว่า "How to split text into chunks with 500 characters overlap in Python?" เพื่อปรับปรุงความแม่นยำ

Step 5: Generating Embeddings with Ollama

แปลงข้อความเป็น Vector และบันทึกลงฐานข้อมูล

import ollama

def save_vector(text, doc_instance):

  response = ollama.embed(model='nomic-embed-text', input=text)

  doc_instance.embedding = response['embeddings']

  doc_instance.save()

Admin Feature: ระบบจะเรียกใช้ฟังก์ชันนี้โดยอัตโนมัติเมื่อ Admin อัปโหลดไฟล์ผ่านหน้าจัดการ

Step 6: Semantic Retrieval

ใช้ CosineDistance ค้นหาเนื้อหาที่ใกล้เคียงกับคำถามผู้ใช้ที่สุด

from pgvector.django import CosineDistance

def get_context(query_text):

  query_vec = ollama.embed(model='nomic-embed-text', input=query_text)['embeddings']

  similar_docs = Document.objects.annotate(

    distance=CosineDistance('embedding', query_vec)

  ).order_by('distance')[:3] # ดึง 3 ชิ้นที่ใกล้ที่สุด

  return "\n".join([d.content for d in similar_docs])

Step 7: RAG Chat API

รวม Context เข้ากับ Prompt และส่งให้ LLM ตามที่ Admin กำหนด

@router.post("/chat")

def chat_endpoint(request, user_query: str):

  config = ChatConfig.objects.first()

  context = get_context(user_query)

  full_prompt = f"{config.system_prompt}\nContext: {context}\nQuestion: {user_query}"


  response = ollama.chat(model=config.default_model,

    messages=[{'role': 'user', 'content': full_prompt}])

  return {"answer": response['message']['content']}

Step 8: Frontend with Vite-React

สร้างโปรเจกต์ React และติดตั้งเครื่องมือจัดการแชท:

$ npm create vite@latest frontend -- --template react
$ cd frontend
$ npm install axios lucide-react
$ npm install tailwindcss @tailwindcss/vite
# add tailwindcss() to vite.config.js

โครงสร้าง UI:

  • AdminView: ฟอร์มอัปโหลด PDF และฟิลด์แก้ไข ChatConfig.
  • ChatView: หน้าต่างแชทสำหรับผู้ใช้ทั่วไป พร้อมฟังก์ชันแสดงผลแบบ Markdown.

Step 9: Chat Interaction Logic

const handleSend = async () => {

  const res = await axios.post('/api/chat', { user_query: input });

  setMessages([...messages, { role: 'user', text: input }, { role: 'ai', text: res.data.answer }]);

};

Tip: ใช้ StreamingHttpResponse จากฝั่ง Django เพื่อให้ Chatbot แสดงผลทีละคำเหมือน ChatGPT

Step 10: Admin Settings Interface

อนุญาตให้ Admin เปลี่ยนโมเดลและ Tokenizer ผ่าน UI:

Model Selection:

Dropdown สำหรับเลือก llama3, gemma, หรือ mistral ที่ติดตั้งใน Ollama.

Prompt Builder:

Textarea สำหรับแก้ไข Persona ของ AI (เช่น "ตอบเฉพาะภาษาไทยเท่านั้น")

Step 11: Production Deployment

สร้างสภาพแวดล้อมจริงโดยการรวม Frontend และ Backend

  • Build Frontend: npm run build แล้วให้ Django Serve ไฟล์ Static.
  • Gunicorn: ใช้ Gunicorn เป็น Web Server สำหรับ Django ใน Container.
  • Reverse Proxy: ใช้ Nginx เพื่อจัดการ Traffic และ SSL.
  • OR
  • setup CI to deploy to cloud https://render.com

*คำเตือน: อย่าลืมตั้งค่า ALLOWED_HOSTS และ DEBUG=False ใน Production.*

บทสรุปและสิ่งที่ต้องส่ง

  • GitHub: อัปโหลดโปรเจกต์ที่มี Docker Compose สมบูรณ์.
  • Demo: แสดงการอัปโหลด PDF และการแชทที่อ้างอิงข้อมูลในไฟล์นั้น.
  • Reflection: บันทึกว่าการเปลี่ยนโมเดล ส่งผลต่อความแม่นยำอย่างไร.

"ยินดีด้วย! คุณได้สร้างระบบ RAG Full-stack ที่ใช้งานได้จริงแล้ว"