Kiến trúc (Hướng dẫn cho Vibe Coder)
Tìm hiểu sâu về RAG pipeline cho lập trình viên muốn hiểu cách hoạt động.
Tổng quan RAG Pipeline
LaunchChat sử dụng Retrieval Augmented Generation (RAG) để trả lời câu hỏi dựa trên tài liệu của bạn.
1. Nhập liệu
Phân tích → Chia nhỏ → Nhúng vector → Lưu trữ
2. Truy xuất
Truy vấn → Tìm kiếm vector → Xếp hạng
3. Tạo câu trả lời
Ngữ cảnh → LLM → Câu trả lời + Trích dẫn
Ingestion Pipeline
1. Phân tích
Nội dung được phân tích từ nhiều nguồn thành văn bản thuần:
- Notion: Phân tích từng block giữ nguyên cấu trúc phân cấp
- DOCX: Trích xuất qua mammoth.js
- Markdown: Phân tích với remark/unified
- Website: Trang web: Thu thập và loại bỏ phần điều hướng/chân trang
2. Chia nhỏ
Văn bản được chia thành các phân đoạn chồng lấp để truy xuất tối ưu:
{
targetSize: 400, // tokens per chunk
overlap: 50, // token overlap between chunks
preserveHeadings: true, // keep heading context
minChunkSize: 100 // minimum viable chunk
}Mỗi phân đoạn giữ nguyên cấu trúc tiêu đề cha để cung cấp ngữ cảnh.
3. Nhúng vector
Các phân đoạn được chuyển đổi thành vector 1536 chiều:
Model: text-embedding-3-small
Dimensions: 1536
Provider: OpenAI (via OpenRouter)4. Lưu trữ
Vector được lưu trữ trong PostgreSQL với phần mở rộng pgvector:
-- content_chunks table
id: uuid
knowledge_base_id: uuid
page_id: string
page_title: string
content: text
embedding: vector(1536)
parent_heading: stringChiến lược truy xuất
Tìm kiếm kết hợp
Chúng tôi sử dụng quy trình truy xuất hai giai đoạn:
- Vector Search: Tìm kiếm vector: Độ tương đồng cosine sử dụng toán tử <=> của pgvector
- Keyword Fallback: Tìm kiếm từ khóa dự phòng: Nếu kết quả vector có độ tương đồng thấp, chúng tôi thêm các phân đoạn khớp từ khóa
Chấm điểm tương đồng
-- Vector similarity query
SELECT *, 1 - (embedding <=> query_embedding) as similarity
FROM content_chunks
WHERE knowledge_base_id = $1
ORDER BY embedding <=> query_embedding
LIMIT 5Tạo câu trả lời
Chấm điểm độ tin cậy
Trước khi tạo câu trả lời, chúng tôi tính điểm độ tin cậy:
confidence = bestSimilarity + (hasMultipleChunks ? 0.1 : 0) + 0.2
// Capped at 1.0
if (confidence < threshold) {
return refusalMessage; // Don't hallucinate
}Trích xuất trích dẫn
LLM được hướng dẫn sử dụng định dạng [Source N]. Chúng tôi phân tích và liên kết đến trang gốc:
// 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])Thực hành tốt cho tài liệu
Cấu trúc tài liệu để AI truy xuất tối ưu:
Nên làm
- Sử dụng tiêu đề rõ ràng, mô tả chi tiết
- Giữ mỗi phần tập trung vào một chủ đề
- Bao gồm ví dụ và đoạn mã
- Định nghĩa thuật ngữ và từ viết tắt
- Cập nhật tài liệu khi tính năng thay đổi
Nên tránh
- Trang quá dài không có cấu trúc
- Nội dung trùng lặp giữa các trang
- Thông tin lỗi thời hoặc mâu thuẫn
- Sử dụng nhiều hình ảnh không có alt text
- Trang chỉ có điều hướng
Mẫu prompt AI
Sao chép prompt này vào Cursor, Windsurf hoặc Claude Code để hỗ trợ tích hợp 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.