Ngưỡng bằng 0 bị hiểu là không có ngưỡng: cách phát hiện
Bạn đặt một ngưỡng cảnh báo cho tài khoản quảng cáo, thấy hệ thống chạy đều mỗi ngày, và tin rằng mình đã được bảo vệ. Có một tình huống làm niềm tin đó sai hoàn toàn: ngưỡng bằng 0 bị phần mềm hiểu thành "người này chưa đặt ngưỡng nào cả". Ngưỡng vẫn hiện trên màn hình, hệ thống vẫn chạy, báo cáo vẫn đẹp, nhưng con số đang được dùng để lọc chiến dịch không phải con số bạn gõ vào.
Hậu quả đi theo hai hướng, cả hai đều tốn tiền. Nếu ngưỡng của bạn là chốt chặn chi tiêu, nó không chặn gì cả và tiền cứ chạy. Nếu ngưỡng của bạn dùng để chọn chiến dịch cần tạm dừng, hệ thống lấy một con số mặc định khác hẳn và tạm dừng nhầm những chiến dịch đang chạy tốt.
Bài này chỉ bạn cách phát hiện chuyện đó trong bất kỳ công cụ tự động nào bạn đang dùng, bằng một bài thử mười phút không cần biết lập trình. Phần đầu kể một ca thật để bạn thấy hình dạng của lỗi, phần sau là danh sách chỗ cần kiểm trong tài khoản của bạn.
Ca thật: một ngưỡng bằng 0 và mười bốn chiến dịch khớp nhầm
Bối cảnh là một công cụ cho phép dựng quy trình chạy tự động cho tài khoản quảng cáo: mỗi bước là một điều kiện hoặc một hành động, mỗi điều kiện có ngưỡng do người dùng nhập.
Một trong các điều kiện là "doanh thu trên chi phí thấp hơn ngưỡng". Người dùng nhập ngưỡng, hệ thống so sánh với số thật của từng chiến dịch, chiến dịch nào thấp hơn thì lọt vào diện xử lý.
Người dùng gõ số 0 vào ô ngưỡng đó. Hệ thống chạy, và trả về mười bốn chiến dịch khớp điều kiện.
Nghe qua không có gì lạ, cho tới khi bạn để ý một chuyện: doanh thu trên chi phí không bao giờ âm. Không chiến dịch nào có thể "thấp hơn 0". Nếu ngưỡng thật sự là 0 thì kết quả đúng phải là không có chiến dịch nào khớp, hoặc chỉ khớp những chiến dịch có doanh thu đúng bằng không, tuỳ cách so sánh. Mười bốn chiến dịch là con số không thể xảy ra.
Nguyên nhân nằm ở một dòng đọc tham số. Đoạn mã đọc ngưỡng viết đại ý: lấy giá trị người dùng nhập, nếu giá trị đó rỗng thì dùng giá trị mặc định. Cách viết này phổ biến tới mức gần như là phản xạ, nó gọn và trong phần lớn trường hợp thì đúng.
Vấn đề nằm ở phần còn lại. Trong hầu hết ngôn ngữ lập trình, phép kiểm tra "có rỗng không" trả về kết quả đúng cho nhiều thứ chứ không chỉ ô để trống: chuỗi rỗng, danh sách rỗng, giá trị không xác định, và số 0.
Nên khi người dùng gõ 0, đoạn mã hiểu là "chưa nhập gì", lấy giá trị mặc định, và áp dụng con số đó. Ngưỡng hiện trên màn hình là 0. Ngưỡng đang được dùng để lọc là một số khác.
Lỗi này được bắt trong đợt chạy thử, khi các lệnh xuống nền tảng còn ở chế độ giả lập, nên không có tài khoản thật nào bị đụng vào. Nhưng hình dạng của nó thì đáng học, vì cách viết gây ra nó có mặt trong rất nhiều hệ thống khác.
Vì sao người ta lại gõ số 0 vào ô ngưỡng
Đây là phần quan trọng, vì nó cho thấy lỗi không phải chuyện lý thuyết mà là chuyện sẽ gặp.
Người dùng gõ 0 vào ngưỡng doanh thu trên chi phí không phải vì nhầm. Ý của họ rất rõ: báo cho tôi mọi chiến dịch không mang về đồng doanh thu nào.
Với người chạy quảng cáo, đó là một yêu cầu hợp lý và khá phổ biến. Doanh thu trên chi phí bằng 0 nghĩa là tiêu tiền mà không thu được gì, đúng thứ cần biết sớm nhất trong ngày.
Số 0 còn có nghĩa riêng ở nhiều ô khác trong quảng cáo, và mỗi lần nó có nghĩa riêng là một lần lỗi này có thể xảy ra:
- Số chuyển đổi bằng 0. "Cảnh báo khi chiến dịch tiêu tiền mà chưa có chuyển đổi nào."
- Số lượt nhấp bằng 0. "Báo cho tôi nhóm quảng cáo nào đã hiển thị mà không ai bấm."
- Số ngày chờ bằng 0. "Chạy ngay, không cần chờ."
- Giới hạn tần suất bằng 0. "Không giới hạn" hoặc "không cho hiện lần nào nữa", tuỳ nền tảng — và chính chỗ mập mờ này là nơi lỗi hay nấp.
- Mức điều chỉnh giá thầu bằng 0%. "Giữ nguyên, đừng điều chỉnh gì."
Trong cả năm trường hợp, số 0 là một lựa chọn có chủ đích chứ không phải một ô bỏ trống. Nếu hệ thống gộp hai thứ đó làm một, ý định của bạn bị thay bằng ý định của người viết mã, và bạn không có cách nào biết.
Vì sao loại lỗi này khó phát hiện
Ba đặc điểm khiến nó sống dai.
Không có thông báo lỗi. Hệ thống chạy đúng theo logic của nó. Không ngoại lệ, không dòng nào trong nhật ký lỗi, không cảnh báo nào cho người dùng. Với mọi công cụ giám sát kỹ thuật, hệ thống hoàn toàn khoẻ mạnh.
Kết quả vẫn hợp lý. Mười bốn chiến dịch bị đánh dấu đều là chiến dịch có thật, số liệu có thật, và phần giải thích kèm theo cũng đúng theo ngưỡng mà hệ thống đang dùng. Người đọc kết quả không có cách nào biết ngưỡng đó không phải ngưỡng mình đặt.
Nó chỉ xảy ra với đúng một giá trị đầu vào. Gõ 1, gõ 2, gõ 0,5 đều chạy đúng. Chỉ riêng số 0 là sai. Nghĩa là mọi phép thử thông thường đều qua, vì ai đi thử lại chọn đúng con số 0 để thử.
Đặc điểm thứ ba là điểm mấu chốt. Nó nói cho bạn biết loại phép thử nào bắt được lỗi và loại nào không: thử với dữ liệu bình thường thì không bao giờ chạm tới, phải cố tình thử đúng giá trị biên.
Giá trị 0 đi qua những tầng nào trước khi thành quyết định
Để biết chỗ nào cần kiểm, hình dung con số bạn gõ đi qua bốn chặng.
Chặng một: ô nhập trên màn hình. Ô để trống và ô chứa số 0 là hai trạng thái khác nhau, nhưng nhiều giao diện gửi cả hai đi dưới dạng chuỗi rỗng. Nếu chuyện rơi ở đây thì lỗi xảy ra trước cả khi dữ liệu rời khỏi trình duyệt.
Chặng hai: lúc lưu vào kho dữ liệu. Một số hệ thống chuyển giá trị "giả" thành ô trống khi lưu cho gọn. Sau bước này, không ai còn phân biệt được nữa, kể cả khi phần đọc tham số viết đúng.
Chặng ba: lúc đọc tham số ra để chạy. Đây là chặng gây ra ca thật ở trên, và cũng là chặng phổ biến nhất, vì cách viết "nếu rỗng thì lấy mặc định" nằm đúng ở đây.
Chặng bốn: lúc so sánh. Kể cả khi ba chặng trước đều giữ được số 0, phép so sánh vẫn có thể sai nếu nó dùng "lớn hơn 0" ở chỗ đáng ra phải là "lớn hơn hoặc bằng 0", hoặc nếu nó bỏ qua những chiến dịch có số liệu bằng 0 vì coi đó là "không có dữ liệu".
Bạn không sửa được ba chặng đầu trong một công cụ mua sẵn. Nhưng bạn kiểm được kết quả cuối, và một bài kiểm ở đầu ra là đủ để biết có chặng nào hỏng hay không.
Cách phát hiện: kiểm từng nút, mỗi nút hai tình huống
Cách bắt được lỗi này không phải là đọc mã, mà là chạy thử có hệ thống. Nguyên tắc: mọi điều kiện và mọi hành động đều phải chạy thật trên dữ liệu thật, không lấy vài cái tiêu biểu rồi suy ra phần còn lại.
Tình huống A, ngưỡng chắc chắn khớp. Đặt ngưỡng ở mức mà theo dữ liệu hiện có thì gần như mọi chiến dịch đều lọt. Kỳ vọng: nút phải kích hoạt. Nếu không kích hoạt, nút hỏng.
Tình huống B, ngưỡng không thể khớp. Đặt ngưỡng ở mức mà không chiến dịch nào có thể lọt. Kỳ vọng: không có hành động nào. Nếu vẫn có hành động, nghĩa là nút đang khớp vì một lý do khác chứ không phải vì điều kiện bạn nghĩ.
Bảy điều kiện cộng mười hành động, mỗi cái hai tình huống, thành ba mươi lượt chạy thật. Lỗi ngưỡng bằng 0 lộ ra ở tình huống B, và đợt kiểm đó bắt được tổng cộng ba lỗi.
Phép thử ngược này ít ai làm, vì bản năng con người là kiểm xem thứ mình muốn có chạy không, chứ không phải kiểm xem thứ mình không muốn có im không. Nhưng nó là phép thử duy nhất bắt được loại lỗi mà kết quả sai vẫn trông hợp lý.
Lập luận cho việc bỏ công kiểm từng nút gồm ba ý, dành cho ai đang phân vân có nên làm tương tự với công cụ của mình.
Chi phí kiểm tăng đều theo số nút, còn chi phí lỗi thì không. Kiểm thêm một nút tốn thêm khoảng mười phút. Một lỗi lọt ra tài khoản thật không chỉ tốn tiền của lần chạy đó, nó tốn thời gian truy nguyên và tốn niềm tin.
Lỗi tìm sớm rẻ hơn nhiều lần. Lỗi ngưỡng bằng 0 sửa mất khoảng hai mươi phút vì tìm được lúc còn đang chạy thử. Cùng lỗi đó phát hiện sau ba tháng, khi đã có người xây quy trình quanh nó, thì việc sửa còn phải kèm rà lại dữ liệu lịch sử.
Và kiểm có hệ thống bắt được loại lỗi mà kiểm ngẫu nhiên không bắt được. Xác suất một phép thử ngẫu nhiên chọn đúng con số 0 gần như bằng không. Chỉ quy trình bắt buộc "mỗi nút hai tình huống, trong đó một tình huống là không thể khớp" mới đảm bảo chạm tới nó.
Cách sửa: phân biệt "chưa nhập" với "đã nhập số 0" ở mọi tầng
Cách chữa đơn giản về mặt kỹ thuật: thay phép kiểm tra "có rỗng không" bằng phép kiểm tra chính xác hơn, là "giá trị này có được cung cấp hay không", chứ không phải "giá trị này có bằng không, rỗng, hay không xác định hay không".
Cụ thể là viết một hàm nhỏ chuyên đọc số, phân biệt rạch ròi giữa "chưa nhập" và "nhập số 0", rồi thay mọi chỗ đọc ngưỡng bằng hàm đó. Sửa mất khoảng hai mươi phút, tìm ra mất một buổi. Tỉ lệ đó là đặc trưng của loại lỗi này.
Nhưng sửa một chỗ chưa đủ. Ba việc đi kèm mới làm lỗi không quay lại:
Việc một: sửa ở cả bốn chặng. Nếu chỉ sửa chỗ đọc tham số mà giao diện vẫn gửi chuỗi rỗng thay cho số 0, lỗi vẫn còn nguyên. Ô nhập phải gửi đúng giá trị 0, kho dữ liệu phải lưu được giá trị 0 khác với ô trống, và phép so sánh phải xử lý đúng biên.
Việc hai: nói ra khi dùng giá trị mặc định. Vấn đề không chỉ ở chỗ số 0 bị hiểu nhầm, mà ở chỗ khi hệ thống quyết định dùng mặc định, nó im lặng. Nếu kết quả có ghi "đang dùng ngưỡng mặc định vì bạn chưa đặt", người dùng thấy sai ngay, vì họ nhớ mình có đặt. Chính sự im lặng đã che lỗi. Nguyên tắc rút ra: khi hệ thống thay người dùng quyết định một con số, nó phải nói ra, ở đâu cũng được miễn là có.
Việc ba: giữ một lớp chặn không phụ thuộc lớp thứ nhất. Ngưỡng an toàn cũng chỉ là mấy dòng mã, và mấy dòng mã thì có lỗi. Lớp thứ hai trong trường hợp này là giới hạn số lượng: mỗi lượt chạy chỉ được đụng tối đa mấy chiến dịch, bất kể điều kiện khớp bao nhiêu cái. Lớp thứ hai không sửa được lỗi của lớp thứ nhất, nhưng nó bó thiệt hại lại. Với hệ thống đụng tới tiền, giới hạn thiệt hại là mục tiêu thực tế hơn là không bao giờ sai.
Ba kiểu viết tắt khác cũng nguy hiểm y hệt
Ngưỡng bằng 0 thuộc một họ lỗi lớn hơn: những chỗ ngôn ngữ lập trình gộp nhiều ý nghĩa vào một cách biểu diễn. Ai đang tự dựng công cụ nên biết ba họ hàng của nó.
Chuỗi rỗng và giá trị chưa có
Người dùng để trống ô tên chiến dịch, và người dùng gõ vào rồi xoá, là hai chuyện khác nhau về ý định nhưng thường được lưu giống hệt nhau. Trong bộ lọc "tên chiến dịch chứa...", một ô trống nghĩa là không lọc hay nghĩa là lọc những chiến dịch có tên rỗng? Hai cách hiểu cho hai kết quả rất khác, và một trong hai kết quả là quét cả tài khoản.
Danh sách rỗng và danh sách chưa được nạp
Hệ thống hỏi "có chiến dịch nào khớp không" và nhận về một danh sách rỗng. Nhưng rỗng vì thật sự không có chiến dịch nào khớp, hay rỗng vì lần gọi dữ liệu vừa rồi thất bại và trả về mặc định?
Nhầm hai chuyện này nguy hiểm hơn ngưỡng bằng 0, vì nó dẫn tới kết luận "mọi thứ đều ổn" trong khi thực tế là "không biết gì cả". Cách chữa: phân biệt rạch ròi giữa lấy dữ liệu thành công mà kết quả rỗng, với lấy dữ liệu thất bại. Dấu hiệu bạn kiểm được từ bên ngoài: nếu nhật ký của công cụ chưa bao giờ có dòng nào kiểu "không lấy được dữ liệu", nhiều khả năng nó đang gộp hai trạng thái đó làm một.
Số âm dùng làm mã đặc biệt
Một số chỉ số có thể âm hợp lệ, chẳng hạn mức thay đổi so với kỳ trước. Nhiều hệ thống lại dùng số âm như một mã đặc biệt nghĩa là "không có dữ liệu". Khi hai cách dùng gặp nhau, một chiến dịch giảm chi phí 15% bị đọc thành chiến dịch không có dữ liệu, hoặc ngược lại.
Nguyên tắc chung cho cả ba: đừng dùng một giá trị hợp lệ để mang ý nghĩa "không có giá trị". Nghe hiển nhiên, nhưng nó bị vi phạm liên tục vì cách làm đó tiện.
Hai lỗi khác bắt được trong cùng đợt kiểm
Đợt kiểm ba mươi lượt đó bắt được ba lỗi, và ba lỗi thuộc ba loại hoàn toàn khác nhau. Đó là lý do đáng kể ra hai lỗi còn lại.
Lỗi thứ hai là lỗi thiết kế sản phẩm. Kho dữ liệu có cả tài khoản chạy bằng đô la lẫn tài khoản chạy bằng đồng. Một điều kiện đặt ngưỡng "tổng chi tiêu vượt 500" thì 500 đó là đô hay đồng? Câu ghi chú trên giao diện ghi cứng đơn vị là đồng, nhưng dữ liệu thì trộn cả hai, nên với người đang cấu hình cho tài khoản đô la thì câu ghi chú đang nói sai.
Cách xử được chọn là bắt người dùng chọn đơn vị tiền cho từng ngưỡng, lọc chiến dịch theo đúng đơn vị đó, và chặn không cho chạy nếu phạm vi bao gồm nhiều loại tiền lẫn lộn. Chặn thì phiền hơn tự đoán, nhưng với tiền của người khác, phiền còn hơn đoán sai.
Lỗi thứ ba là lỗi cấu trúc mã. Hai tệp mã nguồn nhập lẫn nhau tạo thành vòng tròn, khiến hệ thống không khởi động được trong một số trường hợp. Khô khan, nhưng nó cho thấy một điều: một lỗi logic, một lỗi thiết kế sản phẩm, một lỗi cấu trúc mã, và không có một cách kiểm nào bắt được cả ba.
Đó là lý do không nên tin vào việc kiểm mẫu. Nếu hôm đó chỉ chạy thử vài nút tiêu biểu, xác suất cao là không nút nào trong số đó dính lỗi ngưỡng bằng 0, và lỗi vẫn nằm đó tới khi có người dùng thật gặp phải.
Vì sao tự động hoá làm mọi lỗi im lặng nặng hơn
Nếu bạn tự tay làm và hiểu nhầm một ngưỡng, hậu quả giới hạn ở vài quyết định trong ngày hôm đó. Bạn còn nhìn màn hình, còn thấy con số kỳ lạ, còn dừng lại hỏi.
Khi việc đó được tự động hoá, cùng một hiểu nhầm áp dụng cho mọi chiến dịch, mỗi ngày, không nghỉ. Tự động hoá không thêm phán đoán, nó thêm tính nhất quán, kể cả nhất quán trong cái sai.
Từ đó ra một cách chọn mức quyền cho công cụ. Một hành động ở chế độ chỉ đề xuất mà logic sai thì chỉ tạo ra vài đề xuất kỳ lạ, và bạn sẽ thấy khi đọc. Cùng hành động đó ở chế độ tự thực hiện thì nó âm thầm làm sai hàng loạt. Mức quyền bạn thả cho một công cụ nên tỉ lệ thuận với mức độ bạn đã kiểm chứng logic của nó, không phải với mức độ bạn tin công nghệ nói chung.
Có một thứ tự thả quyền dùng được: giữ mọi hành động ở chế độ đề xuất trong ít nhất hai tuần, đọc kỹ phần lý do của từng đề xuất, chỉ thả tự thực hiện cho những hành động đảo ngược được dễ như tạm dừng quảng cáo, và giữ ở chế độ đề xuất lâu hơn với những hành động sai thì đắt như tăng ngân sách hay đổi thầu.
Tám chỗ nên kiểm ngay trong tài khoản của bạn
Phần này không nói về một phần mềm cụ thể nào mà nói về cách bạn tự bảo vệ mình, dùng công cụ nào cũng áp được.
Một: viết ra mọi ngưỡng bạn đã đặt. Nghe buồn cười, nhưng ba tháng sau bạn sẽ không nhớ. Không nhớ ngưỡng mình đặt là bao nhiêu thì không thể phát hiện khi hệ thống đang dùng con số khác. Một bảng tính bốn cột là đủ: tên quy tắc, ngưỡng, đơn vị, ngày đặt.
Hai: đối chiếu mỗi tháng một lần. Mở phần cài đặt, so ngưỡng đang lưu với ngưỡng trong ghi chú của bạn. Mất năm phút, và nó bắt được cả lỗi hệ thống lẫn lỗi con người, chẳng hạn đồng nghiệp sửa mà quên báo.
Ba: tìm mọi ô ngưỡng mà số 0 có nghĩa riêng. Đi qua từng quy tắc, hỏi ở mỗi ô: nếu tôi gõ 0 vào đây thì tôi đang muốn nói gì. Nếu câu trả lời khác hẳn với việc bỏ trống ô, đó là một chỗ cần thử.
Bốn: chạy bài thử ngược cho những ô đó. Đặt tạm một ngưỡng không thể khớp, chạy, xác nhận hệ thống im lặng, rồi trả ngưỡng về như cũ. Ví dụ: yêu cầu chi phí cao hơn mục tiêu 500%, hoặc yêu cầu doanh thu trên chi phí thấp hơn 0. Nếu hệ thống vẫn đề xuất gì đó, bạn vừa tìm ra một chỗ hỏng.
Năm: đọc phần lý do, không chỉ đọc kết luận. Khi một đề xuất nói nên tạm dừng chiến dịch, phần lý do phải nhắc tới đúng ngưỡng bạn đặt. Nếu nó nhắc tới một con số lạ, hoặc không nhắc con số nào, đó là dấu hiệu.
Sáu: kiểm giới hạn số lượng mỗi lượt chạy. Hỏi hoặc tự thử xem một lượt chạy có thể đụng tối đa bao nhiêu chiến dịch. Nếu không có giới hạn nào, một lỗi logic đơn lẻ có thể quét cả tài khoản trong một buổi sáng.
Bảy: kiểm nhật ký của những lần không làm gì. Nhật ký chỉ ghi những lần có hành động là nhật ký vô dụng, vì bạn không phân biệt được "chạy và không có gì khớp" với "không chạy". Hai chuyện đó cách nhau rất xa khi bạn đang chờ một cảnh báo mà nó không tới.
Tám: đặt một cảnh báo đối chứng. Tạo thêm một quy tắc mà bạn biết chắc phải kích hoạt, chẳng hạn báo khi chi tiêu ngày vượt một con số rất thấp. Nếu tuần nào nó cũng gửi thông báo thì bạn biết đường dẫn cảnh báo còn sống. Ngày nào nó im, bạn biết cần đi kiểm, và bạn biết trước khi mất tiền chứ không phải sau.
Ba câu hỏi cho bất kỳ hệ thống nào tự nhận là an toàn
Chữ "an toàn" không phải một trạng thái mà là một tập hợp câu trả lời cụ thể. Ba câu dưới đây lộ ra nhiều nhất.
Hệ thống có biết là nó không biết không?
Lỗi ngưỡng bằng 0 nguy hiểm vì hệ thống tự tin. Nó không có chỗ nào ghi "tôi không chắc giá trị này là gì", nó chỉ lấy mặc định rồi đi tiếp.
Hệ thống thiết kế tốt phải phân biệt được ba trạng thái: biết chắc, không biết, và biết là dữ liệu có vấn đề. Cách kiểm nhanh nhất là xem nó có bao giờ trả lời "không đủ dữ liệu để kết luận" không. Nếu nó luôn có câu trả lời cho mọi câu hỏi, đó là dấu hiệu đáng ngờ chứ không phải điểm mạnh.
Sai một chỗ thì lan tới đâu?
Đây là câu về bán kính thiệt hại. Với lỗi ngưỡng bằng 0, bán kính lẽ ra là toàn bộ chiến dịch khớp điều kiện, nhưng nhờ giới hạn số lượng mỗi lượt, bán kính thật bị bó lại còn vài chiến dịch.
Hệ thống đụng tới tiền nên được thiết kế từ câu hỏi này chứ không phải từ câu "làm sao để không sai". Không sai là mục tiêu không đạt được. Sai mà không lan là mục tiêu đạt được.
Có ai đọc lại được không?
Lỗi này được phát hiện vì có người ngồi đối chiếu kết quả với ý định. Nếu hệ thống chạy trong bóng tối, không nhật ký, không lý do, không ai xem, thì nó sẽ chạy sai mãi mà không ai biết.
Nhật ký không làm hệ thống đúng hơn. Nó làm cái sai trở nên nhìn thấy được, và đó là điều kiện cần để sửa.
Cách hỏi nhà cung cấp về chuyện này
Nếu bạn đang chọn hoặc đang dùng một công cụ tự động cho quảng cáo, bốn câu dưới đây hỏi được trong một email và câu trả lời nói lên nhiều điều.
"Các anh kiểm từng nút hay lấy mẫu?" Câu trả lời trung thực thường là lấy mẫu, và đó không hẳn là sai. Nhưng biết được thì bạn chỉnh mức tin cậy cho phù hợp, và biết mình phải tự kiểm những chỗ nào.
"Khi hệ thống dùng giá trị mặc định, tôi có biết không?" Nếu không, mọi ngưỡng bạn đặt đều có thể đang bị bỏ qua mà bạn không hay. Câu trả lời tốt là "có, nó ghi trong phần lý do", và bạn kiểm được ngay bằng cách mở một kết quả gần nhất ra đọc.
"Có giới hạn số lượng cho mỗi lượt chạy không, và là bao nhiêu?" Đây là lớp bảo vệ thứ hai. Câu trả lời phải là một con số, không phải "hệ thống rất an toàn".
"Tôi kiểm tra được rằng nó im lặng đúng lúc không?" Nếu nhà cung cấp khuyến khích bạn thử đặt ngưỡng không thể khớp để tự kiểm, đó là dấu hiệu tốt. Nếu họ né câu này, bạn cứ tự thử.
Cách hỏi cũng quan trọng như câu hỏi. Đừng hỏi "sản phẩm của các anh có an toàn không", vì câu trả lời luôn là có. Hỏi những câu mà câu trả lời phải là một con số hoặc một chỗ cụ thể trên màn hình.
Dấu hiệu nhận ra một hệ thống đang hỏng im lặng
Sáu dấu hiệu dưới đây không chứng minh có lỗi, nhưng mỗi dấu hiệu là một lý do để đi kiểm.
- Nhật ký chỉ có dòng khi có hành động. Không phân biệt được "đã chạy, không có gì khớp" với "không chạy".
- Kết quả không bao giờ nhắc tới con số ngưỡng bạn đặt. Nếu phần lý do chỉ nói chung chung, bạn không có cách nào đối chiếu.
- Một quy tắc chưa kích hoạt lần nào suốt nhiều tháng. Có thể tài khoản đang khoẻ, cũng có thể quy tắc đó chết từ lâu. Hai khả năng này trông giống hệt nhau từ bên ngoài.
- Số lượng đối tượng bị đụng vào mỗi lượt thay đổi đột ngột. Hôm qua hai chiến dịch, hôm nay mười bốn, mà bạn không đổi gì.
- Hệ thống chưa bao giờ từ chối chạy vì bất kỳ lý do gì. Nghĩa là nó luôn đoán khi gặp chỗ mập mờ.
- Đổi ngưỡng mà kết quả không đổi. Đây là dấu hiệu mạnh nhất, và cũng là bài thử nhanh nhất: sửa ngưỡng thành một con số khác hẳn, chạy lại, và xem danh sách kết quả có đổi không. Không đổi nghĩa là ngưỡng của bạn đang không được dùng.
Câu hỏi thường gặp
Vì sao lỗi này không bị phát hiện trong lúc phát triển?
Vì người viết mã thử với những con số bình thường như 2, 3, 5 và tất cả đều chạy đúng. Không ai nghĩ tới việc thử số 0, bởi nó trông như một giá trị vô nghĩa. Chỉ tới khi đặt câu hỏi "người dùng nào lại gõ 0 vào đây, và vì sao" thì mới thấy đó là một ý định hoàn toàn hợp lý.
Làm sao tôi biết công cụ mình đang dùng có lỗi tương tự không?
Thử bài kiểm mười phút: đặt một ngưỡng theo hướng không thể khớp, chẳng hạn yêu cầu chi phí cao hơn mục tiêu 500%, rồi chạy. Kết quả phải là không có hành động nào. Nếu vẫn có, hỏi nhà cung cấp vì sao.
Vì sao không tự động phát hiện được loại lỗi này?
Vì với hệ thống, không có gì bất thường: không ngoại lệ, không lỗi, kết quả đúng theo logic đang chạy. Chỉ có người biết ý định thật của mình mới nhận ra kết quả không khớp ý định.
Kiểm tự động có thay được việc chạy tay ba mươi lượt không?
Không thay hẳn được. Kiểm tự động kiểm xem hệ thống có làm đúng điều nó được lập trình để làm hay không, chứ không kiểm điều đó có đúng ý người dùng hay không. Loại lỗi này nằm đúng ở chỗ giao giữa hai câu hỏi đó.
Nếu tôi tự viết script cho tài khoản mình thì cần lưu ý gì?
Ba điều theo thứ tự quan trọng. Một là phân biệt "chưa nhập" với "nhập số 0" ngay từ đầu, vì sửa sau thì phải rà lại mọi chỗ đọc tham số. Hai là luôn có giới hạn số lượng đối tượng được xử lý mỗi lượt, kể cả khi script chỉ đọc chứ chưa ghi, vì rồi nó sẽ ghi. Ba là ghi nhật ký cả những lần không làm gì, vì nhật ký trống nghĩa là script chết chứ không phải mọi thứ đều ổn.
Ngưỡng bằng 0 có bao giờ là lựa chọn sai của người dùng không?
Có, trong một số ô thì 0 là vô nghĩa và nên bị chặn ngay ở giao diện, chẳng hạn ngân sách bằng 0 hoặc số ngày lấy số liệu bằng 0. Điểm quan trọng là hệ thống phải chặn và nói rõ, chứ không được im lặng đổi nó thành giá trị khác. Chặn có báo thì bạn sửa được, im lặng đổi thì bạn không biết.
Còn lỗi nào chưa tìm ra không?
Gần như chắc chắn là còn, với bất kỳ hệ thống đủ phức tạp nào. Điều nói được là cách tìm: kiểm từng nút, thử cả tình huống không thể khớp, và giữ lớp giới hạn thứ hai để lỗi chưa biết cũng không gây thiệt hại lớn.
Đọc thêm: vì sao AI phải giải thích được quyết định của mình, chống rò rỉ chi tiêu bằng trần ngân sách, và phát hiện bất thường trong tài khoản quảng cáo.
Nếu bạn muốn xem các chốt an toàn này hoạt động thế nào trên tài khoản của mình, bắt đầu ở orova.vn.
Để Orova SEO lo phần việc lặp lại
Nghiên cứu từ khoá, viết bài, tối ưu lại bài cũ và theo dõi thứ hạng — chạy tự động trên chính website của bạn.
Xem Orova SEO