Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 43 — RFC Process — Quyết định Quan trọng có Lưu vết

Technical Leadership Bài 43/60

Mở đầu — vì sao bài này quan trọng

Hãy hình dung một tình huống mà bạn chắc chắn đã từng gặp: sáu tháng trước, team của bạn quyết định chuyển từ REST sang GraphQL cho API nội bộ. Bây giờ có người mới vào, đặt câu hỏi ngây thơ mà chí mạng: "Sao mình lại dùng GraphQL vậy anh? Nó phức tạp quá." Và bạn... ú ớ. Người đưa ra quyết định đã nghỉ việc. Không ai nhớ rõ lý do. Cái Slack thread bàn về nó đã bị chôn vùi dưới hàng ngàn tin nhắn khác. Cái "context" quý giá — những đánh đổi, những phương án bị loại, những giả định ban đầu — đã bốc hơi hoàn toàn.

Đây chính là vấn đề mà RFC Process ra đời để giải quyết. Trong vai trò Technical Leadership, một trong những trách nhiệm quan trọng nhất — nhưng ít được nói tới — của bạn không phải là ra quyết định, mà là làm cho quyết định có lưu vết, có thể tranh luận, và có thể tra cứu lại về sau. Quyết định kỹ thuật tốt mà không được ghi chép lại thì cũng chỉ là may mắn. Còn quyết định được ghi chép cẩn thận, dù đôi khi sai, vẫn là tài sản: bạn học được từ nó.

RFC (Request For Comments) là công cụ để biến những cuộc tranh luận kỹ thuật rời rạc thành một quy trình có kỷ luật. Nó là sợi dây kết nối giữa "ai đó nghĩ ra ý tưởng" và "cả team đồng thuận triển khai" — với đầy đủ dấu vết để mười tám tháng sau vẫn hiểu được tại sao. Bài này sẽ dạy bạn cách thiết kế và vận hành một RFC Process thực chiến, không rườm rà quan liêu, phù hợp với đội ngũ kỹ sư Việt Nam và startup Đông Nam Á.

Khái niệm cốt lõi

RFC là gì?

RFC — viết tắt của Request For Comments — là một tài liệu mô tả một đề xuất quyết định kỹ thuật quan trọng, được viết ra để mời gọi phản hồi từ những người liên quan trước khi cam kết thực hiện. Cụm từ này có nguồn gốc từ những năm 1969, khi các kỹ sư xây dựng ARPANET (tiền thân của Internet) dùng "RFC" để trao đổi và chuẩn hóa giao thức mạng. Tinh thần cốt lõi vẫn không đổi sau hơn 50 năm: viết xuống, mời góp ý, đạt đồng thuận, rồi mới làm.

Điểm mấu chốt cần hiểu: RFC không phải là tài liệu thiết kế chi tiết (design doc thuần túy), cũng không phải là biên bản họp. Nó là một tài liệu sống nhằm ba mục đích cùng lúc:

  • Buộc người đề xuất phải suy nghĩ thấu đáo. Hành động viết ra một đề xuất mạch lạc — bao gồm cả các phương án thay thế và lý do loại bỏ — buộc bạn phải đối mặt với những lỗ hổng trong lập luận của chính mình. Rất nhiều RFC "chết" ngay ở khâu viết, vì tác giả nhận ra ý tưởng không đứng vững. Đó là điều tốt.
  • Phân tán việc ra quyết định. Thay vì một người quyền lực gõ bàn "làm thế này đi", RFC cho phép người có context tốt nhất — dù họ là junior — đóng góp trước khi quyết định chốt lại.
  • Lưu vết context cho tương lai. Đây là giá trị bị đánh giá thấp nhất nhưng lại lớn nhất về dài hạn.

Khi nào cần một RFC?

Không phải mọi quyết định đều cần RFC — nếu bắt mọi thay đổi phải qua RFC, bạn sẽ giết chết tốc độ và làm cả team ghét quy trình. Nguyên tắc vàng: RFC dành cho những quyết định khó đảo ngược, ảnh hưởng nhiều team, hoặc tốn kém nếu sai. Cụ thể, hãy cân nhắc viết RFC khi:

  • Chọn công nghệ mới hoặc thay thế công nghệ cũ (đổi database, thêm message queue, chọn framework frontend mới).
  • Thay đổi kiến trúc lớn (tách monolith thành microservices, đổi cách xác thực, thay đổi mô hình dữ liệu cốt lõi).
  • Quyết định ảnh hưởng nhiều team (thay đổi contract API dùng chung, chuẩn hóa cách logging toàn công ty).
  • Thiết lập một chuẩn/quy ước mới (naming convention, chiến lược branching, chính sách versioning).
  • Đánh đổi lớn về chi phí, bảo mật hoặc hiệu năng mà nếu sai sẽ khó sửa.
Ngược lại, những việc như thêm một endpoint mới theo pattern đã có, sửa bug, refactor nhỏ trong một service — thì không cần RFC. Dùng Pull Request review là đủ.

Có một cách tư duy hay từ Amazon và Google: gọi là one-way door vs two-way door. Quyết định "cửa một chiều" (khó quay lại) thì cần RFC. Quyết định "cửa hai chiều" (dễ đảo ngược) thì cứ làm nhanh, sai thì sửa.

Cấu trúc chuẩn của một RFC

Một RFC tốt thường có các phần sau (bạn có thể tinh chỉnh theo văn hóa team):

  • Tiêu đề & metadata: tên, tác giả, ngày, trạng thái (Draft / In Review / Approved / Rejected / Superseded).
  • Bối cảnh & vấn đề (Context / Problem): chuyện gì đang xảy ra, vì sao cần giải quyết. Đây là phần quan trọng nhất — nếu người đọc không hiểu vấn đề, họ không thể đánh giá giải pháp.
  • Mục tiêu & phi mục tiêu (Goals / Non-goals): nêu rõ RFC này không giải quyết điều gì, để tránh scope creep trong tranh luận.
  • Giải pháp đề xuất (Proposed Solution): chi tiết cách làm.
  • Các phương án đã cân nhắc (Alternatives Considered): đây là phần phân biệt RFC nghiệp dư với chuyên nghiệp. Liệt kê các lựa chọn khác và lý do loại bỏ.
  • Đánh đổi & rủi ro (Trade-offs / Risks): thành thật về nhược điểm của phương án được chọn.
  • Kế hoạch triển khai & rollout: bước đi, migration, cách rollback.
  • Câu hỏi mở (Open Questions): những điều tác giả chưa chắc — mời mọi người trả lời.

Tình huống thực tế

Tình huống 1: Startup fintech ở TP.HCM và cái database chọn vội

Một startup fintech ở Sài Gòn (gọi là công ty A, khoảng 25 kỹ sư) đang tăng trưởng nhanh. Một senior engineer, dưới áp lực deadline, tự quyết định dùng MongoDB làm database chính cho module ví điện tử vì "làm cho nhanh, schema linh hoạt". Không có RFC, không có tranh luận — chỉ một tin nhắn trong Slack: "Mình dùng Mongo nhé anh em."

Tám tháng sau, khi cần đối soát giao dịch tài chính và đảm bảo tính nhất quán (ACID transactions), team vỡ lẽ MongoDB tại thời điểm đó không phù hợp cho use case tài chính đòi hỏi tính toàn vẹn cao. Chi phí migrate sang PostgreSQL: gần 4 tháng công sức của 3 kỹ sư, cộng với hai sự cố sai số dư ví trong quá trình chuyển đổi.

Bài học rút ra: Nếu có một RFC ngắn ngay từ đầu, phần "Alternatives Considered" sẽ buộc người đề xuất so sánh MongoDB với PostgreSQL trên tiêu chí tính nhất quán giao dịch — và gần như chắc chắn ai đó trong team đã lên tiếng về nhu cầu ACID. RFC không phải để làm chậm; nó là bảo hiểm rẻ tiền chống lại những sai lầm đắt đỏ khó đảo ngược. Một buổi chiều viết RFC có thể tiết kiệm 4 tháng làm lại.

Tình huống 2: Grab và văn hóa "Working Backwards" cho quyết định kỹ thuật

Ở các công ty công nghệ lớn của Đông Nam Á như Grab, quy trình tài liệu hóa quyết định là một phần văn hóa kỹ thuật. Khi một team đề xuất thay đổi lớn — ví dụ chuẩn hóa cách các microservice giao tiếp qua một service mesh mới — họ viết một tài liệu đề xuất, chia sẻ rộng rãi cho các team liên quan, và dành ra một khoảng thời gian cố định (thường 1–2 tuần) để nhận comment bất đồng bộ (asynchronous).

Điểm hay ở đây là comment bất đồng bộ. Thay vì tổ chức một cuộc họp 15 người cãi nhau (nơi người nói to nhất thắng), mọi người đọc RFC và để lại bình luận trực tiếp trên tài liệu, kèm theo lý lẽ. Một kỹ sư ở Singapore, một ở Việt Nam, một ở Ấn Độ — tất cả đều có thể đóng góp mà không cần cùng múi giờ. Tác giả tổng hợp phản hồi, cập nhật RFC, và chỉ tổ chức họp đồng bộ khi có bất đồng lớn không giải quyết được qua bình luận.

Bài học rút ra: RFC không chỉ là tài liệu — nó là một cơ chế cộng tác bất đồng bộ, cực kỳ hợp với team remote/hybrid và đa quốc gia. Nó dân chủ hóa việc ra quyết định: junior engineer ở Đà Nẵng có thể phản biện đề xuất của một staff engineer ở HQ, bằng lý lẽ viết ra, mà không bị lấn át bởi thứ bậc trong phòng họp.

Tình huống 3: RFC bị biến thành thủ tục hành chính vô nghĩa

Một công ty phần mềm gia công (outsourcing) ở Hà Nội, khoảng 80 kỹ sư, nghe nói RFC là "best practice" nên áp dụng cứng nhắc: mọi thay đổi kỹ thuật đều phải viết RFC, phải được ít nhất 2 tech lead và 1 architect ký duyệt, quy trình review tối thiểu 1 tuần. Chỉ sau 2 tháng, kết quả: kỹ sư bắt đầu né tránh — họ gộp nhiều thay đổi nhỏ vào một PR khổng lồ để tránh viết RFC, hoặc viết RFC qua loa cho có. Tốc độ giao hàng chậm lại 30%, và tinh thần đội ngũ đi xuống vì "quan liêu".

Team lead nhận ra sai lầm và điều chỉnh: chỉ những quyết định khó đảo ngược hoặc ảnh hưởng nhiều team mới cần RFC; thời gian review linh hoạt (2 ngày cho RFC nhỏ, 1 tuần cho RFC lớn); và bỏ yêu cầu "ký duyệt", thay bằng "đủ thời gian cho ai muốn phản đối lên tiếng — nếu không ai phản đối mạnh, xem như đồng thuận" (mô hình lazy consensus).

Bài học rút ra: RFC Process là công cụ, không phải mục tiêu. Áp dụng sai — quá nặng nề — còn tệ hơn không có. Một quy trình tốt phải tối ưu cho tốc độ đọc và đồng thuận, không phải cho việc thu thập chữ ký.

Hướng dẫn từng bước

Đây là quy trình triển khai một RFC Process thực chiến cho team của bạn:

Bước 1 — Tạo template và nơi lưu trữ. Tạo một template RFC chuẩn (theo cấu trúc ở phần Khái niệm cốt lõi) và một nơi tập trung để lưu: một thư mục rfcs/ trong Git repo (dạng file Markdown, đánh số 0001-title.md), hoặc một database trong Notion/Confluence. Ưu tiên Git nếu team quen dùng — RFC nằm cạnh code, versioned tự nhiên, review qua Pull Request.

Bước 2 — Đánh số và gán trạng thái. Mỗi RFC có một số thứ tự (RFC-001, RFC-002...) và một trạng thái rõ ràng: Draft → In Review → Approved / Rejected → (Implemented / Superseded). Trạng thái giúp ai cũng biết RFC đang ở đâu trong vòng đời.

Bước 3 — Viết bản nháp (Draft). Tác giả viết, tập trung mạnh vào phần Vấn đềPhương án thay thế. Nếu bạn không thể diễn đạt rõ vấn đề trong 2 đoạn, bạn chưa hiểu vấn đề đủ sâu để đề xuất giải pháp.

Bước 4 — Mở giai đoạn review với deadline rõ ràng. Chia sẻ RFC, ghi rõ: "Xin comment trước ngày X" (ví dụ 5 ngày làm việc). Deadline là bắt buộc — RFC không có deadline sẽ trôi mãi mãi. Chỉ định rõ ai là người cần review (stakeholder bắt buộc) và ai được mời (optional).

Bước 5 — Thu thập & phản hồi comment. Tác giả trả lời mọi comment, dù chỉ là "Đã ghi nhận, sẽ cập nhật" hoặc "Mình không đồng ý vì lý do này". Cập nhật RFC theo phản hồi. Đây là phần "Comments" trong tên gọi — đừng bỏ qua nó.

Bước 6 — Giải quyết bất đồng. Nếu có bất đồng lớn không thể giải quyết qua bình luận, tổ chức một cuộc họp ngắn có tập trung. Ghi lại kết luận vào RFC. Nếu vẫn deadlock, cần một decision maker được chỉ định (thường là tech lead hoặc architect) chốt — nhưng phải ghi rõ lý do chốt như vậy.

Bước 7 — Chốt trạng thái & lưu vết. Chuyển RFC sang Approved hoặc Rejected. Quan trọng: RFC bị từ chối vẫn giữ lại, đừng xóa. "Tại sao ta không làm X" cũng quý giá như "tại sao ta làm Y".

Bước 8 — Liên kết ngược từ code. Khi triển khai, tham chiếu RFC trong commit message, PR, hoặc comment code quan trọng ("Xem RFC-014 để hiểu vì sao dùng cách này"). Đây là cách bạn nối context với hiện thực.

Lỗi thường gặp & mẹo

Lỗi 1 — Viết giải pháp mà bỏ qua vấn đề. Nhiều RFC lao thẳng vào "chúng ta sẽ dùng Kafka" mà không giải thích rõ vấn đề đang cần giải quyết. Người đọc không thể đánh giá giải pháp nếu không hiểu vấn đề. Mẹo: dành 40% dung lượng RFC cho phần bối cảnh và vấn đề.

Lỗi 2 — Bỏ trống phần "Alternatives Considered". Nếu RFC chỉ có một phương án, đó không phải quyết định — đó là mệnh lệnh. Mẹo: luôn liệt kê ít nhất 2 phương án khác (kể cả "không làm gì cả") và lý do loại.

Lỗi 3 — RFC không có deadline review. Nó sẽ mãi ở trạng thái Draft. Mẹo: mọi RFC vào review phải có ngày chốt comment. Không ai phản đối trong thời hạn = đồng thuận (lazy consensus).

Lỗi 4 — Bắt mọi thứ phải qua RFC. Giết chết tốc độ, tạo văn hóa né tránh. Mẹo: dùng phép thử "cửa một chiều": chỉ RFC những gì khó đảo ngược.

Lỗi 5 — Review đồng bộ trong phòng họp. Người nói to thắng, người introvert im lặng. Mẹo: ưu tiên comment bất đồng bộ trên tài liệu; họp chỉ khi thật sự cần.

Lỗi 6 — Coi RFC là tài liệu chết sau khi approve. Mẹo: khi thực tế khác với RFC, đánh dấu Superseded by RFC-XXX và viết RFC mới. RFC là bản ghi lịch sử của tư duy, không phải bản khắc đá.

Mẹo văn hóa: Người có thẩm quyền cao nhất (tech lead, CTO) nên là người comment trên RFC của người khác, và cũng phải viết RFC của chính mình. Khi lãnh đạo cũng tuân theo quy trình, cả team mới coi trọng nó.

Bài tập thực hành

  • Viết một RFC hồi tố (retroactive). Chọn một quyết định kỹ thuật lớn mà team bạn đã thực hiện trong 6 tháng qua nhưng không có tài liệu. Viết một RFC ngắn (1–2 trang) cho nó ở dạng như thể bạn đề xuất trước khi làm: bối cảnh, vấn đề, giải pháp đã chọn, và ít nhất 2 phương án thay thế cùng lý do loại. Bài tập này giúp bạn thấy rõ bao nhiêu context đã bị mất.
  • Xây template RFC cho team. Tạo một file rfc-template.md với đầy đủ các phần: metadata, trạng thái, vấn đề, mục tiêu/phi mục tiêu, giải pháp, phương án thay thế, đánh đổi, kế hoạch rollout, câu hỏi mở. Đặt vào thư mục rfcs/ trong repo chung.
  • Phân loại quyết định. Liệt kê 5 quyết định kỹ thuật gần đây của team. Với mỗi quyết định, đánh dấu "cửa một chiều" hay "cửa hai chiều", và kết luận cái nào đáng lẽ nên có RFC. So sánh với thực tế đã diễn ra.
  • Chạy thử một vòng review. Lấy RFC ở bài tập 1, chia sẻ cho 2–3 đồng nghiệp với deadline comment 3 ngày. Quan sát: chất lượng phản hồi bất đồng bộ so với thảo luận miệng thông thường khác nhau thế nào?

Tóm tắt

RFC Process là công cụ để biến những quyết định kỹ thuật quan trọng thành thứ có lưu vết, có thể tranh luận, và tra cứu được về sau. Cốt lõi cần nhớ:

  • RFC = Request For Comments: viết đề xuất, mời phản hồi, đạt đồng thuận trước khi cam kết thực hiện.
  • Chỉ dùng cho quyết định khó đảo ngược hoặc ảnh hưởng rộng (cửa một chiều) — đừng bắt mọi thứ qua RFC.
  • Phần "Vấn đề" và "Phương án thay thế" là linh hồn của RFC; thiếu chúng thì đó chỉ là mệnh lệnh trá hình.
  • Ưu tiên comment bất đồng bộ, có deadline rõ ràng, dùng lazy consensus để giữ tốc độ.
  • Giữ lại cả RFC bị từ chối — "tại sao ta không làm X" cũng quý như "tại sao ta làm Y".
  • Liên kết RFC với code để context không bao giờ mất.
Ba câu chuyện — startup fintech mất 4 tháng vì chọn database vội, Grab với văn hóa comment bất đồng bộ đa quốc gia, và công ty Hà Nội biến RFC thành thủ tục quan liêu — cho thấy cùng một chân lý: RFC làm đúng là bảo hiểm rẻ tiền chống sai lầm đắt đỏ; làm sai là gánh nặng quan liêu. Là một technical leader, nhiệm vụ của bạn là tìm ra liều lượng vừa đủ cho team mình — đủ kỷ luật để lưu vết tư duy, đủ nhẹ nhàng để không ai muốn né tránh.