Một framework xài AI của bản thân mình

Một framework xài AI của bản thân mình

5 phút đọc

Mình đã cố gắng viết bài này để không bị phụ thuộc vào một công cụ cụ thể. Chỉ rõ ra mình làm việc với tool X như thế nào, dùng tips gì... sẽ khá gượng ép, vì mình cũng không chắc là các công cụ mình đang dùng là tốt nhất không. Mình chỉ biết nó phù hợp với mình. Bài viết này có thể được xem như một "framework" vận dụng AI để tham khảo.

Framework vận dụng AI từng bước

Bước 1 - hiểu mình - hiểu người

Hiểu bản thân mình

Mình không thể làm việc hiệu quả nếu mình không biết được mình mạnh gì và yếu gì. Biết được điểm mạnh - yếu của bản thân là yếu tố tiên quyết để xác định chiến lược mình sẽ dùng công cụ nào, phương pháp nào để khắc phục điểm yếu, tăng cường điểm mạnh. Nếu dùng công cụ thì làm sao mình kiểm soát được khi nó tạo ra những thứ mình không biết, không rõ (vì điểm yếu của mình).

Hiểu người

Trong ngữ cảnh này là hiểu công việc mình phải hoàn thành, hiểu công cụ mình sẽ dùng.

Hiểu rõ công việc mình cần làm: Bản chất công việc của chúng ta là một lập trình viên không chỉ là "coding", mà là "giải quyết vấn đề". Tùy vào đặc thù của vấn đề mà bạn cần giải quyết, mà các bước sẽ có sự khác biệt.

  • Nếu bạn là một QA, bạn sẽ cần phân tích yêu cầu, quyết định chiến lược test. Sau đó đưa ra test cases, rồi implementation, execute test..
  • Nếu bạn là một backend developer, bạn sẽ cần phân tích yêu cầu để hiểu rõ hệ thống -> tạo tài liệu kiến trúc -> khởi tạo skeleton của project -> implement từng feature / unit test ... Mình viết càng rõ ra các bước mình cần làm càng tốt. Để từ đó, xác định mình muốn AI giúp mình ở phần nào. Từ những kì vọng này, mình sẽ đi tìm công cụ hỗ trợ.

Output: một bản liệt kê những công việc mình cần phải làm, phần việc nào mình muốn tăng hiệu suất với AI, mong muốn cụ thể là gì.

Hiểu công cụ

Bước này bao gồm cả việc khám phá tìm hiểu công cụ mà mình muốn áp dụng để tự động hóa phần việc mình muốn.

Mỗi công cụ sử dụng sẽ có những điểm mạnh - yếu riêng. Mình nên đi tìm hiểu để biết cách sử dụng nó tốt nhất.

Điểm yếu chung hiện nay: các công cụ AI hiện tại gặp một vấn đề lớn trong việc nắm giữ ngữ cảnh. Do đó, rất khó để mình có thể thực hiện các tác vụ phức tạp xuyên suốt với chỉ một session làm việc kéo dài vô tận.

Ngoài ra, bạn cũng đừng quá kì vọng tìm ra công cụ hoàn hảo. Tập trung vào mục tiêu chính mình muốn đạt được là ưu tiên hàng đầu. Không có công cụ tốt nhất, mà chỉ có công cụ phù hợp với bản thân mình thôi.

Output: cập nhật lại bản danh sách ở trên, với các công cụ AI mình lựa chọn để thử nghiệm + đặc thù của từng công cụ mình đã tìm hiểu.

Bước 2: Thử nghiệm và đánh giá

Bước này là một quá trình cần sự trải nghiệm. Mình nên theo dõi để xem hiệu suất của mình được tăng lên như thế nào khi sử dụng AI cho các bước mình đã liệt kê. Nên có một số KPI cho bản thân để có động lực thử nghiệm và nhìn lại.

Bên cạnh đó, việc học và ghi chú lại các pattern về hành vi / prompt khi làm việc với tool rất quan trọng. Điều này sẽ giúp ta tối ưu và làm tốt hơn về sau.

Bước 3: Cải tiến liên tục

Sau quá trình thử nghiệm (thật ra là xài thiệt luôn), mình thường review lại hàng tháng để xem việc sử dụng các công cụ của mình có cần cải thiện gì không, những bài học nào mình học được trong quá trình sử dụng. Từ đó nghiên cứu những cách thức mình có thể cải tiến nó.

Tất cả các bước này không phải làm một lần rồi bỏ. Nó sẽ lặp lại liên tục, tuần hoàn để giúp mình khám phá những cách tốt hơn và làm việc hiệu quả hơn với AI và chính tool mình đang dùng.

Những practice mình hay áp dụng khi mình pair programming với AI

Practice 1 - divide to conquer

AI không phù hợp để xử lý các vấn đề quá phức tạp, hoặc có quá nhiều hướng đi. Trong những ngữ cảnh đó, bản thân mình phải phân bài toán thành những vấn đề nhỏ hơn, độ phức tạp thấp hơn, ít lựa chọn hơn để nó xử lý tốt nhất. Trong trường hợp bài toán dù nhỏ, nhưng vẫn có khá nhiều option về giải pháp, mình cần tận dụng lợi thế mình có về domain knowledge, solution để đưa ra chỉ dẫn cho hướng đi mình mong muốn.

Practice 2 - design and planning first

Thường mình sẽ làm một session nhỏ với AI để tạo ra thiết kế phù hợp. Cụ thể là với Github Copilot (công cụ chính mình dùng), mình dùng Agent mode để đưa ra prompt yêu cầu thiết kế về bài toán -> output ra file markdown. Sau đó, sẽ review, clarify, tinh chỉnh cho đến khi có thiết kế vừa ý.

Từ bản thiết kế -> mình sẽ yêu cầu AI phân rã kế hoạch implementation thành từng bước nhỏ hơn và có thể verify được ở từng bước (planning). Sau đó sẽ review planning, tinh chỉnh lại cho phù hợp.

Practice 3 - áp dụng mode "sáng tạo" hay "tuân thủ" một cách mềm dẻo

Mỗi khi mình làm việc với AI, mình hay đặt câu hỏi: mình cần hoàn thiện việc này theo mode nào: "sáng tạo" hay "tuân thủ".

Mode sáng tạo: được áp dụng cho những tình huống mình cần brainstorming về giải pháp, tung hứng với thiết kế, làm prototype, hoặc một tình huống khác là "bản thân mình không có thế mạnh trong mảng đó".

Ví dụ cụ thể: mình không mạnh về design, UI/UX, frontend styling, cho nên mình thường cố gắng tận dụng AI để giúp mình làm việc này. Mình chỉ prompt yêu cầu về tính năng mình kỳ vọng và nhờ AI giúp mình để đưa ra thiết kế cụ thể. Bước này có thể mình tận dùng nhiều tool. Mình thường dùng v0 của Vercel để đưa ra prototype đầu tiên. Khi ưng ý, mình sẽ chuyển toàn bộ code của prototype thành implementation với Github Coplot. Kể từ thời điểm này trở đi, toàn bộ UI của app gần như mình chỉ dùng Copilot để thiết kế.

Làm sao để mình chắc chắn rằng AI tạo ra một thứ ở mode sáng tạo "đúng" khi mình không có kinh nghiệm ở lĩnh vực đó?

  • Trong prompt luôn kèm theo câu: You must do this task following the best practices in domain...
  • Dùng trực giác con người và kinh nghiệm để đánh giá. Mình thường verify output rất kĩ. Khi vào implementation thực tế, Copilot implement luôn đến component details và tương tác giữa các components, state ... Mình phải luôn đặt ra câu hỏi: design như vậy có ổn chưa, có extend được không, dùng lại được không ... Có thể mình không có kinh nghiệm trong design, styling, nhưng mình rất dễ dàng chỉ ra được các tạo component như vậy không ổn vì khó dùng lại, hoặc thiết kế như vậy chưa hợp lý để người dùng cảm thấy happy ở góc độ một end user.

Mode tuân thủ: thường được mình áp dụng khi muốn AI hoàn toàn tuân thủ các rule mình mong muốn. Nó được áp dụng với những trường hợp mình hoàn toàn hiểu việc đó nên làm như thế nào, chỉ là mình không muốn động tay, động chân vào.

Ở mode tuân thủ, mình cần đưa vào prompt một chỉ dẫn rõ ràng, và context chi tiết. Nên nhớ rằng, mỗi khi mình start một session mới với AI nó hoàn toàn quên sạch mọi thứ trước đây. Cho nên, để tiết kiệm thời gian, mình thường làm như vầy:

  • Với những thứ thuộc về principles mình muốn follow trong project, mình sẽ tạo một file riêng để làm một context chung.
  • Với những feature đặc thù và đã được mình và AI pair cùng nhau, khi kết thúc phiên làm việc với AI, mình sẽ nhờ summarize và update lại file đó nếu cần. Lần sau khi đụng đến, mình sẽ dùng file này làm một phần context

Cái hay của AI là nó thường bonus cho mình những "feature" bất ngờ. Tuy nhiên, trong một vài ngữ cảnh của mode tuân thủ, mình sẽ hoàn toàn không muốn có thêm bất cứ điều gì dư thừa được thêm vào. Những lúc đó, bạn có thể thêm vào prompt: "Do exactly the described scope. Do not add anything else".

Thực tế không hoàn hảo để rạch ròi giữa 2 mode. Có lúc mình cũng mix lung tung các mode này. Tuy nhiên, ở thời điểm nào cần dùng mode nào sẽ cần một sự cân bằng để mang lại hiệu quả tốt nhất.

Practice 4 - Top down hay bottom up

Top down là phương pháp mình phân rã công việc từ trên xuống (đúng với kiểu chia để trị). Top down rất phù hợp với những loại công việc mình quá am tường, và có kiến thức sâu.

Bottom up là cách mình sử dụng AI trong những tình huống bản thân mình cũng chưa biết rõ công việc đó sẽ như thế nào đến khi hoàn chỉnh, thường phù hợp với giai đoạn prototype, demo. Bottom up ở đây có nghĩa là mình nhìn thấy một phiên bản draft những gì mình tạm ưng ý (về layout, feature demo, integration ...), rồi từ đó mình quyết định sẽ xây những thành phần nào chi tiết để dùng lại, cấu trúc lại theo hướng tốt hơn.

Mỗi approach có điểm mạnh, điểm yếu riêng. Và ứng với từng approach, cách mình prompt cũng khác biệt.

Practice 5 - Luôn thẩm định

Không deliver bất cứ dòng code nào sinh ra từ AI nếu không thẩm định kĩ càng và hiểu rõ lý do tại sao nó nên được làm như vậy. Việc này có nhiều cái lợi:

  • Giúp mình hiểu thật rõ từng dòng code được tạo ra, xóa đi, chỉnh sửa để kiểm soát được chất lượng.
  • Giúp mình học được từ AI. Thật ra cũng có nhiều thứ mình không biết, hoặc giải pháp chưa hoàn hảo. Từ AI mình hiểu rõ hơn những điều cần thiết và tăng thêm kinh nghiệm cho bản thân.
  • Giúp tránh được những sai sót do AI bị ảo giác.

Mẹo 1: nếu có điểm nào mình không hiểu, mình thường switch từ agent mode sang chat mode để hỏi: "Lý do tại sao phải làm như vậy?".

Mẹo 2: khi có cảm giác vấn đề được giải quyết phức tạp hơn mình nghĩ, hãy thử brainstorm với AI: "Có cách nào khác làm điều này đơn giản hơn không?"

Thực tế là có những đoạn mình không thẩm định được 100% vì nó nằm ngoài vùng knowledge domain của mình, vd: styling, css, animation ... Trong các case này, mình sẽ yêu cầu AI thẩm định. Hài hước là mỗi lần thẩm định nó sẽ chỉ ra những điểm improve khác nhau. Cho nên mình phải cân bằng và không cần quá cầu toàn.

Điểm then chốt: thẩm định những phần quan trọng và tận dụng kinh nghiệm, trải nghiệm của mình để đưa ra quyết định, đặt câu hỏi. Không biết phải hỏi, không hiểu thì đừng làm.

Practice 6 - Lùi một bước để tiến 3 bước

Hồi xưa xem phim kiếm hiệp hay nghe câu: lùi một bước thấy trời cao đất rộng.

Sẽ có những trường hợp bài toán cần xử lý quá phức tạp đối với AI (và cả đối với bạn). Trong các tình huống này dù bạn có đốt hết token, credits bạn cũng không thể làm cho AI giải quyết được. Trong những case này, các cách mình thường làm là:

  • Lùi lại một bước bằng việc review lại toàn bộ cấu trúc, thuật toán cùng AI. Có khi chỉ cần thay đổi cấu trúc - refactor lại là vấn đề được solve ngay.
  • Đặt câu hỏi cho AI để truy đến tận cùng những điểm bế tắc. Rồi explore thêm để verify từng điểm. Khi mình biết được thật sự bế tắc ở đâu thì solve rất nhanh.
  • Revert lại đến commit mà vấn đề chưa phát sinh, và xem như làm lại từ đầu. Sau đó, break nhỏ vấn đề phức tạp của mình ra thành từng phần có thể giải được, hoặc ít nhất là có hướng đi để thử.
  • Nhìn bức tranh rộng ra. Có cần thiết phải solve vấn đề này không? Có cách nào khác tốt hơn không, vì đôi khi cái ta cần là làm thỏa mãn người dùng - không phải thỏa mãn việc giải quyết vấn đề.

Tips: nếu bạn thấy AI ráng làm một task cho bạn mà failed hơn 3 lần (không phải vì những lỗi của network, timeout...) thì là lúc cần review lại vấn đề mình đang muốn giải quyết.

Mình hy vọng là những chia sẻ này có thể giúp ích cho mọi người. Cũng có thể sẽ có vài practices của mình chỉ phù hợp trong vài ngữ cảnh nhất định.

Trong bài trước mình đề cập đến AI pair programming, mình có nhấn mạnh một điểm: đối với mình sự khác nhau giữa AI pair programming và vibe coding chỉ là ở việc mình có hiểu thật rõ những gì AI và mình đang làm hay không. Ở thời điểm hiện tại, gần như 95% code của mình đều do Copilot tạo ra. Tuy nhiên, ai code mình nghĩ không còn quan trọng nữa.

AI là thanh kiếm, lập trình viên là kiếm sĩ. Nếu hiểu rõ từng đường kiếm, thì kiếm và kiếm sĩ chỉ là một mà thôi!