Xây một content pipeline không có con người trong vòng lặp
Chúng tôi xây một content engine vận hành trọn một lĩnh vực từ khám phá nguồn tới phân phối social, không ai trong vòng lặp. Đây là cái bộ máy nhàm chán đã khiến 'tự động' thật sự an toàn.
Lần đầu tiên cả hệ thống chạy trọn vòng từ đầu tới cuối, không ai ngồi canh.
Tầm 2 giờ sáng, nó tìm thấy một nguồn chưa từng gặp, crawl về, rewrite bài viết, chấm điểm kết quả theo một ngưỡng chất lượng, publish, sinh SEO metadata, rồi đẩy vài bài social. Không ai duyệt gì cả. Không ai thức.
Đó chính là toàn bộ mục đích của nền tảng: một content engine vận hành một lĩnh vực từ khám phá nguồn tới phân phối, không có con người trong vòng lặp. Và đó cũng là thứ ngốn của chúng tôi gần trọn một năm để làm cho an toàn, vì mỗi stage trong cái pipeline đó đều tìm cách hạ gục hệ thống trước khi nó chịu cư xử đàng hoàng.
Đây là chuyến đi qua từng stage, và cái sự cố đứng sau mỗi quyết định.
Vì sao là pipeline, không phải một script
Phiên bản ngây thơ của "tự động hoá nội dung" là một script dài: fetch, rewrite, post. Chúng tôi làm kiểu đó trước. Nó vỡ ngay khi bất kỳ bước nào chậm, bị rate-limit, hay sai, vì một script không nhớ nó đang ở đâu lúc ngã.
Nên hệ thống thật là một pipeline gồm các job độc lập và bền. Chúng tôi chạy trên Elixir/Phoenix với Oban làm lớp job, nghĩa là mỗi stage (crawl, rewrite, quality check, publish, SEO, distribute) là một queue riêng, với retry policy riêng, giới hạn concurrency riêng, và backpressure riêng. Một provider timeout ở stage rewrite không làm tắc đám crawler. Một nguồn chập chờn không chặn việc publish mọi thứ đang xếp hàng phía sau.
Tầng crawl nằm ở edge, trên Cloudflare Workers, nên việc khám phá và fetch chạy gần nguồn và song song, hàng chục crawler cùng lúc trên đủ loại cấu trúc website mà chúng tôi ném vào. Phần việc nặng và có state (orchestration, chấm điểm, cái database chứa mọi thứ từng thấy) thì ở lại phía Elixir.
Đây, một cách có chủ đích, là một hệ phân tán nhàm chán. Phần thú vị không phải là chuyện AI viết được bài. Phần thú vị là tất cả những gì giữ cho AI không làm chúng tôi vỡ nợ, không nói dối, và không khiến chúng tôi bị chặn.
Hoá đơn AI tới trước cả traffic
Bất ngờ đầu tiên là cái hoá đơn.
Một vòng lặp tự động có một tính chất mà quy trình do người điều khiển không có: không ai canh đồng hồ. Khi một người bấm "generate", họ cảm nhận được từng lời gọi. Khi một pipeline tự chạy, nó sẽ vui vẻ gọi model cả chục nghìn lần qua đêm, kể cả cho những thứ nó vừa làm một tiếng trước.
Hai failure mode gây ra gần như toàn bộ. Làm trùng: cùng một nguồn, cùng một đoạn, bị rewrite lại vì chẳng có gì nhớ kết quả lần trước. Và bão retry: một lỗi tạm thời đẩy job quay lại queue, thế là nó trả tiền cho cùng một completion đắt đỏ hai ba lần.
Chúng tôi vá bằng hai mẩu đường ống, chẳng cái nào cao siêu. Một two-tier cache (hot in-memory, rồi một lớp bền) để một request giống hệt không bao giờ chạm API tính phí lần thứ hai. Và request coalescing, để khi hai mươi job cùng hỏi một thứ trong cùng một khoảng, chỉ một lời gọi đi ra và hai mươi job dùng chung câu trả lời. Cộng lại, cái đó cắt chừng 40 tới 60 phần trăm chi phí AI. Cùng đầu ra, nửa hoá đơn, vì một nửa hoá đơn là phần lãng phí chúng tôi không nhìn thấy.
Trong hệ có con người, chi phí tự giới hạn. Trong hệ tự động, chi phí là một cái bug bạn phải thiết kế để loại bỏ.
Coi model như một hạ tầng sẽ hỏng
Điều thứ hai chúng tôi học được là không thể xây một hệ tự động trên lưng một AI provider duy nhất, vì provider sẽ sập, sẽ rate-limit bạn, sẽ đổi hành vi, và sẽ khai tử model, thường là vào lúc tệ nhất.
Giai đoạn đầu, chỉ một cú trục trặc của một provider là đủ làm tắc cả stage rewrite. Job dồn đống. Queue rút sai hướng. Chúng tôi chỉ cách một sự cố upstream là tới một pipeline chết.
Nên AI engine trở thành multi-provider mặc định, nấp sau một circuit breaker. Chúng tôi chạy trên ba (Gemini, DeepSeek, và OpenRouter làm fallback rộng), và lớp orchestration tự failover: khi một provider bắt đầu lỗi hoặc chậm quá ngưỡng, breaker bật, traffic dời sang cái kế tiếp, và cái đã chết bị thăm dò lặng lẽ cho tới khi hồi phục. Job không biết và không quan tâm model nào đã trả lời. Nó chỉ nhận lại text.
Cú chuyển trong đầu mới là toàn bộ bài học. Đừng nghĩ LLM như một API thông minh để bạn gọi. Hãy nghĩ nó như một dependency không đáng tin mà bạn định tuyến để né, đúng kiểu bạn đối xử với một cổng thanh toán bên thứ ba hay một DNS resolver chập chờn. Failover, health check, timeout, breaker. Mấy pattern resilience nhàm chán, áp lên phần mới nhất của stack.
Cái cổng phải biết nói không
Đây là sự thật khó nghe về "zero human intervention": nó chỉ đáng tin bằng đúng cái thứ đứng thay cho phán đoán của con người. Với chúng tôi đó là quality gate, và đó là phần tôi sẽ bảo vệ tới cùng.
Pipeline thuở đầu publish bất cứ thứ gì rớt ra từ stage rewrite. Phần lớn thì ổn. Một số thì mỏng, lạc đề, hoặc sai một cách tinh vi, và vẫn lên sóng, vì chẳng có ai để nói không.
Nên chúng tôi dựng một bộ chấm điểm tự động với ngưỡng tùy chỉnh theo từng lĩnh vực. Mọi bài ứng viên đều bị chấm trước khi được publish. Dưới vạch, nó không được chuyển cho người (làm gì có người); nó được một smart retry, nơi lý do trượt được đưa ngược vào một lần tạo lại có mục tiêu, thay vì roll lại một cách mù quáng. Mỏng quá thì bị bảo đào sâu vào đúng những chỗ thiếu. Lạc đề thì bị kéo về lại brief. Chỉ thứ nào qua vạch mới được ship.
Đây cũng là chỗ xử lý bài dài, vì một nguồn 20.000 từ không thể rewrite trong một phát mà model không lạc mất mạch giữa chừng. Chúng tôi chunk nó ra, xử lý từng mảnh, và validate lúc ghép lại, để độ dài không âm thầm bào mòn chất lượng.
Cái gate là lý do tôi ngủ được trong khi cái máy vẫn publish. "Tự động" mà không có một cái gate đủ cứng thì không phải tự động, nó chỉ là không có ai giám sát.
Stage khó chịu nhất: phân phối
Publish một bài là nửa dễ. Để nó được nhìn thấy thì phải đẩy vào các nền tảng social (Pinterest, Reddit, X), và mấy nền tảng đó không ưa loại automation trông giống automation.
Đây là stage tôi thành thật nhất khi nói nó là một mục tiêu di động. Nó là bài toán mèo vờn chuột, không phải một thứ đã giải xong. Lớp phân phối hành xử như một con người cẩn thận chứ không như một con bot: nó giãn các bài theo nhịp giống người, xoay vòng danh tính và đường mạng để traffic không dồn từ một chỗ lộ liễu, và lùi lại ngay khi một nền tảng phản ứng. Khi một tài khoản bị hạn chế, hệ thống coi đó là tín hiệu và chậm lại, thay vì cố đấm xuyên qua và đốt cháy tài khoản.
Tôi không giả vờ rằng cái này là vĩnh viễn. Các nền tảng đổi luật và đổi cách phát hiện, và phần này của hệ thống cần được để mắt liên tục hơn bất kỳ phần nào khác. Bài học chúng tôi rút ra: thiết kế phân phối để xuống cấp một cách êm ái dưới áp lực, vì áp lực mới là trạng thái thường trực, không phải ngoại lệ.
Cái gì thật sự làm nó tự động
Lùi ra xa mà nhìn, gần như chẳng phần khó nào là AI cả.
Sinh ra một bài viết là 20 phần trăm dễ, và thẳng thắn mà nói là phần tự nó dễ đi sau mỗi vài tháng khi model khá lên. 80 phần trăm còn lại là cái bộ máy không hào nhoáng quanh nó: job bền để không mất gì, cache và coalescing để không vỡ nợ, circuit breaker để một sự cố không kéo sập dây chuyền, một quality gate để không publish rác, và một lớp phân phối biết cách thua một cách êm.
Cái bộ máy đó cũng là thứ làm cho bài toán kinh tế chạy được. Một khi nền tảng đã tồn tại, thêm một lĩnh vực mới gần như chỉ là cấu hình, vì phần đắt đỏ (orchestration, resilience, cái gate) được dùng chung. Chi phí cận biên cho vertical kế tiếp gần bằng không, điều chỉ đúng vì chi phí cố định để xây cái sự-tự-động đã được trả trước, trả đủ, đúng vào những chỗ nhàm chán này.
Nếu bạn đang xây một thứ đáng lẽ phải chạy mà không có bạn, đó là chỗ tôi sẽ khuyên bạn dồn cả năm vào. Không phải cái model. Mà là tất cả những gì quyết định liệu bạn có thể tin cái model khi không ai ngồi canh.
Chúng tôi thiết kế và xây những pipeline tự động, production-grade kiểu thế này theo hướng trọn gói. Nếu bạn có một workflow muốn nó chạy mà không cần người trông, liên hệ với chúng tôi.
Có hệ thống cần xây?
Chúng tôi thiết kế và xây phần mềm cho doanh nghiệp đang lớn — trọn gói.
Gửi yêu cầu tư vấn