Bỏ qua đến nội dung chính

The Friction is Your Judgment — Armin Ronacher & Cristina Poncela Cubeiro, Earendil

TL;DR

  • Việc áp dụng AI tạo mã "không ma sát" đã dẫn đến "cái bẫy năng suất", khiến các kỹ sư tin rằng họ hiệu quả hơn trong khi thực tế lại bỏ qua tư duy phản biện và xem xét kỹ lưỡng.
  • Các tác nhân AI, tối ưu hóa cho tiến độ và khả năng tự giải quyết, có xu hướng tạo ra mã chất lượng thấp hơn, dễ vỡ hơn và làm tăng entropy trong codebase, đặc biệt là với các sản phẩm phức tạp.
  • Để giải quyết, cần thiết kế lại codebase để "dễ đọc đối với tác nhân" thông qua mô đun hóa, tuân thủ các mẫu thiết kế đã biết, thực thi các quy tắc cơ học nghiêm ngặt (linting), và tái thiết lập sự can thiệp của con người trong các đánh giá mã cho các thay đổi quan trọng.

Điểm chính

  • Nhận diện "cái bẫy năng suất AI": Năng suất ban đầu từ AI có thể biến thành áp lực phải triển khai nhanh hơn, làm giảm thời gian tư duy và xem xét mã, dẫn đến mã kém chất lượng hơn.
  • Hiểu cách tác nhân AI hoạt động: Các tác nhân tối ưu hóa cho việc đạt được tiến độ và "tự giải phóng", điều này có thể dẫn đến việc tạo ra nhiều điều kiện lỗi và hệ thống dễ vỡ vì chúng không có "cảm xúc" về chất lượng mã.
  • Thay đổi tỷ lệ tạo/xem xét mã: Khả năng sản xuất mã của kỹ sư đã vượt xa khả năng xem xét, dẫn đến các pull request bị "đóng dấu cao su" và sự gia tăng tổng số thực thể tham gia vào quy trình mã hóa mà không đi kèm trách nhiệm.
  • Thiết kế codebase cho tác nhân AI: Xử lý codebase như một "cơ sở hạ tầng" cần được thiết kế để dễ đọc đối với tác nhân ("agent-legible codebase"). Điều này bao gồm mô đun hóa mạnh mẽ các thành phần và luồng mã để tác nhân dễ dàng hiểu và thay đổi cục bộ.
  • Tuân thủ các mẫu thiết kế đã biết và trừu tượng hóa: Tận dụng "học tăng cường" bằng cách tuân theo các mẫu quen thuộc, đẩy sự phức tạp sang các lớp trừu tượng để đơn giản hóa lõi mã và tránh "phép thuật" (ví dụ: ORM phức tạp) che giấu ý định khỏi tác nhân.
  • Thực thi các quy tắc cơ học nghiêm ngặt: Sử dụng các quy tắc linting để bắt buộc các thực hành tốt như không có khối catch trống, giao diện truy vấn SQL duy nhất, component UI nguyên thủy, tên hàm độc đáo (để tăng hiệu quả mã thông báo), và chế độ TypeScript chỉ có cú pháp để giảm sự nhầm lẫn.
  • Tái giới thiệu ma sát của con người: Xây dựng công cụ để tách biệt các lỗi cơ học mà tác nhân có thể tự sửa khỏi các quyết định quan trọng (ví dụ: di chuyển cơ sở dữ liệu, thay đổi quyền hạn) yêu cầu đánh giá và phán đoán của con người.

Từ vựng

  • ma sát — friction
  • kỹ thuật tác nhân — agentic engineering
  • kỹ sư AI bản địa — native AI engineer
  • cái bẫy năng suất — productivity trap
  • cơ sở mã — codebase
  • cơ sở mã dễ đọc đối với tác nhân — agent-legible codebase
  • mô đun hóa — modularization
  • thực thi cơ học — mechanical enforcement
  • học tăng cường — reinforcement learning (RL)
  • đánh giá mã — code review

Nội dung chi tiết

Giới thiệu và Bối cảnh

Chào buổi sáng. Cảm ơn đã mời chúng tôi. Hôm nay tôi muốn nói chuyện với Christina một chút về "ma sát" (friction). Đây là một bản xem trước xã hội (social preview) tự động xuất hiện khi ai đó gửi một vấn đề – về cơ bản là một bài đăng diễn đàn liên quan đến một sự cố bảo mật được triển khai ngẫu nhiên. Đó là một thay đổi cấu hình gây ra vấn đề. Và bài đăng xem trước xã hội đó có khẩu hiệu tiếp thị của công ty: "giao hàng không ma sát" (ship without friction). Chúng tôi muốn khuyến khích thêm một chút "ma sát" vào đó, và tôi sẽ giải thích tại sao.

Vậy, chúng tôi là ai? Tôi đã làm phát triển phần mềm được 20 năm, hầu hết trong không gian nguồn mở (open-source). Tôi đã tạo ra Flask, một framework Python mà trớ trêu thay, lại đang được rất nhiều người tìm hiểu vì các cỗ máy đang tạo ra nó. Tôi rời công ty cũ vào tháng 4 năm ngoái, điều này trùng khớp hoàn hảo với việc tôi có thời gian và sau đó là mã nguồn của Claude. Và thế là tôi dấn sâu vào lĩnh vực agentic engineering, bắt đầu viết blog của mình, và rất nhiều người đã liên hệ với tôi trong năm qua bày tỏ sự phấn khích về điều này. Sau đó, vào tháng 10, tôi cùng một người bạn thành lập công ty Arandel, nơi chúng tôi đang cố gắng hiểu rõ tất cả các vấn đề về AI. Còn tôi là Christina, và tôi làm việc với Armin tại công ty Arandel này. Nhưng điều quan trọng là, tôi là người mà tôi thích gọi là một kỹ sư AI bản địa (native AI engineer), và điều đó có nghĩa là các công cụ này đã tồn tại lâu hơn tôi. Điều này có nghĩa là chúng đã đóng vai trò nền tảng quan trọng trong việc tôi trở thành một kỹ sư phần mềm như thế nào. Không chỉ vì rõ ràng tôi sử dụng chúng để làm việc, mà còn vì đây là phương tiện giúp tôi học cách làm những gì tôi đang làm. Trước Arandel, tôi làm việc tại Ben and Spuz.

Thách thức của Kỹ thuật Tác nhân AI

Vì vậy, chúng tôi muốn chia sẻ một chút từ thực tế, không chỉ là lý thuyết, nhưng tôi sẵn sàng thừa nhận rằng tôi không nghĩ mình có tất cả các giải pháp. Chúng tôi đã xây dựng với hoặc dựa trên các tác nhân (agents) trong suốt 12 tháng qua. Chúng tôi đã có những lợi thế lớn và cả những thất vọng to lớn. Và chúng tôi thực sự liên tục gặp phải hai loại vấn đề. Tôi nghĩ đặc biệt nếu bạn đã nghe một số bài nói chuyện trước đó tại hội nghị này, bạn sẽ học được rất nhiều điều về việc bạn nên tiếp tục sử dụng bộ não của mình. Vì một lý do nào đó, điều đó thực sự, thực sự khó khăn. Vậy nên có một vấn đề tâm lý, và một vấn đề khác là thách thức kỹ thuật (engineering challenge). Các tác nhân dường như tạo ra mã tệ hơn cho một số người và mã tốt hơn cho những người khác, và điều gì thực sự làm nên điều đó? Vì vậy, đây thực sự không phải là một giải pháp, mà là một phần trong hành trình và cách chúng tôi nghĩ rằng mình đã quản lý cho đến nay.

Vấn đề Tâm lý: Bẫy Năng suất AI

Vậy, vấn đề số một là khía cạnh tâm lý: tại sao, mặc dù mọi người đã nói với bạn rất nhiều lần rằng bạn nên sử dụng bộ não của mình, bạn nên chậm lại, điều đó thực sự lại khó đến vậy? Đó chỉ là một vấn đề nữa, và chúng ta không ngủ nhiều. Điều gì thực sự khiến nó khó đến vậy? Và liệu nó có khó như vậy không nếu các cỗ máy thực sự viết ra mã hoàn hảo, và chúng ta không phải suy nghĩ nhiều đến thế? Liệu có điều gì chúng ta có thể làm để cải thiện điều này một chút không?

Vì vậy, tôi sẽ bắt đầu bằng cách giới thiệu phần đầu tiên của các vấn đề này, vấn đề tâm lý. Và điều tôi muốn nói trước tiên là sự thay đổi. Tôi chắc rằng rất nhiều người trong chúng ta ở đây, những người đã sử dụng các công cụ này một thời gian, đã trải qua điều này vào một lúc nào đó. Chúng ta liên tục đưa lời nhắc (prompting), lời nhắc, nhưng không hiệu quả lắm. Và rồi đến một lúc nào đó, đột nhiên mọi thứ trở nên rõ ràng và chúng thực sự, thực sự hữu ích cho chúng ta. Ban đầu thì rất vui, và chúng mang lại cho chúng ta rất nhiều thời gian rảnh, đúng không? Vì không phải ai cũng sử dụng chúng, chúng thực sự là những công cụ giúp chúng ta năng suất hơn, giúp công việc của chúng ta thú vị hơn. Rất nhanh chóng, vì chúng quá hữu ích và khiến chúng ta bị cuốn hút, mọi người đều sử dụng chúng. Và điều này đã tạo ra hiệu ứng ngược lại, khi đột nhiên, kỳ vọng cơ bản là mọi người đều đang sử dụng chúng và bạn phải sử dụng chúng. Và thế là niềm vui và thời gian rảnh rỗi này đã biến thành áp lực. Bây giờ tất cả chúng ta phải triển khai nhanh hơn và tạo ra nhiều mã hơn, và việc xem xét cũng như thực sự có thời gian để suy nghĩ là không bền vững. Và điều này dẫn chúng ta đến cái bẫy (trap).

Và tôi thực sự nghĩ có hai phần của vấn đề này, của cái bẫy này. Một trong số đó, mà nhiều kỹ sư đã nói đến, là những công cụ này cực kỳ gây nghiện. Bạn không bao giờ biết liệu lời nhắc tiếp theo có phải là cái sẽ làm cho sản phẩm của bạn hoạt động và bạn đã thêm một tính năng mới, hay nó sẽ là giọt chất thải cuối cùng khiến sản phẩm của bạn sụp đổ. Và vì vậy, nó rất gây nghiện. Chúng ta cứ tiếp tục làm những gì đang làm. Đó không phải là một giải pháp tuyệt vời. Nhưng quan trọng nhất, và tôi không nghĩ chúng ta nhận ra điều này nhiều, là vì chúng ta tạo ra rất nhiều sản phẩm đầu ra rất nhanh, chúng ta bị lừa rằng mình thực sự đang hiệu quả hơn, làm được nhiều việc hơn. Và điều này hoàn toàn ngược lại, bởi vì bây giờ chúng ta không có nhiều thời gian để thực sự dừng lại và suy nghĩ, và trong khi thực hiện, tự hỏi: "Đây có phải là cách tốt nhất để tôi triển khai điều này, hay tôi có thể làm điều gì đó tốt hơn không?" Và khi bạn đang trong luồng này, rất khó để bản thân bạn dừng lại, và chắc chắn rất khó để tác nhân của bạn dừng lại vì nó cứ chạy loanh quanh và đọc các tệp mà đáng lẽ nó không bao giờ nên đọc. Vì vậy, chúng ta là những người cần thực sự có khả năng kiểm soát (agency) để làm chủ ở đây.

Thay đổi trong Quy trình Kỹ thuật

Và một điều mà, nếu bạn bắt đầu mở rộng điều này từ một người sang một nhóm kỹ thuật (engineering team), điều mà thực sự phải mất một thời gian khá lâu tôi mới nhận ra, đó là nó thực sự thay đổi thành phần của nhóm kỹ thuật. Chúng ta từng bị hạn chế về nguồn cung (supply-constrained) bởi việc tạo mã (code creation), và vì vậy sự cân bằng giữa viết mã và xem xét mã trong các nhóm kỹ thuật thường khá hợp lý (decent). Giờ đây, mỗi kỹ sư có khả năng sản xuất (producing power) gấp nhiều lần so với khả năng xem xét (reviewing power) của họ. Và rõ ràng là chúng ta đang chồng chất các pull request. Nhưng chúng ta cũng đang dần mở rộng tổng số con người trong một tổ chức tham gia vào quy trình kỹ thuật (engineering process). Tôi đã nói chuyện với rất nhiều kỹ sư trong năm qua, và ngày càng có một điều được đề cập là giờ đây có những người làm marketing đang triển khai mã (shipping code). Tôi có các cựu CEO, những người từng là kỹ sư, lại đang triển khai mã. Và vì vậy, vai trò của những người đó trong các công ty cũng không tự thân mang theo cùng một trách nhiệm. Trách nhiệm vẫn thuộc về nhóm kỹ thuật. Và vì vậy, tổng số thực thể – cả con người và máy móc – tham gia vào quy trình tạo mã đã vượt quá số lượng những người có thể chịu trách nhiệm. Chúng ta vẫn chưa ở giai đoạn mà máy móc có thể chịu trách nhiệm về thay đổi mã (code changes). Và điều đó đã dẫn đến việc ngày càng nhiều đánh giá mã (code reviews) bị bỏ qua, bị đóng dấu cao su (rubber stamped). Mặc dù chúng ta hướng tới các PR (small PRs) nhỏ để tạo điều kiện cho quy trình đánh giá, nhưng hiệu ứng khuếch đại này là điều mà ít nhất chúng ta cần phải nhận ra. Và vì vậy, khi bạn nhận được một pull request trông thực sự đáng sợ và có 5.000 dòng mã, đây thực sự là lúc bạn nên suy nghĩ. Và đó chính xác là lúc nó gây quá tải nhất. Và chúng ta ngày càng từ bỏ việc này.

Thách thức Kỹ thuật: Mã do Tác nhân Tạo ra

Về khía cạnh kỹ thuật (engineering side), điều chúng ta đang làm là tạo ra các pull request lớn hơn. Chúng ta đang tạo ra những thay đổi khổng lồ này vì giờ đây chúng miễn phí. Và nếu bạn nghĩ về cách các tác nhân hoạt động, chúng thực sự được tối ưu hóa để tạo ra mã có thể chạy. Mục tiêu chính của chúng là viết mã, chạy các bài kiểm tra (tests), và đạt được tiến độ. Học tăng cường (reinforcement learning) phần nào đưa điều này vào. Và vì vậy, các tác nhân đang viết loại mã mà một kỹ sư phần mềm con người sẽ học không nên viết khi mới bắt đầu. Ví dụ, bạn thấy khá nhiều mã cố gắng đọc một tệp cấu hình (config file), và nếu nó không đọc được cấu hình, nó sẽ tải một số giá trị mặc định. Và với tư cách là một kỹ sư, bạn biết rằng điều đó thực sự không tốt vì tôi có thể không nhận thấy mình đang đọc tệp cấu hình mặc định. Và vì vậy, tôi có thể chỉ phát hiện ra rằng mình có một vấn đề lớn sau hai giờ khi tôi đã ghi các bản ghi cơ sở dữ liệu (database records) với dữ liệu sai. Và vì vậy, những cỗ máy này tối ưu hóa cho việc đạt được tiến độ, cho việc triển khai sản phẩm (shipping stuff), cho việc tự giải phóng (unblocking themselves). Và kết quả là, chúng đang tạo ra nhiều điều kiện lỗi (failure conditions) hơn so với mã do con người viết thông thường. Một phần, vì bạn là con người cảm thấy hơi tệ khi viết mã như thế này. Có điều gì đó tích tụ cảm xúc trong bạn. Nhưng tác nhân không có lý do cho điều này. Nó không cảm thấy gì cả. Và vì vậy, nếu bạn tạo ra các dịch vụ cứ thế hoạt động chật vật (hobbling along) và thực sự sẵn sàng khôi phục từ các lỗi cục bộ (recover from local failures), bạn thực sự tạo ra các hệ thống rất dễ vỡ (brittle systems). Và điều này cũng có nghĩa là bạn đang rất nhanh chóng tạo ra một cơ sở mã (codebase) có kích thước và độ phức tạp mà bản thân tác nhân không còn có thể tự giải quyết được (dig itself out from). Nó sẽ bắt đầu không đọc tất cả các tệp mà nó nên đọc. Nó đang tạo mã trong một tệp mới cho chức năng đã tồn tại ở nơi khác. Và vì vậy, toàn bộ cỗ máy này theo thời gian tạo ra nhiều entropy (hỗn loạn) hơn trong mã nguồn (source code) so với bình thường nếu con người làm việc đó. Và phần lớn điều này là do con người cảm thấy tệ, còn các tác nhân thì không thực sự có cảm xúc nào mà chúng truyền đạt cho bạn.

Tối ưu hóa Cơ sở Mã cho Tác nhân AI

Nhưng như Armin thường nói, "đừng lo, không phải tất cả đều mất". Chúng tôi đã tìm thấy một số mối tương quan giữa những gì các tác nhân thực sự làm tốt và các loại cơ sở mã mà chúng tôi giao cho chúng làm việc. Ví dụ điển hình ở đây là thư viện (libraries) so với sản phẩm (products). Điều chúng tôi nhận thấy là đối với thư viện, chúng có xu hướng vượt trội hơn nhiều. Điều này có lý vì về bản chất, khi bạn xây dựng một thư viện, bạn thường có một vấn đề rất rõ ràng mà bạn đang cố gắng giải quyết. Và hầu hết thời gian, bạn thậm chí có thể ánh xạ tập hợp các tính năng (features) bạn muốn xây dựng tới dịch vụ API (API service). Và nó có các ràng buộc (constraints) rất chặt chẽ. Và bởi vì đây là thứ mà bạn có thể muốn xây dựng dựa trên hoặc cung cấp cho người khác, rất có thể nó sẽ là một lõi rất đơn giản mà bạn có thể tích hợp vào. Mặt khác, các sản phẩm, và có lẽ điều này hơi kém may mắn hơn đối với phần còn lại của chúng ta vì chúng ta có lẽ quan tâm nhiều hơn đến việc xây dựng sản phẩm, thì khó hơn nhiều. Bởi vì có quá nhiều mối quan tâm tương tác (interactive concerns) và thành phần (components). Chẳng hạn, bạn có giao diện người dùng (UI), phản hồi API (API response), bạn có các quyền (permissions) khác nhau tùy thuộc vào cờ tính năng (feature flags), thanh toán (billing), v.v. Và vì vậy có sự đan xen (intertwining) rất chặt chẽ giữa các thành phần khác nhau. Điều này có nghĩa là đối với bản thân tác nhân, việc đưa tất cả những điều này vào cửa sổ ngữ cảnh (context window) của nó là không thể. Nó không có cách nào để thực sự hiểu toàn bộ cấu trúc toàn cầu (global structure). Và vì vậy, ở cấp độ cục bộ, tác nhân có xu hướng rất hợp lý. Nhưng khi đạt đến quy mô toàn cầu (global scale), nó trở nên hơi mất trí (demented).

Vì vậy, điều chúng tôi đang đề xuất ở đây là giống như cách bạn đã làm với bất kỳ loại thiết kế hệ thống (system design) nào trong quá khứ, cơ sở mã của bạn giờ đây đã trở thành cơ sở hạ tầng (infrastructure). Và như vậy, bạn phải thiết kế nó theo cách để nó cũng dễ đọc đối với tác nhân. Và nó có thể tận dụng tối đa điều đó. Và đây là điều chúng tôi đang đề xuất: một cơ sở mã dễ đọc đối với tác nhân (agent-legible codebase). Và một trong những điểm chính rất rõ ràng với tất cả chúng ta, tôi chắc chắn, là modularization (phân mảnh/mô đun hóa). Vì vậy, chúng ta có các thành phần khác nhau. Và điều này giúp tác nhân dễ dàng thêm một tính năng vào một vị trí mà không làm hỏng mọi thứ khác. Nhưng quan trọng hơn, điều này cũng có nghĩa là phân mảnh luồng mã (modularizing your code flow) của chính bạn. Ví dụ, tôi đã làm một số tái cấu trúc (refactoring). Chúng tôi đang xây dựng một trợ lý AI (AI assistant). Và đối với tôi, điều cực kỳ quan trọng là phải hiểu những bước nào trong mã của tôi thực sự là những điểm chính. Ví dụ, bạn nhận được thông điệp người dùng (user message), sau đó tôi chuyển thông điệp đến vòng lặp tác nhân (agent loop), và sau đó tôi phải xử lý đầu ra. Và đây là nơi các điểm này được xác định rất rõ ràng đối với tôi. Vì vậy, mã không quá lộn xộn. Nhưng điều xảy ra là giữa những điểm này, giữa những bước này, đó là nơi tác nhân có xu hướng thêm vào nhiều sự mập mờ (fuzz) nhất.

Tối ưu hóa mã nguồn cho Tác nhân AI

Vì vậy, nó sẽ phân tích giữa các kiểu dữ liệu khác nhau. Nó thêm những thứ vào trạng thái mà lẽ ra không nên ở đó. Và vì thế, bạn sẽ gặp phải những hành vi mà bạn không muốn hỗ trợ và không lường trước được. Do đó, những hành động này có thể khá nguy hiểm. Một điểm khác là cố gắng tuân theo tất cả các mẫu đã biết. Bởi vì tôi nghĩ tất cả chúng ta đều biết rằng, không có ích gì khi chống lại RL (học tăng cường). Chúng ta càng có thể tận dụng nó, đầu ra sẽ càng tốt hơn. Và nó cũng có khả năng mở rộng hơn về sau. Như đã đề cập với các thư viện, nếu bạn có một lõi đơn giản và bạn đẩy sự phức tạp sang các lớp trừu tượng khác, thì sẽ dễ dàng hơn cho bản thân bạn và tác nhân để đọc codebase của bạn. Và không có "phép thuật" ẩn. Chẳng hạn, ở đây, việc sử dụng React Server Actions hoặc sử dụng ORM thay vì RoyceQL, điều này che giấu ý định khỏi tác nhân. Và nếu tác nhân không thể thấy điều gì đó, chắc chắn nó không thể tôn trọng điều đó.

Thực thi cơ học và hiệu quả của mã nguồn

Để chính xác hơn, đây là những ví dụ về thực thi cơ học mà chúng tôi đã sử dụng tại công ty. Và hầu hết những điều này, chúng tôi thực sự đạt được bằng các quy tắc linting. Ví dụ chính sẽ là không có các khối catch trống/chung chung. Tuyệt vời. Hãy tưởng tượng có một ví dụ ở đây. Tác nhân tìm thấy một khối catch trống/chung chung và nghĩ rằng, "Ồ không, cái này tệ. Hãy sửa nó." Nhưng đúng vậy, chúng tôi cũng cố gắng để SQL của mình luôn ở một giao diện truy vấn duy nhất để tác nhân không phải "săn lùng" khắp codebase, tìm kiếm nhiều nơi khác nhau. Bởi vì nếu nó bỏ lỡ một chỗ, thì bạn có thể gặp phải các hành vi gây lỗi. Và một lần nữa, điều đó nguy hiểm. Chúng tôi cố gắng có một thư viện component nguyên thủy cho UI và không có bất kỳ hộp nhập liệu "thô" nào, chẳng hạn, để nó luôn có một kiểu styling. Nó rất nhất quán, một loại hành vi. Chúng tôi không có bất kỳ import động nào. Và điều này có thể nghe không quan trọng, nhưng thực ra chúng tôi thực thi các tên hàm độc đáo. Và lý do cho điều này không chỉ là khả năng đọc tốt hơn cho bạn và tác nhân, mà thực sự còn là hiệu quả mã thông báo. Vì vậy, nếu tác nhân của bạn đang tìm kiếm một tính năng cụ thể hoặc một thứ gì đó trong codebase của bạn, nếu nó chỉ nhận được một đầu ra, nó sẽ tốt hơn nhiều trong việc tiếp tục với vòng lặp. Và gần đây chúng tôi bắt đầu khám phá một cái gì đó gọi là chế độ TypeScript chỉ có cú pháp Erasable. Và điều này có nghĩa là mã của bạn về cơ bản là JavaScript và nó có các chú thích kiểu ở trên. Và điều này có nghĩa là không có hướng chuyển mã bởi vì có một nguồn sự thật duy nhất giữa mã thực tế của bạn và trình biên dịch. Và vì vậy, khi tác nhân đang tìm kiếm lỗi, nó không phải bối rối kiểu "Trời ơi, tôi đang xem cái gì vậy?". Nó tìm chúng tốt hơn nhiều.

Can thiệp của con người trong đánh giá mã

Và mục tiêu thực sự là bằng cách nào đó đi vào vòng lặp này, kiểu như để tác nhân tạo ra mã tốt nhất có thể. Nhưng bạn thực sự cần tìm cách để cảm nhận nỗi đau mà tác nhân không cảm thấy. Và bạn cần phải tiếp cận theo cách mà bạn nên xem xét điều này. Và một trong những điều chúng tôi đã làm là chúng tôi xây dựng một tiện ích mở rộng pi cho nhu cầu đánh giá của mình, nơi chúng tôi tách biệt loại đầu vào mà thông thường sẽ quay trở lại tác nhân. Vì vậy, đây là những lỗi cơ học. Đây là nơi nó rõ ràng đã vi phạm nhiệm vụ của tác nhân. Nhưng sau đó chúng tôi đặc biệt chỉ ra những loại thay đổi mà bộ não con người nên được kích hoạt lại, phải không? Giống như, chúng tôi không nghĩ rằng quá trình di chuyển cơ sở dữ liệu nên diễn ra mà không có sự phán đoán của con người vì nó rất phụ thuộc vào các lock, kích thước dữ liệu trong môi trường sản xuất. Nếu có thay đổi quyền hạn, tốt hơn hết bạn nên tự mình suy nghĩ về điều này thay vì tác nhân vì chúng có thể được ghi chép không đầy đủ. Nhưng chỉ là một số ví dụ mà chúng tôi đã học được, nếu bỏ lỡ, chúng tôi sẽ hối tiếc. Và bạn sẽ bỏ lỡ. Nhưng những cỗ máy này có thể giúp bạn tìm thấy điều này. Và sau đó bạn thấy điều này. Và sau đó bạn thực sự nhận được một chút tác động. Giống như, "Ồ, bây giờ tôi phải bắt tay vào việc và làm gì đó ở đây."

Tốc độ: Lợi ích và cạm bẫy

Đây là giao diện trông như thế nào trong Pi. Bạn có phần dưới, bạn có các điểm cần con người xem xét ở trên, bạn có những gì, về cơ bản, nếu bạn muốn kết thúc đánh giá này và khắc phục các sự cố, tác nhân sẽ quay lại và tự động hành động trên hai điểm đầu tiên. Nhưng đây là thời điểm mà tôi sẽ đi và xem, đây có phải là phụ thuộc mà tôi thực sự muốn có trong codebase không? Tôi có thích những người bảo trì không? Điều này có phù hợp với tôi không? Và chúng tôi rõ ràng thích tốc độ. Điều này gây nghiện, nó tuyệt vời, chúng tôi cảm thấy có rất nhiều năng suất. Nhưng thật xảo quyệt nếu bạn bắt đầu dựa vào tốc độ đó ở những nơi bạn thực sự không nên. Và vì vậy, tôi chỉ có thể khuyến khích bạn tìm những khu vực mà bạn có cảm giác rằng điều này thực sự không tích cực. Đối với tôi, nhiều điều này là các trường hợp tái tạo lỗi. Giống như khi một khách hàng báo cáo một sự cố, tôi có thể để tác nhân tái tạo điều này một cách hoàn hảo. Và tôi có một điểm khởi đầu thực sự tốt. Khám phá các hướng sản phẩm khác nhau miễn là tôi không cam kết sử dụng mã mà nó tạo ra trực tiếp. Tất cả những điều này đều tuyệt vời. Nhưng mặt khác, kiến trúc hệ thống, tạo ra độ tin cậy trong hệ thống, chúng không thực sự giỏi về điều đó. Bởi vì chúng ta thực sự vẫn phải đi chậm. Có quá nhiều sự lộn xộn có thể xuất hiện trong một codebase trong rất ít thời gian. Mario đã nói về điều này trước đó. Nhưng chúng ta quên rằng chúng ta đang tạo ra hàng tháng trời nợ kỹ thuật trong vài tuần, đôi khi trong vài ngày. Và việc thực sự hiểu điều gì đang diễn ra trong codebase này trở nên khó khăn hơn nhiều. Khi sự hiểu biết về mã của chính bạn giảm đi, điều đó thực sự, thực sự khó khăn. Và nó cũng khó khăn về mặt tâm lý. Tôi đã tìm thấy một số đoạn mã thực sự không hoạt động trong môi trường sản xuất. Và tôi đã khá thất vọng khi biết rằng chính tôi là người đã commit nó cùng với tác nhân và chỉ đơn giản là không nhận ra điều đó. Đó là một trải nghiệm rất đáng thất vọng khi nó xảy ra. Và sau đó bạn nhận ra rằng bạn thực sự là người đã mắc lỗi. Và vì vậy, thật khó khăn về mặt tâm lý để thực sự đánh giá khách quan trạng thái của codebase. Và cách duy nhất hiện nay là thực sự giảm tốc độ một chút ở khía cạnh đó.

Vai trò của "ma sát" trong quy trình kỹ thuật

Và "ma sát" này, tôi biết rằng "ma sát", giống như mọi nhóm kỹ thuật mà tôi từng làm việc, đều nói rằng chúng ta cần loại bỏ "ma sát" trong việc triển khai. Và điều đó là đúng. Có rất nhiều thứ rất, rất khó chịu và không nên tồn tại. Nhưng nếu bạn đã làm việc trong những dự án kỹ thuật đủ lớn, các mục tiêu cấp độ dịch vụ (SLO) là một hệ thống tuyệt vời được thiết kế có chủ đích để tạo ra "ma sát" trong quy trình kỹ thuật nhằm khiến bạn suy nghĩ, "Tôi có cần độ tin cậy này không? Tôi có cần mức độ quan trọng này của dịch vụ không? Tôi có đủ nhân sự để vận hành nó không?" Và với các tác nhân, chúng ta hiện nay đã có ý tưởng rằng chúng ta nên loại bỏ tất cả những điều này trong khi thực tế chúng ta cần chúng. Bởi vì "ma sát" trên nhiều phương diện là điều cần thiết ở cấp độ vật lý để điều khiển. Giống như không có "ma sát" thì không có khả năng điều khiển và điều đó thực sự cần thiết. Vì vậy, bạn nên đặt một liên tưởng tích cực hơn một chút cho ý tưởng về "ma sát" này. Bởi vì đây thực sự là nơi của sự phán đoán, đây là nơi của kinh nghiệm, và bạn nên đưa điều đó vào và bắt đầu cảm nhận nó. Cảm ơn.

Góp ý / Báo lỗiPhát hiện sai sót hoặc có ý tưởng cải thiện?