Vidtory Engineering Take-Home Challenge 48 Hours

Build a RAG Document
Intelligence System

Thiết kế và implement một hệ thống xử lý tài liệu thông minh — từ ingestion đến retrieval và generation.

Thời gian 48 giờ kể từ khi nhận đề
Level Junior → Mid
Format GitHub repo + Demo link
AI-first Khuyến khích dùng AI tools

Vidtory đang build các AI SaaS product cho mảng media & e-commerce. Một trong những bài toán cốt lõi là giúp các SME tìm kiếm và khai thác thông tin từ kho tài liệu nội bộ của họ — product spec, hợp đồng, catalog — thay vì phải mò mẫm từng file.

Challenge này mô phỏng một phần bài toán đó. Bạn sẽ build một RAG (Retrieval-Augmented Generation) pipeline hoàn chỉnh: upload tài liệu, xử lý + embedding, lưu vector, và trả lời câu hỏi dựa trên nội dung tài liệu — với nguồn trích dẫn rõ ràng.

Không có đáp án duy nhất. Chúng tôi quan tâm đến cách bạn tư duy, research, vibe code và tổ chức hệ thống.

01 — Architecture Overview

System Design

Hệ thống bao gồm hai luồng chính: Ingestion Pipeline (xử lý và lưu trữ tài liệu) và Query Pipeline (truy vấn và tổng hợp câu trả lời).

// Ingestion Pipeline
Upload
PDF / DOCX / TXT
Parse
Extract text
Chunk
Split + overlap
Embed
OpenAI / Gemini
Store
Vector DB
// Query Pipeline
Question
User input
Embed
Query vector
Retrieve
Similarity search
Generate
LLM + context
Answer
+ citations

02 — Recommended Tech Stack

Gợi ý công nghệ

Đây là gợi ý, không phải yêu cầu bắt buộc. Bạn có thể thay thế bất kỳ layer nào nếu có lý do chính đáng — hãy giải thích trong README.

🖥️

Backend API

Server & business logic
NestJS Express TypeScript Multer
⚛️

Frontend

UI & interaction
Next.js Vite + React Tailwind CSS Radix UI
🧠

AI / Embedding

LLM & vector generation
OpenAI API Gemini text-embedding-3-small
🗃️

Vector Database

Lưu trữ & tìm kiếm vector
pgvector Qdrant Pinecone Chroma
💾

Database

Metadata & document store
PostgreSQL TypeORM MongoDB Prisma
🔧

Document Parsing

Trích xuất nội dung file
pdf-parse mammoth LangChain loaders
💡 Gợi ý nhanh: Nếu muốn setup nhanh trong 48h, dùng pgvector (extension của PostgreSQL) để tránh thêm một service mới. Còn nếu muốn thể hiện kiến thức về vector DB chuyên dụng thì Qdrant hoặc Chroma là lựa chọn tốt.

03 — Processing Pipeline

Chi tiết các bước xử lý

01

Document Ingestion

Nhận file upload (PDF, DOCX, TXT). Validate format, extract raw text bằng parser phù hợp. Lưu file gốc vào storage và metadata vào DB (tên file, size, mime type, created_at, status).

02

Text Chunking

Chia văn bản thành các chunks nhỏ. Gợi ý: chunk_size ~500 tokens, overlap ~50 tokens. Lưu ý giữ nguyên ngữ cảnh đoạn — tránh cắt giữa câu. Đây là bước ảnh hưởng lớn đến chất lượng retrieval.

03

Embedding Generation

Gọi Embedding API (OpenAI text-embedding-3-small hoặc Gemini) cho từng chunk. Lưu vector (1536-dim) cùng với chunk_id, document_id, chunk_index, và nội dung text gốc vào vector store.

04

Semantic Retrieval

Khi nhận query, embed câu hỏi rồi thực hiện cosine similarity search trong vector store. Lấy top-K chunks (K = 3–5). Filter theo document_id nếu user muốn search trong file cụ thể.

05

Answer Generation

Build prompt: "Based on the following context, answer the question. If the answer is not in the context, say so." + inject các chunks retrieved. Gọi LLM (GPT-4o-mini hoặc Gemini Flash). Trả về answer kèm danh sách chunk sources (document name, page, snippet).


04 — API Specification

Các API cần implement

Đây là interface contract tối thiểu. Bạn có thể thêm fields hoặc endpoints nếu cần — miễn là backward compatible.

Document Management
POST /api/documents/upload Upload & trigger ingestion pipeline

Request (multipart/form-data)

file: File // PDF, DOCX, TXT name: "string" // optional display name

Response 201

{ "id": "doc_abc123", "name": "Q3 Report.pdf", "status": "processing", "createdAt": "2024-01-15T..." }
GET /api/documents List all documents

Query Params

page: 1 // pagination limit: 20 status: "ready" // filter

Response 200

{ "data": [{ "id", "name", "status", "chunkCount", "createdAt" }], "total": 42, "page": 1 }
GET /api/documents/:id Get document detail & processing status
DELETE /api/documents/:id Delete document + all associated chunks/vectors
Query & Chat
POST /api/query Ask a question, get AI-generated answer

Request body

{ "question": "Doanh thu Q3 là bao nhiêu?", "documentIds": ["doc_abc"], // optional filter "topK": 5 // chunks to retrieve }

Response 200

{ "answer": "Doanh thu Q3 đạt 2.4 tỷ...", "sources": [{ "documentId": "doc_abc", "documentName": "Q3 Report.pdf", "snippet": "...text trích dẫn...", "score": 0.92 }], "model": "gpt-4o-mini" }
POST /api/query/stream Streaming version — Server-Sent Events
Bonus: Implement SSE streaming cho câu trả lời. Client lắng nghe từng token được generate realtime thay vì chờ full response. Format: data: {"token": "..."}
Chunks (optional but nice)
GET /api/documents/:id/chunks List chunks of a document (for debugging)
POST /api/documents/:id/reprocess Re-chunk & re-embed document

05 — Deliverables

Bạn cần nộp gì


06 — Evaluation Criteria

Tiêu chí đánh giá

Tiêu chí Mô tả Điểm
System Thinking Kiến trúc rõ ràng, tách biệt concerns, dễ mở rộng
25pt
Code Quality TypeScript types, error handling, clean structure, naming
20pt
RAG Quality Chunking strategy, retrieval accuracy, citation quality
25pt
Documentation README chất lượng, giải thích quyết định kỹ thuật
15pt
Delivery Demo chạy được, setup dễ, UX có thể dùng
15pt
07 — Bonus Points

Điểm cộng

Không bắt buộc — nhưng nếu bạn có thời gian hoặc hứng thú, đây là những điểm cộng đáng kể.

🌊

Streaming SSE

Stream answer từng token realtime thay vì chờ response hoàn chỉnh.

🔍

Hybrid Search

Kết hợp vector search với full-text search (BM25) để tăng accuracy.

💬

Chat History

Lưu conversation history, support multi-turn với context từ lượt trước.

🌐

Vietnamese NLP

Xử lý tốt tài liệu tiếng Việt — tokenize, chunking phù hợp ngữ pháp.

📊

Observability

Log latency, token usage, retrieval score. Có thể là simple table trong DB.

🔒

Auth Layer

JWT auth đơn giản. Mỗi user chỉ thấy documents của mình (multi-tenant).


08 — Ground Rules

Quy định

Được phép: Dùng tất cả AI tools (Cursor, Claude Code, Copilot, ChatGPT...). Đây là môi trường AI-first — chúng tôi khuyến khích điều này.

Được phép: Dùng bất kỳ thư viện open-source nào. LangChain, LlamaIndex, Haystack đều ổn.

⚠️ Lưu ý: Bạn cần hiểu code mình viết. Reviewer sẽ hỏi về các quyết định kỹ thuật trong buổi interview. Vibe code thì ok, nhưng không phải copy-paste không hiểu.

⚠️ Lưu ý: Không cần hoàn hảo 100%. Một hệ thống 80% hoàn thiện nhưng có README giải thích tốt "trade-offs và next steps" còn tốt hơn một system hoàn hảo nhưng không documented.


Nộp bài trong vòng 48 giờ

Gửi link GitHub repo + link demo về địa chỉ email bên dưới kèm subject [Challenge] Tên của bạn.

gửi bài → vidtory.ai@gmail.com