Bỏ qua đến nội dung
Trần Tuấn Anh
beginaiknowledge_searchstackllmtôi làm gìcategorizekinh nghiệmhttpdự ánagentragentamessageliên hệ

agent graph · kéo để xoay · bấm một node

01Kỹ sư phần mềm · Hà Nội · sẵn sàng nhận việc

Tôi làm những phần trong sản phẩm AI bắt buộc phải đúng: retrieval trích dẫn đúng đoạn văn gốc, agent sống qua mỗi lần deploy, và sổ cái credit chỉ tính tiền một lần.

02Ragenta

Một tài liệu trở thành câu trả lời có trích dẫn như thế nào

Ragenta là SaaS RAG + agents đa tenant tôi đã xây ở NYB AI. Một workspace upload tài liệu của mình, đặt câu hỏi, và nhận câu trả lời chỉ đúng đoạn văn gốc mà nó lấy ra. Mọi lần gọi model đều trừ từ sổ credit, và mọi job ingestion phải sống sót nếu deploy rơi đúng lúc nó đang chạy.

Dưới đây là đường đi của một tài liệu, từ lúc upload đến khi thành trích dẫn [[n]] trong câu trả lời chat. Sáu stage id đúng là những id backend đang dùng; sơ đồ bên cạnh chạy theo thẻ bạn đang đọc.

Pipeline của Ragenta: từ upload đến câu trả lời có trích dẫnSáu trạm nối tiếp nhau — ingest, parse, chunk, embed, retrieve, cite. Trạm của stage bạn đang đọc được làm nổi bật.Ingest — upload được xếp thành job BullMQpending1 ingestParse — các section kèm khoảng trangparsing2 parseChunk — mảnh 512 token có overlapsummarychunking3 chunkEmbed — vector vào Qdrant, text ở Postgresqdranttsvector4 embedRetrieve — hybrid search dense + lexicalhybridtop-k5 retrieveCite — đoạn văn đóng băng trên message[[1]] [[2]]6 cite
trạng thái pending ·
  1. 01

    Ingest

    Upload đẩy một job BullMQ mà payload chỉ có {documentId, workspaceId}; mọi thứ còn lại đọc từ DB lúc job chạy. Job id là ingest:{documentId}:{attempt} và khoản trừ credit được key theo id đó — retry không bao giờ tính tiền hai lần. Ba lần thử, không dùng mặc định của BullMQ: tài liệu đã hỏng hai lần thì lần ba thường cũng hỏng, mà mỗi lần thử là một cuộc gọi provider mất tiền.

  2. 02

    Parse

    Bộ extractor theo từng định dạng (unpdf, mammoth, exceljs, email, hierarchy) cho ra các section kèm khoảng trang. PDF scan không có lớp text nên fail với lý do mà người đọc xử lý được, thay vì âm thầm index ra rỗng. Không có OCR trong đường ingestion — lý do fail nói thẳng như vậy.

  3. 03

    Chunk

    Port lại naive_merge của RAGFlow: cắt tại dấu kết câu (kể cả CJK 。;!?, để knowledge base tiếng Việt hay tiếng Trung không biến thành một chunk khổng lồ), gộp lại tới 512 token, rồi gắn phần đuôi của chunk trước vào đầu chunk sau. Tóm tắt RAPTOR (tuỳ chọn) được index như chunk kind = 'summary' và trích dẫn như mọi đoạn văn khác.

  4. 04

    Embed

    100 input mỗi lần gọi (giới hạn của provider), input dài quá thì cắt ở 8 000 token thay vì fail cả tài liệu. Model embedding được cố định cho từng knowledge base ngay lúc tạo — đổi model không thể embed lại những gì đã có. Text ở lại Postgres cùng tsvector; vector sang Qdrant, key theo id dòng chunk. Các khoảng đã embed và đã trả tiền được dùng lại khi retry.

  5. 05

    Retrieve

    Hybrid: cosine của Qdrant (trong [0,1]) và ts_rank_cd của Postgres (không chặn trên, chuẩn hoá theo kết quả tốt nhất) trộn với vectorWeight, cắt ở ngưỡng similarity. Ba mode hybrid · vector · keyword; nửa nào bị tắt thì bỏ luôn cuộc gọi chứ không gán trọng số 0. Reranker (tuỳ chọn) chỉ chạy trên tập ứng viên đã trộn, không bao giờ trên cả corpus.

  6. 06

    Cite

    Model trích dẫn bằng [[n]]; server đóng băng các đoạn văn tương ứng ngay trên dòng message, nên render chỉ là tra theo chỉ số — không có bước khớp similarity hậu kỳ có thể trôi sang sai đoạn. Trong agent run, CitationCollector đánh số đoạn văn một lần cho cả run, nên [[1]] là cùng một đoạn dù tool call nào tìm ra nó.

Bốn quyết định tôi sẵn sàng bảo vệ khi review

Trích dẫn được đóng băng phía server.
Render là tra theo chỉ số, không bao giờ là khớp similarity có thể trôi sang sai đoạn. Vì sao không khớp lại lúc render: ít code hơn, nhưng similarity có thể rơi vào đoạn kế bên, và trích dẫn sai còn tệ hơn không có.
State streaming nằm ở local, không nằm trong query cache.
Mỗi token một lần setQueryData thì mọi subscriber đều render lại. Stream ghi vào local state; cache được invalidate một lần lúc kết thúc và dữ liệu của server — kèm trích dẫn, model và chi phí — được lấy làm chuẩn.
Chỉ poll khi còn thứ đang chạy.
Danh sách tài liệu dừng ngay khi mọi dòng đã ready hoặc failed. Vì sao không poll theo chu kỳ cố định: một trang đang đứng yên sẽ gọi API liên tục mà chẳng để làm gì.
Từ chối xảy ra trước khi stream mở.
Hết credit, model ngoài gói, thiếu knowledge base: một 4xx bình thường kèm thông báo, không bao giờ là error frame sau khi UI đã chuyển sang trạng thái "đang trả lời".

Đọc case study đầy đủ — kiến trúc, trình soạn agent flow, cả bảy quyết định →

03Kinh nghiệm

Nhật ký vận hành

  1. 03

    NYB AI

    Software Engineer · ragenta

    checkpointTính năng promo-code và credit từ đầu đến cuối — admin API, giao diện console và luồng redeem — cùng lịch webinar theo timezone và luồng đăng nhập Google One Tap đã gia cố.

    TypeScript · Hono · Next.js · PostgreSQL · Qdrant · Redis · BullMQ · Better Auth · Stripe · MinIO · Docker · Google One Tap · PostHog · GitOps

    06/202609/2026 · 4 tháng
  2. 02

    Global AI

    Fullstack Developer · tradewize

    checkpointTính năng frontend và backend cho TradeWize, trình mô phỏng giao dịch giáo dục tại Mỹ — web/app module, API, dashboard, user flow — làm việc trực tiếp với BA và tester.

    TypeScript · Node.js · PostgreSQL · Docker

    12/202506/2026 · 7 tháng
  3. 01

    Avada Group

    Node.js Intern · shopify apps

    checkpointBa app demo Shopify trong ba tháng — auth, webhook, API và tương tác với store, cùng phần event-driven trên Firebase Pub/Sub và Cloud Functions.

    Koa.js · Shopify Polaris · Firebase · Liquid

    09/202511/2025 · 3 tháng
  4. 00

    Hanoi University of Industry

    Kỹ sư Công nghệ phần mềm

    10/202208/2026
04Dự án

Bảng thông số

Ragenta AI — ảnh chụp màn hình
Không gian làm việc Ragenta — chat có căn cứ, trích dẫn nguồn
project · 012026

Ragenta AI

RAG đa tenant kèm agent có thể cấu hình. Workspace dựa trên organisation của Better Auth, một worker ingestion, hybrid retrieval với trích dẫn chính xác, sổ credit nạp từ webhook Stripe, và một trình soạn agent flow 16 node.

role
fullstack — pipeline RAG, agent runner, billing
stack
TypeScript · Hono · Next.js · PostgreSQL · Qdrant · Redis · BullMQ · Better Auth · Stripe · MinIO · Docker
scale
16 loại node · 3 lần thử ingest · chunk 512 token
links
case studystaging (mở trong tab mới)github (mở trong tab mới)
E-commerce microservices — ảnh chụp màn hình
Trang chủ cửa hàng Stationery
project · 022026

E-commerce microservices

Auth, catalogue, đơn hàng, thanh toán và thông báo là các microservice độc lập giao tiếp qua gRPC và Kafka; webhook Stripe; chatbot tư vấn sản phẩm dùng OpenAI với retrieval trên catalogue.

arch
microservices · gRPC · Kafka
stack
TypeScript · NestJS · Next.js · PostgreSQL · Stripe · OpenAI · Docker
links
demo (mở trong tab mới)github (mở trong tab mới)
Job Portal API — ảnh chụp màn hình
Trang quản trị Job Portal
project · 032024

Job Portal API

Backend REST cho nền tảng tuyển dụng: nhà tuyển dụng quản lý tin đăng, ứng viên tìm và ứng tuyển việc làm.

arch
monolith REST · JWT
stack
Node.js · Express · TypeScript · PostgreSQL · Prisma · JWT
links
github (mở trong tab mới)