Tự động phân loại sách mới trong Inbox vào đúng thư mục thể loại/chủ đề bằng Antigravity AI Agent
Skill này được thực thi bởi Antigravity AI Agent (không cần API key ngoài). Agent sẽ: quét tất cả → chuẩn hóa tên → phân loại + viết mô tả HÀNG LOẠT → hỏi user 1 lần → di chuyển batch → tạo bìa → chèn mô tả → upload → cập nhật website.
Nguyên tắc cốt lõi: Giảm thiểu tương tác với user, tối đa hóa xử lý trong bộ nhớ.
| Cũ (Sequential) | Mới (Batch) |
|---|---|
| Phân loại từng file → hỏi user từng lần | Phân loại TẤT CẢ → hỏi user 1 lần duy nhất |
| Viết description từng entry |
| Soạn description TẤT CẢ trong bộ nhớ → chèn 1 lần |
| Di chuyển từng file riêng lẻ | Di chuyển TẤT CẢ file bằng batch bash commands |
| Edit data.json từng entry | Edit data.json bằng multi_replace_file_content 1 lần |
My-Bookshelves/
├── Inbox/ # Sách mới cần phân loại
├── Books/ # Thư viện sách đã tổ chức (Dynamic Categories)
│ ├── {N}_{Category_Name}/ # Category folders (số + Snake_Case)
│ │ └── {Topic_Name}/ # Topic folders (Snake_Case)
│ │ └── Book_Name.pdf # File sách (ASCII Snake_Case, không dấu)
├── site/ # Website tĩnh (HTML/CSS/JS)
│ ├── index.html
│ ├── app.js # Dynamic category icons/colors via hash
│ ├── data.json # Dữ liệu sách (auto-generated)
│ └── assets/covers/ # Ảnh bìa sách (.webp, 600px, q85)
├── scripts/
│ ├── rename_books.py # Chuẩn hóa tên file → ASCII Snake_Case
│ ├── generate_data.py # Quét sách → tạo data.json + cover WebP
│ ├── upload_releases.py # Smart Incremental Sync → GitHub Releases
│ ├── auto_organize.py # Helper: quét cấu trúc thư viện
│ └── optimize_covers.py # Legacy: re-optimize covers → WebP
└── .agents/skills/auto-organize/
├── SKILL.md # File này
├── prompts/classify_book.md # Quy tắc phân loại (Dynamic Categories)
└── config/settings.json # Cấu hình
Hệ thống hỗ trợ không giới hạn số lượng danh mục:
6_Ten_Danh_Mucapp.js) tự động gán icon và màu badge qua hash — không cần cập nhật codeGo_With_Domain.pdf, Kien_truc_ung_dung_web.epub_ phân cách, KHÔNG dùng khoảng trắng, -, +, .python scripts/rename_books.py --base-dir . --execute để chuẩn hóaKhi generate_data.py chạy, nó tạo lại data.json từ đầu. Script có logic preserve download_url bằng cách match file_path hoặc title từ data.json cũ. Tuy nhiên:
download_urlfile_path cũ không match → phải rely vào title match (rủi ro hơn). Nếu đổi tên file, chạy rename_books.py --execute trước — script sẽ tự cập nhật file_path trong data.json.rename_books.py --execute nếu cầngenerate_data.py — KHÔNG chạy khi thiếugenerate_data.py CHỈ 1 LẦN — nếu fail thì fix nguyên nhân rồi mới chạy lạidownload_url ngay sau khi generate_data.py chạy xongdownload_url nhiều hơn expected → DỪNG, báo userKhi user gọi /auto-organize hoặc yêu cầu phân loại sách, Agent phải thực hiện đúng các bước sau:
Đọc file config/settings.json để biết:
inbox_dir)book_extensions)Liệt kê tất cả file trong thư mục Inbox/.
Chỉ xử lý file có extension .pdf hoặc .epub.
Ghi nhận N = tổng số sách mới để dùng cho bước verify sau.
python scripts/rename_books.py --base-dir .
Kiểm tra dry-run. Nếu có file cần đổi tên:
python scripts/rename_books.py --base-dir . --execute
Bước này đảm bảo tên file ASCII-safe trước khi upload lên GitHub Releases (tránh lỗi Unicode trong URL).
python scripts/auto_organize.py --structure --base-dir .
⚠️ ĐÂY LÀ BƯỚC QUAN TRỌNG NHẤT — THAY ĐỔI CỐT LÕI SO VỚI WORKFLOW CŨ
Đọc file prompts/classify_book.md để nắm quy tắc phân loại.
Agent PHẢI xử lý TẤT CẢ N cuốn sách cùng lúc trong một lần suy luận:
Với mỗi file trong Inbox, Agent xác định:
category_folder: Folder cấp 1 phù hợp nhất (có sẵn HOẶC tạo mới)topic_folder: Folder cấp 2 (hoặc cấp 3) phù hợp nhấtdescription: Mô tả 3 phần hoàn chỉnh (Context + Overview + Key Takeaways)Quy tắc phân loại:
{N}_Snake_Case)Quy tắc description (3 phần):
•, ngăn cách bằng \nCác đoạn ngăn cách bằng \n\n trong JSON string.
🌐 Quy tắc ngôn ngữ description (BẮT BUỘC):
| Tên file sách | Ngôn ngữ description |
|---|---|
| Tiếng Anh (ASCII, không dấu tiếng Việt) | ✅ Viết bằng tiếng Anh |
| Tiếng Việt (có dấu: ă, ơ, ư, đ, v.v. HOẶC từ khóa tiếng Việt rõ ràng) | ✅ Viết bằng tiếng Việt |
Cách nhận biết:
Gia_tri, Ky_su, Kien_truc...) hoặc các từ tiếng Việt không dấu rõ ràng như Giao_trinh, Bai_giang, Vi_du, Ch01_, PTTKHT, v.v.⚠️ KHÔNG hỏi user xác nhận từng cuốn. Agent lưu TẤT CẢ kết quả trong bộ nhớ rồi mới hiển thị.
Hiển thị kết quả phân loại TẤT CẢ N cuốn trong một bảng duy nhất:
## 📚 Kết quả phân loại (N cuốn sách)
| # | File | Category → Topic | Mô tả (tóm tắt dòng đầu) |
|---|------|-------------------|---------------------------|
| 1 | Clean_Code.pdf | Software Engineering / Software Architecture | A practical guide to writing clean... |
| 2 | Head_First_Java.pdf | Computer Science / Programming Languages/Java | Introduction to object-oriented... |
| ... | ... | ... | ... |
> Bạn có muốn tiến hành di chuyển và xử lý tất cả? (Yes/No)
Tạo thư mục đích (nếu chưa có) và di chuyển tất cả file bằng batch commands:
mkdir -p "Books/[cat1]/[topic1]" "Books/[cat2]/[topic2]" ...
mv "Inbox/[file1]" "Books/[cat1]/[topic1]/[file1]"
mv "Inbox/[file2]" "Books/[cat2]/[topic2]/[file2]"
LƯU Ý: Đường dẫn đích luôn bắt đầu bằng
Books/(không phải root). Gộp tất cảmkdir -pvàmvvào ít lệnh bash nhất có thể.
python -c "import fitz; print('PyMuPDF OK')" 2>&1 || echo "MISSING PyMuPDF"
python -c "from PIL import Image; print('Pillow OK')" 2>&1 || echo "MISSING Pillow"
python -m pip install PyMuPDFpython -m pip install Pillowpython -m pip install — hệ thống có thể có nhiều Python versions.generate_data.py khi thiếu PyMuPDF hoặc Pillow.python scripts/generate_data.py --base-dir .
Script sẽ tự động:
site/assets/covers/ dạng .webpsite/data.json với entry mới (preserve description + download_url cũ)⚠️ KHÔNG CHẠY LẠI LẦN 2 — nếu có lỗi, fix nguyên nhân root cause trước.
python -c "import json; data=json.load(open('site/data.json','r',encoding='utf-8')); missing=[b['title'] for b in data if not b.get('download_url')]; print(f'Sách thiếu download_url: {len(missing)}'); [print(f' - {t}') for t in missing]"
Kiểm tra kết quả:
download_url == N (đúng bằng số sách mới vừa thêm) → OKdownload_url > N → generate_data.py đã xóa mất URL cũ → DỪNG LẠI
git checkout site/data.json rồi fix nguyên nhânAgent mở site/data.json, tìm TẤT CẢ entry mới có "description": "", và chèn descriptions đã soạn ở bước 5 trong một lần chỉnh sửa duy nhất.
⚠️ Sử dụng
multi_replace_file_contentđể thay thế tất cả"description": ""entries cùng lúc. KHÔNG edit từng entry riêng lẻ — quá tốn thời gian và token.
Ví dụ JSON sau khi chèn:
"description": "Context paragraph about the problem domain...\n\nBook overview and author introduction...\n\n• Key takeaway 1\n• Key takeaway 2\n• Key takeaway 3\n• Key takeaway 4\n• Key takeaway 5"
python scripts/upload_releases.py --dry-run
Kiểm tra kết quả:
download_url → DỪNG LẠI
Chạy script upload — CHỈ file mới sẽ được upload (không re-upload tất cả):
python scripts/upload_releases.py
Script sẽ tự động:
download_url)storage-v1)download_url trong data.jsongit add -A && git commit -m "add: [N] books to library" && git push
Hiển thị bảng tổng kết cho user:
✅ Hoàn tất: N cuốn sách đã xử lý
| # | Sách | Đích | Bìa | Mô tả | Upload |
|---|------|------|------|-------|--------|
| 1 | Clean_Code.pdf | Books/.../Software_Architecture/ | ✅ WebP | ✅ 3 phần | ✅ |
| 2 | Head_First_Java.pdf | Books/.../Java/ | ✅ WebP | ✅ 3 phần | ✅ |
📤 Upload: N file mới (KHÔNG re-upload sách cũ)
🔗 Links: ?book={id1}, ?book={id2}, ...
prompts/classify_book.md trước khi phân loạimv commands, không chạy từng filerename_books.py trước khi generate/uploadBooks/ — tất cả sách nằm trong folder Books/generate_data.py — bắt buộc cả haigenerate_data.py CHỈ 1 LẦN — không chạy lại nếu đã thành côngdownload_url sau khi generate — đếm số thiếu phải = đúng N sách mớimulti_replace_file_content 1 lần{N}_Snake_Case)python -m pip install — tránh cài nhầm Python version khi hệ thống có nhiều Python