Bot thứ hai phá vỡ con bot đầu tiên — và đó là tin tốt
Tháng Sáu tôi xóa một file code mà mình đã mất cả buổi để viết. Không phải vì nó hỏng — nó đang chạy thật, đang trả lời đúng bảng giá của một spa thật. Mà vì con bot thứ hai cho tôi thấy cái cách nó được viết không thể nhân lên được.
Cái bẫy của "chỉ có một"
Con bot đầu tiên của tôi phục vụ một spa. Tôi viết một file riêng để bot sales đọc file giá tĩnh. Tôi viết một file riêng để bot spa đọc database. Hai loại bot, hai đường đọc dữ liệu, hai bộ logic — nhưng đều chạy. Khách trả tiền. Tôi vui.
Khi chỉ có một bot, kiến trúc tệ không đau. Nó chỉ nằm im dưới đó, chưa có lý do để lộ ra.
Rồi tôi cần thêm bot thứ hai.
Câu hỏi mà bot thứ hai đặt ra
Spa mới muốn bot tư vấn. Tôi ngồi setup và thấy ngay vấn đề: copy file cũ thành file mới cho spa hai? Viết thêm một nhánh elif nữa trong code?
Cả hai câu trả lời đều sai. Nhân lên theo cách đó là xây một đống gạch, không phải một hệ thống.
Tôi phải dừng lại và nhìn thật vào đống code: tôi đang code cho từng loại bot, không phải code cho mọi bot.
Đây là câu chuyện quen. Bạn build nhanh, ship được, mừng. Rồi đến lúc phải nhân lên, bạn mới thấy cái kiến trúc bên dưới không được thiết kế cho điều đó. Bởi vì lúc bắt đầu bạn không nghĩ tới điều đó — và không nên nghĩ tới, vì lúc đó nhiệm vụ là ship, không phải thiết kế cho năm sau.
Quyết định: xóa nhánh, không thêm nhánh
Tôi không thêm file mới cho spa hai. Tôi xóa file cũ của sales.
Nguyên tắc mới: mọi bot chạy cùng một pipeline. Không còn "loại spa làm kiểu này, loại sales làm kiểu khác". "Spa" hay "Sales" chỉ là một preset — một gói cấu hình mặc định được nhét vào khi tạo bot mới, giống như chọn template. Sau đó bot đó là một instance bình thường: persona riêng, knowledge riêng, danh sách tool riêng — tất cả lưu trong database, không nằm cứng trong code.
Một hàm duy nhất tra bảng preset để biết bot loại gì cần gì, thay vì rẽ nhánh if/elif khắp nơi trong code. Bật/tắt từng tool là cấu hình per-bot trong database — không hardcode nữa.
Hệ quả ngay lập tức: thêm spa thứ ba không cần viết thêm một dòng code. Nhập dữ liệu vào admin, chọn template, bot lên sóng.
Mất một ngày, được một hệ thống
Cái refactor đó mất một ngày thật — chạy lại hết test, sửa hai chỗ vỡ khi gộp code, confirm con bot TA Beauty vẫn trả lời đúng bảng giá sau khi code bên dưới thay đổi hoàn toàn.
Không đau. Nhưng tôi sẽ không thể làm refactor đó nếu không có con bot thứ hai — vì con bot thứ hai mới là thứ đặt câu hỏi. Con bot đầu tiên không đặt câu hỏi gì cả. Nó chỉ chạy.
Đây là điều tôi muốn người mới build nhớ: bạn không biết kiến trúc của mình có vấn đề gì cho đến khi bạn cần nhân nó lên. Và bạn chỉ biết cần nhân lên khi đã có thứ gì đó đang chạy thật rồi.
Cái giả định sai nào cũng có lý do
Tôi không xây file logic riêng cho mỗi loại bot vì tôi ngốc. Tôi xây vì lúc đó mục tiêu là: ship con bot đầu tiên, chạy được, có doanh thu. Cái kiến trúc tệ đó là điều kiện cần để bắt đầu.
Nếu tôi ngồi nghĩ ra thiết kế "mọi bot uniform" từ buổi đầu, tôi đã ngồi thiết kế thêm hai tuần trước khi viết dòng code đầu tiên. Và con bot đầu tiên có thể sẽ không bao giờ được ship.
Cái giả định sai là học phí rẻ nhất bạn có thể trả — vì nó đến từ thực tế, không phải từ suy đoán. Thực tế luôn dạy chính xác hơn sơ đồ kiến trúc vẽ trên giấy trắng khi chưa có một dòng code nào chạy.
Bài học mang đi
Ship con bot đầu tiên bằng kiến trúc "đủ để chạy". Đừng tối ưu sớm. Đừng thiết kế cho scale ở bước 1.
Nhưng khi con bot thứ hai gõ cửa — hãy để nó hỏi. Nó sẽ chỉ cho bạn chính xác cái gì trong con bot đầu cần phải sửa. Đó sẽ là refactor tốt nhất bạn từng làm — vì có thực tế đứng sau, không phải lý thuyết.
Người build bot đầu tiên cần dũng cảm để bắt đầu. Người build bot thứ hai cần dũng cảm để sửa lại. Cả hai đều là bài học, chỉ khác lúc.
👉 Muốn tự tay build con bot đầu tiên — không cần hoàn hảo, chỉ cần lên sóng và bắt đầu học từ thực tế? Bắt đầu với mini-course miễn phí: Bot AI đầu tiên của bạn — làm xong trong một buổi tối, và bạn sẽ có đủ bài học thật để biết mình cần sửa gì tiếp theo.