สถาปัตยกรรม (คู่มือสำหรับ Vibe Coder)

เจาะลึก RAG pipeline สำหรับนักพัฒนาที่ต้องการเข้าใจวิธีการทำงาน

ภาพรวม RAG Pipeline

LaunchChat ใช้ Retrieval Augmented Generation (RAG) เพื่อตอบคำถามจากเอกสารของคุณ

1. การนำเข้า

แยกวิเคราะห์ → แบ่งชิ้น → ฝังเวกเตอร์ → จัดเก็บ

2. การค้นหา

คำค้น → ค้นหาเวกเตอร์ → จัดอันดับ

3. การสร้าง

บริบท → LLM → คำตอบ + การอ้างอิง

Ingestion Pipeline

1. การแยกวิเคราะห์

เนื้อหาถูกแยกวิเคราะห์จากแหล่งต่างๆ เป็นข้อความธรรมดา:

  • Notion: แยกวิเคราะห์ทีละบล็อกโดยรักษาลำดับชั้น
  • DOCX: แยกข้อมูลผ่าน mammoth.js
  • Markdown: แยกวิเคราะห์ด้วย remark/unified
  • Website: เว็บไซต์: ครอว์ลและลบส่วนนำทาง/ส่วนท้าย

2. การแบ่งชิ้น

ข้อความถูกแบ่งเป็นชิ้นส่วนที่ซ้อนทับกันเพื่อการค้นหาที่เหมาะสม:

{
  targetSize: 400,    // tokens per chunk
  overlap: 50,        // token overlap between chunks
  preserveHeadings: true,  // keep heading context
  minChunkSize: 100   // minimum viable chunk
}

แต่ละชิ้นส่วนรักษาลำดับชั้นหัวข้อหลักเพื่อบริบท

3. การฝังเวกเตอร์

ชิ้นส่วนถูกแปลงเป็นเวกเตอร์ 1536 มิติ:

Model: text-embedding-3-small
Dimensions: 1536
Provider: OpenAI (via OpenRouter)

4. การจัดเก็บ

เวกเตอร์ถูกจัดเก็บใน PostgreSQL ด้วยส่วนขยาย pgvector:

-- content_chunks table
id: uuid
knowledge_base_id: uuid
page_id: string
page_title: string
content: text
embedding: vector(1536)
parent_heading: string

กลยุทธ์การค้นหา

การค้นหาแบบผสม

เราใช้กระบวนการค้นหาสองขั้นตอน:

  1. Vector Search: การค้นหาเวกเตอร์: ความคล้ายคลึงโคไซน์โดยใช้ตัวดำเนินการ <=> ของ pgvector
  2. Keyword Fallback: การค้นหาคำสำรอง: หากผลลัพธ์เวกเตอร์มีความคล้ายคลึงต่ำ เราจะเพิ่มชิ้นส่วนที่ตรงกับคำค้น

การให้คะแนนความคล้ายคลึง

-- Vector similarity query
SELECT *, 1 - (embedding <=> query_embedding) as similarity
FROM content_chunks
WHERE knowledge_base_id = $1
ORDER BY embedding <=> query_embedding
LIMIT 5

การสร้างคำตอบ

การให้คะแนนความมั่นใจ

ก่อนสร้างคำตอบ เราคำนวณคะแนนความมั่นใจ:

confidence = bestSimilarity + (hasMultipleChunks ? 0.1 : 0) + 0.2
// Capped at 1.0

if (confidence < threshold) {
  return refusalMessage;  // Don't hallucinate
}

การแยกการอ้างอิง

LLM ถูกสั่งให้ใช้รูปแบบ [Source N] เราแยกวิเคราะห์และลิงก์ไปยังหน้าต้นฉบับ:

// Extract citations from answer
const citationPattern = /\[Source (\d+)\]/g;
const matches = answer.matchAll(citationPattern);

// Map to original pages
citations = matches.map(m => chunks[m[1] - 1])

แนวปฏิบัติที่ดีสำหรับเอกสาร

จัดโครงสร้างเอกสารของคุณเพื่อการค้นหา AI ที่เหมาะสม:

ควรทำ

  • ใช้หัวข้อที่ชัดเจนและอธิบายได้ดี
  • ให้แต่ละส่วนเน้นหัวข้อเดียว
  • รวมตัวอย่างและตัวอย่างโค้ด
  • กำหนดคำศัพท์และตัวย่อ
  • อัปเดตเอกสารเมื่อฟีเจอร์เปลี่ยนแปลง

ควรหลีกเลี่ยง

  • หน้าที่ยาวมากโดยไม่มีโครงสร้าง
  • เนื้อหาซ้ำซ้อนข้ามหน้า
  • ข้อมูลที่ล้าสมัยหรือขัดแย้งกัน
  • ใช้รูปภาพมากโดยไม่มี alt text
  • หน้าที่มีเฉพาะการนำทาง

เทมเพลตพรอมต์ AI

คัดลอกพรอมต์นี้ลงใน Cursor, Windsurf หรือ Claude Code เพื่อช่วยเชื่อมต่อ LaunchChat:

I'm integrating LaunchChat, an AI-powered support widget.

Widget Setup:
1. Add to HTML: <script>window.LaunchChatConfig = {widgetId: "ID"}</script>
   <script src="https://domain.com/widget.js" async></script>

2. For React/Next.js, create a client component that:
   - Sets window.LaunchChatConfig
   - Dynamically loads widget.js
   - Cleans up on unmount

API Reference:
- window.LaunchChatWidget.open() - Open chat
- window.LaunchChatWidget.close() - Close chat
- window.LaunchChatWidget.on(event, callback) - Listen to events
- Events: 'open', 'close', 'message', 'escalate', 'feedback'

Help me integrate this into my [FRAMEWORK] app.