caltalys.dev
Hai con số lệch nhau 8%. Không ai tính sai.
Hai báo cáo lệch nhau 8%, không ai tính sai. Một chữ đi qua ranh giới hai phòng ban thì chỉ có chữ đi được; cái neo nghĩa của nó thì ở lại.
Trong phòng họp có một cái máy chiếu và hai con số.
Báo cáo vận hành: 12.480 đơn hoàn tất trong tháng. Báo cáo doanh thu: 11.503. Lệch gần một nghìn đơn, tức khoảng 8%. Cả hai đều lấy từ cùng một database, cùng một tháng, cùng một chữ in trên đầu cột: đơn hoàn tất.
Câu đầu tiên trong phòng, tất nhiên: “Query nào sai?”
Thảo nhận việc đi tìm. Hai ngày. Đọc cả hai câu SQL, dò từng điều kiện, chạy lại trên dữ liệu tháng trước, đối chiếu từng ngày. Rồi quay lại báo cáo: cả hai câu đều đúng.
Không ai hài lòng với câu trả lời đó. Vì nếu cả hai đều đúng thì phải có một cái sai - logic thông thường là vậy. Người ta bảo Thảo kiểm lại. Nó kiểm lại. Vẫn đúng.
Và trong suốt hai ngày đó, không có một dòng lỗi nào. Không có cảnh báo, không có exception, không có bản ghi nào hỏng. Hai con số cứ đứng đó trên máy chiếu, cả hai đều được tính đúng, và chúng vẫn không bằng nhau.
Bài trước mình nói về chuyện thông tin rụng khi đi xuống - quyết định bị nén thành một câu task, và cái rụng là lý do câu đó tồn tại. Lần này khác. Lần này không ai nén gì cả. Chữ “hoàn tất” được truyền đi nguyên vẹn từng ký tự, từ phòng này sang phòng kia, không sai một dấu. Cái rụng không phải chữ. Là chỗ đứng của người nói ra chữ đó.
Với phòng vận hành, một đơn hoàn tất khi hàng ra khỏi kho và khách ký nhận. Đó là lúc phần việc của họ kết thúc, lúc họ hết trách nhiệm, lúc con số ấy đi vào chỉ tiêu của họ.
Với phòng kế toán, một đơn hoàn tất khi đã đối soát xong với đối tác vận chuyển và chốt được nghĩa vụ hai bên. Trước mốc đó, con số còn động: trong cửa sổ bảy ngày hoàn trả, đơn vẫn có thể quay về, và phần tiền thu hộ vẫn có thể lệch so với sao kê. Cái báo cáo của họ phục vụ việc đối soát, nên nó phải đếm theo mốc đối soát.
Giữa hai mốc đó là ba đến bảy ngày. Số đơn đang nằm giữa hai mốc lúc chốt sổ, cộng lại, ra gần một nghìn.
Ở đây không nhất thiết có bên nào định nghĩa sai. Mỗi bên đang dùng chữ đó đúng theo phần việc mà họ phải chịu trách nhiệm - và đó là trường hợp khó nhất, vì không có ai để sửa. Và đây là chỗ cần đóng đinh: một định nghĩa nghiệp vụ không sống trong từ điển. Nó sống trong quy trình đẻ ra nó. Chữ thì chung, nhưng nghĩa được sinh ra ở chỗ có người phải chịu hậu quả - mà mỗi phòng ban chịu một loại hậu quả khác nhau.
Khi chữ đi ngang từ phòng này sang phòng kia, phần chữ đi qua trọn vẹn. Phần quy trình sinh ra nó thì ở lại. Và vì phần đi qua trông vẫn nguyên vẹn, không ai nhận ra có thứ gì đã ở lại phía sau.
Nói thật với bạn một chuyện, để bạn đừng tưởng chuyện này gọn gàng như hai nghĩa mình vừa kể: thường không phải hai. Thường là ba hoặc bốn. Chăm sóc khách hàng có một mốc riêng - đơn hoàn tất là lúc hết cửa sổ khiếu nại, vì trước đó khách còn gọi lên được. Sàn thương mại điện tử có mốc của họ. Và có những nghĩa không ai phát biểu thành lời được, nó chỉ nằm trong tay người làm lâu năm, dưới dạng “cái đơn đó thì phải chờ”.
Đến đây thì bạn đang nghĩ tới một giải pháp, và mình đoán được bạn đang nghĩ gì: dựng cái data dictionary, chốt một định nghĩa chính thức, xong.
Mình đã từng làm đúng như vậy. Nó không chạy, và lý do nó không chạy mới là phần đáng học.
Chốt một định nghĩa chính thức nghĩa là chọn một phòng ban rồi tuyên bố các phòng còn lại đang tính sai. Nhưng phòng kế toán không thể dùng mốc của kho để ghi nhận doanh thu - làm vậy là ghi nhận doanh thu cho những đơn có thể bị trả lại, và đó là chuyện của kiểm toán chứ không còn là chuyện của báo cáo. Cho nên sau khi có từ điển, họ vẫn phải tính con số cũ. Chỉ khác là giờ họ tính nó bên ngoài hệ thống, trong một file riêng, và không ai còn nhìn thấy nó nữa.
Từ điển không xoá được nghĩa cũ. Nó chỉ đẩy nghĩa cũ xuống dưới mặt đất.
Nguyên nhân là chỗ này: định nghĩa không phải cái nhãn dán lên một con số, nó là hệ quả của việc ai đang phải trả giá cho cái gì. Đổi cái nhãn mà không đổi ai chịu trách nhiệm thì cái nghĩa cũ vẫn còn nguyên, vì cái nhu cầu sinh ra nó vẫn còn nguyên.
Cái sửa thật ra buồn cười y như lần trước, và cũng rẻ y như vậy: đừng chọn một nghĩa. Đặt hai cái tên cho hai thứ khác nhau. Không còn cột “đơn hoàn tất”. Có cột “đơn đã giao” và cột “đơn đã đối soát”. Hai con số, hai cái tên, và cái lệch 8% kia không còn là mâu thuẫn nữa - nó thành ra một khoảng thời gian có thể đọc được, thậm chí còn đáng theo dõi.
Nhưng chỉ tách tên khi hai mốc thật sự là hai trạng thái nghiệp vụ khác nhau - có hai thời điểm, hai người chịu trách nhiệm, hai hệ quả. Nếu chỉ là cùng một trạng thái mà hai bên đang hiểu lệch, tách tên là cách nhanh nhất để nhân đôi sự lộn xộn thay vì gỡ nó.
Mà kể cả khi tách đúng, chuyện này cũng không dễ chịu như nghe. Sẽ có người nói “rõ ràng là cùng một thứ mà, sao phải làm phức tạp lên”. Sẽ phải sửa mười mấy cái report. Và hai tháng sau vẫn còn một cái báo cáo cho ban giám đốc mà không ai chắc nên lấy cột nào - cột giao hay cột đối soát - vì bản thân câu hỏi ban giám đốc muốn trả lời cũng chưa ai hỏi rõ. Gỡ một chỗ mơ hồ thường không làm nó biến mất; nó làm chỗ mơ hồ tiếp theo lộ ra. Và cô kế toán trưởng, người mười hai năm gọi nó là “đơn hoàn tất”, sẽ mất một thời gian để cái tên mới nghe không chối tai. Cô không sai chỗ nào cả - trong nhà cô, chữ ấy vẫn luôn chỉ đúng một thứ.
Giờ mình kể lại đúng chuyện đó, ở một chỗ mà bạn sẽ không nghĩ là cùng gốc.
Tích hợp với một đối tác. Spec viết rõ: hệ thống mình bắn webhook khi đơn chuyển sang completed. Bên kia đọc đúng field đó, làm đúng tài liệu. Ba tháng sau họ báo lên: có một nhóm shop bị âm ví, tháng nào cũng vài chục ca.
Không ai làm sai spec. Mình bắn completed đúng lúc, họ nhận đúng lúc. Chỉ có điều bên kia dùng tín hiệu đó để giải ngân tiền về ví shop, còn bên mình set completed ở mốc giao hàng - trước cửa sổ hoàn trả. Đơn nào bị trả lại sau đó thì tiền đã ra khỏi ví rồi.
Cùng một chữ. Hai bên đọc đều đúng. Nhưng lần này chữ đó đi qua một ranh giới khác hẳn: nó không còn được người đọc nữa, nó được máy đọc. Người đọc một con số lệch thì còn thấy gợn và đi hỏi lại. Máy thì không gợn bao giờ. Sai lệch nằm im ba tháng, tính bằng tiền thật.
Hai triệu chứng. Một cái là hai con số trên máy chiếu, một cái là mấy chục cái ví âm ở một công ty khác. Nhưng cùng một chỗ hỏng: một chữ đi ngang qua ranh giới, chữ qua được, hệ quy chiếu ở lại.
Và đây là chỗ nó khác hẳn bài trước, khác đến mức nếu không để ý thì bạn sẽ áp nhầm cách sửa. Lần trước, khi câu task bị nén, bạn hỏi ngược lên một tầng là lấy lại được thứ đã rụng - vì có một tầng ở trên để mà hỏi. Lần này không có tầng nào cả. Kho và kế toán ngang nhau. Mình và đối tác ngang nhau. Không ai ở trên ai để mà giải nén ngược lên. Và quan trọng hơn: không bên nào có đủ bối cảnh của bên kia để tự mình chốt nghĩa. Ở đâu đó trong công ty có thể có người nắm được cả hai - một anh phân tích hệ thống lâu năm, một cái tài liệu kiến trúc dữ liệu - nhưng người đó không ngồi trong cuộc trao đổi này, và cả hai bên đều không biết là mình cần hỏi.
Chuyện này không phải mình tự nghĩ ra. Có một khảo sát quốc tế về các vấn đề trong khâu làm yêu cầu, dữ liệu đợt được trích nhiều nhất thu năm 2014–2015 ở 228 tổ chức thuộc mười quốc gia. Trong danh mục hai mươi mốt vấn đề mà những người tham gia nêu ra, “vấn đề thuật ngữ” được liệt riêng thành một mục - nằm cạnh những thứ nghe to tát hơn nhiều như yêu cầu bị giấu hay mục tiêu trôi. Một chữ hiểu hai kiểu, hoá ra không phải chuyện vặt của riêng công ty nào.
Nhưng bạn không thể đi làm rõ mọi từ. Nếu bài này khiến bạn ngồi tra định nghĩa từng danh từ trong mọi cuộc họp thì mình đã viết hỏng.
Và cũng đừng cố hợp nhất mọi nghĩa về một mối. Kho cứ đếm theo mốc của kho, kế toán cứ đếm theo mốc của kế toán - đó là chuyện lành mạnh, vì hai bên làm hai việc khác nhau. Thứ cần làm rõ không phải cái nghĩa, mà là chỗ hai nghĩa gặp nhau: một cái báo cáo dùng chung, một cái field bắn qua API, một dòng trong hợp đồng. Nghĩa thì để yên trong nhà mỗi bên. Chỗ giao nhau thì phải nói cho hết.
Thang đo mình dùng để biết chỗ giao nào đáng dừng: chữ đó có đang được máy hoặc hợp đồng đọc không. Một chữ mơ hồ dùng nội bộ, sai thì sửa cái report, nửa buổi là xong - ghi nhận rồi đi tiếp. Một chữ nằm trong điều khoản nghiệm thu, trong công thức tính hoa hồng, hoặc trong một cái webhook tự động kích hoạt chuyển tiền - dừng lại, làm rõ trước khi viết tiếp. Khác biệt không nằm ở chữ đó mơ hồ đến đâu, mà ở chỗ khi nó bị hiểu lệch thì gỡ lại dễ hay khó.
Và cái nguyên lý đằng sau thì chẳng dính gì tới báo cáo hay webhook. Hai nhóm người làm hai việc khác nhau sẽ dùng chung một số từ, vì họ làm chung một quy trình. Nhưng nghĩa của mỗi từ được neo vào phần việc mà nhóm đó phải chịu trách nhiệm. Khi từ đi qua ranh giới, chỉ có chữ đi được. Cái neo ở lại. Và vì chữ đi qua nguyên vẹn, không có gì báo cho ai biết rằng nó vừa rụng mất cái neo.
Một việc bạn thử được ngay tuần này. Mở báo cáo gần nhất, chọn một chỉ số bất kỳ có chữ trạng thái trong tên - hoàn tất, đã xử lý, thành công, đang hoạt động. Rồi hỏi hai người ở hai phòng ban khác nhau đúng một câu: “Theo anh, một cái tính là hoàn tất kể từ lúc nào?” Đừng gợi ý, đừng đưa lựa chọn. Nghe hết câu trả lời rồi mới hỏi người thứ hai.
Có thể hai người trả lời giống nhau. Nếu vậy thì tốt, bạn vừa mất năm phút để biết một chuyện đáng biết.
Còn nếu hai câu trả lời lệch nhau, đừng vội kết luận báo cáo của bạn đang sai. Có thể hai người ấy chẳng ai làm ra cái báo cáo đó. Có thể một trong hai đang nhớ nhầm quy trình của chính mình. Cái bạn vừa biết chỉ là: chữ đó không tự mang nghĩa đi theo nó. Còn chỗ nào đáng làm rõ thì quay lại thang đo ở trên - chữ ấy đang được ai đọc, và đọc lệch thì gỡ có dễ không.
Thảo, sau vụ hai con số, có nói với mình một câu mà mình nghĩ mãi: