|
|
# สร้างผู้ช่วยแชทด้วย AI
|
|
|
|
|
|
จำได้ไหมในซีรีส์ Star Trek ที่ลูกเรือจะพูดคุยอย่างไม่เป็นทางการกับคอมพิวเตอร์ของยาน เรียกมันด้วยคำถามซับซ้อนและได้รับคำตอบที่ลึกซึ้ง? สิ่งที่ดูเหมือนนิยายวิทยาศาสตร์บริสุทธิ์ในทศวรรษ 1960 วันนี้คุณสามารถสร้างได้ด้วยเทคโนโลยีเว็บที่คุณรู้จักอยู่แล้ว
|
|
|
|
|
|
ในบทเรียนนี้ เราจะสร้างผู้ช่วยแชท AI โดยใช้ HTML, CSS, JavaScript และการเชื่อมต่อ backend บางส่วน คุณจะได้ค้นพบว่าทักษะเดียวกันที่คุณเรียนรู้มาสามารถเชื่อมต่อกับบริการ AI ที่ทรงพลังซึ่งเข้าใจบริบทและสร้างคำตอบที่มีความหมายได้อย่างไร
|
|
|
|
|
|
คิดว่า AI เป็นเหมือนการเข้าถึงห้องสมุดขนาดใหญ่ที่ไม่เพียงแต่หาข้อมูลได้ แต่ยังสังเคราะห์ข้อมูลเหล่านั้นเป็นคำตอบที่สอดคล้องและเหมาะสมกับคำถามเฉพาะของคุณ แทนที่จะค้นหาผ่านหลายพันหน้า คุณจะได้รับคำตอบโดยตรงและมีบริบท
|
|
|
|
|
|
การผสานเกิดขึ้นผ่านเทคโนโลยีเว็บที่คุ้นเคยทำงานร่วมกัน HTML สร้างอินเทอร์เฟซแชท CSS จัดการการออกแบบเชิงภาพ JavaScript ควบคุมปฏิสัมพันธ์ของผู้ใช้ และ API ฝั่ง backend เชื่อมโยงทุกอย่างเข้ากับบริการ AI มันคล้ายกับวิธีที่วงดนตรีออร์เคสตราต่างๆ ทำงานร่วมกันเพื่อสร้างบทประพันธ์
|
|
|
|
|
|
เรากำลังสร้างสะพานเชื่อมระหว่างการสื่อสารตามธรรมชาติของมนุษย์กับการประมวลผลของเครื่องจักร คุณจะได้เรียนรู้ทั้งการนำบริการ AI ไปใช้งานทางเทคนิคและรูปแบบการออกแบบที่ทำให้ปฏิสัมพันธ์รู้สึกเป็นธรรมชาติ
|
|
|
|
|
|
จนถึงตอนจบของบทเรียนนี้ การผสาน AI จะไม่รู้สึกเหมือนกระบวนการลึกลับอีกต่อไป แต่เป็น API อีกตัวที่คุณทำงานด้วยได้ คุณจะเข้าใจรูปแบบพื้นฐานที่เป็นหัวใจของแอปพลิเคชันอย่าง ChatGPT และ Claude โดยใช้หลักการพัฒนาเว็บเดียวกับที่คุณได้เรียนรู้
|
|
|
|
|
|
## ⚡ สิ่งที่คุณทำได้ในอีก 5 นาทีข้างหน้า
|
|
|
|
|
|
**เส้นทางเริ่มต้นอย่างรวดเร็วสำหรับนักพัฒนาที่เร่งรีบ**
|
|
|
|
|
|
```mermaid
|
|
|
flowchart LR
|
|
|
A[⚡ 5 นาที] --> B[รับโทเค็น GitHub]
|
|
|
B --> C[ทดสอบสนามเด็กเล่น AI]
|
|
|
C --> D[คัดลอกโค้ด Python]
|
|
|
D --> E[ดูการตอบกลับ AI]
|
|
|
```
|
|
|
- **นาทีที่ 1**: เยี่ยมชม [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) และสร้างโทเค็นเข้าถึงส่วนตัว
|
|
|
- **นาทีที่ 2**: ทดสอบปฏิสัมพันธ์กับ AI โดยตรงในอินเทอร์เฟซ playground
|
|
|
- **นาทีที่ 3**: คลิกแท็บ "Code" และคัดลอกโค้ดตัวอย่าง Python
|
|
|
- **นาทีที่ 4**: รันโค้ดในเครื่องของคุณพร้อมโทเค็น: `GITHUB_TOKEN=your_token python test.py`
|
|
|
- **นาทีที่ 5**: ชมการตอบสนอง AI ครั้งแรกที่สร้างจากโค้ดของคุณเอง
|
|
|
|
|
|
**โค้ดทดสอบด่วน**:
|
|
|
```python
|
|
|
import os
|
|
|
from openai import OpenAI
|
|
|
|
|
|
client = OpenAI(
|
|
|
base_url="https://models.github.ai/inference",
|
|
|
api_key="your_token_here"
|
|
|
)
|
|
|
|
|
|
response = client.chat.completions.create(
|
|
|
messages=[{"role": "user", "content": "Hello AI!"}],
|
|
|
model="openai/gpt-4o-mini"
|
|
|
)
|
|
|
|
|
|
print(response.choices[0].message.content)
|
|
|
```
|
|
|
|
|
|
**ทำไมถึงสำคัญ**: ใน 5 นาที คุณจะได้สัมผัสกับเวทมนตร์ของการปฏิสัมพันธ์ AI ผ่านโปรแกรม ซึ่งเป็นบล็อกพื้นฐานที่ขับเคลื่อนแอป AI ทุกตัวที่คุณใช้
|
|
|
|
|
|
นี่คือลักษณะโปรเจกต์สำเร็จรูปของคุณ:
|
|
|
|
|
|

|
|
|
|
|
|
## 🗺️ การเดินทางเรียนรู้ของคุณผ่านการพัฒนาแอป AI
|
|
|
|
|
|
```mermaid
|
|
|
journey
|
|
|
title จากการพัฒนาเว็บสู่การผสาน AI
|
|
|
section การเข้าใจพื้นฐาน AI
|
|
|
ค้นพบแนวคิด AI สร้างสรรค์: 4: You
|
|
|
สำรวจแพลตฟอร์ม GitHub Models: 6: You
|
|
|
เชี่ยวชาญพารามิเตอร์และคำสั่ง AI: 8: You
|
|
|
section การผสานแบ็คเอนด์
|
|
|
สร้างเซิร์ฟเวอร์ API ด้วย Python: 5: You
|
|
|
นำฟังก์ชัน AI มาใช้งาน: 7: You
|
|
|
จัดการการทำงานแบบอะซิงโครนัส: 8: You
|
|
|
section การพัฒนาหน้าบ้าน
|
|
|
สร้างอินเทอร์เฟซแชทสมัยใหม่: 6: You
|
|
|
เชี่ยวชาญการโต้ตอบเรียลไทม์: 8: You
|
|
|
สร้างประสบการณ์ผู้ใช้ตอบสนองดี: 9: You
|
|
|
section การประยุกต์ใช้ระดับมืออาชีพ
|
|
|
นำระบบ AI สมบูรณ์ออกใช้งาน: 7: You
|
|
|
ปรับแต่งรูปแบบประสิทธิภาพ: 8: You
|
|
|
สร้างแอปพร้อมใช้ในผลิตจริง: 9: You
|
|
|
```
|
|
|
**ปลายทางการเดินทางของคุณ**: สิ้นสุดบทเรียนนี้ คุณจะได้สร้างแอป AI ที่สมบูรณ์โดยใช้เทคโนโลยีและรูปแบบเดียวกับที่ใช้ในผู้ช่วย AI สมัยใหม่อย่าง ChatGPT, Claude และ Google Bard
|
|
|
|
|
|
## ทำความเข้าใจ AI: จากความลึกลับสู่ความชำนาญ
|
|
|
|
|
|
ก่อนที่จะลงมือเขียนโค้ด มาทำความเข้าใจว่ากำลังทำอะไรอยู่ หากคุณเคยใช้ API มาก่อน คุณจะรู้รูปแบบพื้นฐาน: ส่งคำขอ รับคำตอบ
|
|
|
|
|
|
API AI ก็ใช้โครงสร้างคล้ายกัน แต่แทนที่จะดึงข้อมูลเก็บไว้ล่วงหน้าจากฐานข้อมูล จะสร้างคำตอบใหม่ตามรูปแบบที่เรียนรู้จากข้อความจำนวนมหาศาล คิดเหมือนกับความแตกต่างระหว่างระบบห้องสมุดกับบรรณารักษ์ที่มีความรู้ซึ่งสังเคราะห์ข้อมูลจากแหล่งต่าง ๆ
|
|
|
|
|
|
### "Generative AI" คืออะไร?
|
|
|
|
|
|
ลองพิจารณาวิธีที่หินโรเซตตาอนุญาตให้นักวิชาการเข้าใจอักษรอียิปต์โดยหารูปแบบระหว่างภาษาที่รู้จักและไม่รู้จัก โมเดล AI ทำงานในลักษณะเดียวกัน — พวกมันหารูปแบบในข้อมูลข้อความปริมาณมหาศาลเพื่อเข้าใจการทำงานของภาษา จากนั้นใช้รูปแบบเหล่านั้นสร้างคำตอบที่เหมาะสมกับคำถามใหม่
|
|
|
|
|
|
**ขออธิบายง่าย ๆ ด้วยการเปรียบเทียบ:**
|
|
|
- **ฐานข้อมูลแบบดั้งเดิม**: เหมือนขอใบสูติบัตรของคุณ – ได้เอกสารเดิมทุกครั้ง
|
|
|
- **เครื่องมือค้นหา**: เหมือนถามบรรณารักษ์หาหนังสือเรื่องแมว – เขาจะแสดงสิ่งที่มีให้ดู
|
|
|
- **Generative AI**: เหมือนถามเพื่อนที่รู้เรื่องแมวอย่างดี – เขาจะเล่าสิ่งน่าสนใจด้วยคำพูดของตัวเอง เหมาะกับสิ่งที่คุณอยากรู้
|
|
|
|
|
|
```mermaid
|
|
|
graph LR
|
|
|
A[คำถามของคุณ] --> B[โมเดล AI]
|
|
|
B --> C[การจดจำรูปแบบ]
|
|
|
C --> D[การสร้างเนื้อหา]
|
|
|
D --> E[การตอบสนองตามบริบท]
|
|
|
|
|
|
F[ข้อมูลฝึกอบรม<br/>หนังสือ, บทความ, เว็บ] --> B
|
|
|
```
|
|
|
### วิธีที่โมเดล AI เรียนรู้ (เวอร์ชันง่าย)
|
|
|
|
|
|
โมเดล AI เรียนรู้จากการถูกแสดงชุดข้อมูลใหญ่มากซึ่งมีข้อความจากหนังสือ, บทความ และการสนทนา ผ่านกระบวนการนี้ โมเดลจะจดจำรูปแบบเรื่อง:
|
|
|
- การจัดโครงสร้างความคิดในข้อความเขียน
|
|
|
- คำที่ปรากฏขึ้นบ่อยร่วมกัน
|
|
|
- วิธีไหลของการสนทนาโดยทั่วไป
|
|
|
- ความแตกต่างในบริบทระหว่างการสื่อสารเป็นทางการกับไม่เป็นทางการ
|
|
|
|
|
|
**คล้ายกับโบราณคดีที่ถอดรหัสภาษาโบราณ**: พวกเขาวิเคราะห์ตัวอย่างนับพันเพื่อเข้าใจไวยากรณ์ คำศัพท์ และบริบททางวัฒนธรรม จนสามารถตีความข้อความใหม่ได้ด้วยรูปแบบที่เรียนรู้
|
|
|
|
|
|
### ทำไมต้อง GitHub Models?
|
|
|
|
|
|
เราใช้ GitHub Models ด้วยเหตุผลที่ค่อนข้างใช้งานจริง — มันให้เราเข้าถึง AI ระดับองค์กรโดยไม่ต้องตั้งโครงสร้างพื้นฐาน AI เอง (เชื่อฉันเถอะ คุณไม่อยากทำตอนนี้!) คิดเหมือนใช้ API พยากรณ์อากาศแทนการตั้งสถานีอากาศเอง
|
|
|
|
|
|
มันคือ "AI-as-a-Service" และข้อดีที่สุด? เริ่มฟรี ทำให้คุณทดลองได้โดยไม่ต้องกังวลเรื่องค่าใช้จ่ายสูง
|
|
|
|
|
|
```mermaid
|
|
|
graph LR
|
|
|
A[อินเทอร์เฟซแชทฝั่งหน้า] --> B[API ฝั่งหลังของคุณ]
|
|
|
B --> C[API โมเดล GitHub]
|
|
|
C --> D[การประมวลผลโมเดล AI]
|
|
|
D --> C
|
|
|
C --> B
|
|
|
B --> A
|
|
|
```
|
|
|
เราจะใช้ GitHub Models สำหรับการเชื่อมต่อ backend ซึ่งให้การเข้าถึง AI ระดับมืออาชีพผ่านอินเทอร์เฟซที่เป็นมิตรกับนักพัฒนา [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground) เป็นสภาพแวดล้อมทดสอบที่ให้คุณทดลองกับโมเดล AI ต่างๆ และเข้าใจความสามารถก่อนนำไปใช้กับโค้ด
|
|
|
|
|
|
## 🧠 ระบบนิเวศการพัฒนาแอป AI
|
|
|
|
|
|
```mermaid
|
|
|
mindmap
|
|
|
root((การพัฒนา AI))
|
|
|
Understanding AI
|
|
|
Generative Models
|
|
|
การจดจำรูปแบบ
|
|
|
การสร้างเนื้อหา
|
|
|
การเข้าใจบริบท
|
|
|
การสังเคราะห์การตอบสนอง
|
|
|
AI Parameters
|
|
|
การควบคุมอุณหภูมิ
|
|
|
ขีดจำกัดโทเค็น
|
|
|
การกรอง Top-p
|
|
|
คำสั่งระบบ
|
|
|
Backend Architecture
|
|
|
API Integration
|
|
|
โมเดล GitHub
|
|
|
การตรวจสอบสิทธิ์
|
|
|
การจัดการคำขอ
|
|
|
การจัดการข้อผิดพลาด
|
|
|
Python Infrastructure
|
|
|
โครงสร้าง FastAPI
|
|
|
การทำงานแบบอะซิงโครนัส
|
|
|
ความปลอดภัยของสภาพแวดล้อม
|
|
|
การกำหนดค่า CORS
|
|
|
Frontend Experience
|
|
|
Chat Interface
|
|
|
การอัปเดตแบบเรียลไทม์
|
|
|
ประวัติข้อความ
|
|
|
ข้อเสนอแนะจากผู้ใช้
|
|
|
สถานะการโหลด
|
|
|
Modern Web Tech
|
|
|
คลาส ES6
|
|
|
Async/Await
|
|
|
การจัดการ DOM
|
|
|
การจัดการเหตุการณ์
|
|
|
Professional Patterns
|
|
|
Security Best Practices
|
|
|
การจัดการโทเค็น
|
|
|
การตรวจสอบข้อมูลเข้า
|
|
|
การป้องกัน XSS
|
|
|
ขอบเขตข้อผิดพลาด
|
|
|
Production Readiness
|
|
|
การเพิ่มประสิทธิภาพการทำงาน
|
|
|
การออกแบบที่ตอบสนอง
|
|
|
การเข้าถึง
|
|
|
กลยุทธ์การทดสอบ
|
|
|
```
|
|
|
**หลักการสำคัญ**: การพัฒนาแอป AI ผสมผสานทักษะการพัฒนาเว็บแบบดั้งเดิมกับการผสานบริการ AI สร้างแอปอัจฉริยะที่ตอบสนองและเป็นธรรมชาติต่อผู้ใช้
|
|
|
|
|
|

|
|
|
|
|
|
**นี่คือเหตุผลที่ playground มีประโยชน์มาก:**
|
|
|
- **ลองใช้งาน** โมเดล AI ต่าง ๆ เช่น GPT-4o-mini, Claude และอื่น ๆ (ฟรีทั้งหมด!)
|
|
|
- **ทดสอบ** ไอเดียและพรอมต์ก่อนเขียนโค้ดจริง
|
|
|
- **รับ** โค้ดพร้อมใช้ในภาษาที่คุณถนัด
|
|
|
- **ปรับ** การตั้งค่าเช่นระดับความคิดสร้างสรรค์และความยาวคำตอบเพื่อตรวจสอบผลลัพธ์
|
|
|
|
|
|
เมื่อลองเล่นสักพัก แค่คลิกแท็บ "Code" และเลือกภาษาการเขียนโปรแกรมเพื่อรับโค้ดสำหรับใช้งานจริง
|
|
|
|
|
|

|
|
|
|
|
|
## การตั้งค่า Python Backend Integration
|
|
|
|
|
|
ตอนนี้เราจะนำ AI Integration ไปใช้ด้วย Python Python ดีสำหรับแอป AI เพราะไวยากรณ์ง่ายและไลบรารีทรงพลัง เราจะเริ่มจากโค้ดใน GitHub Models playground แล้วปรับเปลี่ยนให้เป็นฟังก์ชันที่ใช้ซ้ำได้และพร้อมสำหรับโปรดักชัน
|
|
|
|
|
|
### ความเข้าใจพื้นฐานของการนำไปใช้
|
|
|
|
|
|
เมื่อคุณดึงโค้ด Python จาก playground คุณจะได้โค้ดประมาณนี้ อย่ากังวลถ้าดูเยอะเกินไปทีแรก — เราจะอธิบายทีละส่วน:
|
|
|
|
|
|
```python
|
|
|
"""Run this model in Python
|
|
|
|
|
|
> pip install openai
|
|
|
"""
|
|
|
import os
|
|
|
from openai import OpenAI
|
|
|
|
|
|
# ในการยืนยันตัวตนกับโมเดล คุณจะต้องสร้างโทเค็นการเข้าถึงส่วนตัว (PAT) ในการตั้งค่า GitHub ของคุณ
|
|
|
# สร้างโทเค็น PAT ของคุณโดยทำตามคำแนะนำที่นี่: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
|
|
|
client = OpenAI(
|
|
|
base_url="https://models.github.ai/inference",
|
|
|
api_key=os.environ["GITHUB_TOKEN"],
|
|
|
)
|
|
|
|
|
|
response = client.chat.completions.create(
|
|
|
messages=[
|
|
|
{
|
|
|
"role": "system",
|
|
|
"content": "",
|
|
|
},
|
|
|
{
|
|
|
"role": "user",
|
|
|
"content": "What is the capital of France?",
|
|
|
}
|
|
|
],
|
|
|
model="openai/gpt-4o-mini",
|
|
|
temperature=1,
|
|
|
max_tokens=4096,
|
|
|
top_p=1
|
|
|
)
|
|
|
|
|
|
print(response.choices[0].message.content)
|
|
|
```
|
|
|
|
|
|
**สิ่งที่เกิดขึ้นในโค้ดนี้:**
|
|
|
- **เราอิมพอร์ต** เครื่องมือที่ต้องใช้: `os` สำหรับอ่านตัวแปรแวดล้อม และ `OpenAI` สำหรับติดต่อ AI
|
|
|
- **เราตั้งค่า** ไคลเอนต์ OpenAI ให้ชี้ไปยังเซิร์ฟเวอร์ AI ของ GitHub แทน OpenAI ตรงๆ
|
|
|
- **เราเข้าสู่ระบบ** โดยใช้โทเค็น GitHub พิเศษ (จะอธิบายเพิ่มในตอนต่อไป!)
|
|
|
- **เราโครงสร้าง** บทสนทนาด้วย "บทบาท" ต่าง ๆ – คิดเสมือนตั้งฉากละคร
|
|
|
- **เรา ส่ง** คำขอไปยัง AI พร้อมพารามิเตอร์จูนแต่ง
|
|
|
- **เราแยก** ข้อความคำตอบจริงจากข้อมูลทั้งหมดที่ได้รับกลับมา
|
|
|
|
|
|
### เข้าใจบทบาทข้อความ: โครงสร้างการสนทนา AI
|
|
|
|
|
|
การสนทนา AI ใช้โครงสร้างเฉพาะโดยมี "บทบาท" ต่างกันที่ทำหน้าที่เฉพาะ:
|
|
|
|
|
|
```python
|
|
|
messages=[
|
|
|
{
|
|
|
"role": "system",
|
|
|
"content": "You are a helpful assistant who explains things simply."
|
|
|
},
|
|
|
{
|
|
|
"role": "user",
|
|
|
"content": "What is machine learning?"
|
|
|
}
|
|
|
]
|
|
|
```
|
|
|
|
|
|
**คิดเหมือนกำกับละคร:**
|
|
|
- **บทบาทระบบ**: เหมือนทิศทางบนเวทีสำหรับนักแสดง — บอก AI ว่าควรทำตัวอย่างไร มีบุคลิกแบบไหน และจะตอบอย่างไร
|
|
|
- **บทบาทผู้ใช้**: คำถามหรือข้อความจริงจากผู้ใช้แอปของคุณ
|
|
|
- **บทบาทผู้ช่วย**: คำตอบของ AI (คุณไม่ได้ส่งส่วนนี้ แต่จะแสดงในประวัติการสนทนา)
|
|
|
|
|
|
**เปรียบในชีวิตจริง**: สมมุติคุณแนะนำเพื่อนให้คนอื่นในงานปาร์ตี้ฟัง:
|
|
|
- **ข้อความระบบ**: "นี่คือเพื่อนฉัน ซาราห์ เป็นหมอที่เก่งในการอธิบายความรู้ทางการแพทย์ให้เข้าใจง่าย"
|
|
|
- **ข้อความผู้ใช้**: "ช่วยอธิบายว่าวัคซีนทำงานอย่างไรได้ไหม?"
|
|
|
- **คำตอบผู้ช่วย**: ซาราห์ตอบในฐานะหมอที่เป็นมิตร ไม่ใช่นักกฎหมายหรือเชฟ
|
|
|
|
|
|
### ทำความเข้าใจพารามิเตอร์ AI: ปรับแต่งพฤติกรรมการตอบกลับ
|
|
|
|
|
|
พารามิเตอร์เชิงตัวเลขในการเรียก AI API ควบคุมวิธีที่โมเดลสร้างคำตอบ การตั้งค่าช่วยให้คุณปรับพฤติกรรม AI ให้เหมาะกับกรณีใช้งานต่าง ๆ
|
|
|
|
|
|
#### Temperature (0.0 ถึง 2.0): ปุ่มปรับความคิดสร้างสรรค์
|
|
|
|
|
|
**ทำหน้าที่**: ควบคุมความคิดสร้างสรรค์หรือน่าเดาทำนายของคำตอบ AI
|
|
|
|
|
|
**คิดเหมือนระดับการด้นสดของนักดนตรีแจ๊ส:**
|
|
|
- **Temperature = 0.1**: เล่นทำนองเดิมเป๊ะทุกครั้ง (ทำนายได้สูงมาก)
|
|
|
- **Temperature = 0.7**: เพิ่มการเปลี่ยนแปลงเล็กน้อยแบบมีรสนิยมยังจำได้ (ความคิดสร้างสรรค์สมดุล)
|
|
|
- **Temperature = 1.5**: แจ๊สเต็มรูปแบบกับวลีที่คาดไม่ถึง (ไม่สามารถทำนายได้สูง)
|
|
|
|
|
|
```python
|
|
|
# การตอบที่คาดเดาได้ง่ายมาก (ดีสำหรับคำถามเชิงข้อเท็จจริง)
|
|
|
response = client.chat.completions.create(
|
|
|
messages=[{"role": "user", "content": "What is 2+2?"}],
|
|
|
temperature=0.1 # แทบจะบอกเสมอว่า "4"
|
|
|
)
|
|
|
|
|
|
# การตอบแบบสร้างสรรค์ (ดีสำหรับการระดมความคิด)
|
|
|
response = client.chat.completions.create(
|
|
|
messages=[{"role": "user", "content": "Write a creative story opening"}],
|
|
|
temperature=1.2 # จะสร้างเรื่องราวที่ไม่ซ้ำใครและไม่คาดคิด
|
|
|
)
|
|
|
```
|
|
|
|
|
|
#### Max Tokens (1 ถึง 4096+): ตัวควบคุมความยาวคำตอบ
|
|
|
|
|
|
**ทำหน้าที่**: กำหนดขีดจำกัดความยาวคำตอบ AI
|
|
|
|
|
|
**นึก tokens เป็นคำโดยประมาณ** (ประมาณ 1 token = 0.75 คำในภาษาอังกฤษ):
|
|
|
- **max_tokens=50**: สั้นและหวาน (เหมือนข้อความสั้น)
|
|
|
- **max_tokens=500**: ย่อหน้าหรือสองย่อหน้า
|
|
|
- **max_tokens=2000**: คำอธิบายละเอียดพร้อมตัวอย่าง
|
|
|
|
|
|
```python
|
|
|
# คำตอบสั้น กระชับ
|
|
|
response = client.chat.completions.create(
|
|
|
messages=[{"role": "user", "content": "Explain JavaScript"}],
|
|
|
max_tokens=100 # บังคับให้อธิบายสั้น ๆ
|
|
|
)
|
|
|
|
|
|
# คำตอบละเอียด ครอบคลุม
|
|
|
response = client.chat.completions.create(
|
|
|
messages=[{"role": "user", "content": "Explain JavaScript"}],
|
|
|
max_tokens=1500 # อนุญาตให้อธิบายละเอียดพร้อมตัวอย่าง
|
|
|
)
|
|
|
```
|
|
|
|
|
|
#### Top_p (0.0 ถึง 1.0): ตัวควบคุมโฟกัส
|
|
|
|
|
|
**ทำหน้าที่**: ควบคุมว่าคำตอบ AI จะโฟกัสกับคำที่มีความน่าจะเป็นสูงสุดเพียงใด
|
|
|
|
|
|
**จินตนาการว่า AI มีคำศัพท์จำนวนมาก จัดอันดับตามความน่าจะเป็นของแต่ละคำ:**
|
|
|
- **top_p=0.1**: พิจารณาเพียง 10% คำที่น่าจะเป็นมากที่สุด (โฟกัสสูง)
|
|
|
- **top_p=0.9**: พิจารณา 90% ของคำที่เป็นไปได้ (สร้างสรรค์กว่า)
|
|
|
- **top_p=1.0**: พิจารณาทุกคำ (หลากหลายสูงสุด)
|
|
|
|
|
|
**ตัวอย่าง**: ถ้าถาม "ท้องฟ้ามักจะเป็น..."
|
|
|
- **top_p ต่ำ**: ตอบว่า "สีฟ้า" เกือบแน่นอน
|
|
|
- **top_p สูง**: อาจตอบว่า "สีฟ้า", "มีเมฆ", "กว้างใหญ่", "เปลี่ยนแปลง", "สวยงาม" ฯลฯ
|
|
|
|
|
|
### รวบรวมทุกอย่างเข้าด้วยกัน: การผสมพารามิเตอร์สำหรับกรณีใช้งานต่าง ๆ
|
|
|
|
|
|
```python
|
|
|
# สำหรับคำตอบที่เป็นข้อเท็จจริงและสม่ำเสมอ (เช่น บอทเอกสาร)
|
|
|
factual_params = {
|
|
|
"temperature": 0.2,
|
|
|
"max_tokens": 300,
|
|
|
"top_p": 0.3
|
|
|
}
|
|
|
|
|
|
# สำหรับช่วยเขียนเชิงสร้างสรรค์
|
|
|
creative_params = {
|
|
|
"temperature": 1.1,
|
|
|
"max_tokens": 1000,
|
|
|
"top_p": 0.9
|
|
|
}
|
|
|
|
|
|
# สำหรับการตอบสนองที่สนทนาและเป็นประโยชน์ (สมดุล)
|
|
|
conversational_params = {
|
|
|
"temperature": 0.7,
|
|
|
"max_tokens": 500,
|
|
|
"top_p": 0.8
|
|
|
}
|
|
|
```
|
|
|
|
|
|
```mermaid
|
|
|
quadrantChart
|
|
|
title เมทริกซ์การเพิ่มประสิทธิภาพพารามิเตอร์ AI
|
|
|
x-axis ความคิดสร้างสรรค์ต่ำ --> ความคิดสร้างสรรค์สูง
|
|
|
y-axis การตอบสนองสั้น --> การตอบสนองยาว
|
|
|
|
|
|
quadrant-1 เนื้อหาสร้างสรรค์
|
|
|
quadrant-2 การวิเคราะห์อย่างละเอียด
|
|
|
quadrant-3 ข้อเท็จจริงด่วน
|
|
|
quadrant-4 AI สนทนา
|
|
|
|
|
|
Documentation Bot: [0.2, 0.3]
|
|
|
Customer Service: [0.4, 0.4]
|
|
|
General Assistant: [0.7, 0.5]
|
|
|
Creative Writer: [0.9, 0.9]
|
|
|
Brainstorming Tool: [0.8, 0.8]
|
|
|
```
|
|
|
**ทำไมพารามิเตอร์เหล่านี้สำคัญ**: แอปที่แตกต่างกันต้องการคำตอบที่แตกต่างกัน บอทบริการลูกค้าควรมีความน่าเชื่อถือและข้อเท็จจริง (temperature ต่ำ) ในขณะที่ผู้ช่วยเขียนเชิงสร้างสรรค์ควรมีจินตนาการและหลากหลาย (temperature สูง) การเข้าใจพารามิเตอร์เหล่านี้ช่วยให้คุณควบคุมบุคลิกและรูปแบบคำตอบของ AI ได้
|
|
|
|
|
|
```
|
|
|
|
|
|
**Here's what's happening in this code:**
|
|
|
- **We import** the tools we need: `os` for reading environment variables and `OpenAI` for talking to the AI
|
|
|
- **We set up** the OpenAI client to point to GitHub's AI servers instead of OpenAI directly
|
|
|
- **We authenticate** using a special GitHub token (more on that in a minute!)
|
|
|
- **We structure** our conversation with different "roles" – think of it like setting the scene for a play
|
|
|
- **We send** our request to the AI with some fine-tuning parameters
|
|
|
- **We extract** the actual response text from all the data that comes back
|
|
|
|
|
|
> 🔐 **Security Note**: Never hardcode API keys in your source code! Always use environment variables to store sensitive credentials like your `GITHUB_TOKEN`.
|
|
|
|
|
|
### Creating a Reusable AI Function
|
|
|
|
|
|
Let's refactor this code into a clean, reusable function that we can easily integrate into our web application:
|
|
|
|
|
|
```python
|
|
|
import asyncio
|
|
|
from openai import AsyncOpenAI
|
|
|
|
|
|
# Use AsyncOpenAI for better performance
|
|
|
client = AsyncOpenAI(
|
|
|
base_url="https://models.github.ai/inference",
|
|
|
api_key=os.environ["GITHUB_TOKEN"],
|
|
|
)
|
|
|
|
|
|
async def call_llm_async(prompt: str, system_message: str = "You are a helpful assistant."):
|
|
|
"""
|
|
|
Sends a prompt to the AI model asynchronously and returns the response.
|
|
|
|
|
|
Args:
|
|
|
prompt: The user's question or message
|
|
|
system_message: Instructions that define the AI's behavior and personality
|
|
|
|
|
|
Returns:
|
|
|
str: The AI's response to the prompt
|
|
|
"""
|
|
|
try:
|
|
|
response = await client.chat.completions.create(
|
|
|
messages=[
|
|
|
{
|
|
|
"role": "system",
|
|
|
"content": system_message,
|
|
|
},
|
|
|
{
|
|
|
"role": "user",
|
|
|
"content": prompt,
|
|
|
}
|
|
|
],
|
|
|
model="openai/gpt-4o-mini",
|
|
|
temperature=1,
|
|
|
max_tokens=4096,
|
|
|
top_p=1
|
|
|
)
|
|
|
return response.choices[0].message.content
|
|
|
except Exception as e:
|
|
|
logger.error(f"AI API error: {str(e)}")
|
|
|
return "I'm sorry, I'm having trouble processing your request right now."
|
|
|
|
|
|
# Backward compatibility function for synchronous calls
|
|
|
def call_llm(prompt: str, system_message: str = "You are a helpful assistant."):
|
|
|
"""Synchronous wrapper for async AI calls."""
|
|
|
return asyncio.run(call_llm_async(prompt, system_message))
|
|
|
```
|
|
|
|
|
|
**ทำความเข้าใจฟังก์ชันที่ปรับปรุงนี้:**
|
|
|
- **รับ** พารามิเตอร์สองตัว: พรอมต์ของผู้ใช้และข้อความระบบที่เป็นทางเลือก
|
|
|
- **มี** ข้อความระบบเริ่มต้นสำหรับพฤติกรรมผู้ช่วยทั่วไป
|
|
|
- **ใช้** type hint ของ Python เพื่อการเขียนโค้ดที่ดีขึ้น
|
|
|
- **มี** docstring อธิบายวัตถุประสงค์และพารามิเตอร์ของฟังก์ชันรายละเอียด
|
|
|
- **คืนค่า** เฉพาะเนื้อหาคำตอบเพื่อความง่ายต่อการใช้งานใน API เว็บของเรา
|
|
|
- **คงไว้** พารามิเตอร์โมเดลเดียวกันเพื่อพฤติกรรม AI ที่สม่ำเสมอ
|
|
|
|
|
|
### เวทมนตร์ของ System Prompts: การตั้งโปรแกรมบุคลิก AI
|
|
|
|
|
|
ถ้าพารามิเตอร์ควบคุมว่า AI คิดอย่างไร, system prompts ควบคุมว่า AI คิดว่าตัวเองเป็นใคร นี่เป็นหนึ่งในส่วนที่เจ๋งที่สุดของการทำงานกับ AI – คุณกำลังให้ AI บุคลิกเต็มตัว ระดับความชำนาญ และสไตล์การสื่อสาร
|
|
|
|
|
|
**คิดว่า system prompts เหมือนการคัดเลือกนักแสดงสำหรับบทบาทต่างๆ**: แทนที่จะมีผู้ช่วยทั่วไปเดียว คุณสามารถสร้างผู้เชี่ยวชาญเฉพาะสำหรับสถานการณ์ต่างๆ ต้องการครูใจเย็น? พาร์ทเนอร์ระดมหาความคิดสร้างสรรค์? ที่ปรึกษาทางธุรกิจจริงจัง? แค่เปลี่ยน system prompt!
|
|
|
|
|
|
#### ทำไม System Prompts ถึงทรงพลัง
|
|
|
|
|
|
สิ่งที่น่าทึ่งคือ: โมเดล AI ถูกฝึกจากบทสนทนานับไม่ถ้วนที่คนแสดงบทบาทและระดับความชำนาญต่างๆ เมื่อคุณสั่ง AI ด้วยบทบาทเฉพาะ มันเหมือนกับการเปิดสวิตช์ที่กระตุ้นรูปแบบที่เรียนรู้นั้นทั้งหมด
|
|
|
|
|
|
**เหมือนการแสดงแบบ method acting สำหรับ AI**: บอกนักแสดงว่า "คุณเป็นศาสตราจารย์แก่ผู้เฉลียวฉลาด" แล้วดูพวกเขาปรับท่าทาง คำศัพท์ และลักษณะเฉพาะโดยอัตโนมัติ AI ก็ทำงานคล้ายกันกับรูปแบบภาษา
|
|
|
|
|
|
#### การสร้าง System Prompts ที่มีประสิทธิภาพ: ศิลปะและวิทยาศาสตร์
|
|
|
|
|
|
**องค์ประกอบของ system prompt ที่ดี:**
|
|
|
1. **บทบาท/ตัวตน**: AI เป็นใคร?
|
|
|
2. **ความชำนาญ**: รู้เรื่องอะไร?
|
|
|
3. **สไตล์การสื่อสาร**: การพูดเป็นอย่างไร?
|
|
|
4. **คำแนะนำเฉพาะเจาะจง**: ควรเน้นเรื่องอะไร?
|
|
|
|
|
|
```python
|
|
|
# ❌ คำสั่งระบบที่คลุมเครือ
|
|
|
"You are helpful."
|
|
|
|
|
|
# ✅ คำสั่งระบบที่ละเอียดและมีประสิทธิภาพ
|
|
|
"You are Dr. Sarah Chen, a senior software engineer with 15 years of experience at major tech companies. You explain programming concepts using real-world analogies and always provide practical examples. You're patient with beginners and enthusiastic about helping them understand complex topics."
|
|
|
```
|
|
|
|
|
|
#### ตัวอย่าง System Prompts พร้อมบริบท
|
|
|
|
|
|
มาดูว่าระบบ prompt ต่าง ๆ สร้างบุคลิก AI ที่แตกต่างกันอย่างไร:
|
|
|
|
|
|
```python
|
|
|
# ตัวอย่างที่ 1: ครูผู้มีความอดทน
|
|
|
teacher_prompt = """
|
|
|
You are an experienced programming instructor who has taught thousands of students.
|
|
|
You break down complex concepts into simple steps, use analogies from everyday life,
|
|
|
and always check if the student understands before moving on. You're encouraging
|
|
|
and never make students feel bad for not knowing something.
|
|
|
"""
|
|
|
|
|
|
# ตัวอย่างที่ 2: ผู้ร่วมงานที่มีความคิดสร้างสรรค์
|
|
|
creative_prompt = """
|
|
|
You are a creative writing partner who loves brainstorming wild ideas. You're
|
|
|
enthusiastic, imaginative, and always build on the user's ideas rather than
|
|
|
replacing them. You ask thought-provoking questions to spark creativity and
|
|
|
offer unexpected perspectives that make stories more interesting.
|
|
|
"""
|
|
|
|
|
|
# ตัวอย่างที่ 3: ที่ปรึกษาธุรกิจเชิงกลยุทธ์
|
|
|
business_prompt = """
|
|
|
You are a strategic business consultant with an MBA and 20 years of experience
|
|
|
helping startups scale. You think in frameworks, provide structured advice,
|
|
|
and always consider both short-term tactics and long-term strategy. You ask
|
|
|
probing questions to understand the full business context before giving advice.
|
|
|
"""
|
|
|
```
|
|
|
|
|
|
#### ดูการทำงานของ System Prompts
|
|
|
|
|
|
มาทดสอบคำถามเดียวกันกับ system prompts ต่างกันเพื่อดูความแตกต่างอย่างชัดเจน:
|
|
|
|
|
|
**คำถาม**: "ฉันจะจัดการการยืนยันตัวตนของผู้ใช้ในเว็บแอปของฉันอย่างไร?"
|
|
|
|
|
|
```python
|
|
|
# กับพรอมต์ของครู:
|
|
|
teacher_response = call_llm(
|
|
|
"How do I handle user authentication in my web app?",
|
|
|
teacher_prompt
|
|
|
)
|
|
|
# การตอบกลับทั่วไป: "คำถามดีมาก! มาลองแยกกระบวนการยืนยันตัวตนออกเป็นขั้นตอนง่ายๆ กันเถอะ
|
|
|
# คิดเหมือนกับยามที่คลับไนท์เช็คบัตรประชาชน..."
|
|
|
|
|
|
# กับพรอมต์ทางธุรกิจ:
|
|
|
business_response = call_llm(
|
|
|
"How do I handle user authentication in my web app?",
|
|
|
business_prompt
|
|
|
)
|
|
|
# การตอบกลับทั่วไป: "จากมุมมองเชิงกลยุทธ์ การยืนยันตัวตนมีความสำคัญต่อความไว้วางใจของผู้ใช้และการปฏิบัติตามกฎหมาย
|
|
|
# ให้ฉันสรุปกรอบงานที่พิจารณาถึงความปลอดภัย,
|
|
|
# ประสบการณ์ผู้ใช้ และความสามารถในการปรับขนาด..."
|
|
|
```
|
|
|
|
|
|
#### เทคนิคขั้นสูงของ System Prompts
|
|
|
|
|
|
**1. การตั้งค่าบริบท**: ให้ข้อมูลพื้นหลังกับ AI
|
|
|
```python
|
|
|
system_prompt = """
|
|
|
You are helping a junior developer who just started their first job at a startup.
|
|
|
They know basic HTML/CSS/JavaScript but are new to backend development and databases.
|
|
|
Be encouraging and explain things step-by-step without being condescending.
|
|
|
"""
|
|
|
```
|
|
|
|
|
|
**2. การจัดรูปแบบผลลัพธ์**: บอก AI ว่าควรจัดโครงสร้างคำตอบอย่างไร
|
|
|
```python
|
|
|
system_prompt = """
|
|
|
You are a technical mentor. Always structure your responses as:
|
|
|
1. Quick Answer (1-2 sentences)
|
|
|
2. Detailed Explanation
|
|
|
3. Code Example
|
|
|
4. Common Pitfalls to Avoid
|
|
|
5. Next Steps for Learning
|
|
|
"""
|
|
|
```
|
|
|
|
|
|
**3. การตั้งข้อจำกัด**: กำหนดสิ่งที่ AI ไม่ควรทำ
|
|
|
```python
|
|
|
system_prompt = """
|
|
|
You are a coding tutor focused on teaching best practices. Never write complete
|
|
|
solutions for the user - instead, guide them with hints and questions so they
|
|
|
learn by doing. Always explain the 'why' behind coding decisions.
|
|
|
"""
|
|
|
```
|
|
|
|
|
|
#### ทำไมสิ่งนี้จึงสำคัญสำหรับผู้ช่วยแชทของคุณ
|
|
|
|
|
|
การเข้าใจ system prompts จะช่วยให้คุณมีพลังอย่างมากในการสร้างผู้ช่วย AI แบบเฉพาะทาง:
|
|
|
- **บอทบริการลูกค้า**: ช่วยเหลือ อดทน และรู้จักนโยบาย
|
|
|
- **ติวเตอร์แบบเรียนรู้**: กระตุ้น แนะนำเป็นขั้นตอน และตรวจสอบความเข้าใจ
|
|
|
- **คู่คิดเชิงสร้างสรรค์**: จินตนาการ สร้างสรรค์จากไอเดีย และตั้งคำถามว่า "ถ้าเป็นอย่างนี้ล่ะ?"
|
|
|
- **ผู้เชี่ยวชาญทางเทคนิค**: แม่นยำ ละเอียด และระวังเรื่องความปลอดภัย
|
|
|
|
|
|
**ข้อสังเกตที่สำคัญ**: คุณไม่ได้แค่เรียกใช้ API ของ AI เท่านั้น – คุณกำลังสร้างบุคลิก AI แบบกำหนดเองที่ตอบสนองต่อกรณีการใช้งานเฉพาะของคุณ ซึ่งนี่คือสิ่งที่ทำให้แอป AI สมัยใหม่รู้สึกเฉพาะตัวและมีประโยชน์ แทนที่จะเป็นเพียงแบบทั่วไป
|
|
|
|
|
|
### 🎯 การตรวจสอบเชิงการสอน: การเขียนโปรแกรมบุคลิก AI
|
|
|
|
|
|
**หยุดและคิด**: คุณเพิ่งเรียนรู้วิธีเขียนโปรแกรมบุคลิก AI ผ่าน system prompts ซึ่งเป็นทักษะพื้นฐานในพัฒนาการแอป AI สมัยใหม่
|
|
|
|
|
|
**การประเมินตัวเองอย่างรวดเร็ว**:
|
|
|
- คุณสามารถอธิบายว่าระหว่าง system prompts กับข้อความผู้ใช้ทั่วไปแตกต่างกันอย่างไรได้ไหม?
|
|
|
- ความแตกต่างระหว่างพารามิเตอร์ temperature กับ top_p คืออะไร?
|
|
|
- คุณจะสร้าง system prompt เฉพาะสำหรับกรณีใช้งานหนึ่ง ๆ (เช่นติวเตอร์โค้ดดิ้ง) อย่างไร?
|
|
|
|
|
|
**ความเชื่อมโยงกับโลกจริง**: เทคนิค system prompt ที่คุณเรียนรู้มีใช้ในแอป AI ชั้นนำทุกรายการ – ตั้งแต่ผู้ช่วยโค้ดของ GitHub Copilot ไปจนถึงอินเทอร์เฟซสนทนาของ ChatGPT คุณกำลังฝึกฝนรูปแบบเดียวกับทีมผลิต AI ในบริษัทเทคโนโลยีใหญ่ๆ
|
|
|
|
|
|
**คำถามท้าทาย**: คุณจะออกแบบบุคลิก AI ต่างกันสำหรับประเภทผู้ใช้ที่แตกต่างกันอย่างไร (มือใหม่กับผู้เชี่ยวชาญ)? ลองพิจารณาว่าโมเดล AI เดียวกันสามารถตอบสนองผู้ชมต่างกันผ่านวิศวกรรม prompt ได้อย่างไร
|
|
|
|
|
|
## การสร้าง Web API ด้วย FastAPI: ศูนย์กลางการสื่อสาร AI ที่มีประสิทธิภาพสูงของคุณ
|
|
|
|
|
|
ตอนนี้เรามาสร้าง backend ที่เชื่อมต่อ frontend ของคุณกับบริการ AI กัน เราจะใช้ FastAPI ซึ่งเป็น framework Python สมัยใหม่ที่โดดเด่นในการสร้าง API สำหรับแอป AI
|
|
|
|
|
|
FastAPI มีข้อดีหลายอย่างสำหรับโปรเจกต์ประเภทนี้: รองรับ async ในตัวสำหรับจัดการคำขอพร้อมกัน, สร้างเอกสาร API อัตโนมัติ, และประสิทธิภาพยอดเยี่ยม เซิร์ฟเวอร์ FastAPI ของคุณทำหน้าที่เป็นตัวกลางที่รับคำขอจาก frontend, สื่อสารกับบริการ AI และส่งคืนคำตอบที่จัดรูปแบบแล้ว
|
|
|
|
|
|
### ทำไมต้อง FastAPI สำหรับแอป AI?
|
|
|
|
|
|
คุณอาจสงสัย: "ทำไมไม่เรียก AI ตรงจาก JavaScript ฝั่ง frontend เลย?" หรือ "ทำไมต้อง FastAPI แทน Flask หรือ Django?" คำถามดีมาก!
|
|
|
|
|
|
**นี่คือเหตุผลที่ FastAPI เหมาะกับสิ่งที่เรากำลังสร้าง:**
|
|
|
- **Async โดยดีฟอลต์**: จัดการคำขอ AI หลายคำขอพร้อมกันได้โดยไม่ติดขัด
|
|
|
- **เอกสารอัตโนมัติ**: เข้าไปที่ `/docs` แล้วจะได้เอกสาร API สวยงามและโต้ตอบได้โดยไม่เสียค่าใช้จ่าย
|
|
|
- **ตรวจสอบข้อมูลในตัว**: ดักจับข้อผิดพลาดก่อนเกิดปัญหา
|
|
|
- **เร็วมาก**: เป็นหนึ่งใน framework Python ที่เร็วที่สุด
|
|
|
- **Python สมัยใหม่**: ใช้ฟีเจอร์ล่าสุดของ Python
|
|
|
|
|
|
**และนี่คือเหตุผลว่าทำไมเราต้องมี backend:**
|
|
|
|
|
|
**ความปลอดภัย**: คีย์ API ของ AI เปรียบเหมือนรหัสผ่าน – ถ้าคุณใส่ไว้ใน JavaScript ฝั่ง frontend ใครก็ตามที่ดูโค้ดเว็บของคุณสามารถขโมยและใช้เครดิต AI ของคุณได้ backend จะเก็บข้อมูลลับอย่างปลอดภัย
|
|
|
|
|
|
**จำกัดและตรวจสอบการใช้งาน**: backend ช่วยให้คุณควบคุมความถี่คำขอของผู้ใช้, เพิ่มการยืนยันตัวตน, และเก็บบันทึกการใช้งาน
|
|
|
|
|
|
**ประมวลผลข้อมูล**: คุณอาจต้องการบันทึกการสนทนา, กรองเนื้อหาที่ไม่เหมาะสม, หรือรวมบริการ AI หลายตัว Backend คือที่สำหรับตรรกะเหล่านี้
|
|
|
|
|
|
**สถาปัตยกรรมคล้ายแบบลูกข่าย-เซิร์ฟเวอร์:**
|
|
|
- **Frontend**: ชั้นอินเทอร์เฟซสำหรับผู้ใช้
|
|
|
- **Backend API**: ชั้นประมวลผลคำขอและเส้นทาง
|
|
|
- **AI Service**: การคำนวณและสร้างคำตอบภายนอก
|
|
|
- **Environment Variables**: การตั้งค่าและเก็บข้อมูลลับอย่างปลอดภัย
|
|
|
|
|
|
### ทำความเข้าใจการไหลของคำขอ-ตอบกลับ
|
|
|
|
|
|
เรามาดูสิ่งที่จะเกิดขึ้นเมื่อผู้ใช้ส่งข้อความ:
|
|
|
|
|
|
```mermaid
|
|
|
sequenceDiagram
|
|
|
participant User as 👤 ผู้ใช้
|
|
|
participant Frontend as 🌐 ส่วนหน้าของเว็บ
|
|
|
participant API as 🔧 เซิร์ฟเวอร์ FastAPI
|
|
|
participant AI as 🤖 บริการ AI
|
|
|
|
|
|
User->>Frontend: พิมพ์ "สวัสดี AI!"
|
|
|
Frontend->>API: POST /hello {"message": "สวัสดี AI!"}
|
|
|
Note over API: ตรวจสอบความถูกต้องของคำร้อง<br/>เพิ่มคำสั่งระบบ
|
|
|
API->>AI: ส่งคำร้องที่จัดรูปแบบ
|
|
|
AI->>API: ส่งกลับคำตอบจาก AI
|
|
|
Note over API: ประมวลผลคำตอบ<br/>บันทึกการสนทนา
|
|
|
API->>Frontend: {"response": "สวัสดี! ฉันช่วยอะไรได้บ้าง?"}
|
|
|
Frontend->>User: แสดงข้อความจาก AI
|
|
|
```
|
|
|
**ทำความเข้าใจแต่ละขั้นตอน:**
|
|
|
1. **การโต้ตอบของผู้ใช้**: คนพิมพ์ข้อความในอินเทอร์เฟซแชท
|
|
|
2. **การประมวลผล frontend**: JavaScript เก็บข้อมูลอินพุตและจัดรูปแบบเป็น JSON
|
|
|
3. **การตรวจสอบ API**: FastAPI ตรวจสอบคำขอโดยอัตโนมัติผ่าน Pydantic models
|
|
|
4. **การผนวก AI**: backend เพิ่ม context (system prompt) และเรียกใช้บริการ AI
|
|
|
5. **การจัดการคำตอบ**: API รับคำตอบ AI และปรับเปลี่ยนได้หากจำเป็น
|
|
|
6. **การแสดงผล frontend**: JavaScript แสดงคำตอบในอินเทอร์เฟซแชท
|
|
|
|
|
|
### ทำความเข้าใจสถาปัตยกรรม API
|
|
|
|
|
|
```mermaid
|
|
|
sequenceDiagram
|
|
|
participant Frontend
|
|
|
participant FastAPI
|
|
|
participant AI Function
|
|
|
participant GitHub Models
|
|
|
|
|
|
Frontend->>FastAPI: POST /hello {"message": "สวัสดี AI!"}
|
|
|
FastAPI->>AI Function: call_llm(message, system_prompt)
|
|
|
AI Function->>GitHub Models: API request
|
|
|
GitHub Models->>AI Function: AI response
|
|
|
AI Function->>FastAPI: response text
|
|
|
FastAPI->>Frontend: {"response": "สวัสดี! ฉันช่วยอะไรได้บ้าง?"}
|
|
|
```
|
|
|
```mermaid
|
|
|
flowchart TD
|
|
|
A[ป้อนข้อมูลผู้ใช้] --> B[ตรวจสอบความถูกต้องด้านหน้า]
|
|
|
B --> C[คำขอ HTTP POST]
|
|
|
C --> D[ตัวกำหนดเส้นทาง FastAPI]
|
|
|
D --> E[ตรวจสอบความถูกต้อง Pydantic]
|
|
|
E --> F[เรียกใช้ฟังก์ชัน AI]
|
|
|
F --> G[API โมเดล GitHub]
|
|
|
G --> H[การประมวลผลการตอบกลับ]
|
|
|
H --> I[ตอบกลับ JSON]
|
|
|
I --> J[อัปเดตด้านหน้า]
|
|
|
|
|
|
subgraph "เลเยอร์ความปลอดภัย"
|
|
|
K[มิดเดิลแวร์ CORS]
|
|
|
L[ตัวแปรสภาพแวดล้อม]
|
|
|
M[การจัดการข้อผิดพลาด]
|
|
|
end
|
|
|
|
|
|
D --> K
|
|
|
F --> L
|
|
|
H --> M
|
|
|
```
|
|
|
### การสร้างแอป FastAPI
|
|
|
|
|
|
เราจะสร้าง API ทีละขั้นตอน สร้างไฟล์ชื่อ `api.py` พร้อมกับโค้ด FastAPI ดังนี้:
|
|
|
|
|
|
```python
|
|
|
# api.py
|
|
|
from fastapi import FastAPI, HTTPException
|
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
from pydantic import BaseModel
|
|
|
from llm import call_llm
|
|
|
import logging
|
|
|
|
|
|
# กำหนดค่าการบันทึกข้อมูล
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# สร้างแอปพลิเคชัน FastAPI
|
|
|
app = FastAPI(
|
|
|
title="AI Chat API",
|
|
|
description="A high-performance API for AI-powered chat applications",
|
|
|
version="1.0.0"
|
|
|
)
|
|
|
|
|
|
# กำหนดค่า CORS
|
|
|
app.add_middleware(
|
|
|
CORSMiddleware,
|
|
|
allow_origins=["*"], # กำหนดค่าให้เหมาะสมสำหรับการใช้งานจริง
|
|
|
allow_credentials=True,
|
|
|
allow_methods=["*"],
|
|
|
allow_headers=["*"],
|
|
|
)
|
|
|
|
|
|
# โมเดล Pydantic สำหรับการตรวจสอบคำร้องขอ/ตอบกลับ
|
|
|
class ChatMessage(BaseModel):
|
|
|
message: str
|
|
|
|
|
|
class ChatResponse(BaseModel):
|
|
|
response: str
|
|
|
|
|
|
@app.get("/")
|
|
|
async def root():
|
|
|
"""Root endpoint providing API information."""
|
|
|
return {
|
|
|
"message": "Welcome to the AI Chat API",
|
|
|
"docs": "/docs",
|
|
|
"health": "/health"
|
|
|
}
|
|
|
|
|
|
@app.get("/health")
|
|
|
async def health_check():
|
|
|
"""Health check endpoint."""
|
|
|
return {"status": "healthy", "service": "ai-chat-api"}
|
|
|
|
|
|
@app.post("/hello", response_model=ChatResponse)
|
|
|
async def chat_endpoint(chat_message: ChatMessage):
|
|
|
"""Main chat endpoint that processes messages and returns AI responses."""
|
|
|
try:
|
|
|
# ดึงข้อความและตรวจสอบความถูกต้อง
|
|
|
message = chat_message.message.strip()
|
|
|
if not message:
|
|
|
raise HTTPException(status_code=400, detail="Message cannot be empty")
|
|
|
|
|
|
logger.info(f"Processing message: {message[:50]}...")
|
|
|
|
|
|
# เรียกใช้บริการ AI (หมายเหตุ: ควรทำ call_llm เป็นแบบ async เพื่อประสิทธิภาพที่ดีกว่า)
|
|
|
ai_response = await call_llm_async(message, "You are a helpful and friendly assistant.")
|
|
|
|
|
|
logger.info("AI response generated successfully")
|
|
|
return ChatResponse(response=ai_response)
|
|
|
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
logger.error(f"Error processing chat message: {str(e)}")
|
|
|
raise HTTPException(status_code=500, detail="Internal server error")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
import uvicorn
|
|
|
uvicorn.run(app, host="0.0.0.0", port=5000, reload=True)
|
|
|
```
|
|
|
|
|
|
**ทำความเข้าใจการใช้งาน FastAPI:**
|
|
|
- **นำเข้า** FastAPI สำหรับฟังก์ชันเว็บเฟรมเวิร์กสมัยใหม่ และ Pydantic สำหรับตรวจสอบข้อมูล
|
|
|
- **สร้าง** เอกสาร API อัตโนมัติ (เข้าถึงได้ที่ `/docs` เมื่อเซิร์ฟเวอร์รัน)
|
|
|
- **เปิดใช้** middleware CORS เพื่ออนุญาตคำขอจาก frontend ที่มีต้นทางต่างกัน
|
|
|
- **กำหนด** โมเดล Pydantic สำหรับตรวจสอบและสร้างเอกสารคำขอ/คำตอบอัตโนมัติ
|
|
|
- **ใช้** endpoints แบบ async เพื่อประสิทธิภาพที่ดีกับการร้องขอพร้อมกัน
|
|
|
- **จัดการ** รหัสสถานะ HTTP และข้อผิดพลาดด้วย HTTPException อย่างเหมาะสม
|
|
|
- **รวม** การบันทึกแบบมีโครงสร้างสำหรับการตรวจสอบและดีบัก
|
|
|
- **มี** endpoint ตรวจสอบสถานะสุขภาพของบริการ
|
|
|
|
|
|
**ข้อได้เปรียบหลักของ FastAPI เมื่อเทียบกับเฟรมเวิร์กทั่วไป:**
|
|
|
- **ตรวจสอบข้อมูลอัตโนมัติ**: โมเดล Pydantic ช่วยรับประกันความถูกต้องของข้อมูลก่อนประมวลผล
|
|
|
- **เอกสารโต้ตอบได้**: เข้า `/docs` เพื่อดูเอกสาร API ที่สร้างอัตโนมัติและทดสอบได้
|
|
|
- **ความปลอดภัยของชนิดข้อมูล**: คำบอกประเภท Python ช่วยป้องกันข้อผิดพลาดขณะรันและปรับปรุงคุณภาพโค้ด
|
|
|
- **รองรับ async**: จัดการคำขอ AI หลายคำขอพร้อมกันโดยไม่บล็อก
|
|
|
- **ประสิทธิภาพสูง**: การประมวลผลคำขอเร็วขึ้นมากสำหรับแอปเรียลไทม์
|
|
|
|
|
|
### เข้าใจ CORS: ผู้รักษาความปลอดภัยของเว็บ
|
|
|
|
|
|
CORS (Cross-Origin Resource Sharing) เป็นเหมือนยามรักษาความปลอดภัยของอาคารที่ตรวจสอบว่าผู้เข้าชมได้รับอนุญาตเข้าหรือไม่ มาดูว่าทำไมมันถึงสำคัญและส่งผลต่อแอปของคุณอย่างไร
|
|
|
|
|
|
#### CORS คืออะไรและทำไมมันถึงมีอยู่?
|
|
|
|
|
|
**ปัญหา**: สมมติว่าเว็บไซต์ใดก็ได้สามารถส่งคำขอไปยังเว็บของธนาคารคุณโดยไม่ขออนุญาต นั่นคือฝันร้ายของความปลอดภัย! เบราว์เซอร์จึงป้องกันด้วย "นโยบาย Same-Origin"
|
|
|
|
|
|
**นโยบาย Same-Origin**: เบราว์เซอร์อนุญาตให้เว็บเพจส่งคำขอไปที่โดเมน, พอร์ต และโปรโตคอลเดียวกับที่โหลดหน้าเว็บมาเท่านั้น
|
|
|
|
|
|
**เปรียบเทียบกับโลกจริง**: เหมือนที่พักอาศัยที่มีระบบรักษาความปลอดภัย – ผู้พักอาศัย (ต้นทางเดียวกัน) เท่านั้นที่เข้าถึงอาคารได้โดยดีฟอลต์ ถ้าคุณอยากให้เพื่อน (ต้นทางต่าง) เข้าเยี่ยม คุณต้องบอกยามโดยตรงว่าอนุญาต
|
|
|
|
|
|
#### CORS ในสภาพแวดล้อมการพัฒนาของคุณ
|
|
|
|
|
|
ระหว่างการพัฒนา frontend และ backend จะรันที่พอร์ตต่างกัน:
|
|
|
- Frontend: `http://localhost:3000` (หรือไฟล์:// ถ้าเปิดไฟล์ HTML โดยตรง)
|
|
|
- Backend: `http://localhost:5000`
|
|
|
|
|
|
สิ่งเหล่านี้ถือเป็น "ต้นทางต่าง" แม้อยู่บนเครื่องเดียวกัน!
|
|
|
|
|
|
```python
|
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
|
|
app = FastAPI(__name__)
|
|
|
CORS(app) # สิ่งนี้บอกเบราว์เซอร์ว่า: "อนุญาตให้ต้นกำเนิดอื่นทำคำขอไปยัง API นี้ได้"
|
|
|
```
|
|
|
|
|
|
**CORS กำหนดค่าอย่างไรในทางปฏิบัติ:**
|
|
|
- **เพิ่ม** HTTP headers พิเศษในคำตอบ API แจ้งเบราว์เซอร์ว่า "คำขอข้ามต้นทางนี้อนุญาต"
|
|
|
- **จัดการ** คำขอ "preflight" (เบราว์เซอร์ตรวจสอบสิทธิ์ก่อนส่งคำขอจริง)
|
|
|
- **ป้องกัน** ข้อผิดพลาด "ถูกบล็อกโดยนโยบาย CORS" ในคอนโซลเบราว์เซอร์ของคุณ
|
|
|
|
|
|
#### ความปลอดภัยของ CORS: การพัฒนากับการผลิต
|
|
|
|
|
|
```python
|
|
|
# 🚨 การพัฒนา: อนุญาตให้ทุกแหล่งที่มา (สะดวกแต่ไม่ปลอดภัย)
|
|
|
CORS(app)
|
|
|
|
|
|
# ✅ การผลิต: อนุญาตเฉพาะโดเมน frontend ของคุณ
|
|
|
CORS(app, origins=["https://yourdomain.com", "https://www.yourdomain.com"])
|
|
|
|
|
|
# 🔒 ขั้นสูง: แหล่งที่มาต่างกันสำหรับสภาพแวดล้อมที่ต่างกัน
|
|
|
if app.debug: # โหมดการพัฒนา
|
|
|
CORS(app, origins=["http://localhost:3000", "http://127.0.0.1:3000"])
|
|
|
else: # โหมดการผลิต
|
|
|
CORS(app, origins=["https://yourdomain.com"])
|
|
|
```
|
|
|
|
|
|
**ทำไมถึงสำคัญ**: ในการพัฒนา `CORS(app)` เปรียบเหมือนปลดล็อกประตูหน้า – สะดวกแต่ไม่ปลอดภัย ในสภาพแวดล้อมจริง คุณควรกำหนดว่าเว็บไซต์ไหนสามารถเรียก API ของคุณได้อย่างชัดเจน
|
|
|
|
|
|
#### สถานการณ์และวิธีแก้ปัญหา CORS ทั่วไป
|
|
|
|
|
|
| สถานการณ์ | ปัญหา | วิธีแก้ปัญหา |
|
|
|
|----------|---------|----------|
|
|
|
| **การพัฒนาท้องถิ่น** | Frontend เข้าถึง backend ไม่ได้ | เพิ่ม CORSMiddleware ให้ FastAPI |
|
|
|
| **GitHub Pages + Heroku** | Frontend ที่ปรับใช้เข้าถึง API ไม่ได้ | เพิ่ม URL GitHub Pages ของคุณใน CORS origins |
|
|
|
| **โดเมนส่วนตัว** | พบข้อผิดพลาด CORS ในสภาพแวดล้อมผลิต | อัพเดต origins ของ CORS ให้ตรงกับโดเมน |
|
|
|
| **แอปลิเคชันมือถือ** | แอพเข้าถึงเว็บ API ไม่ได้ | เพิ่มโดเมนแอพหรือใช้ `*` อย่างระมัดระวัง |
|
|
|
|
|
|
**เคล็ดลับ**: คุณสามารถตรวจสอบ header CORS ในเครื่องมือสำหรับนักพัฒนาของเบราว์เซอร์ ในแท็บ Network ดู header อย่าง `Access-Control-Allow-Origin` ในคำตอบ
|
|
|
|
|
|
### การจัดการข้อผิดพลาดและการตรวจสอบข้อมูล
|
|
|
|
|
|
สังเกตว่า API ของเรารวมการจัดการข้อผิดพลาดอย่างเหมาะสม:
|
|
|
|
|
|
```python
|
|
|
# ตรวจสอบว่าเราได้รับข้อความแล้วหรือไม่
|
|
|
if not message:
|
|
|
return jsonify({"error": "Message field is required"}), 400
|
|
|
```
|
|
|
|
|
|
**หลักการตรวจสอบข้อมูลสำคัญ:**
|
|
|
- **ตรวจสอบ** ว่ามีฟิลด์ที่จำเป็นก่อนประมวลผลคำขอ
|
|
|
- **ส่งคืน** ข้อความผิดพลาดที่เข้าใจได้ในรูปแบบ JSON
|
|
|
- **ใช้** รหัสสถานะ HTTP ที่เหมาะสม (400 สำหรับคำขอผิด)
|
|
|
- **ให้** ฟีดแบ็คชัดเจนเพื่อช่วยนักพัฒนา frontend แก้ไขบั๊ก
|
|
|
|
|
|
## การตั้งค่าและรัน Backend ของคุณ
|
|
|
|
|
|
ตอนนี้ที่เราเตรียมการผนวก AI และเซิร์ฟเวอร์ FastAPI เรียบร้อยแล้ว มาเริ่มรันกันเลย ขั้นตอนนี้รวมถึงการติดตั้งไลบรารี Python, ตั้งค่าตัวแปรแวดล้อม, และสตาร์ตเซิร์ฟเวอร์การพัฒนา
|
|
|
|
|
|
### การตั้งค่าสภาพแวดล้อม Python
|
|
|
|
|
|
มาสร้างสภาพแวดล้อมพัฒนา Python ของคุณกัน Virtual environments เหมือนกับแนวทางแยกส่วนของโครงการแมนฮัตตัน – โปรเจกต์แต่ละตัวจะมีพื้นที่แยกเฉพาะของตัวเองพร้อมเครื่องมือและไลบรารีที่เฉพาะเจาะจง ป้องกันปัญหาความขัดแย้งระหว่างโปรเจกต์
|
|
|
|
|
|
```bash
|
|
|
# ไปที่ไดเรกทอรี backend ของคุณ
|
|
|
cd backend
|
|
|
|
|
|
# สร้างสภาพแวดล้อมเสมือน (เหมือนการสร้างห้องสะอาดสำหรับโปรเจคของคุณ)
|
|
|
python -m venv venv
|
|
|
|
|
|
# เปิดใช้งานมัน (Linux/Mac)
|
|
|
source ./venv/bin/activate
|
|
|
|
|
|
# บน Windows ใช้:
|
|
|
# venv\Scripts\activate
|
|
|
|
|
|
# ติดตั้งของดี
|
|
|
pip install openai fastapi uvicorn python-dotenv
|
|
|
```
|
|
|
|
|
|
**สิ่งที่เราทำไป:**
|
|
|
- **สร้าง** บับเบิล Python ส่วนตัวที่ติดตั้งแพ็กเกจได้โดยไม่กระทบระบบอื่น
|
|
|
- **เปิดใช้งาน** เพื่อให้ terminal รู้จักสภาพแวดล้อมนี้โดยเฉพาะ
|
|
|
- **ติดตั้ง** ไลบรารีที่จำเป็น: OpenAI สำหรับเวทมนตร์ AI, FastAPI สำหรับเว็บ API, Uvicorn สำหรับรันเซิร์ฟเวอร์, และ python-dotenv เพื่อจัดการลับอย่างปลอดภัย
|
|
|
|
|
|
**อธิบายไลบรารีหลัก:**
|
|
|
- **FastAPI**: เว็บเฟรมเวิร์กสมัยใหม่และรวดเร็วพร้อมเอกสาร API อัตโนมัติ
|
|
|
- **Uvicorn**: เซิร์ฟเวอร์ ASGI เร็วปานสายฟ้า สำหรับรันแอป FastAPI
|
|
|
- **OpenAI**: ไลบรารีอย่างเป็นทางการสำหรับ GitHub Models และ OpenAI API
|
|
|
- **python-dotenv**: โหลดตัวแปรแวดล้อมจากไฟล์ .env อย่างปลอดภัย
|
|
|
|
|
|
### การตั้งค่าสภาพแวดล้อม: รักษาความลับให้ปลอดภัย
|
|
|
|
|
|
ก่อนเริ่ม API เราต้องพูดถึงบทเรียนสำคัญในการพัฒนาเว็บ: วิธีเก็บความลับให้ปลอดภัย ตัวแปรแวดล้อม (environment variables) เปรียบเหมือนตู้นิรภัยที่แอปของคุณเท่านั้นที่เข้าถึงได้
|
|
|
|
|
|
#### ตัวแปรแวดล้อมคืออะไร?
|
|
|
|
|
|
**คิดว่าตัวแปรแวดล้อมเหมือนกล่องเซฟ:** คุณใส่ของมีค่าไว้ และมีแค่คุณ (และแอปคุณ) ที่มีลูกกุญแจเปิดออก แทนที่จะเขียนข้อมูลลับในโค้ด (ซึ่งใครก็เห็นได้) คุณเก็บไว้อย่างปลอดภัยใน environment
|
|
|
|
|
|
**ความแตกต่างเช่นนี้:**
|
|
|
- **วิธีผิด**: เขียนรหัสผ่านไว้ในโพสต์อิทบนหน้าจอ
|
|
|
- **วิธีถูก**: เก็บรหัสผ่านในตัวจัดการรหัสผ่านที่ปลอดภัยที่มีแค่คุณเข้าถึงได้
|
|
|
|
|
|
#### ทำไมตัวแปรแวดล้อมถึงสำคัญ
|
|
|
|
|
|
```python
|
|
|
# 🚨 อย่าทำแบบนี้เด็ดขาด - คีย์ API โผล่ให้ทุกคนเห็น
|
|
|
client = OpenAI(
|
|
|
api_key="ghp_1234567890abcdef...", # ใครก็ได้สามารถขโมยสิ่งนี้!
|
|
|
base_url="https://models.github.ai/inference"
|
|
|
)
|
|
|
|
|
|
# ✅ ทำแบบนี้ - เก็บคีย์ API อย่างปลอดภัย
|
|
|
client = OpenAI(
|
|
|
api_key=os.environ["GITHUB_TOKEN"], # มีแค่แอปของคุณเท่านั้นที่เข้าถึงได้
|
|
|
base_url="https://models.github.ai/inference"
|
|
|
)
|
|
|
```
|
|
|
|
|
|
**ผลลัพธ์เมื่อคุณเขียนข้อมูลลับในโค้ด:**
|
|
|
1. **ถูกเปิดเผยในระบบควบคุมเวอร์ชัน**: ใครก็ได้ที่เข้าถึง repo จะเห็นคีย์ API ของคุณ
|
|
|
2. **ที่เก็บคอมมอนสาธารณะ**: ถ้าคุณ push ไป GitHub คีย์จะเปิดเผยต่อสาธารณะ
|
|
|
3. **แชร์สำหรับทีม**: นักพัฒนาคนอื่นได้คีย์ส่วนตัวของคุณด้วย
|
|
|
4. **ถูกโจมตีทางความปลอดภัย**: ถ้าใครขโมยคีย์ API คุณ พวกเขาสามารถใช้เครดิต AI ของคุณได้
|
|
|
|
|
|
#### การตั้งค่าไฟล์ .env ของคุณ
|
|
|
|
|
|
สร้างไฟล์ `.env` ในโฟลเดอร์ backend ของคุณ ไฟล์นี้จะเก็บความลับของคุณในเครื่อง:
|
|
|
|
|
|
```bash
|
|
|
# ไฟล์ .env - ไม่ควรถูกเพิ่มเข้า Git เป็นอันขาด
|
|
|
GITHUB_TOKEN=your_github_personal_access_token_here
|
|
|
FASTAPI_DEBUG=True
|
|
|
ENVIRONMENT=development
|
|
|
```
|
|
|
|
|
|
**ทำความเข้าใจไฟล์ .env:**
|
|
|
- **ลับหนึ่งบรรทัดต่อหนึ่งรายการ** ในรูปแบบ `KEY=value`
|
|
|
- **ไม่มีช่องว่าง** รอบเครื่องหมายเท่ากับ
|
|
|
- **ไม่ต้องใช้เครื่องหมายคำพูด** รอบค่ามักไม่ต้องมี
|
|
|
- **คอมเมนต์** เริ่มต้นด้วย `#`
|
|
|
|
|
|
#### การสร้างโทเค็นเข้าถึงส่วนตัว GitHub ของคุณ
|
|
|
|
|
|
โทเค็น GitHub เป็นเหมือนรหัสผ่านพิเศษที่อนุญาตให้แอปคุณใช้บริการ AI ของ GitHub:
|
|
|
|
|
|
**ขั้นตอนสร้างโทเค็นทีละขั้น:**
|
|
|
1. **ไปที่การตั้งค่า GitHub** → Developer settings → Personal access tokens → Tokens (classic)
|
|
|
2. **คลิก "Generate new token (classic)"**
|
|
|
3. **กำหนดวันหมดอายุ** (30 วันสำหรับทดสอบ, นานกว่าสำหรับผลิต)
|
|
|
4. **เลือกสิทธิ์**: ติ๊ก "repo" และสิทธิ์อื่นๆ ที่คุณต้องการ
|
|
|
5. **สร้างโทเค็น** และคัดลอกทันที (คุณจะดูอีกครั้งไม่ได้)
|
|
|
6. **วางในไฟล์ .env ของคุณ**
|
|
|
|
|
|
```bash
|
|
|
# ตัวอย่างว่าโทเค็นของคุณมีลักษณะอย่างไร (นี่คือตัวอย่างปลอม!)
|
|
|
GITHUB_TOKEN=ghp_1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R
|
|
|
```
|
|
|
|
|
|
#### การโหลดตัวแปรแวดล้อมใน Python
|
|
|
|
|
|
```python
|
|
|
import os
|
|
|
from dotenv import load_dotenv
|
|
|
|
|
|
# โหลดตัวแปรสภาพแวดล้อมจากไฟล์ .env
|
|
|
load_dotenv()
|
|
|
|
|
|
# ตอนนี้คุณสามารถเข้าถึงได้อย่างปลอดภัยแล้ว
|
|
|
api_key = os.environ.get("GITHUB_TOKEN")
|
|
|
if not api_key:
|
|
|
raise ValueError("GITHUB_TOKEN not found in environment variables!")
|
|
|
|
|
|
client = OpenAI(
|
|
|
api_key=api_key,
|
|
|
base_url="https://models.github.ai/inference"
|
|
|
)
|
|
|
```
|
|
|
|
|
|
**โค้ดนี้ทำอะไร:**
|
|
|
- **โหลด** ไฟล์ .env และทำให้ตัวแปรพร้อมใช้ใน Python
|
|
|
- **ตรวจสอบ** ว่ามีโทเค็นจำเป็น (จัดการข้อผิดพลาดดีมาก!)
|
|
|
- **ยกข้อผิดพลาดอย่างชัดเจน** หากโทเค็นหายไป
|
|
|
- **ใช้** โทเค็นอย่างปลอดภัยโดยไม่เปิดเผยในโค้ด
|
|
|
|
|
|
#### ความปลอดภัย Git: ไฟล์ .gitignore
|
|
|
|
|
|
ไฟล์ `.gitignore` บอก Git ว่าไฟล์ใดไม่ควรติดตามหรืออัปโหลด:
|
|
|
|
|
|
```bash
|
|
|
# .gitignore - เพิ่มบรรทัดเหล่านี้
|
|
|
.env
|
|
|
*.env
|
|
|
.env.local
|
|
|
.env.production
|
|
|
__pycache__/
|
|
|
venv/
|
|
|
.vscode/
|
|
|
```
|
|
|
|
|
|
**ทำไมสิ่งนี้จึงสำคัญ**: เมื่อคุณเพิ่ม `.env` ใน `.gitignore` Git จะไม่สนใจไฟล์ environment อีกต่อไป ป้องกันไม่ให้คุณเผลออัปโหลดความลับไปยัง GitHub
|
|
|
|
|
|
#### สภาพแวดล้อมต่างกัน ความลับต่างกัน
|
|
|
|
|
|
แอปมืออาชีพใช้ API keys ต่างกันในแต่ละสภาพแวดล้อม:
|
|
|
|
|
|
```bash
|
|
|
# .env.development
|
|
|
GITHUB_TOKEN=your_development_token
|
|
|
DEBUG=True
|
|
|
|
|
|
# .env.production
|
|
|
GITHUB_TOKEN=your_production_token
|
|
|
DEBUG=False
|
|
|
```
|
|
|
|
|
|
**เพราะเหตุนี้:** คุณไม่ต้องการให้งานทดลองพัฒนาของคุณกระทบโควต้าการใช้ AI ในผลิต และต้องการระดับความปลอดภัยต่างกันในแต่ละสภาพแวดล้อม
|
|
|
|
|
|
### การเริ่มเซิร์ฟเวอร์การพัฒนาของคุณ: ให้ FastAPI มีชีวิตขึ้นมา
|
|
|
ตอนนี้ถึงช่วงเวลาที่น่าตื่นเต้น – การเริ่มเซิร์ฟเวอร์พัฒนา FastAPI ของคุณและเห็นการผสาน AI ของคุณมีชีวิต! FastAPI ใช้ Uvicorn ซึ่งเป็นเซิร์ฟเวอร์ ASGI ที่รวดเร็วมากซึ่งออกแบบมาเฉพาะสำหรับแอปพลิเคชัน Python แบบอะซิงโครนัส
|
|
|
|
|
|
#### ทำความเข้าใจกระบวนการเริ่มต้นเซิร์ฟเวอร์ FastAPI
|
|
|
|
|
|
```bash
|
|
|
# วิธีที่ 1: การรัน Python โดยตรง (รวมการโหลดซ้ำอัตโนมัติ)
|
|
|
python api.py
|
|
|
|
|
|
# วิธีที่ 2: ใช้ Uvicorn โดยตรง (ควบคุมได้มากขึ้น)
|
|
|
uvicorn api:app --host 0.0.0.0 --port 5000 --reload
|
|
|
```
|
|
|
|
|
|
เมื่อคุณรันคำสั่งนี้ สิ่งที่เกิดขึ้นเบื้องหลังมีดังนี้:
|
|
|
|
|
|
**1. Python โหลดแอปพลิเคชัน FastAPI ของคุณ**:
|
|
|
- นำเข้าไลบรารีที่จำเป็นทั้งหมด (FastAPI, Pydantic, OpenAI เป็นต้น)
|
|
|
- โหลดตัวแปรสภาพแวดล้อมจากไฟล์ `.env` ของคุณ
|
|
|
- สร้างอินสแตนซ์แอปพลิเคชัน FastAPI พร้อมเอกสารอัตโนมัติ
|
|
|
|
|
|
**2. Uvicorn กำหนดค่าเซิร์ฟเวอร์ ASGI**:
|
|
|
- ผูกกับพอร์ต 5000 ที่รองรับการจัดการคำขอแบบอะซิงโครนัส
|
|
|
- ตั้งค่าการกำหนดเส้นทางคำขอพร้อมการตรวจสอบอัตโนมัติ
|
|
|
- เปิดใช้งานการรีโหลดร้อนสำหรับการพัฒนา (รีสตาร์ทเมื่อไฟล์เปลี่ยนแปลง)
|
|
|
- สร้างเอกสาร API แบบโต้ตอบ
|
|
|
|
|
|
**3. เซิร์ฟเวอร์เริ่มรับคำขอ**:
|
|
|
- เทอร์มินัลของคุณแสดง: `INFO: Uvicorn running on http://0.0.0.0:5000`
|
|
|
- เซิร์ฟเวอร์สามารถจัดการคำขอ AI พร้อมกันหลายคำขอ
|
|
|
- API ของคุณพร้อมใช้งานพร้อมเอกสารอัตโนมัติที่ `http://localhost:5000/docs`
|
|
|
|
|
|
#### สิ่งที่คุณควรเห็นเมื่อทุกอย่างทำงานได้
|
|
|
|
|
|
```bash
|
|
|
$ python api.py
|
|
|
INFO: Will watch for changes in these directories: ['/your/project/path']
|
|
|
INFO: Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)
|
|
|
INFO: Started reloader process [12345] using WatchFiles
|
|
|
INFO: Started server process [12346]
|
|
|
INFO: Waiting for application startup.
|
|
|
INFO: Application startup complete.
|
|
|
```
|
|
|
|
|
|
**ทำความเข้าใจกับผลลัพธ์จาก FastAPI:**
|
|
|
- **Will watch for changes**: เปิดใช้งานการรีโหลดอัตโนมัติสำหรับการพัฒนา
|
|
|
- **Uvicorn running**: เซิร์ฟเวอร์ ASGI ประสิทธิภาพสูงกำลังทำงาน
|
|
|
- **Started reloader process**: ตัวตรวจจับไฟล์สำหรับรีสตาร์ทอัตโนมัติ
|
|
|
- **Application startup complete**: แอป FastAPI เริ่มทำงานสำเร็จ
|
|
|
- **Interactive docs available**: เยี่ยมชม `/docs` สำหรับเอกสาร API อัตโนมัติ
|
|
|
|
|
|
#### การทดสอบ FastAPI ของคุณ: หลายวิธีที่ทรงพลัง
|
|
|
|
|
|
FastAPI มีวิธีง่ายๆ หลายวิธีในการทดสอบ API ของคุณ รวมถึงเอกสาร API แบบโต้ตอบอัตโนมัติ:
|
|
|
|
|
|
**วิธีที่ 1: เอกสาร API แบบโต้ตอบ (แนะนำ)**
|
|
|
1. เปิดเบราว์เซอร์และไปที่ `http://localhost:5000/docs`
|
|
|
2. คุณจะเห็น Swagger UI ที่แสดงจุดเชื่อมต่อทั้งหมดของคุณ
|
|
|
3. คลิกที่ `/hello` → "Try it out" → ป้อนข้อความทดสอบ → "Execute"
|
|
|
4. ดูผลลัพธ์ตอบกลับทันทีในเบราว์เซอร์พร้อมรูปแบบที่เหมาะสม
|
|
|
|
|
|
**วิธีที่ 2: ทดสอบด้วยเบราว์เซอร์แบบพื้นฐาน**
|
|
|
1. ไปที่ `http://localhost:5000` สำหรับจุดเชื่อมต่อรูท
|
|
|
2. ไปที่ `http://localhost:5000/health` เพื่อตรวจสอบสถานะเซิร์ฟเวอร์
|
|
|
3. วิธีนี้ยืนยันว่าเซิร์ฟเวอร์ FastAPI ของคุณทำงานได้อย่างถูกต้อง
|
|
|
|
|
|
**วิธีที่ 2: ทดสอบด้วยบรรทัดคำสั่ง (ขั้นสูง)**
|
|
|
```bash
|
|
|
# ทดสอบด้วย curl (ถ้ามี)
|
|
|
curl -X POST http://localhost:5000/hello \
|
|
|
-H "Content-Type: application/json" \
|
|
|
-d '{"message": "Hello AI!"}'
|
|
|
|
|
|
# คำตอบที่คาดหวัง:
|
|
|
# {"response": "สวัสดี! ฉันคือผู้ช่วย AI ของคุณ มีอะไรให้ช่วยวันนี้ไหม?"}
|
|
|
```
|
|
|
|
|
|
**วิธีที่ 3: สคริปต์ทดสอบ Python**
|
|
|
```python
|
|
|
# test_api.py - สร้างไฟล์นี้เพื่อทดสอบ API ของคุณ
|
|
|
import requests
|
|
|
import json
|
|
|
|
|
|
# ทดสอบจุดสิ้นสุด API
|
|
|
url = "http://localhost:5000/hello"
|
|
|
data = {"message": "Tell me a joke about programming"}
|
|
|
|
|
|
response = requests.post(url, json=data)
|
|
|
if response.status_code == 200:
|
|
|
result = response.json()
|
|
|
print("AI Response:", result['response'])
|
|
|
else:
|
|
|
print("Error:", response.status_code, response.text)
|
|
|
```
|
|
|
|
|
|
#### การแก้ไขปัญหาปัญหาเริ่มต้นทั่วไป
|
|
|
|
|
|
| ข้อความแสดงข้อผิดพลาด | ความหมาย | วิธีแก้ไข |
|
|
|
|---------------|---------------|------------|
|
|
|
| `ModuleNotFoundError: No module named 'fastapi'` | ยังไม่ได้ติดตั้ง FastAPI | รัน `pip install fastapi uvicorn` ใน virtual environment ของคุณ |
|
|
|
| `ModuleNotFoundError: No module named 'uvicorn'` | ยังไม่ได้ติดตั้งเซิร์ฟเวอร์ ASGI | รัน `pip install uvicorn` ใน virtual environment ของคุณ |
|
|
|
| `KeyError: 'GITHUB_TOKEN'` | ไม่พบตัวแปรสภาพแวดล้อม | ตรวจสอบไฟล์ `.env` และการเรียก `load_dotenv()` |
|
|
|
| `Address already in use` | พอร์ต 5000 ถูกใช้งานอยู่ | ปิดโปรเซสที่ใช้พอร์ต 5000 หรือเปลี่ยนพอร์ต |
|
|
|
| `ValidationError` | ข้อมูลคำขอไม่ตรงกับโมเดล Pydantic | ตรวจสอบรูปแบบคำขอให้ตรงกับสคีมา |
|
|
|
| `HTTPException 422` | ข้อมูลไม่ผ่านการประมวลผล | การตรวจสอบคำขอผิดพลาด, ตรวจสอบ `/docs` สำหรับรูปแบบที่ถูกต้อง |
|
|
|
| `OpenAI API error` | การยืนยันตัวตนบริการ AI ล้มเหลว | ตรวจสอบว่าท็อกเค็น GitHub ของคุณถูกต้องและมีสิทธิ์เหมาะสม |
|
|
|
|
|
|
#### แนวปฏิบัติที่ดีที่สุดสำหรับการพัฒนา
|
|
|
|
|
|
**รีโหลดร้อน**: FastAPI ร่วมกับ Uvicorn มีระบบรีโหลดอัตโนมัติเมื่อคุณบันทึกการเปลี่ยนแปลงในไฟล์ Python ของคุณ หมายความว่าคุณสามารถแก้ไขโค้ดและทดสอบได้ทันทีโดยไม่ต้องรีสตาร์ทด้วยตนเอง
|
|
|
|
|
|
```python
|
|
|
# เปิดใช้งานการโหลดร้อนอย่างชัดเจน
|
|
|
if __name__ == "__main__":
|
|
|
app.run(host="0.0.0.0", port=5000, debug=True) # debug=True เปิดใช้งานการโหลดร้อน
|
|
|
```
|
|
|
|
|
|
**การบันทึกข้อมูลสำหรับการพัฒนา**: เพิ่มการบันทึกข้อมูลเพื่อเข้าใจสิ่งที่เกิดขึ้น:
|
|
|
|
|
|
```python
|
|
|
import logging
|
|
|
|
|
|
# ตั้งค่าการบันทึกล็อก
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@app.route("/hello", methods=["POST"])
|
|
|
def hello():
|
|
|
data = request.get_json()
|
|
|
message = data.get("message", "")
|
|
|
|
|
|
logger.info(f"Received message: {message}")
|
|
|
|
|
|
if not message:
|
|
|
logger.warning("Empty message received")
|
|
|
return jsonify({"error": "Message field is required"}), 400
|
|
|
|
|
|
try:
|
|
|
response = call_llm(message, "You are a helpful and friendly assistant.")
|
|
|
logger.info(f"AI response generated successfully")
|
|
|
return jsonify({"response": response})
|
|
|
except Exception as e:
|
|
|
logger.error(f"AI API error: {str(e)}")
|
|
|
return jsonify({"error": "AI service temporarily unavailable"}), 500
|
|
|
```
|
|
|
|
|
|
**ทำไมการบันทึกช่วยได้**: ในระหว่างพัฒนา คุณจะเห็นคำขอที่เข้ามา สิ่งที่ AI ตอบกลับ และจุดที่เกิดข้อผิดพลาด ซึ่งทำให้การดีบักรวดเร็วขึ้นมาก
|
|
|
|
|
|
### การกำหนดค่า GitHub Codespaces: การพัฒนาในคลาวด์ที่ง่ายดาย
|
|
|
|
|
|
GitHub Codespaces เหมือนกับมีเครื่องคอมพิวเตอร์พัฒนาโปรแกรมที่ทรงพลังในคลาวด์ซึ่งคุณสามารถเข้าถึงได้จากเบราว์เซอร์ใดก็ได้ หากคุณทำงานใน Codespaces จะมีขั้นตอนเพิ่มเติมเล็กน้อยเพื่อทำให้แบ็กเอนด์ของคุณเข้าถึงได้จากส่วนหน้า
|
|
|
|
|
|
#### ทำความเข้าใจกับเครือข่ายใน Codespaces
|
|
|
|
|
|
ในสภาพแวดล้อมพัฒนาในเครื่อง ทุกอย่างรันบนคอมพิวเตอร์เครื่องเดียวกัน:
|
|
|
- แบ็กเอนด์: `http://localhost:5000`
|
|
|
- ส่วนหน้า: `http://localhost:3000` (หรือ file://)
|
|
|
|
|
|
ใน Codespaces สภาพแวดล้อมการพัฒนาของคุณรันบนเซิร์ฟเวอร์ของ GitHub ดังนั้น "localhost" จะมีความหมายต่างกัน GitHub จะสร้าง URL สาธารณะสำหรับบริการของคุณโดยอัตโนมัติ แต่คุณต้องกำหนดค่าอย่างเหมาะสม
|
|
|
|
|
|
#### การกำหนดค่า Codespaces ทีละขั้นตอน
|
|
|
|
|
|
**1. เริ่มเซิร์ฟเวอร์แบ็กเอนด์ของคุณ**:
|
|
|
```bash
|
|
|
cd backend
|
|
|
python api.py
|
|
|
```
|
|
|
|
|
|
คุณจะเห็นข้อความเริ่มต้น FastAPI/Uvicorn ที่คุ้นเคย แต่สังเกตว่ากำลังรันภายในสภาพแวดล้อม Codespace
|
|
|
|
|
|
**2. กำหนดการมองเห็นพอร์ต**:
|
|
|
- มองหาแท็บ "Ports" ในแผงล่างของ VS Code
|
|
|
- หาพอร์ต 5000 ในรายการ
|
|
|
- คลิกขวาที่พอร์ต 5000
|
|
|
- เลือก "Port Visibility" → "Public"
|
|
|
|
|
|
**ทำไมต้องเป็นสาธารณะ?** ตามค่าเริ่มต้นพอร์ตใน Codespace จะเป็นส่วนตัว (เข้าถึงได้เฉพาะคุณเท่านั้น) การตั้งเป็นสาธารณะช่วยให้ส่วนหน้าซึ่งรันในเบราว์เซอร์สามารถสื่อสารกับแบ็กเอนด์ได้
|
|
|
|
|
|
**3. รับ URL สาธารณะของคุณ**:
|
|
|
หลังจากกำหนดพอร์ตเป็นสาธารณะ คุณจะเห็น URL แบบนี้:
|
|
|
```
|
|
|
https://your-codespace-name-5000.app.github.dev
|
|
|
```
|
|
|
|
|
|
**4. ปรับปรุงการกำหนดค่าของส่วนหน้า**:
|
|
|
```javascript
|
|
|
// ในไฟล์ app.js ของ frontend ของคุณ ให้ปรับ BASE_URL:
|
|
|
this.BASE_URL = "https://your-codespace-name-5000.app.github.dev";
|
|
|
```
|
|
|
|
|
|
#### ทำความเข้าใจกับ URL ของ Codespace
|
|
|
|
|
|
URL ของ Codespace มีรูปแบบที่คาดเดาได้:
|
|
|
```
|
|
|
https://[codespace-name]-[port].app.github.dev
|
|
|
```
|
|
|
|
|
|
**แยกส่วนประกอบ**:
|
|
|
- `codespace-name`: ตัวระบุเฉพาะของ Codespace ของคุณ (โดยปกติจะมีชื่อผู้ใช้ของคุณ)
|
|
|
- `port`: หมายเลขพอร์ตที่บริการของคุณกำลังรัน (5000 สำหรับแอป FastAPI ของเรา)
|
|
|
- `app.github.dev`: โดเมนของ GitHub สำหรับแอป Codespace
|
|
|
|
|
|
#### การทดสอบการตั้งค่า Codespace ของคุณ
|
|
|
|
|
|
**1. ทดสอบแบ็กเอนด์โดยตรง**:
|
|
|
เปิด URL สาธารณะในแท็บเบราว์เซอร์ใหม่ คุณควรเห็น:
|
|
|
```
|
|
|
Welcome to the AI Chat API. Send POST requests to /hello with JSON payload containing 'message' field.
|
|
|
```
|
|
|
|
|
|
**2. ทดสอบด้วยเครื่องมือสำหรับนักพัฒนาเบราว์เซอร์**:
|
|
|
```javascript
|
|
|
// เปิดคอนโซลของเบราว์เซอร์และทดสอบ API ของคุณ
|
|
|
fetch('https://your-codespace-name-5000.app.github.dev/hello', {
|
|
|
method: 'POST',
|
|
|
headers: {'Content-Type': 'application/json'},
|
|
|
body: JSON.stringify({message: 'Hello from Codespaces!'})
|
|
|
})
|
|
|
.then(response => response.json())
|
|
|
.then(data => console.log(data));
|
|
|
```
|
|
|
|
|
|
#### Codespaces เทียบกับการพัฒนาในเครื่อง
|
|
|
|
|
|
| ด้าน | การพัฒนาในเครื่อง | GitHub Codespaces |
|
|
|
|--------|-------------------|-------------------|
|
|
|
| **เวลาติดตั้ง** | นานกว่า (ติดตั้ง Python และ dependencies) | ทันที (สภาพแวดล้อมตั้งค่าล่วงหน้า) |
|
|
|
| **การเข้าถึง URL** | `http://localhost:5000` | `https://xyz-5000.app.github.dev` |
|
|
|
| **การกำหนดค่าพอร์ต** | อัตโนมัติ | ด้วยตนเอง (ตั้งพอร์ตเป็นสาธารณะ) |
|
|
|
| **การเก็บไฟล์** | บนเครื่อง | ใน repository GitHub |
|
|
|
| **การทำงานร่วมกัน** | ยากต่อการแชร์สภาพแวดล้อม | ง่ายต่อการแชร์ลิงก์ Codespace |
|
|
|
| **การพึ่งพาอินเทอร์เน็ต** | สำหรับเรียกใช้ AI API เท่านั้น | จำเป็นสำหรับทุกอย่าง |
|
|
|
|
|
|
#### เคล็ดลับการพัฒนาใน Codespace
|
|
|
|
|
|
**ตัวแปรสภาพแวดล้อมใน Codespaces**:
|
|
|
ไฟล์ `.env` ของคุณทำงานเหมือนเดิมใน Codespaces แต่คุณยังสามารถตั้งค่าตัวแปรสภาพแวดล้อมใน Codespace ได้โดยตรง:
|
|
|
|
|
|
```bash
|
|
|
# ตั้งค่าตัวแปรสภาพแวดล้อมสำหรับเซสชันปัจจุบัน
|
|
|
export GITHUB_TOKEN="your_token_here"
|
|
|
|
|
|
# หรือเพิ่มในไฟล์ .bashrc ของคุณเพื่อความคงทน
|
|
|
echo 'export GITHUB_TOKEN="your_token_here"' >> ~/.bashrc
|
|
|
```
|
|
|
|
|
|
**การจัดการพอร์ต**:
|
|
|
- Codespaces จะตรวจจับเมื่อแอปของคุณเริ่มฟังที่พอร์ต
|
|
|
- คุณสามารถส่งต่อพอร์ตหลายพอร์ตพร้อมกันได้ (มีประโยชน์เมื่อติดตั้งฐานข้อมูลในอนาคต)
|
|
|
- พอร์ตจะยังคงเข้าถึงได้ตราบใดที่ Codespace ของคุณยังทำงานอยู่
|
|
|
|
|
|
**เวิร์กโฟลว์การพัฒนา**:
|
|
|
1. แก้ไขโค้ดใน VS Code
|
|
|
2. FastAPI รีโหลดอัตโนมัติ (ด้วยโหมดรีโหลดของ Uvicorn)
|
|
|
3. ทดสอบการเปลี่ยนแปลงทันทีผ่าน URL สาธารณะ
|
|
|
4. คอมมิตและพุชเมื่อพร้อม
|
|
|
|
|
|
> 💡 **เคล็ดลับโปร**: บุ๊กมาร์ก URL แบ็กเอนด์ของ Codespace ในระหว่างการพัฒนา เนื่องจากชื่อ Codespace มีความคงที่ URL จะไม่เปลี่ยนแปลงตราบใดที่คุณใช้ Codespace เดิม
|
|
|
|
|
|
## การสร้างอินเทอร์เฟซแชทส่วนหน้า: จุดที่มนุษย์พบ AI
|
|
|
|
|
|
ตอนนี้เราจะสร้างอินเทอร์เฟซผู้ใช้ — ส่วนที่กำหนดว่าผู้คนโต้ตอบกับผู้ช่วย AI ของคุณอย่างไร เช่นเดียวกับการออกแบบอินเทอร์เฟซต้นฉบับของไอโฟน เรามุ่งเน้นทำให้เทคโนโลยีที่ซับซ้อนรู้สึกเป็นธรรมชาติและเข้าใจง่ายในการใช้งาน
|
|
|
|
|
|
### ทำความเข้าใจกับสถาปัตยกรรมส่วนหน้าสมัยใหม่
|
|
|
|
|
|
อินเทอร์เฟซแชทของเราจะเป็น "Single Page Application" หรือ SPA แทนที่จะใช้วิธีเก่าที่ทุกคลิกโหลดหน้าใหม่ แอปของเราจะอัพเดตอย่างราบรื่นและทันที:
|
|
|
|
|
|
**เว็บไซต์แบบเก่า**: เหมือนการอ่านหนังสือเล่มที่จริง – คุณพลิกไปหน้าใหม่ทั้งหมด
|
|
|
**แอปแชทของเรา**: เหมือนใช้โทรศัพท์ – ทุกอย่างไหลและอัพเดตอย่างต่อเนื่อง
|
|
|
|
|
|
```mermaid
|
|
|
graph TD
|
|
|
A[ผู้ใช้พิมพ์ข้อความ] --> B[JavaScript จับข้อมูลอินพุต]
|
|
|
B --> C[ตรวจสอบและจัดรูปแบบข้อมูล]
|
|
|
C --> D[ส่งไปยัง API ฝั่งเซิร์ฟเวอร์]
|
|
|
D --> E[แสดงสถานะกำลังโหลด]
|
|
|
E --> F[ได้รับการตอบกลับจาก AI]
|
|
|
F --> G[อัปเดตอินเทอร์เฟซแชท]
|
|
|
G --> H[พร้อมสำหรับข้อความถัดไป]
|
|
|
```
|
|
|
```mermaid
|
|
|
classDiagram
|
|
|
class ChatApp {
|
|
|
+messages: HTMLElement
|
|
|
+form: HTMLElement
|
|
|
+input: HTMLElement
|
|
|
+sendButton: HTMLElement
|
|
|
+BASE_URL: string
|
|
|
+API_ENDPOINT: string
|
|
|
|
|
|
+constructor()
|
|
|
+initializeEventListeners()
|
|
|
+handleSubmit(event)
|
|
|
+callAPI(message)
|
|
|
+appendMessage(ข้อความ, บทบาท)
|
|
|
+escapeHtml(ข้อความ)
|
|
|
+scrollToBottom()
|
|
|
+setLoading(กำลังโหลด)
|
|
|
}
|
|
|
|
|
|
ChatApp --> DOM : จัดการ
|
|
|
ChatApp --> FastAPI : ส่งคำขอ
|
|
|
```
|
|
|
### เสาหลักสามประการของการพัฒนาส่วนหน้า
|
|
|
|
|
|
แอปพลิเคชันส่วนหน้าทุกตัว – ตั้งแต่เว็บไซต์ธรรมดาจนถึงแอปซับซ้อนอย่าง Discord หรือ Slack – สร้างขึ้นบนสามเทคโนโลยีหลัก ลองคิดว่าเป็นรากฐานของทุกสิ่งที่คุณเห็นและโต้ตอบบนเว็บ:
|
|
|
|
|
|
**HTML (โครงสร้าง)**: นี่คือรากฐานของคุณ
|
|
|
- กำหนดองค์ประกอบที่มีอยู่ (ปุ่ม, พื้นที่ข้อความ, คอนเทนเนอร์)
|
|
|
- ให้ความหมายกับเนื้อหา (นี่คือหัวเรื่อง, นี่คือแบบฟอร์ม ฯลฯ)
|
|
|
- สร้างโครงสร้างพื้นฐานที่ทุกอย่างอื่นขึ้นอยู่บนนี้
|
|
|
|
|
|
**CSS (รูปแบบการนำเสนอ)**: นี่คือผู้ออกแบบภายในของคุณ
|
|
|
- ทำให้ทุกอย่างดูสวยงาม (สี, ฟอนต์, เค้าโครง)
|
|
|
- รองรับขนาดหน้าจอที่แตกต่างกัน (โทรศัพท์ vs แล็ปท็อป vs แท็บเล็ต)
|
|
|
- สร้างแอนิเมชันที่นุ่มนวลและการตอบสนองทางสายตา
|
|
|
|
|
|
**JavaScript (พฤติกรรม)**: นี่คือสมองของคุณ
|
|
|
- ตอบสนองต่อสิ่งที่ผู้ใช้ทำ (คลิก, พิมพ์, เลื่อน)
|
|
|
- สื่อสารกับแบ็กเอนด์และอัพเดตหน้าเว็บ
|
|
|
- ทำให้ทุกอย่างโต้ตอบและมีไดนามิก
|
|
|
|
|
|
**คิดเหมือนเป็นการออกแบบสถาปัตยกรรม:**
|
|
|
- **HTML**: แบบแปลนโครงสร้าง (กำหนดพื้นที่และความสัมพันธ์)
|
|
|
- **CSS**: การออกแบบสไตล์และสิ่งแวดล้อม (สไตล์ภาพและประสบการณ์ผู้ใช้)
|
|
|
- **JavaScript**: ระบบกลไก (ฟังก์ชันและการโต้ตอบ)
|
|
|
|
|
|
### ทำไมสถาปัตยกรรม JavaScript สมัยใหม่จึงสำคัญ
|
|
|
|
|
|
แอปแชทของเราจะใช้รูปแบบ JavaScript สมัยใหม่ที่คุณจะเห็นในแอปมืออาชีพ การเข้าใจแนวคิดเหล่านี้จะช่วยคุณเมื่อเติบโตเป็นนักพัฒนาซอฟต์แวร์:
|
|
|
|
|
|
**สถาปัตยกรรมแบบคลาส**: เราจะจัดระเบียบโค้ดเป็นคลาส เหมือนการสร้างแบบแปลนสำหรับวัตถุ
|
|
|
**Async/Await**: วิธีสมัยใหม่ในการจัดการงานที่ใช้เวลา (เช่น การเรียก API)
|
|
|
**การเขียนโปรแกรมแบบอีเวนต์ไดรฟ์**: แอปของเราตอบสนองกับการกระทำของผู้ใช้ (คลิก, กดคีย์) แทนการทำงานแบบลูป
|
|
|
**การจัดการ DOM**: การอัปเดตเนื้อหาเว็บเพจแบบไดนามิกตามการโต้ตอบของผู้ใช้และผลลัพธ์ API
|
|
|
|
|
|
### การตั้งค่าโครงสร้างโปรเจค
|
|
|
|
|
|
สร้างไดเรกทอรีส่วนหน้าโดยมีโครงสร้างที่จัดระเบียบดังนี้:
|
|
|
|
|
|
```text
|
|
|
frontend/
|
|
|
├── index.html # Main HTML structure
|
|
|
├── app.js # JavaScript functionality
|
|
|
└── styles.css # Visual styling
|
|
|
```
|
|
|
|
|
|
**ทำความเข้าใจกับสถาปัตยกรรม:**
|
|
|
- **แยก** ความกังวลระหว่างโครงสร้าง (HTML), พฤติกรรม (JavaScript), และการนำเสนอ (CSS)
|
|
|
- **รักษา** โครงสร้างไฟล์ที่เรียบง่ายที่ใช้งานง่ายและแก้ไขได้สะดวก
|
|
|
- **ปฏิบัติตาม** แนวทางพัฒนาเว็บที่ดีที่สุดเพื่อความเป็นระเบียบและดูแลรักษาง่าย
|
|
|
|
|
|
### สร้างโครงสร้าง HTML พื้นฐาน: โครงสร้างตามความหมายเพื่อการเข้าถึง
|
|
|
|
|
|
เริ่มด้วยโครงสร้าง HTML การพัฒนาเว็บสมัยใหม่เน้น "semantic HTML" – การใช้แท็ก HTML ที่อธิบายวัตถุประสงค์อย่างชัดเจน ไม่ใช่แค่รูปลักษณ์ สิ่งนี้ช่วยให้แอปของคุณเข้าถึงได้สำหรับโปรแกรมอ่านหน้าจอ เครื่องมือค้นหา และเครื่องมืออื่นๆ
|
|
|
|
|
|
**ทำไม semantic HTML สำคัญ**: ลองนึกภาพอธิบายแอปแชทของคุณกับใครสักคนทางโทรศัพท์ คุณอาจพูดว่า "มีส่วนหัวพร้อมชื่อเรื่อง พื้นที่หลักที่แสดงบทสนทนา และแบบฟอร์มที่ด้านล่างสำหรับพิมพ์ข้อความ" semantic HTML ใช้องค์ประกอบที่ตรงกับคำอธิบายนี้อย่างเป็นธรรมชาติ
|
|
|
|
|
|
สร้างไฟล์ `index.html` ด้วยมาร์กอัปที่จัดวางอย่างรอบคอบดังนี้:
|
|
|
|
|
|
```html
|
|
|
<!DOCTYPE html>
|
|
|
<html lang="en">
|
|
|
<head>
|
|
|
<meta charset="UTF-8">
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
<title>AI Chat Assistant</title>
|
|
|
<link rel="stylesheet" href="styles.css">
|
|
|
</head>
|
|
|
<body>
|
|
|
<div class="chat-container">
|
|
|
<header class="chat-header">
|
|
|
<h1>AI Chat Assistant</h1>
|
|
|
<p>Ask me anything!</p>
|
|
|
</header>
|
|
|
|
|
|
<main class="chat-messages" id="messages" role="log" aria-live="polite">
|
|
|
<!-- Messages will be dynamically added here -->
|
|
|
</main>
|
|
|
|
|
|
<form class="chat-form" id="chatForm">
|
|
|
<div class="input-group">
|
|
|
<input
|
|
|
type="text"
|
|
|
id="messageInput"
|
|
|
placeholder="Type your message here..."
|
|
|
required
|
|
|
aria-label="Chat message input"
|
|
|
>
|
|
|
<button type="submit" id="sendBtn" aria-label="Send message">
|
|
|
Send
|
|
|
</button>
|
|
|
</div>
|
|
|
</form>
|
|
|
</div>
|
|
|
<script src="app.js"></script>
|
|
|
</body>
|
|
|
</html>
|
|
|
```
|
|
|
|
|
|
**ทำความเข้าใจแต่ละองค์ประกอบ HTML และวัตถุประสงค์:**
|
|
|
|
|
|
#### โครงสร้างเอกสาร
|
|
|
- **`<!DOCTYPE html>`**: แจ้งเบราว์เซอร์ว่านี่คือ HTML5 สมัยใหม่
|
|
|
- **`<html lang="en">`**: ระบุภาษาหน้าสำหรับโปรแกรมอ่านหน้าจอและเครื่องมือแปลภาษา
|
|
|
- **`<meta charset="UTF-8">`**: ทำให้มีการเข้ารหัสตัวอักษรที่ถูกต้องสำหรับข้อความหลายภาษา
|
|
|
- **`<meta name="viewport"...>`**: ทำให้เพจรองรับอุปกรณ์มือถือโดยควบคุมการซูมและการปรับสเกล
|
|
|
|
|
|
#### องค์ประกอบเชิงความหมาย
|
|
|
- **`<header>`**: บ่งบอกส่วนบนอย่างชัดเจนที่มีชื่อเรื่องและคำอธิบาย
|
|
|
- **`<main>`**: กำหนดพื้นที่เนื้อหาหลัก (ที่เกิดบทสนทนา)
|
|
|
- **`<form>`**: ถูกต้องตามหลักความหมายสำหรับการป้อนข้อมูลผู้ใช้ เปิดใช้งานการนำทางด้วยคีย์บอร์ดที่เหมาะสม
|
|
|
|
|
|
#### ฟีเจอร์การเข้าถึง
|
|
|
- **`role="log"`**: บอกโปรแกรมอ่านหน้าจอว่าพื้นที่นี้มีบันทึกรายการข้อความตามลำดับเวลา
|
|
|
- **`aria-live="polite"`**: แจ้งข้อความใหม่ให้โปรแกรมอ่านหน้าจอโดยไม่รบกวน
|
|
|
- **`aria-label`**: ให้ป้ายคำอธิบายกับคอนโทรลของแบบฟอร์ม
|
|
|
- **`required`**: เบราว์เซอร์จะตรวจสอบให้ผู้ใช้ป้อนข้อความก่อนส่ง
|
|
|
|
|
|
#### การผนวก CSS และ JavaScript
|
|
|
- **`class` attributes**: ให้ตัวเกี่ยวกับการจัดรูปแบบ CSS (เช่น `chat-container`, `input-group`)
|
|
|
- **`id` attributes**: อนุญาตให้ JavaScript หาและจัดการกับองค์ประกอบเฉพาะ
|
|
|
- **การวางสคริปต์**: โหลดไฟล์ JavaScript ที่ส่วนท้ายเพื่อให้ HTML โหลดก่อน
|
|
|
|
|
|
**ทำไมโครงสร้างนี้จึงเวิร์ค:**
|
|
|
- **ลำดับตรรกะ**: ส่วนหัว → เนื้อหาหลัก → แบบฟอร์มอินพุต ตามลำดับการอ่านตามธรรมชาติ
|
|
|
- **เข้าถึงได้ด้วยคีย์บอร์ด**: ผู้ใช้สามารถสลับผ่านองค์ประกอบโต้ตอบทุกชิ้นได้
|
|
|
- **เหมาะสำหรับโปรแกรมอ่านหน้าจอ**: มีเครื่องหมายและคำอธิบายที่ชัดเจนสำหรับผู้มีปัญหาทางสายตา
|
|
|
- **รองรับมือถือ**: แท็ก viewport ช่วยให้การออกแบบตอบสนองต่ออุปกรณ์ต่างๆ
|
|
|
- **การเพิ่มประสิทธิภาพอย่างก้าวหน้า**: ใช้งานได้แม้ CSS หรือ JavaScript ไม่โหลด
|
|
|
|
|
|
### การเพิ่ม JavaScript แบบโต้ตอบ: ตรรกะแอปเว็บสมัยใหม่
|
|
|
|
|
|
ตอนนี้เรามาสร้าง JavaScript ที่ทำให้ส่วนติดต่อแชทของเราเกิดชีวิตชีวา เราจะใช้รูปแบบ JavaScript สมัยใหม่ที่คุณจะเจอในการพัฒนาเว็บระดับมืออาชีพ รวมทั้งคลาส ES6, async/await และการเขียนโปรแกรมโดยใช้เหตุการณ์ (event-driven programming)
|
|
|
|
|
|
#### การเข้าใจสถาปัตยกรรม JavaScript สมัยใหม่
|
|
|
|
|
|
แทนที่จะเขียนโค้ดแบบลำดับขั้นตอน (ชุดของฟังก์ชันที่ทำงานตามลำดับ) เราจะสร้าง **สถาปัตยกรรมแบบคลาส** ลองคิดว่าคลาสคือแบบแปลนสำหรับสร้างอ็อบเจกต์ — เหมือนกับแบบแปลนของสถาปนิกที่สามารถใช้สร้างบ้านหลายหลังได้
|
|
|
|
|
|
**ทำไมต้องใช้คลาสสำหรับแอปเว็บ?**
|
|
|
- **การจัดระเบียบ**: ฟังก์ชันที่เกี่ยวข้องทั้งหมดถูกรวมไว้ด้วยกัน
|
|
|
- **การนำกลับมาใช้ใหม่**: คุณสามารถสร้างอินสแตนซ์แชทหลายตัวบนหน้าเดียวกันได้
|
|
|
- **การบำรุงรักษาง่าย**: ง่ายต่อการดีบักและแก้ไขฟีเจอร์เฉพาะ
|
|
|
- **มาตรฐานระดับมืออาชีพ**: รูปแบบนี้ใช้ในเฟรมเวิร์กอย่าง React, Vue, และ Angular
|
|
|
|
|
|
สร้าง `app.js` ด้วย JavaScript ที่ทันสมัยและมีโครงสร้างดีนี้:
|
|
|
|
|
|
```javascript
|
|
|
// app.js - ตรรกะแอปแชทสมัยใหม่
|
|
|
|
|
|
class ChatApp {
|
|
|
constructor() {
|
|
|
// ดึงอ้างอิงไปยังองค์ประกอบ DOM ที่เราจำเป็นต้องจัดการ
|
|
|
this.messages = document.getElementById("messages");
|
|
|
this.form = document.getElementById("chatForm");
|
|
|
this.input = document.getElementById("messageInput");
|
|
|
this.sendButton = document.getElementById("sendBtn");
|
|
|
|
|
|
// กำหนดค่า URL ของ backend ที่นี่
|
|
|
this.BASE_URL = "http://localhost:5000"; // อัปเดตตามสภาพแวดล้อมของคุณ
|
|
|
this.API_ENDPOINT = `${this.BASE_URL}/hello`;
|
|
|
|
|
|
// ตั้งค่าตัวฟังเหตุการณ์เมื่อแอปแชทถูกสร้าง
|
|
|
this.initializeEventListeners();
|
|
|
}
|
|
|
|
|
|
initializeEventListeners() {
|
|
|
// ฟังการส่งฟอร์ม (เมื่อผู้ใช้คลิกส่งหรือกด Enter)
|
|
|
this.form.addEventListener("submit", (e) => this.handleSubmit(e));
|
|
|
|
|
|
// ฟังการกดปุ่ม Enter ในช่องป้อนข้อมูลด้วย (ประสบการณ์ผู้ใช้ที่ดีกว่า)
|
|
|
this.input.addEventListener("keypress", (e) => {
|
|
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
|
e.preventDefault();
|
|
|
this.handleSubmit(e);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
async handleSubmit(event) {
|
|
|
event.preventDefault(); // ป้องกันไม่ให้ฟอร์มรีเฟรชหน้าเว็บ
|
|
|
|
|
|
const messageText = this.input.value.trim();
|
|
|
if (!messageText) return; // อย่าส่งข้อความว่างเปล่า
|
|
|
|
|
|
// แจ้งผู้ใช้ว่ากำลังดำเนินการบางอย่าง
|
|
|
this.setLoading(true);
|
|
|
|
|
|
// เพิ่มข้อความของผู้ใช้ในแชททันที (UI แบบมุ่งหวัง)
|
|
|
this.appendMessage(messageText, "user");
|
|
|
|
|
|
// เคลียร์ช่องป้อนข้อมูลเพื่อให้ผู้ใช้พิมพ์ข้อความถัดไป
|
|
|
this.input.value = '';
|
|
|
|
|
|
try {
|
|
|
// เรียกใช้ API AI และรอการตอบกลับ
|
|
|
const reply = await this.callAPI(messageText);
|
|
|
|
|
|
// เพิ่มการตอบกลับของ AI ในแชท
|
|
|
this.appendMessage(reply, "assistant");
|
|
|
} catch (error) {
|
|
|
console.error('API Error:', error);
|
|
|
this.appendMessage("Sorry, I'm having trouble connecting right now. Please try again.", "error");
|
|
|
} finally {
|
|
|
// เปิดใช้งานอินเทอร์เฟซอีกครั้งไม่ว่าจะสำเร็จหรือล้มเหลว
|
|
|
this.setLoading(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
async callAPI(message) {
|
|
|
const response = await fetch(this.API_ENDPOINT, {
|
|
|
method: "POST",
|
|
|
headers: {
|
|
|
"Content-Type": "application/json"
|
|
|
},
|
|
|
body: JSON.stringify({ message })
|
|
|
});
|
|
|
|
|
|
if (!response.ok) {
|
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
}
|
|
|
|
|
|
const data = await response.json();
|
|
|
return data.response;
|
|
|
}
|
|
|
|
|
|
appendMessage(text, role) {
|
|
|
const messageElement = document.createElement("div");
|
|
|
messageElement.className = `message ${role}`;
|
|
|
messageElement.innerHTML = `
|
|
|
<div class="message-content">
|
|
|
<span class="message-text">${this.escapeHtml(text)}</span>
|
|
|
<span class="message-time">${new Date().toLocaleTimeString()}</span>
|
|
|
</div>
|
|
|
`;
|
|
|
|
|
|
this.messages.appendChild(messageElement);
|
|
|
this.scrollToBottom();
|
|
|
}
|
|
|
|
|
|
escapeHtml(text) {
|
|
|
const div = document.createElement('div');
|
|
|
div.textContent = text;
|
|
|
return div.innerHTML;
|
|
|
}
|
|
|
|
|
|
scrollToBottom() {
|
|
|
this.messages.scrollTop = this.messages.scrollHeight;
|
|
|
}
|
|
|
|
|
|
setLoading(isLoading) {
|
|
|
this.sendButton.disabled = isLoading;
|
|
|
this.input.disabled = isLoading;
|
|
|
this.sendButton.textContent = isLoading ? "Sending..." : "Send";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// เริ่มต้นแอปแชทเมื่อหน้าโหลดแล้ว
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
|
new ChatApp();
|
|
|
});
|
|
|
```
|
|
|
|
|
|
#### ทำความเข้าใจกับแต่ละแนวคิดของ JavaScript
|
|
|
|
|
|
**โครงสร้างคลาส ES6**:
|
|
|
```javascript
|
|
|
class ChatApp {
|
|
|
constructor() {
|
|
|
// นี่ทำงานเมื่อคุณสร้างอินสแตนซ์ ChatApp ใหม่
|
|
|
// มันเหมือนกับฟังก์ชัน "ตั้งค่า" สำหรับแชทของคุณ
|
|
|
}
|
|
|
|
|
|
methodName() {
|
|
|
// เมธอดคือฟังก์ชันที่เป็นของคลาส
|
|
|
// พวกมันสามารถเข้าถึงคุณสมบัติของคลาสโดยใช้ "this"
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**รูปแบบ Async/Await**:
|
|
|
```javascript
|
|
|
// วิธีเก่า (นรก callback):
|
|
|
fetch(url)
|
|
|
.then(response => response.json())
|
|
|
.then(data => console.log(data))
|
|
|
.catch(error => console.error(error));
|
|
|
|
|
|
// วิธีสมัยใหม่ (async/await):
|
|
|
try {
|
|
|
const response = await fetch(url);
|
|
|
const data = await response.json();
|
|
|
console.log(data);
|
|
|
} catch (error) {
|
|
|
console.error(error);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**การเขียนโปรแกรมแบบขับเคลื่อนด้วยเหตุการณ์**:
|
|
|
แทนที่จะตรวจสอบว่ามีอะไรเกิดขึ้นบ่อย ๆ เราจะ "ฟัง" เหตุการณ์:
|
|
|
```javascript
|
|
|
// เมื่อส่งฟอร์ม ให้รัน handleSubmit
|
|
|
this.form.addEventListener("submit", (e) => this.handleSubmit(e));
|
|
|
|
|
|
// เมื่อกดปุ่ม Enter ก็ให้รัน handleSubmit ด้วยเช่นกัน
|
|
|
this.input.addEventListener("keypress", (e) => { /* ... */ });
|
|
|
```
|
|
|
|
|
|
**การจัดการ DOM**:
|
|
|
```javascript
|
|
|
// สร้างองค์ประกอบใหม่
|
|
|
const messageElement = document.createElement("div");
|
|
|
|
|
|
// ปรับแก้คุณสมบัติของพวกมัน
|
|
|
messageElement.className = "message user";
|
|
|
messageElement.innerHTML = "Hello world!";
|
|
|
|
|
|
// เพิ่มเข้าหน้าเพจ
|
|
|
this.messages.appendChild(messageElement);
|
|
|
```
|
|
|
|
|
|
#### ความปลอดภัยและแนวทางปฏิบัติที่ดีที่สุด
|
|
|
|
|
|
**การป้องกัน XSS**:
|
|
|
```javascript
|
|
|
escapeHtml(text) {
|
|
|
const div = document.createElement('div');
|
|
|
div.textContent = text; // นี่คือการหนีอักขระ HTML อัตโนมัติ
|
|
|
return div.innerHTML;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**ทำไมเรื่องนี้ถึงสำคัญ**: หากผู้ใช้พิมพ์ `<script>alert('hack')</script>` ฟังก์ชันนี้จะทำให้แสดงเป็นข้อความแทนที่จะรันเป็นโค้ด
|
|
|
|
|
|
**การจัดการข้อผิดพลาด**:
|
|
|
```javascript
|
|
|
try {
|
|
|
const reply = await this.callAPI(messageText);
|
|
|
this.appendMessage(reply, "assistant");
|
|
|
} catch (error) {
|
|
|
// แสดงข้อผิดพลาดที่เข้าใจง่ายสำหรับผู้ใช้แทนการทำใหแอปพัง
|
|
|
this.appendMessage("Sorry, I'm having trouble...", "error");
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**ข้อควรพิจารณาด้านประสบการณ์ผู้ใช้ (User Experience)**:
|
|
|
- **UI แบบ Optimistic**: เพิ่มข้อความของผู้ใช้ทันทีโดยไม่รอการตอบกลับจากเซิร์ฟเวอร์
|
|
|
- **สถานะโหลด**: ปิดใช้งานปุ่มและแสดงข้อความ "กำลังส่ง..." ขณะรอ
|
|
|
- **เลื่อนอัตโนมัติ**: ให้ข้อความใหม่ล่าสุดมองเห็นได้เสมอ
|
|
|
- **การตรวจสอบความถูกต้องของอินพุต**: ไม่ส่งข้อความว่าง
|
|
|
- **ทางลัดแป้นพิมพ์**: กด Enter เพื่อส่งข้อความ (เหมือนแอปแชทจริง)
|
|
|
|
|
|
#### ทำความเข้าใจกระบวนการทำงานของแอปพลิเคชัน
|
|
|
|
|
|
1. **โหลดหน้าเว็บ** → เหตุการณ์ `DOMContentLoaded` ถูกเรียก → สร้าง `new ChatApp()`
|
|
|
2. **เรียกใช้งานคอนสตรัคเตอร์** → ดึงอ้างอิงอิลิเมนต์ DOM → ตั้งค่า event listeners
|
|
|
3. **ผู้ใช้พิมพ์ข้อความ** → กด Enter หรือคลิกส่ง → เรียก `handleSubmit`
|
|
|
4. **handleSubmit** → ตรวจสอบอินพุต → แสดงสถานะกำลังโหลด → เรียก API
|
|
|
5. **API ตอบกลับ** → เพิ่มข้อความ AI ในแชท → เปิดใช้งานอินเทอร์เฟซ
|
|
|
6. **พร้อมรับข้อความถัดไป** → ผู้ใช้สามารถแชทต่อได้
|
|
|
|
|
|
สถาปัตยกรรมนี้ขยายได้ง่าย — คุณสามารถเพิ่มฟีเจอร์อย่างการแก้ไขข้อความ, การอัปโหลดไฟล์ หรือหลายเส้นเรื่องการสนทนาโดยไม่ต้องเขียนใหม่โครงสร้างหลัก
|
|
|
|
|
|
### 🎯 เช็กความเข้าใจเชิงการสอน: สถาปัตยกรรม Frontend สมัยใหม่
|
|
|
|
|
|
**การเข้าใจสถาปัตยกรรม**: คุณได้สร้างแอปหน้าเดียวที่สมบูรณ์โดยใช้รูปแบบ JavaScript สมัยใหม่ ซึ่งเป็นตัวแทนของการพัฒนา frontend ระดับมืออาชีพ
|
|
|
|
|
|
**แนวคิดสำคัญที่ควบคุมได้**:
|
|
|
- **สถาปัตยกรรมคลาส ES6**: โครงสร้างโค้ดที่จัดระเบียบและดูแลรักษาง่าย
|
|
|
- **รูปแบบ Async/Await**: การเขียนโปรแกรมแบบอะซิงโครนัสสมัยใหม่
|
|
|
- **การเขียนโปรแกรมแบบขับเคลื่อนด้วยเหตุการณ์**: การออกแบบอินเทอร์เฟซตอบสนองผู้ใช้
|
|
|
- **แนวทางปฏิบัติด้านความปลอดภัย**: ป้องกัน XSS และตรวจสอบความถูกต้องของอินพุต
|
|
|
|
|
|
**การเชื่อมต่อกับอุตสาหกรรม**: รูปแบบที่คุณเรียนรู้ (สถาปัตยกรรมแบบคลาส, งานอะซิงค์, การจัดการ DOM) คือรากฐานของเฟรมเวิร์กสมัยใหม่อย่าง React, Vue และ Angular คุณกำลังสร้างด้วยแนวคิดสถาปัตยกรรมเดียวกับที่ใช้ในแอปจริง
|
|
|
|
|
|
**คำถามสะท้อน**: คุณจะขยายแอปแชทนี้อย่างไรให้รองรับหลายบทสนทนาหรือการยืนยันตัวผู้ใช้? คิดถึงการเปลี่ยนแปลงสถาปัตยกรรมที่จำเป็นและวิวัฒนาการของโครงสร้างคลาส
|
|
|
|
|
|
### การตกแต่งอินเทอร์เฟซแชทของคุณ
|
|
|
|
|
|
มาสร้างอินเทอร์เฟซแชทที่ทันสมัยและดูดีด้วย CSS กัน การตกแต่งดีจะช่วยให้แอปของคุณดูมืออาชีพและปรับปรุงประสบการณ์ผู้ใช้โดยรวม เราจะใช้ฟีเจอร์ CSS สมัยใหม่ เช่น Flexbox, CSS Grid และตัวแปรกำหนดเองสำหรับการออกแบบที่ตอบสนองและเข้าถึงได้
|
|
|
|
|
|
สร้าง `styles.css` ด้วยสไตล์ครบถ้วนดังนี้:
|
|
|
|
|
|
```css
|
|
|
/* styles.css - Modern chat interface styling */
|
|
|
|
|
|
:root {
|
|
|
--primary-color: #2563eb;
|
|
|
--secondary-color: #f1f5f9;
|
|
|
--user-color: #3b82f6;
|
|
|
--assistant-color: #6b7280;
|
|
|
--error-color: #ef4444;
|
|
|
--text-primary: #1e293b;
|
|
|
--text-secondary: #64748b;
|
|
|
--border-radius: 12px;
|
|
|
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
|
}
|
|
|
|
|
|
* {
|
|
|
margin: 0;
|
|
|
padding: 0;
|
|
|
box-sizing: border-box;
|
|
|
}
|
|
|
|
|
|
body {
|
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
min-height: 100vh;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
padding: 20px;
|
|
|
}
|
|
|
|
|
|
.chat-container {
|
|
|
width: 100%;
|
|
|
max-width: 800px;
|
|
|
height: 600px;
|
|
|
background: white;
|
|
|
border-radius: var(--border-radius);
|
|
|
box-shadow: var(--shadow);
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
|
|
|
.chat-header {
|
|
|
background: var(--primary-color);
|
|
|
color: white;
|
|
|
padding: 20px;
|
|
|
text-align: center;
|
|
|
}
|
|
|
|
|
|
.chat-header h1 {
|
|
|
font-size: 1.5rem;
|
|
|
margin-bottom: 5px;
|
|
|
}
|
|
|
|
|
|
.chat-header p {
|
|
|
opacity: 0.9;
|
|
|
font-size: 0.9rem;
|
|
|
}
|
|
|
|
|
|
.chat-messages {
|
|
|
flex: 1;
|
|
|
padding: 20px;
|
|
|
overflow-y: auto;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
gap: 15px;
|
|
|
background: var(--secondary-color);
|
|
|
}
|
|
|
|
|
|
.message {
|
|
|
display: flex;
|
|
|
max-width: 80%;
|
|
|
animation: slideIn 0.3s ease-out;
|
|
|
}
|
|
|
|
|
|
.message.user {
|
|
|
align-self: flex-end;
|
|
|
}
|
|
|
|
|
|
.message.user .message-content {
|
|
|
background: var(--user-color);
|
|
|
color: white;
|
|
|
border-radius: var(--border-radius) var(--border-radius) 4px var(--border-radius);
|
|
|
}
|
|
|
|
|
|
.message.assistant {
|
|
|
align-self: flex-start;
|
|
|
}
|
|
|
|
|
|
.message.assistant .message-content {
|
|
|
background: white;
|
|
|
color: var(--text-primary);
|
|
|
border-radius: var(--border-radius) var(--border-radius) var(--border-radius) 4px;
|
|
|
border: 1px solid #e2e8f0;
|
|
|
}
|
|
|
|
|
|
.message.error .message-content {
|
|
|
background: var(--error-color);
|
|
|
color: white;
|
|
|
border-radius: var(--border-radius);
|
|
|
}
|
|
|
|
|
|
.message-content {
|
|
|
padding: 12px 16px;
|
|
|
box-shadow: var(--shadow);
|
|
|
position: relative;
|
|
|
}
|
|
|
|
|
|
.message-text {
|
|
|
display: block;
|
|
|
line-height: 1.5;
|
|
|
word-wrap: break-word;
|
|
|
}
|
|
|
|
|
|
.message-time {
|
|
|
display: block;
|
|
|
font-size: 0.75rem;
|
|
|
opacity: 0.7;
|
|
|
margin-top: 5px;
|
|
|
}
|
|
|
|
|
|
.chat-form {
|
|
|
padding: 20px;
|
|
|
border-top: 1px solid #e2e8f0;
|
|
|
background: white;
|
|
|
}
|
|
|
|
|
|
.input-group {
|
|
|
display: flex;
|
|
|
gap: 10px;
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
#messageInput {
|
|
|
flex: 1;
|
|
|
padding: 12px 16px;
|
|
|
border: 2px solid #e2e8f0;
|
|
|
border-radius: var(--border-radius);
|
|
|
font-size: 1rem;
|
|
|
outline: none;
|
|
|
transition: border-color 0.2s ease;
|
|
|
}
|
|
|
|
|
|
#messageInput:focus {
|
|
|
border-color: var(--primary-color);
|
|
|
}
|
|
|
|
|
|
#messageInput:disabled {
|
|
|
background: #f8fafc;
|
|
|
opacity: 0.6;
|
|
|
cursor: not-allowed;
|
|
|
}
|
|
|
|
|
|
#sendBtn {
|
|
|
padding: 12px 24px;
|
|
|
background: var(--primary-color);
|
|
|
color: white;
|
|
|
border: none;
|
|
|
border-radius: var(--border-radius);
|
|
|
font-size: 1rem;
|
|
|
font-weight: 600;
|
|
|
cursor: pointer;
|
|
|
transition: background-color 0.2s ease;
|
|
|
min-width: 80px;
|
|
|
}
|
|
|
|
|
|
#sendBtn:hover:not(:disabled) {
|
|
|
background: #1d4ed8;
|
|
|
}
|
|
|
|
|
|
#sendBtn:disabled {
|
|
|
background: #94a3b8;
|
|
|
cursor: not-allowed;
|
|
|
}
|
|
|
|
|
|
@keyframes slideIn {
|
|
|
from {
|
|
|
opacity: 0;
|
|
|
transform: translateY(10px);
|
|
|
}
|
|
|
to {
|
|
|
opacity: 1;
|
|
|
transform: translateY(0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Responsive design for mobile devices */
|
|
|
@media (max-width: 768px) {
|
|
|
body {
|
|
|
padding: 10px;
|
|
|
}
|
|
|
|
|
|
.chat-container {
|
|
|
height: calc(100vh - 20px);
|
|
|
border-radius: 8px;
|
|
|
}
|
|
|
|
|
|
.message {
|
|
|
max-width: 90%;
|
|
|
}
|
|
|
|
|
|
.input-group {
|
|
|
flex-direction: column;
|
|
|
gap: 10px;
|
|
|
}
|
|
|
|
|
|
#messageInput {
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
#sendBtn {
|
|
|
width: 100%;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Accessibility improvements */
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
|
.message {
|
|
|
animation: none;
|
|
|
}
|
|
|
|
|
|
* {
|
|
|
transition: none !important;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Dark mode support */
|
|
|
@media (prefers-color-scheme: dark) {
|
|
|
.chat-container {
|
|
|
background: #1e293b;
|
|
|
color: #f1f5f9;
|
|
|
}
|
|
|
|
|
|
.chat-messages {
|
|
|
background: #0f172a;
|
|
|
}
|
|
|
|
|
|
.message.assistant .message-content {
|
|
|
background: #334155;
|
|
|
color: #f1f5f9;
|
|
|
border-color: #475569;
|
|
|
}
|
|
|
|
|
|
.chat-form {
|
|
|
background: #1e293b;
|
|
|
border-color: #475569;
|
|
|
}
|
|
|
|
|
|
#messageInput {
|
|
|
background: #334155;
|
|
|
color: #f1f5f9;
|
|
|
border-color: #475569;
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**เข้าใจสถาปัตยกรรม CSS:**
|
|
|
- **ใช้** ตัวแปร CSS (custom properties) เพื่อการทำธีมที่สม่ำเสมอและการบำรุงรักษาง่าย
|
|
|
- **นำไปใช้** เลย์เอาต์ Flexbox สำหรับการออกแบบตอบสนองและจัดตำแหน่งที่เหมาะสม
|
|
|
- **รวม** การเคลื่อนไหวที่นุ่มนวลสำหรับการแสดงผลข้อความโดยไม่รบกวน
|
|
|
- **ให้** การแยกแยะภาพระหว่างข้อความผู้ใช้, การตอบของ AI, และสถานะข้อผิดพลาด
|
|
|
- **รองรับ** การออกแบบตอบสนองที่ใช้งานได้ทั้งเดสก์ท็อปและมือถือ
|
|
|
- **พิจารณา** การเข้าถึงด้วยการลดการเคลื่อนไหวและอัตราความคอนทราสต์ที่เหมาะสม
|
|
|
- **มี** โหมดมืดตามการตั้งค่าของระบบผู้ใช้
|
|
|
|
|
|
### การตั้งค่า URL Backend ของคุณ
|
|
|
|
|
|
ขั้นตอนสุดท้ายคือการอัปเดต `BASE_URL` ใน JavaScript ให้ตรงกับเซิร์ฟเวอร์ backend ของคุณ:
|
|
|
|
|
|
```javascript
|
|
|
// สำหรับการพัฒนาในเครื่อง
|
|
|
this.BASE_URL = "http://localhost:5000";
|
|
|
|
|
|
// สำหรับ GitHub Codespaces (แทนที่ด้วย URL จริงของคุณ)
|
|
|
this.BASE_URL = "https://your-codespace-name-5000.app.github.dev";
|
|
|
```
|
|
|
|
|
|
**การกำหนด URL backend ของคุณ:**
|
|
|
- **การพัฒนาในเครื่อง (Local development)**: ใช้ `http://localhost:5000` หากรันทั้ง frontend และ backend ในเครื่องเดียวกัน
|
|
|
- **Codespaces**: หาดู URL backend ได้ในแท็บ Ports หลังจากตั้งค่าให้พอร์ต 5000 เป็นสาธารณะ
|
|
|
- **บน Production**: เปลี่ยนเป็นโดเมนจริงเมื่อดีพลอยบนบริการโฮสติ้ง
|
|
|
|
|
|
> 💡 **เคล็ดลับการทดสอบ**: คุณสามารถทดสอบ backend โดยตรงโดยเข้า URL หลักในเบราว์เซอร์ของคุณ คุณควรเห็นข้อความต้อนรับจากเซิร์ฟเวอร์ FastAPI
|
|
|
|
|
|
|
|
|
|
|
|
## การทดสอบและการดีพลอย
|
|
|
|
|
|
ตอนนี้ที่คุณมีทั้งส่วน frontend และ backend ที่สร้างเสร็จแล้ว มาทดสอบว่าทุกอย่างทำงานร่วมกันและสำรวจกระบวนการดีพลอยเพื่อแชร์ผู้ช่วยแชทกับคนอื่น
|
|
|
|
|
|
### กระบวนการทดสอบในเครื่อง
|
|
|
|
|
|
ทำตามขั้นตอนเหล่านี้เพื่อทดสอบแอปทั้งหมดของคุณ:
|
|
|
|
|
|
```mermaid
|
|
|
graph TD
|
|
|
A[เริ่มต้นเซิร์ฟเวอร์แบ็คเอนด์] --> B[กำหนดค่าตัวแปรแวดล้อม]
|
|
|
B --> C[ทดสอบจุดสิ้นสุด API]
|
|
|
C --> D[เปิดส่วนหน้าผ่านเบราว์เซอร์]
|
|
|
D --> E[ทดสอบฟังก์ชันแชท]
|
|
|
E --> F[แก้ไขข้อผิดพลาดใด ๆ]
|
|
|
```
|
|
|
**ขั้นตอนการทดสอบทีละขั้น:**
|
|
|
|
|
|
1. **เริ่มเซิร์ฟเวอร์ backend ของคุณ**:
|
|
|
```bash
|
|
|
cd backend
|
|
|
source venv/bin/activate # หรือ venv\Scripts\activate บน Windows
|
|
|
python api.py
|
|
|
```
|
|
|
|
|
|
2. **ยืนยันว่า API ทำงาน**:
|
|
|
- เปิด `http://localhost:5000` ในเบราว์เซอร์
|
|
|
- คุณควรเห็นข้อความต้อนรับจากเซิร์ฟเวอร์ FastAPI
|
|
|
|
|
|
3. **เปิดส่วน frontend**:
|
|
|
- ไปที่ไดเรกทอรี frontend ของคุณ
|
|
|
- เปิด `index.html` ในเว็บเบราว์เซอร์ของคุณ
|
|
|
- หรือติดตั้ง Live Server ใน VS Code เพื่อประสบการณ์พัฒนาที่ดีกว่า
|
|
|
|
|
|
4. **ทดสอบฟังก์ชันแชท**:
|
|
|
- พิมพ์ข้อความในช่องอินพุต
|
|
|
- คลิก "ส่ง" หรือกด Enter
|
|
|
- ตรวจสอบว่า AI ตอบสนองอย่างเหมาะสมไหม
|
|
|
- ตรวจสอบคอนโซลเบราว์เซอร์ว่ามีข้อผิดพลาด JavaScript หรือไม่
|
|
|
|
|
|
### การแก้ไขปัญหาทั่วไป
|
|
|
|
|
|
| ปัญหา | อาการ | วิธีแก้ไข |
|
|
|
|---------|----------|----------|
|
|
|
| **ข้อผิดพลาด CORS** | frontend ติดต่อ backend ไม่ได้ | ตรวจสอบการตั้งค่า FastAPI CORSMiddleware ให้ถูกต้อง |
|
|
|
| **ข้อผิดพลาด API Key** | การตอบ 401 Unauthorized | ตรวจสอบตัวแปรแวดล้อม `GITHUB_TOKEN` |
|
|
|
| **การเชื่อมต่อถูกปฏิเสธ** | มีข้อผิดพลาดเน็ตเวิร์กบน frontend | ตรวจสอบ URL backend และว่ามีเซิร์ฟเวอร์ Flask รันอยู่หรือไม่ |
|
|
|
| **ไม่มีการตอบกลับจาก AI** | คำตอบว่างหรือมีข้อผิดพลาด | ตรวจสอบบันทึก backend ว่ามีปัญหาควอตาหรือการยืนยันตัวตนไหม |
|
|
|
|
|
|
**ขั้นตอนการดีบักทั่วไป:**
|
|
|
- **ตรวจสอบ** คอนโซล Developer Tools ในเบราว์เซอร์สำหรับข้อผิดพลาด JavaScript
|
|
|
- **ยืนยัน** ในแท็บ Network ว่าคำขอและการตอบกลับ API สำเร็จ
|
|
|
- **รีวิว** เทอร์มินัล backend สำหรับข้อผิดพลาด Python หรือปัญหา API
|
|
|
- **ยืนยัน** ตัวแปรแวดล้อมถูกโหลดและเข้าถึงได้อย่างถูกต้อง
|
|
|
|
|
|
## 📈 ไทม์ไลน์ความชำนาญการพัฒนาแอป AI ของคุณ
|
|
|
|
|
|
```mermaid
|
|
|
timeline
|
|
|
title การเดินทางพัฒนาแอปพลิเคชัน AI อย่างครบถ้วน
|
|
|
|
|
|
section รากฐาน AI
|
|
|
การเข้าใจ Generative AI
|
|
|
: เข้าใจแนวคิดการรู้จำรูปแบบ
|
|
|
: เชี่ยวชาญการควบคุมพารามิเตอร์ AI
|
|
|
: เรียนรู้เทคนิคการสร้าง prompt
|
|
|
|
|
|
การรวมโมเดล GitHub
|
|
|
: นำทางแพลตฟอร์มบริการ AI
|
|
|
: จัดการการรับรองความปลอดภัยอย่างปลอดภัย
|
|
|
: ปรับแต่งพารามิเตอร์โมเดล
|
|
|
|
|
|
section การพัฒนา Backend
|
|
|
สถาปัตยกรรม Python API
|
|
|
: สร้างแอปพลิเคชัน FastAPI
|
|
|
: ใช้งาน async ในการดำเนินการ
|
|
|
: สร้าง endpoints ที่ปลอดภัย
|
|
|
|
|
|
การรวมบริการ AI
|
|
|
: เชื่อมต่อกับ API AI ภายนอก
|
|
|
: จัดการข้อจำกัดอัตราการใช้งาน
|
|
|
: ใช้งานขอบเขตข้อผิดพลาด
|
|
|
|
|
|
section ความเชี่ยวชาญ Frontend
|
|
|
รูปแบบ JavaScript สมัยใหม่
|
|
|
: เชี่ยวชาญสถาปัตยกรรมคลาส ES6
|
|
|
: ใช้งาน async/await
|
|
|
: สร้างอินเทอร์เฟซที่ตอบสนอง
|
|
|
|
|
|
ประสบการณ์ผู้ใช้แบบเรียลไทม์
|
|
|
: สร้างอินเทอร์เฟซแชทแบบไดนามิก
|
|
|
: จัดการสถานะการโหลด
|
|
|
: ปรับแต่งปฏิสัมพันธ์ของผู้ใช้
|
|
|
|
|
|
section ความพร้อมสำหรับการผลิต
|
|
|
ความปลอดภัย & ประสิทธิภาพ
|
|
|
: ใช้งานการจัดการโทเค็นที่ปลอดภัย
|
|
|
: ป้องกันช่องโหว่ XSS
|
|
|
: ปรับปรุงประสิทธิภาพ API
|
|
|
|
|
|
การปรับใช้ระดับมืออาชีพ
|
|
|
: สร้างสถาปัตยกรรมที่ปรับขยายได้
|
|
|
: เขียนโค้ดที่ดูแลรักษาได้
|
|
|
: บันทึกกระบวนการพัฒนา
|
|
|
```
|
|
|
**🎓 ก้าวสู่การสำเร็จการศึกษา**: คุณได้สร้างแอป AI ที่สมบูรณ์ด้วยเทคโนโลยีและรูปแบบสถาปัตยกรรมเดียวกับผู้ช่วย AI สมัยใหม่ ความสามารถเหล่านี้คือจุดตัดของการพัฒนาเว็บดั้งเดิมกับการผนวก AI ขั้นสูง
|
|
|
|
|
|
**🔄 ความสามารถระดับต่อไป:**
|
|
|
- พร้อมสำรวจเฟรมเวิร์ค AI ขั้นสูง (LangChain, LangGraph)
|
|
|
- เตรียมสร้างแอป AI แบบมัลติ-โมดอล (ข้อความ, รูปภาพ, เสียง)
|
|
|
- มีความรู้ในการใช้งานฐานข้อมูลเวกเตอร์และระบบดึงข้อมูล
|
|
|
- วางรากฐานสำหรับการเรียนรู้เครื่องและการปรับแต่งโมเดล AI
|
|
|
|
|
|
## ความท้าทาย GitHub Copilot Agent 🚀
|
|
|
|
|
|
ใช้โหมด Agent เพื่อทำความท้าทายต่อไปนี้ให้สำเร็จ:
|
|
|
|
|
|
**คำอธิบาย:** ปรับปรุงผู้ช่วยแชทโดยเพิ่มประวัติการสนทนาและการเก็บข้อความอย่างถาวร ความท้าทายนี้จะช่วยให้คุณเข้าใจการจัดการสถานะในแอปแชทและการจัดเก็บข้อมูลเพื่อประสบการณ์ผู้ใช้ที่ดีขึ้น
|
|
|
|
|
|
**พรอมต์:** แก้ไขแอปแชทเพื่อรวมประวัติการสนทนาที่คงอยู่ระหว่างเซสชัน เพิ่มฟังก์ชันบันทึกข้อความแชทลง local storage, แสดงประวัติการสนทนาเมื่อโหลดหน้าเว็บ, และเพิ่มปุ่ม "ล้างประวัติ" รวมทั้งเพิ่มตัวบ่งชี้การพิมพ์และแสดงเวลาส่งข้อความเพื่อให้ประสบการณ์แชทสมจริงยิ่งขึ้น
|
|
|
|
|
|
เรียนรู้เพิ่มเติมเกี่ยวกับ [โหมด agent](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) ที่นี่
|
|
|
|
|
|
## งานมอบหมาย: สร้างผู้ช่วย AI ส่วนตัวของคุณ
|
|
|
|
|
|
ตอนนี้คุณจะสร้างผู้ช่วย AI ของตัวเอง แทนที่จะทำซ้ำโค้ดบทเรียน คุณจะได้ใช้แนวคิดเหล่านี้พร้อมสร้างสิ่งที่สะท้อนความสนใจและการใช้งานของคุณเอง
|
|
|
|
|
|
### ความต้องการของโปรเจกต์
|
|
|
|
|
|
มาจัดโครงสร้างโปรเจกต์ให้สะอาดและเป็นระเบียบ:
|
|
|
|
|
|
```text
|
|
|
my-ai-assistant/
|
|
|
├── backend/
|
|
|
│ ├── api.py # Your FastAPI server
|
|
|
│ ├── llm.py # AI integration functions
|
|
|
│ ├── .env # Your secrets (keep this safe!)
|
|
|
│ └── requirements.txt # Python dependencies
|
|
|
├── frontend/
|
|
|
│ ├── index.html # Your chat interface
|
|
|
│ ├── app.js # The JavaScript magic
|
|
|
│ └── styles.css # Make it look amazing
|
|
|
└── README.md # Tell the world about your creation
|
|
|
```
|
|
|
|
|
|
### งานการพัฒนาแกนหลัก
|
|
|
|
|
|
**พัฒนา Backend:**
|
|
|
- **นำ** โค้ด FastAPI ของเราไปดัดแปลงให้ออกมาเป็นของคุณเอง
|
|
|
- **สร้าง** บุคลิก AI ที่มีเอกลักษณ์ — อาจเป็นผู้ช่วยทำอาหารที่ช่วยแนะนำ, คู่หูเขียนเชิงสร้างสรรค์, หรือเพื่อนอ่านหนังสือ?
|
|
|
- **เพิ่ม** การจัดการข้อผิดพลาดที่แข็งแกร่งเพื่อให้แอปไม่ล่มเมื่อผิดพลาด
|
|
|
- **เขียน** เอกสารที่ชัดเจนเพื่อให้ใครก็ได้เข้าใจวิธีการทำงานของ API
|
|
|
|
|
|
**พัฒนา Frontend:**
|
|
|
- **สร้าง** อินเทอร์เฟซแชทที่ใช้งานง่ายและต้อนรับผู้ใช้
|
|
|
- **เขียน** JavaScript สมัยใหม่ที่สะอาดและคุณภูมิใจจะแสดงให้คนอื่นดู
|
|
|
- **ออกแบบ** สไตล์ที่ปรับแต่งได้สะท้อนบุคลิก AI ของคุณ — สนุกและมีสีสัน? เนี้ยบและมินิมัล? แล้วแต่คุณ!
|
|
|
- **มั่นใจ** ว่าทำงานได้ดีทั้งบนโทรศัพท์และคอมพิวเตอร์
|
|
|
|
|
|
**ความต้องการการปรับแต่งส่วนตัว:**
|
|
|
- **เลือก** ชื่อและบุคลิกเฉพาะสำหรับผู้ช่วย AI ของคุณ — อาจสะท้อนความสนใจหรือปัญหาที่คุณอยากแก้ไข
|
|
|
- **ปรับแต่ง** การออกแบบภาพให้เข้ากับบรรยากาศผู้ช่วยของคุณ
|
|
|
- **เขียน** ข้อความต้อนรับที่น่าสนใจเพื่อให้คนอยากเริ่มแชท
|
|
|
- **ทดสอบ** ผู้ช่วยของคุณด้วยคำถามหลากหลายรูปแบบเพื่อตรวจสอบการตอบสนอง
|
|
|
|
|
|
### ไอเดียการเพิ่มประสิทธิภาพ (ไม่บังคับ)
|
|
|
|
|
|
อยากพัฒนาโปรเจกต์ไปอีกขั้น? นี่คือไอเดียเจ๋ง ๆ ให้ลอง:
|
|
|
|
|
|
| ฟีเจอร์ | คำอธิบาย | ทักษะที่คุณจะฝึก |
|
|
|
|---------|-------------|------------------------|
|
|
|
| **ประวัติข้อความ** | จำบทสนทนาแม้รีเฟรชหน้า | การทำงานกับ localStorage, การจัดการ JSON |
|
|
|
| **ตัวบ่งชี้การพิมพ์** | แสดง "AI กำลังพิมพ์..." ขณะรอคำตอบ | CSS แอนิเมชัน, โปรแกรมแบบอะซิงค์ |
|
|
|
| **เวลาส่งข้อความ** | แสดงเวลาที่ส่งแต่ละข้อความ | การฟอร์แมตวันที่/เวลา, การออกแบบ UX |
|
|
|
| **ส่งออกแชท** | ให้ผู้ใช้ดาวน์โหลดบทสนทนา | การจัดการไฟล์, การส่งออกข้อมูล |
|
|
|
| **สลับธีม** | สลับโหมดสว่าง/มืด | ตัวแปร CSS, การตั้งค่าผู้ใช้ |
|
|
|
| **ป้อนข้อความด้วยเสียง** | เพิ่มฟังก์ชันแปลงคำพูดเป็นข้อความ | Web APIs, การเข้าถึงได้ |
|
|
|
|
|
|
### การทดสอบและเอกสาร
|
|
|
|
|
|
**การประกันคุณภาพ:**
|
|
|
- **ทดสอบ** แอปของคุณด้วยอินพุตหลากหลายและกรณีขอบเขต
|
|
|
- **ยืนยัน** การออกแบบตอบสนองทำงานบนหน้าจอขนาดต่าง ๆ
|
|
|
- **ตรวจสอบ** ความเข้าถึงด้วยการนำทางผ่านแป้นพิมพ์และโปรแกรมอ่านหน้าจอ
|
|
|
- **ตรวจสอบ** HTML และ CSS ให้ตรงมาตรฐาน
|
|
|
|
|
|
**ความต้องการเอกสาร:**
|
|
|
- **เขียน** README.md อธิบายโปรเจกต์และวิธีรัน
|
|
|
- **ใส่ภาพหน้าจอ** อินเทอร์เฟซแชทของคุณเวลาทำงาน
|
|
|
- **บันทึก** ฟีเจอร์หรือการปรับแต่งที่คุณเพิ่มเข้าไป
|
|
|
- **ให้คำแนะนำ** การติดตั้งที่ชัดเจนสำหรับนักพัฒนารายอื่น
|
|
|
|
|
|
### ข้อกำหนดการส่งงาน
|
|
|
|
|
|
**สิ่งที่ต้องส่ง:**
|
|
|
1. โฟลเดอร์โปรเจกต์ครบชุดพร้อมซอร์สโค้ดทั้งหมด
|
|
|
2. README.md ที่มีคำอธิบายโปรเจกต์และคำแนะนำการติดตั้ง
|
|
|
3. รูปภาพหน้าจอแสดงผู้ช่วยแชทของคุณขณะทำงาน
|
|
|
4. บทสรุปสั้น ๆ ว่าคุณเรียนรู้อะไรและเจอความท้าทายอะไรบ้าง
|
|
|
|
|
|
**เกณฑ์การประเมิน:**
|
|
|
- **ฟังก์ชันการทำงาน**: ผู้ช่วยแชททำงานตามคาดไหม?
|
|
|
- **คุณภาพโค้ด**: โค้ดจัดระเบียบดี, คอมเมนต์ครบ, ดูแลรักษาง่ายไหม?
|
|
|
- **การออกแบบ**: อินเทอร์เฟซดูดีและใช้งานง่ายไหม?
|
|
|
- **ความคิดสร้างสรรค์**: การนำไปใช้มีเอกลักษณ์และปรับแต่งอย่างไรบ้าง?
|
|
|
- **เอกสาร**: คำแนะนำการติดตั้งชัดเจนและครบถ้วนไหม?
|
|
|
|
|
|
> 💡 **เคล็ดลับความสำเร็จ**: เริ่มจากความต้องการพื้นฐานก่อน แล้วค่อยเติมฟีเจอร์เสริมเมื่อทุกอย่างทำงานดีแล้ว ให้ความสำคัญกับการสร้างประสบการณ์หลักที่สมบูรณ์ก่อนเพิ่มฟีเจอร์ขั้นสูง
|
|
|
|
|
|
## โซลูชัน
|
|
|
|
|
|
[Solution](./solution/README.md)
|
|
|
|
|
|
## ความท้าทายเสริม
|
|
|
|
|
|
พร้อมจะพาผู้ช่วย AI ของคุณไปอีกขั้นไหม? ลองทำความท้าทายขั้นสูงเหล่านี้ที่จะลึกซึ้งความเข้าใจเรื่องการผนวก AI และการพัฒนาเว็บ
|
|
|
|
|
|
### การปรับแต่งบุคลิกภาพ
|
|
|
|
|
|
เวทมนตร์จริง ๆ เกิดขึ้นเมื่อคุณมอบบุคลิกเฉพาะเจาะจงให้ผู้ช่วย AI ทดลองใช้พร็อมต์ระบบที่แตกต่างเพื่อสร้างผู้ช่วยเฉพาะทาง:
|
|
|
|
|
|
**ตัวอย่างผู้ช่วยมืออาชีพ:**
|
|
|
```python
|
|
|
call_llm(message, "You are a professional business consultant with 20 years of experience. Provide structured, actionable advice with specific steps and considerations.")
|
|
|
```
|
|
|
|
|
|
**ตัวอย่างผู้ช่วยเขียนเชิงสร้างสรรค์:**
|
|
|
```python
|
|
|
call_llm(message, "You are an enthusiastic creative writing coach. Help users develop their storytelling skills with imaginative prompts and constructive feedback.")
|
|
|
```
|
|
|
|
|
|
**ตัวอย่างที่ปรึกษาทางเทคนิค:**
|
|
|
```python
|
|
|
call_llm(message, "You are a patient senior developer who explains complex programming concepts using simple analogies and practical examples.")
|
|
|
```
|
|
|
|
|
|
### การเพิ่มประสิทธิภาพ Frontend
|
|
|
|
|
|
เปลี่ยนอินเทอร์เฟซแชทของคุณด้วยการปรับปรุงทั้งภาพและฟังก์ชัน:
|
|
|
|
|
|
**ฟีเจอร์ CSS ขั้นสูง:**
|
|
|
- **ใช้** แอนิเมชันและทรานสิชันนุ่มนวลในข้อความ
|
|
|
- **เพิ่ม** ดีไซน์ลูกโป่งแชทด้วยรูปร่างและแสงเงา CSS
|
|
|
- **สร้าง** แอนิเมชันตัวบ่งชี้กำลังพิมพ์เมื่อ AI "กำลังคิด"
|
|
|
- **ออกแบบ** ปฏิกิริยาอีโมจิหรือระบบให้คะแนนข้อความ
|
|
|
|
|
|
**การปรับปรุง JavaScript:**
|
|
|
- **เพิ่ม** ทางลัดแป้นพิมพ์ (Ctrl+Enter ส่ง, Escape ล้างอินพุต)
|
|
|
- **เพิ่ม** ฟังก์ชันค้นหาและกรองข้อความ
|
|
|
- **สร้าง** ฟีเจอร์ส่งออกการสนทนา (ดาวน์โหลดเป็นข้อความหรือ JSON)
|
|
|
- **เพิ่ม** การบันทึกอัตโนมัติลง localStorage เพื่อป้องกันข้อความสูญหาย
|
|
|
|
|
|
### การผนวก AI ขั้นสูง
|
|
|
|
|
|
**หลายบุคลิก AI:**
|
|
|
- **สร้าง** เมนูดร็อปดาวน์เพื่อสลับระหว่างบุคลิก AI ต่าง ๆ
|
|
|
- **บันทึก** บุคลิกที่ผู้ใช้ชอบใน localStorage
|
|
|
- **ใช้** การสลับบริบทที่รักษาโฟลว์การสนทนา
|
|
|
|
|
|
**ฟีเจอร์ตอบสนองอัจฉริยะ:**
|
|
|
- **เพิ่ม** ความสามารถจดจำบริบทบทสนทนา (AI จำข้อความก่อนหน้าได้)
|
|
|
|
|
|
- **นำไปใช้** ข้อเสนอแนะอัจฉริยะตามหัวข้อการสนทนา
|
|
|
- **สร้าง** ปุ่มตอบกลับด่วนสำหรับคำถามที่พบบ่อย
|
|
|
|
|
|
> 🎯 **เป้าหมายการเรียนรู้**: ความท้าทายเสริมเหล่านี้ช่วยให้คุณเข้าใจรูปแบบการพัฒนาเว็บขั้นสูงและเทคนิคการรวม AI ที่ใช้ในแอปพลิเคชันในระดับการผลิต
|
|
|
|
|
|
## สรุปและขั้นตอนถัดไป
|
|
|
|
|
|
ขอแสดงความยินดี! คุณได้สร้างผู้ช่วยแชทที่ขับเคลื่อนด้วย AI แบบครบวงจรตั้งแต่เริ่มต้นได้สำเร็จ โครงการนี้ช่วยให้คุณได้ลงมือปฏิบัติจริงกับเทคโนโลยีการพัฒนาเว็บสมัยใหม่และการรวม AI – ทักษะที่มีคุณค่ามากขึ้นเรื่อยๆ ในวงการเทคโนโลยีปัจจุบัน
|
|
|
|
|
|
### สิ่งที่คุณทำสำเร็จ
|
|
|
|
|
|
ตลอดบทเรียนนี้ คุณได้ฝึกฝนเทคโนโลยีและแนวคิดสำคัญหลายอย่าง:
|
|
|
|
|
|
**การพัฒนาแบ็คเอนด์:**
|
|
|
- **บูรณาการ** กับ GitHub Models API สำหรับฟังก์ชัน AI
|
|
|
- **สร้าง** RESTful API โดยใช้ Flask พร้อมการจัดการข้อผิดพลาดอย่างเหมาะสม
|
|
|
- **นำไปใช้** การยืนยันตัวตนที่ปลอดภัยโดยใช้ตัวแปรสภาพแวดล้อม
|
|
|
- **ตั้งค่า** CORS สำหรับคำขอข้ามต้นทางระหว่าง frontend และ backend
|
|
|
|
|
|
**การพัฒนาฟรอนต์เอนด์:**
|
|
|
- **สร้าง** ส่วนติดต่อแชทที่ตอบสนองโดยใช้ semantic HTML
|
|
|
- **นำไปใช้** JavaScript สมัยใหม่ด้วย async/await และสถาปัตยกรรมแบบคลาส
|
|
|
- **ออกแบบ** อินเทอร์เฟซผู้ใช้ที่น่าสนใจด้วย CSS Grid, Flexbox และอนิเมชัน
|
|
|
- **เพิ่ม** คุณสมบัติการเข้าถึงและหลักการออกแบบที่ตอบสนอง
|
|
|
|
|
|
**การรวมระบบแบบฟูลสแตก:**
|
|
|
- **เชื่อมต่อ** frontend และ backend ผ่านการเรียก API แบบ HTTP
|
|
|
- **จัดการ** การโต้ตอบแบบเรียลไทม์ของผู้ใช้และการไหลของข้อมูลแบบอะซิงโครนัส
|
|
|
- **นำไปใช้** การจัดการข้อผิดพลาดและฟีดแบ็กผู้ใช้ตลอดทั้งแอปพลิเคชัน
|
|
|
- **ทดสอบ** เวิร์กโฟลว์แอปพลิเคชันครบวงจรตั้งแต่รับข้อมูลผู้ใช้จนถึงการตอบกลับของ AI
|
|
|
|
|
|
### ผลลัพธ์การเรียนรู้ที่สำคัญ
|
|
|
|
|
|
```mermaid
|
|
|
mindmap
|
|
|
root((ทักษะแอปแชท AI))
|
|
|
API Integration
|
|
|
Authentication
|
|
|
Error Handling
|
|
|
Async Programming
|
|
|
Web Development
|
|
|
HTML5 Semantics
|
|
|
Modern CSS
|
|
|
ES6+ JavaScript
|
|
|
User Experience
|
|
|
Responsive Design
|
|
|
Accessibility
|
|
|
Real-time Interaction
|
|
|
AI Understanding
|
|
|
Prompt Engineering
|
|
|
Model Parameters
|
|
|
Conversation Flow
|
|
|
```
|
|
|
โครงการนี้ได้แนะนำคุณให้รู้จักกับพื้นฐานของการสร้างแอปพลิเคชันที่ขับเคลื่อนด้วย AI ซึ่งเป็นอนาคตของการพัฒนาเว็บ ตอนนี้คุณเข้าใจวิธีการรวมความสามารถ AI เข้ากับแอปพลิเคชันเว็บแบบดั้งเดิม สร้างประสบการณ์ผู้ใช้ที่น่าดึงดูดใจและตอบสนองอย่างชาญฉลาด
|
|
|
|
|
|
### การประยุกต์ใช้ในเชิงวิชาชีพ
|
|
|
|
|
|
ทักษะที่คุณพัฒนาในบทเรียนนี้สามารถนำไปใช้ได้โดยตรงกับอาชีพการพัฒนาซอฟต์แวร์สมัยใหม่:
|
|
|
|
|
|
- **การพัฒนาเว็บแบบฟูลสแตก** โดยใช้เฟรมเวิร์กและ API สมัยใหม่
|
|
|
- **การผสาน AI** ในเว็บแอปพลิเคชันและแอปมือถือ
|
|
|
- **การออกแบบและพัฒนา API** สำหรับสถาปัตยกรรมไมโครเซอร์วิส
|
|
|
- **การพัฒนาส่วนติดต่อผู้ใช้** โดยเน้นการเข้าถึงและการออกแบบตอบสนอง
|
|
|
- **แนวปฏิบัติ DevOps** รวมถึงการตั้งค่าสภาพแวดล้อมและการปรับใช้
|
|
|
|
|
|
### ต่อเนื่องการเดินทางพัฒนา AI ของคุณ
|
|
|
|
|
|
**ขั้นตอนการเรียนรู้ถัดไป:**
|
|
|
- **สำรวจ** โมเดลและ API AI ขั้นสูงเพิ่มเติม (GPT-4, Claude, Gemini)
|
|
|
- **เรียนรู้** เทคนิคการออกแบบ prompt เพื่อการตอบสนอง AI ที่ดีขึ้น
|
|
|
- **ศึกษาด้าน** การออกแบบบทสนทนาและหลักการประสบการณ์ผู้ใช้แชทบอท
|
|
|
- **วิจัย** ความปลอดภัย AI จริยธรรม และแนวทางการพัฒนา AI อย่างรับผิดชอบ
|
|
|
- **สร้าง** แอปพลิเคชันที่ซับซ้อนขึ้นพร้อมความทรงจำในการสนทนาและการรับรู้บริบท
|
|
|
|
|
|
**ไอเดียโครงการขั้นสูง:**
|
|
|
- ห้องแชทหลายผู้ใช้ที่มีการดูแลด้วย AI
|
|
|
- แชทบอทบริการลูกค้าโดยใช้ AI
|
|
|
- ผู้ช่วยสอนการศึกษาที่ปรับแต่งตามผู้เรียน
|
|
|
- ผู้ร่วมสร้างงานเขียนเชิงสร้างสรรค์ด้วยบุคลิก AI ที่หลากหลาย
|
|
|
- ผู้ช่วยเอกสารทางเทคนิคสำหรับนักพัฒนา
|
|
|
|
|
|
## เริ่มต้นใช้งานกับ GitHub Codespaces
|
|
|
|
|
|
ต้องการทดลองโครงการนี้ในสภาพแวดล้อมพัฒนาบนคลาวด์หรือไม่? GitHub Codespaces มีการตั้งค่าการพัฒนาแบบครบวงจรในเบราว์เซอร์ของคุณ เหมาะสำหรับการทดลองแอป AI โดยไม่ต้องตั้งค่าท้องถิ่น
|
|
|
|
|
|
### การตั้งค่าสภาพแวดล้อมพัฒนาของคุณ
|
|
|
|
|
|
**ขั้นตอนที่ 1: สร้างจากแม่แบบ**
|
|
|
- **ไปที่** [Web Dev For Beginners repository](https://github.com/microsoft/Web-Dev-For-Beginners)
|
|
|
- **คลิก** "Use this template" ที่มุมขวาบน (ตรวจสอบว่าคุณเข้าสู่ระบบ GitHub แล้ว)
|
|
|
|
|
|

|
|
|
|
|
|
**ขั้นตอนที่ 2: เปิด Codespaces**
|
|
|
- **เปิด** รีโพซิทอรีที่คุณสร้างขึ้นใหม่
|
|
|
- **คลิก** ปุ่มสีเขียว "Code" และเลือก "Codespaces"
|
|
|
- **เลือก** "Create codespace on main" เพื่อเริ่มสภาพแวดล้อมการพัฒนาของคุณ
|
|
|
|
|
|

|
|
|
|
|
|
**ขั้นตอนที่ 3: การตั้งค่าสภาพแวดล้อม**
|
|
|
เมื่อ Codespace ของคุณโหลด คุณจะสามารถเข้าถึง:
|
|
|
- **เครื่องมือพร้อมใช้งาน** เช่น Python, Node.js และเครื่องมือพัฒนาที่จำเป็นทั้งหมด
|
|
|
- **อินเทอร์เฟซ VS Code** พร้อมส่วนขยายสำหรับการพัฒนาเว็บ
|
|
|
- **เทอร์มินัล** สำหรับรันเซิร์ฟเวอร์แบ็คเอนด์และฟรอนต์เอนด์
|
|
|
- **การตั้งค่า port forwarding** เพื่อทดสอบแอปพลิเคชันของคุณ
|
|
|
|
|
|
**สิ่งที่ Codespaces มอบให้:**
|
|
|
- **ขจัด** ปัญหาการตั้งค่าสภาพแวดล้อมในเครื่องและการกำหนดค่า
|
|
|
- **มอบ** สภาพแวดล้อมการพัฒนาที่สม่ำเสมอในอุปกรณ์ที่หลากหลาย
|
|
|
- **รวมถึง** เครื่องมือและส่วนขยายที่ตั้งค่าล่วงหน้าสำหรับการพัฒนาเว็บ
|
|
|
- **เสนอ** การรวมระบบแบบไร้รอยต่อกับ GitHub สำหรับควบคุมเวอร์ชันและความร่วมมือ
|
|
|
|
|
|
> 🚀 **เคล็ดลับมือโปร**: Codespaces เหมาะสำหรับการเรียนรู้และสร้างต้นแบบแอป AI เพราะมันจัดการการตั้งค่าสภาพแวดล้อมที่ซับซ้อนทั้งหมดให้อัตโนมัติ ทำให้คุณมุ่งเน้นที่การสร้างสรรค์และเรียนรู้ โดยไม่ต้องกังวลกับการแก้ไขปัญหาการตั้งค่า
|
|
|
|
|
|
---
|
|
|
|
|
|
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
|
|
|
**ข้อจำกัดความรับผิดชอบ**:
|
|
|
เอกสารฉบับนี้ได้รับการแปลโดยใช้บริการแปลภาษาอัตโนมัติ [Co-op Translator](https://github.com/Azure/co-op-translator) แม้เราจะพยายามให้ความถูกต้องสูงสุด แต่โปรดทราบว่าการแปลโดยอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาดั้งเดิมถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ แนะนำให้ใช้บริการแปลโดยมนุษย์ผู้เชี่ยวชาญ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดที่อาจเกิดขึ้นจากการใช้การแปลนี้
|
|
|
<!-- CO-OP TRANSLATOR DISCLAIMER END --> |