Biến AI agent thành công cụ nghiên cứu quảng cáo: hướng dẫn cho người mới tinh
Cho một AI agent soi 100 quảng cáo skincare thật, rút ra insight mà dân chạy ads phải trả tiền, rồi học cách biến cái script đó thành app deploy lên Railway.
🧪 Tài liệu workdathon. Đây là bản viết lại của một buổi build trực tiếp. Điểm chính không phải cái tool skincare này, mà là cái pattern: bạn mô tả một việc nghiên cứu bằng lời thường, rồi để AI agent dựng nó cho bạn. Bài chia 2 tầng. Tầng 1 giúp ai cũng ra insight thật ngay hôm nay. Tầng 2 dành cho việc biến script vứt-đi thành một app thực thụ. Lấy phần nào bạn cần. Nói trước cho rõ: bạn cần một tài khoản ad library trả phí và tốn vài cent mỗi lượt chạy, và chỉ nên nghiên cứu tool mà bạn được phép dùng.
Nếu bạn chưa từng viết một dòng code, bài này viết cho bạn. Tôi sẽ giải thích, không chừa điểm mù nào, cách một AI agent đi từ “tôi muốn nghiên cứu quảng cáo skincare” tới một dashboard nghiên cứu chạy được. Rồi sau đó là cách biến cái script dùng một lần ấy thành một app tự cập nhật mỗi sáng.
Mọi thuật ngữ kỹ thuật đều được giải thích bằng lời thường và một hình ảnh đời thực. Nếu bước nào nghe như phép thuật, đó là lỗi ở cách tôi giải thích, không phải do bạn kém.
Đây là những gì đã được dựng, để bạn biết mình đang đi đâu:
- Một lượt crawl kéo về 100 quảng cáo skincare đang chạy từ một thư viện quảng cáo.
- Mỗi quảng cáo được gắn nhãn theo góc bán hàng, theo đà (đang lên hay đang chết), chạy ở đâu, và brand chi tiêu khoảng bao nhiêu.
- Landing page của từng brand bị mổ xẻ: giá thật, loại phễu, app đánh giá, chiêu upsell.
- Tất cả gom vào một dashboard bấm được để lọc và sắp xếp.
Tầng 1: Workflow, không giấu gì cả
Nhìn hình trên đầu bài. Cả cái tool là 6 việc nhỏ nối thành chuỗi. Tự thân không việc nào thông minh. Cái hay chỉ nằm ở việc nối chúng lại. Ta đi qua từng bước để giết luôn câu hỏi “sao nó làm được vậy?”.
Bước 1: Đăng nhập như người thật
Mục tiêu: vượt qua màn đăng nhập của thư viện quảng cáo (một tool trả phí mà người dùng đã có tài khoản).
Nó thật sự chạy thế nào. Agent dùng một thứ tên là Playwright. Hình dung một tay lái xe đóng thế trèo vào đúng cái xe của bạn mà lái, không phải xe đồ chơi, không phải hình vẽ, mà xe thật. Playwright là con robot điều khiển một trình duyệt Chrome thật: nó rê chuột, gõ vào ô, bấm nút y hệt người. Nó mở trang đăng nhập, gõ email, gõ mật khẩu, bấm “Continue”.
Cổng đăng nhập được canh bởi Clerk. Cứ coi Clerk như anh bảo vệ đứng cửa, kiểm tra giấy tờ theo hai nhịp (đầu tiên email, rồi mới mật khẩu). Mấy lần đầu thất bại vì agent bấm quá nhanh, bấm khi anh bảo vệ chưa kiểm xong nhịp một. Cách sửa thì hiển nhiên như người: chờ một nhịp giữa hai bước. Chờ xong là cửa mở.
Từ khóa, Playwright: robot điều khiển một trình duyệt thật. Clerk: một dịch vụ gác cổng đăng nhập phổ biến.
Bước 2: Tìm chỗ dữ liệu thật sự nằm
Đây là bước người ta thấy rợn nhất, nên tôi kể chính xác chuyện gì đã xảy ra, không nói mập mờ.
Khi một trang web hiện cho bạn một lưới quảng cáo, trình duyệt của bạn đang âm thầm gọi điện cho máy chủ của công ty: “cho tôi xin danh sách quảng cáo”, và máy chủ trả lời bằng một danh sách gọn gàng. Bạn không thấy mấy cuộc gọi đó, nhưng chúng đang diễn ra dưới lớp giao diện. Trình duyệt nào cũng có Network tab (sổ ghi cuộc gọi) để bạn xem chúng.
Agent nhìn cuốn sổ đó và bắt được một cuộc gọi tên getAds. Khi trả lời, nó không gửi về một trang web đẹp đẽ, mà gửi về JSON, tức là dữ liệu để trong các ô có dán nhãn, giống một tờ khai điền sẵn:
{ "brand": "Soluna SKIN", "reach": 11308008, "price": 39, "runningDays": 886 }
Toàn bộ mẹo chỉ có thế. Thay vì chụp màn hình rồi cố đọc từng điểm ảnh, ta tìm ra API, cái cửa sổ nhỏ mà chính trang web dùng để gọi dữ liệu từ bếp của nó, rồi hỏi y hệt cách nó hỏi. Cùng một dữ liệu trang web đang dùng, đã sạch sẵn.
Hình ảnh đời thực: chép thực đơn từ tấm bảng phấn thì chậm và dễ sai. Ta tìm được tờ phiếu order của bếp. Cùng thông tin, đã đánh máy sẵn.
Từ khóa, Network tab: sổ ghi các cuộc gọi ngầm của trang. API: “cửa sổ order” mà một chương trình dùng để xin dữ liệu. JSON: dữ liệu để trong ô có nhãn, không phải trang web.
Bước 3: Biến một trang thành một trăm quảng cáo
Một cuộc gọi getAds trả về 20 quảng cáo và một cursor. Cursor là cái dấu trang. Kèm 20 quảng cáo, máy chủ nói đại ý: “bạn lấy tới đây rồi; hỏi lại kèm cái dấu trang này thì tôi đưa 20 cái tiếp theo”.
Vậy nên agent lặp: lấy 20, giữ dấu trang, hỏi lại, lấy thêm 20. Năm vòng là ra 100 quảng cáo. Cái này gọi là pagination, đúng nghĩa “lật trang”. Cursor là ngón tay bạn giữ chỗ để không đọc lại trang cũ hay lạc mất chỗ đang đọc.
Từ khóa, Pagination: lấy dữ liệu theo từng trang. Cursor: dấu trang báo “đọc tiếp từ đây”. Rate limit: tốc độ tối đa máy chủ cho phép bạn hỏi trước khi nó bảo “từ từ” (nên ta chèn một khoảng nghỉ nhỏ giữa các cuộc gọi, lịch sự để khỏi bị chặn).
Bước 4: Làm sạch, thu nhỏ, gắn nhãn
Dữ liệu thô thì lộn xộn. Bước này là khâu sơ chế trong bếp mà không ai thấy.
- Giữ lại field hữu ích. Mỗi quảng cáo về kèm mấy chục field; ta giữ những cái seller quan tâm (brand, ước lượng chi tiêu, reach, số ngày chạy, quốc gia, giá) và bỏ phần nhiễu.
- Thu nhỏ ảnh. Ảnh thumbnail của từng quảng cáo được tải về và nén nhỏ lại (một công cụ tên sharp resize chúng), để dashboard cuối tải nhanh chứ không phình thành con quái vật 5 megabyte.
- Gắn nhãn góc bán. Chỗ này AI mới đáng đồng tiền. Một nửa số quảng cáo có copy thật (“Cái này sẽ cho bạn cái đường viền hàm bạn hằng mơ”). AI đọc từng cái và gắn nhãn angle: đây là before/after? problem→solution? giải thích cơ chế? hay quảng cáo social proof kiểu “cháy hàng”? Một bộ lọc từ khóa ngu ngốc sẽ gắn sai; còn một cái đọc-hiểu-câu-chữ thì không.
Một ghi chú thật thà mà lại thành insight riêng: nửa còn lại không có chữ nào cả, chúng là quảng cáo “catalog” (nền tảng tự ghép từ product feed). Không có chữ thì không gắn angle được. Nên chúng bị gắn “Catalog / DPA”, và chính khoảng trống đó là một phát hiện: một nửa số quảng cáo skincare top không phải creative viết tay, mà là quảng cáo catalog tự động.
Từ khóa, AI tagging: để mô hình đọc và phân loại, thay vì luật từ khóa cứng nhắc dễ vỡ.
Bước 5: Bước vào cửa hàng của từng đối thủ
Thư viện quảng cáo cho biết khá nhiều, nhưng hiếm khi lộ giá thật hay phễu bán. Nên con robot (lại Playwright) mở landing page của từng brand ra và đọc.
Nó lấy giá từ một khối dữ liệu ẩn, chuẩn hóa mà đa số cửa hàng công bố, gọi là JSON-LD (dữ liệu có cấu trúc mà shop nhét vào để Google hiện kết quả đẹp, ta mượn lại). Nó cũng ghi nhận: đây là trang sản phẩm bình thường, hay một bài advertorial dài kiểu kể chuyện bán trước rồi mới dẫn link? App đánh giá nào đang gắn (Loox, Yotpo, Judge.me)? Có gói upsell không, sticker hối thúc (“chỉ còn 3 cái”) không, tùy chọn subscribe & save không?
Đó là loại tình báo cạnh tranh mà bình thường bạn phải gom bằng tay, từng shop một. Con robot làm hết cả loạt.
Từ khóa, Teardown: mổ trang đối thủ ra xem nó dựng thế nào. JSON-LD: dữ liệu ẩn chuẩn hóa trên trang. Scraping: đọc một trang web bằng chương trình.
Bước 6: Trình bày thành thứ con người dùng được
Đống dữ liệu đó mà nằm trong một file spreadsheet không ai mở thì vô dụng. Bước cuối biến nó thành frontend, cái phần bạn thấy và bấm.
Với một lượt nghiên cứu dùng một lần, ta không dựng máy chủ hay database. Script chỉ ghi ra một file HTML tự chứa: dữ liệu nhồi sẵn bên trong, thumbnail nhúng sẵn, phần lọc và sắp xếp viết bằng chút JavaScript. Mở bằng trình duyệt nào cũng có ngay một tool thật: lọc theo angle, sắp theo mức chi tiêu, bấm vào một card để xem teardown đầy đủ, export mấy cái thắng ra spreadsheet.
Toàn bộ workflow trên một sơ đồ
Vẫn 6 bước đó, nhưng vẽ thành flowchart thật, có cả những nhánh yes/no chỗ “dữ liệu thật lộn xộn” được xử lý. Đọc từ trên xuống.
Phần thật sự quan trọng: hỏi đúng câu
Một cái tool chỉ thông minh bằng câu hỏi đứng sau nó. Trước khi có dòng code nào, việc thật sự khó là quyết định seller cần biết gì khi soi một bức tường quảng cáo đối thủ. “Cho tôi xem quảng cáo” là một brief tồi. Đây mới là những câu hỏi khiến dữ liệu có giá trị:
- Sản phẩm nào đáng bỏ tiền test? Tín hiệu: quảng cáo chạy rất lâu và bị nhân bản nhiều. Một quảng cáo chạy 886 ngày không phải ăn may, mà là đang có lãi. Đó là sản phẩm đã được kiểm chứng, copy lại thì rủi ro thấp.
- Góc nào đang gánh phần bán? Before/after, problem→solution, cơ chế, social proof. Đây là thứ đáng “swipe” nhất trên trang.
- Format nào thắng? Video, ảnh, hay catalog. Nên dồn ngân sách sản xuất vào đâu?
- Offer và giá là gì? Và nhắm thị trường nào (theo currency)?
- Ai và ở đâu? Quốc gia, độ tuổi, giới tính, vị trí hiển thị, và khoảng trống chưa ai nhắm.
- Đang scale hay đang chết? Đừng bao giờ copy một quảng cáo đang tụt. Mức thay đổi reach theo tháng cho biết creative nào đang được đổ thêm tiền ngay lúc này.
- Mỗi brand test nhanh cỡ nào? Số quảng cáo mỗi tháng của từng brand, tức tốc độ ra creative. Nếu đối thủ tung 20 quảng cáo mới mỗi tháng thì một quảng cáo mỗi tháng không đua nổi.
Để ý: không câu nào mang tính kỹ thuật. Đây là cái đầu của người bán hàng. AI dựng cái máy; còn mấy câu hỏi mới là thứ chĩa cái máy vào chỗ hữu ích.
Về prompt, và tại sao câu lỏng lại hiệu quả nhất
Người ta hay tưởng prompt tốt là một bản đặc tả chính xác, ra lệnh chi li. Trong buổi build này thì ngược lại, và đáng để nghiên cứu cách các yêu cầu được đặt ra, vì đó là kỹ năng bạn học được.
Đây là những prompt thật đã dẫn dắt cả buổi build (giữ gần như nguyên văn, chỉ bỏ thông tin đăng nhập). Để ý: chúng không phải bản đặc tả bóng bẩy. Đó mới là điểm hay.
Prompt mở màn:
“tôi đang muốn crawl 10 cái ads chạy bán hàng ngành skincare. tôi muốn bạn login vào website… có thể dùng playwright để giả lập trình duyệt, crawl lấy dữ liệu. chắc là bạn phân tích cấu trúc hiện tại của website, HTML, DOM trích xuất được thông tin phù hợp, hoặc cách nào khác mà bạn thấy hợp lý. kết quả tôi đang hình dung, là một list hiển thị các box quảng cáo dạng grid.”
Hai thứ nổi bật. Nó nêu một ràng buộc cứng (dùng Playwright, đây là chỗ login) và một hình dung rõ về “xong” (grid các box quảng cáo). Còn khúc giữa, cách tìm và lấy dữ liệu, thì cố ý để ngỏ: “hoặc cách nào khác mà bạn thấy hợp lý.” Chính mệnh đề đó cho phép agent đi tìm ra cái API getAds ẩn, thay vì lụi cụi chụp màn hình từng trang.
Prompt đổi góc nhìn:
“từ góc nhìn của seller, tôi muốn nghiên cứu cái ads này một cách chi tiết để có ích cho hoạt động chạy quảng cáo của tôi. bạn hãy thử phân tích xem nếu là một seller mà đi nghiên cứu hàng loạt ads thì cần nhận về những insights gì. Hãy làm artifact, ui ux cho phần trình bày để tôi đánh giá trước khi làm.”
Câu này chủ động trao quyền: “phân tích xem seller cần insight gì”, chứ không phải “đây là 8 chỉ số của tôi”. Chính sự để ngỏ đó khiến agent bật ra những thứ không ai đặt hàng, như ad velocity (brand tung bao nhiêu ad/tháng) và phát hiện một nửa top ad là quảng cáo catalog tự động. Một brief ra lệnh chi li sẽ giới hạn kết quả trong đúng vốn hiểu biết của người hỏi.
Prompt giữ cho mọi thứ thành thật:
“tôi thấy những đoạn có điểm mù, ví dụ bảo claude nó chọc vào thư viện quảng cáo để lấy dữ liệu, nhưng bạn cần giải thích claude đã làm những việc gì mà lấy được dữ liệu để ai đọc cũng hiểu. tôi nghĩ sẽ nhiều đoạn ‘mù’ như này nên bạn hãy đánh giá thêm.”
Câu này là một cái đòn bẩy chất lượng. Thay vì chấp nhận một câu mập mờ “rồi nó lấy được data”, nó buộc agent phơi ra chỗ hổng của chính mình. Bắt mô hình “trình bày cách làm” là cách bạn tóm được những chỗ nó đang nói lấp liếm.
Nhìn chung, cái pattern xuyên suốt:
- Đưa mục tiêu và hình dung “xong”, không đưa từng bước. “Có ích cho việc chạy ads”, “grid các box quảng cáo”. Cái tại sao để agent tự chọn cách làm tốt.
- Trao quyền ra mặt. “cách nào khác mà bạn thấy hợp lý”, “bạn correct hoặc làm cách nào hợp lý”. Không phải lười, mà là chừa chỗ cho agent đóng góp thứ bạn không biết để mà hỏi.
- Đừng anchor. Bằng cách không đặc tả quá kỹ, bạn tránh anchoring câu trả lời vào phán đoán đầu tiên. “Chỉ liệt kê 10 ad kèm ảnh” sẽ nhận đúng chừng đó, không gì hơn.
- Mời nó phơi chỗ hổng. “giải thích rõ tool đã làm gì”, “đánh giá thêm điểm mù”. Prompt để-bị-bắt-lỗi thắng prompt nịnh tai.
Bài học cho một buổi workdathon: mô tả đích đến và ràng buộc, rồi tránh sang một bên. Kịch bản hóa quá tay một agent giỏi là vứt đi đúng cái thứ bạn đang trả tiền: khả năng nó thấy những gì bạn bỏ sót.
Từ khóa, Prompt: lời bạn ra chỉ dẫn cho AI. Anchoring: vô tình nhốt câu trả lời quanh phán đoán đầu tiên của bạn. Agency: để agent tự ra quyết định thật, thay vì chỉ làm theo lệnh.
Tầng 2: Từ script vứt-đi thành một app thực thụ
Tầng 1 cho bạn insight ngay hôm nay. Nhưng cái file HTML đó là một tấm ảnh chụp: đúng sáng nay, tuần sau đã cũ. Muốn nó thành một tool sống, tự làm mới, bạn cần phần còn lại của nhà hàng: một cái bếp, một cái kho, và một chỗ ở không bao giờ ngủ. Đây là cách từng mảnh hoạt động, vẫn bằng lời thường.
Trước hết: “frontend”, “backend”, “database” thật ra là gì
Quay lại hình nhà hàng ở trên.
- Frontend = phòng ăn. Cái bạn thấy và chạm (nút bấm, card, bộ lọc). Dựng bằng HTML (khung), CSS (nước sơn), JavaScript (hành vi).
- Backend = nhà bếp. Code chạy trên máy chủ và làm việc nặng, ở đây là phần crawl và làm sạch.
- Database = kho và tủ lạnh. Nơi giữ nguyên liệu (dữ liệu) giữa các bữa, mát và gọn.
- API = bồi bàn. Mang yêu cầu từ phòng ăn xuống bếp và bưng món trở ra.
Một lượt nghiên cứu dùng một lần thì bỏ qua bếp và kho: script nấu một lần rồi bày ra thành một trang HTML. Còn một tool chạy hàng ngày thì cần đủ cả bốn.
Câu 1: Làm sao giữ database sạch?
Thuật ngữ là normalize, và nó chỉ có một ý: lưu mỗi sự thật đúng một lần. Trong dữ liệu thô của ta, số follower Instagram của brand bị chép vào từng dòng quảng cáo. Brand chạy 60 quảng cáo thì số follower bị ghi 60 lần. Đổi một chỗ là 59 bản còn lại nói dối.
Cách sửa là tách ra: một bảng brands (mỗi brand lưu một lần, kèm một id) và một bảng ads trong đó mỗi quảng cáo chỉ trỏ tới id của brand. Cái con trỏ đó gọi là foreign key, cứ hiểu là “xem chi tiết ở brand B1”. Giờ một sự thật về brand nằm đúng một chỗ. Không gì tự mâu thuẫn với chính nó được nữa.
Vì sao seller cần quan tâm: một database sạch là thứ duy nhất cho phép lượt crawl ngày mai nói được “quảng cáo này mới” hay “cái này chết rồi”, vì nó so được với một bản duy nhất, đã biết, của hôm qua. Dữ liệu bừa không thấy được thay đổi. Dữ liệu gọn thì hóa thành xu hướng.
Câu 2: Làm sao cho nó ổn định, code sạch, QA kỹ?
Ba thói quen, không thuật ngữ đao to búa lớn:
- Hàm nhỏ, tên rõ. Thay vì một con quái vật 500 dòng, viết những mảnh nhỏ mỗi mảnh làm một việc:
login(),getAds(),cleanAd(),saveToDb(). Dễ đọc, dễ sửa. “Code sạch” hằng ngày thật ra là vậy. - Xử lý cái quảng cáo bị lỗi. Dữ liệu thật thì bẩn: thiếu giá, trang không tải được. Bọc những bước rủi ro lại để một quảng cáo hỏng không làm sập cả lượt chạy (trong lượt crawl của ta, một trang bị timeout thì bị bỏ qua và ghi log, chứ không gây chết). Cái này gọi là error handling.
- Test từng mảnh. Một test chỉ là một đoạn script tí hon kiểm tra “nếu tôi đưa vào cái này, có ra cái kia không?”. Chạy sau mỗi lần đổi code; cái nào đỏ là bạn vừa làm hỏng thứ gì đó. Cái này là QA, đảm bảo chất lượng, và nó cho bạn sửa code tháng sau mà không sợ.
Tư duy: cứ giả định mọi đầu vào rồi sẽ có lúc dị, và làm cho chương trình hỏng một cách êm và có báo: bỏ qua dòng lỗi, ghi lại một dòng note, chạy tiếp.
Câu 3: bạn cần những gì, và deploy thật ra diễn ra thế nào
Đây là khúc người mới thấy mù mờ nhất, nên ta đi chậm. Trước hết là tài khoản và công cụ. Rồi Railway rốt cuộc là gì. Rồi deploy, bấm từng nút. Rồi những thứ hay làm người ta khựng lại.
Trước tiên: tài khoản và công cụ, từ số 0
Bạn không cần mấy cái này để hiểu cái tool. Bạn cần để tự dựng và chạy bản của mình. Đây là danh sách đầy đủ, kèm mỗi thứ là gì và lấy ở đâu. Tầng 1 (chạy một lần trên laptop) chỉ cần ba dòng đầu. Phần còn lại là cho app hàng ngày.
| Bạn cần | Nó là gì | Lấy ở đâu |
|---|---|---|
| Tài khoản ad library | Nguồn dữ liệu bạn đi nghiên cứu (một tool spy quảng cáo). | Đăng ký trên trang của tool đó; đa số trả phí. Đây là thứ duy nhất mà tool đăng nhập vào. |
| Node.js | Cái động cơ trên máy bạn để chạy code JavaScript. | Tải bản “LTS” ở nodejs.org rồi cài như mọi app. |
| Terminal | Cửa sổ chữ để gõ lệnh. | Có sẵn trong máy: “Terminal” trên Mac, “PowerShell” trên Windows. |
| Một AI coding agent | Thứ viết và chạy code giúp bạn (ví dụ Claude Code). | Cài một lần; sau đó bạn nói chuyện với nó bằng lời thường. |
| Tài khoản GitHub | Kho lưu code miễn phí trên mây, nhớ mọi phiên bản. | Vào github.com, bấm “Sign up”. Miễn phí. |
| Tài khoản Railway | Dịch vụ chạy code của bạn online 24/7 (giải thích bên dưới). | Vào railway.app, bấm “Login with GitHub”. Bắt đầu miễn phí. |
| Anthropic API key | Một mật khẩu để app xin Claude gắn nhãn angle cho quảng cáo. | Tạo ở console.anthropic.com. Tốn vài cent mỗi lần chạy; không bắt buộc (có fallback từ khóa). |
Đừng để danh sách làm bạn ngợp. Đăng ký mỗi cái cũng chỉ là “nhập email, bấm xác nhận” như bạn đã làm trăm lần. Thói quen mới duy nhất là giữ mật khẩu và key ở chỗ an toàn, không bao giờ để trong code.
Railway rốt cuộc là gì
Railway là một công ty cho bạn thuê một cái máy tính trên mây, cái không bao giờ tắt, kèm một database, kèm một bộ lập lịch, tất cả nối sẵn với nhau. Bạn không đụng tới máy chủ vật lý hay cài hệ điều hành. Bạn kết nối repo GitHub của mình, và Railway chạy code của bạn trên cái máy luôn-bật đó.
Ý tưởng chỉ có vậy: laptop của bạn thì ngủ, máy của Railway thì không. Nên thứ gì phải chạy trong lúc bạn vắng mặt, con crawler hàng ngày và cái database, thì nằm ở đó. (Vercel nhắc ở trên là cùng ý tưởng nhưng tối ưu cho website; Railway tối ưu cho backend, database và việc chạy theo lịch. Nguyên tắc ngón tay cái: phòng ăn để Vercel, bếp và tủ lạnh để Railway.)
Deploy diễn ra thế nào, bấm từng nút
“Deploy” chỉ nghĩa là chuyển code khỏi laptop lên cái máy luôn-bật đó và cấp cho nó một địa chỉ web. Đây là con đường thật, không bỏ bước nào.
- Đưa code lên GitHub. Trong dự án, mở Terminal rồi gõ
git init,git add .,git commit -m "first", rồi tạo một repository ở github.com vàgit push. Một repository (“repo”) đơn giản là thư mục dự án của bạn, chép lên mây, có trí nhớ về mọi thay đổi. (Agent AI có thể chạy mấy lệnh này giúp bạn.) - Đăng nhập Railway bằng GitHub. railway.app → “Login with GitHub”. Giờ Railway thấy được repo của bạn. Đăng nhập bằng GitHub cũng có nghĩa bạn không phải đẻ thêm một mật khẩu nữa.
- New Project → Deploy from GitHub repo. Chọn repo. Railway đọc nó, thấy đây là dự án Node.js, cài những gì cần và khởi động. Cái “cài và khởi động” đó là build, rồi tới deploy. Bạn vừa chạy một máy chủ mà không phải cấu hình gì.
- Thêm database. Trong project, bấm New → Database → PostgreSQL. Railway dựng một database thật (cái tủ lạnh) và lặng lẽ trao cho code của bạn địa chỉ của nó qua biến
DATABASE_URL, để code tự tìm thấy mà bạn không phải copy gì. - Thêm bí mật vào Variables. Mở service → tab Variables → thêm
ADLIB_EMAIL,ADLIB_PASSWORD, vàANTHROPIC_API_KEY. Chúng nằm đây, không bao giờ trong code. Cùng lý do bạn không ghi mã PIN lên thẻ ngân hàng. - Lấy một URL công khai (đây chính là “truy cập online”). Service → Settings → Networking → Generate Domain. Railway cho bạn một địa chỉ kiểu
ten-app.up.railway.app. Mở nó trên trình duyệt bất kỳ, máy nào cũng được, và đó là dashboard của bạn. Cái URL đó chính là “giờ nó online rồi”. - Thêm con crawler hàng ngày làm service thứ hai. Bấm New → GitHub repo và chọn cùng repo đó lần nữa. Service thứ hai này không phục vụ website; đặt start command của nó là
node src/pipeline.js, và ở Settings → Cron Schedule đặt một giờ. Xong: hai service, một repo, chung một database.
Cái cốt lõi cần nhớ: bạn đang thuê một cái máy không bao giờ ngủ, giao code cho nó từ GitHub, cất mật khẩu trong một ngăn kéo khóa riêng, và chĩa nó vào một cái lịch để nó làm việc trong khi bạn nghỉ.
Từ khóa, Deploy: đưa code lên một máy luôn bật, có URL công khai. Repo: thư mục dự án của bạn, trên mây, có phiên bản. Build: cài và chuẩn bị code để chạy. Domain: địa chỉ web người ta mở. Variable: một bí mật code đọc lúc chạy.
Câu 4: bật chế độ tự chạy hàng ngày (cron)
Một cron job là cái đồng hồ báo thức cho code: “mỗi ngày giờ này, chạy cái này”. Trên Railway bạn đặt nó ở Cron Schedule của service thứ hai bằng năm con số, phút-giờ-ngày-tháng-thứ. 0 1 * * * nghĩa là “phút 0 của giờ 1, mỗi ngày”. Một cái bẫy đáng biết trước: đồng hồ Railway chạy theo giờ UTC, không phải giờ bạn. Việt Nam là UTC+7, nên 08:00 giờ Việt Nam là 0 1 * * * (01:00 UTC). Đặt sai chỗ này là crawl chạy nhầm giờ, và đó là cú “sao không thấy gì chạy” phổ biến nhất.
Mỗi sáng báo thức nổ, crawler đăng nhập, kéo quảng cáo mới, so với hôm qua (ad mới thì gắn cờ, ad biến mất thì đánh dấu chết), rồi ghi vào database chung. Web service vốn đang đọc database đó, nên dashboard tươi mới mà không ai đụng tay. Cái vòng lặp đó, báo thức → crawl → so sánh → lưu → hiện, rồi lại mai như vậy, là thứ biến một báo cáo dùng một lần thành một tool sống. Tấm ảnh chụp biến thành cái camera an ninh.
Những gì có thể làm bạn khựng lại
Danh sách thật thà các cục gạch, để chúng không chặn bạn:
- Login bị chặn. Ad library có phòng bot. Chỉ đăng nhập vào tool mà bạn có tài khoản thật, chèn khoảng chờ nhỏ và retry (ta đã làm), và đừng dập liên tục. Nếu nó chặn cứng automation thì tôn trọng, đó là quyền của họ.
- Ảnh trắng bệch sau một ngày. Link thumbnail là tạm thời (URL ký, hết hạn). Cách sửa: tải và lưu ảnh ngay trong lượt chạy, đừng dựa vào link về sau. App của ta lưu ảnh vào database.
- “Chạy được trên laptop mà lên Railway thì không”. Hầu như luôn là trình duyệt: crawler cần Chrome cài trên máy chủ. Cách sửa: dùng Docker image chính thức của Playwright, nó có sẵn Chrome (file
Dockerfilecủa ta làm thế). - Lỗi kết nối database. URL nội bộ của Railway không cần SSL; URL bên ngoài thì cần. Code của ta tự chuyển theo URL, nhưng nếu bạn tự cấu hình thì đây là thủ phạm quen thuộc.
- Cron chạy nhầm giờ. Lại là UTC. Đổi giờ địa phương của bạn trước đã.
- Hoá đơn bất ngờ. Classifier gọi Claude, tốn chút tiền mỗi lượt; database và service luôn-bật tốn chút tiền mỗi tháng. Bắt đầu ở gói free, theo dõi usage, và nhớ classifier có fallback từ khóa miễn phí nếu bạn bỏ API key.
- Lộ bí mật. Đừng bao giờ commit file
.envhay dán mật khẩu vào code. Bỏ mọi thứ nhạy cảm vào Railway Variables. Thêm.envvào.gitignorengay ngày đầu. - Điều khoản dịch vụ. Chỉ nghiên cứu tool mà bạn được phép dùng, và giữ dữ liệu để tự phân tích chứ đừng đem phát tán lại. Hữu ích không phải cái cớ để ẩu.
Bảng từ khóa: giữ lại mà tra
| Từ khóa | Một câu dễ hiểu |
|---|---|
| Playwright | Robot điều khiển một trình duyệt thật (bấm, gõ) như người. |
| Clerk | Một dịch vụ gác cổng đăng nhập; anh bảo vệ kiểm giấy tờ. |
| API | Cửa sổ order mà một chương trình dùng để xin dữ liệu. |
| JSON | Dữ liệu để trong ô có nhãn, không phải trang web. |
| Network tab | Sổ ghi các cuộc gọi ngầm của một trang trong trình duyệt. |
| Pagination | Lấy dữ liệu theo từng trang thay vì một lần tất. |
| Cursor | Dấu trang báo cho máy chủ “đọc tiếp từ đây”. |
| Rate limit | Tốc độ tối đa máy chủ cho hỏi trước khi bảo từ từ. |
| Normalize | Lưu mỗi sự thật một lần rồi nối, không lặp dữ liệu. |
| AI tagging | Để mô hình đọc và phân loại, thay vì luật từ khóa cứng nhắc. |
| Foreign key | Con trỏ từ bảng này tới một dòng ở bảng kia (“xem brand B1”). |
| Scraping | Đọc một trang web bằng chương trình thay vì bằng mắt. |
| Teardown | Mổ trang đối thủ ra xem nó dựng thế nào. |
| JSON-LD | Dữ liệu ẩn chuẩn hóa trang công bố (ta mượn để lấy giá). |
| Frontend | Phòng ăn, cái bạn thấy và bấm (HTML, CSS, JS). |
| Backend | Nhà bếp, code máy chủ làm việc nặng. |
| Database | Cái kho, nơi lưu dữ liệu giữa các lượt chạy. |
| Deploy | Đưa code lên một máy luôn bật, có URL công khai. |
| GitHub | Kho lưu code trên mây, nhớ mọi phiên bản. |
| Vercel | Host hợp nhất cho frontend (website, dashboard). |
| Railway | Host hợp nhất cho backend, database, việc chạy theo lịch. |
| Node.js | Động cơ trên máy bạn để chạy code JavaScript. |
| Terminal | Cửa sổ chữ để gõ lệnh cho máy tính. |
| Repository (repo) | Thư mục dự án của bạn, chép lên mây, có phiên bản. |
| Build | Cài và chuẩn bị code để nó chạy được trên máy chủ. |
| Domain | Địa chỉ web công khai người ta mở (vd ten-app.up.railway.app). |
| Variable | Mẩu ghi chú riêng (như mật khẩu) code đọc lúc chạy. |
| Cron | Đồng hồ báo thức cho code: “mỗi ngày 8 giờ, làm việc này”. |
| QA / test | Đoạn script nhỏ kiểm tra code vẫn làm đúng việc của nó. |
| Prompt | Lời bạn ra chỉ dẫn cho AI. |
| Anchoring | Vô tình nhốt câu trả lời của AI quanh phán đoán đầu của bạn. |
Một điều mang về
Bạn không cần biết code để có được nghiên cứu quảng cáo thật. Bạn cần hỏi một câu sắc và để một agent đủ giỏi dựng cái chuỗi 6 bước nhàm chán đằng sau nó. Tầng 1 ai cũng với tới ngay chiều nay. Tầng 2 chỉ là thêm một cái bếp, một cái kho, và một cái đồng hồ báo thức để tool cứ chạy trong lúc bạn ngủ.
Chĩa nó vào chính thị trường của bạn. Nói cho nó biết một câu trả lời tốt trông thế nào. Rồi tránh sang một bên.