GitHub Blog
85

Sản phẩm

Tại sao công cụ tốt lại khiến việc review code bằng Copilot kém hiệu quả hơn?

(giờ Việt Nam)

Tóm tắt AI

GitHub chia sẻ cách tối ưu hóa quy trình review code bằng cách chuyển đổi sang các công cụ khám phá mã nguồn kiểu Unix, giúp giảm chi phí và cải thiện hiệu suất làm việc của AI agent.

Bản dịch AI

Cách việc chuyển đổi tính năng đánh giá mã nguồn (code review) của Copilot sang các công cụ khám phá mã nguồn dùng chung theo phong cách Unix giúp giảm chi phí đánh giá bằng cách định hình lại quy trình làm việc của tác nhân (agent) dựa trên bằng chứng từ pull request.

Ngày 10 tháng 7 năm 2026

9 phút

Hãy cung cấp cho một tác nhân (agent) những công cụ tốt hơn và nó sẽ làm việc hiệu quả hơn. Dù sao thì đó cũng là bản năng tự nhiên.

Khi bạn mở một pull request, tính năng đánh giá mã nguồn của Copilot sẽ đọc phần diff (những thay đổi) và khám phá mã nguồn xung quanh để tìm ra các vấn đề quan trọng trước khi chúng được triển khai. Để làm điều đó, nó đã sử dụng các công cụ khám phá mã nguồn riêng. Vì vậy, khi chúng tôi thay thế bằng các công cụ dùng chung, được bảo trì tốt hơn vốn cung cấp sức mạnh cho Copilot CLI, grep, glob và view, chúng tôi đã kỳ vọng vào một sự nâng cấp hoàn hảo.

Thay vào đó, trong các bài kiểm tra hiệu năng (benchmarks), chúng tôi nhận thấy chi phí đánh giá lại cao hơn và ít vấn đề được phát hiện hơn.

Nhưng vấn đề không nằm ở các công cụ, mà nằm ở các chỉ dẫn (instructions). Sau khi chúng tôi viết lại các chỉ dẫn này cho phù hợp với cách một người đánh giá thực sự đọc một pull request, sự sụt giảm hiệu năng đã chuyển thành một thắng lợi: chi phí đánh giá trung bình giảm khoảng 20% trong khi vẫn duy trì được chất lượng đánh giá như cũ.

Đây là câu chuyện về việc điều chỉnh quy trình làm việc xung quanh các công cụ đã giúp chúng tôi tìm ra giải pháp như thế nào.

Cùng công cụ, sai bản năng

Nếu bạn đã xây dựng dựa trên một khung tác nhân (agent framework), có lẽ bạn cũng đã kế thừa các công cụ của nó. Chúng hoạt động tốt, vì vậy bạn tiếp tục sử dụng chúng, cho đến ngày mà trường hợp sử dụng của bạn lệch xa khỏi mục đích thiết kế ban đầu và chúng bắt đầu âm thầm gây cản trở cho bạn. Đó chính là tình huống mà chúng tôi gặp phải. Trước khi thử sử dụng các công cụ CLI dùng chung, tính năng đánh giá mã nguồn của Copilot đã sử dụng các công cụ khám phá mã nguồn riêng. Lớp công cụ đó được lấy cảm hứng từ các hệ thống tác nhân trước đây, bao gồm các ý tưởng từ việc điều hướng kho lưu trữ theo phong cách SWE-agent và GitHub Copilot Autofix: liệt kê thư mục, tìm kiếm tệp, tìm kiếm thư mục và đọc mã nguồn. Những công cụ đó hoạt động hiệu quả, nhưng chúng chỉ dành riêng cho việc đánh giá mã nguồn của Copilot và được thiết kế cho cách hành xử của các mô hình tại thời điểm đó. Các mô hình lập trình tác nhân trước đây thực hiện ít lệnh gọi công cụ hơn và kém hơn trong việc tự động thu thập ngữ cảnh cần thiết. Điều này có nghĩa là việc đưa tất cả thông tin liên quan vào một vài lệnh gọi công cụ mà mô hình thực hiện là rất quan trọng.

Trong khi đó, bộ công cụ Copilot CLI có một tập hợp các công cụ khám phá mã nguồn dùng chung lấy cảm hứng từ Unix: grep, glob và view. Bộ công cụ đó cũng được sử dụng bởi ngày càng nhiều sản phẩm tác nhân Copilot, bao gồm cả tác nhân đám mây GitHub Copilot, vì vậy những cải tiến đối với bộ công cụ này có thể mang lại lợi ích cho nhiều sản phẩm hơn. Chúng tôi muốn làm sạch và chia sẻ cơ sở hạ tầng ở bất cứ nơi nào có thể, vì vậy chúng tôi đã thử nghiệm việc sử dụng các công cụ từ bộ công cụ Copilot CLI trong tính năng đánh giá mã nguồn của Copilot. Mục tiêu là giảm bớt việc triển khai công cụ trùng lặp, tạo ra một nơi dùng chung để cải thiện các công cụ khám phá mã nguồn và giúp việc đưa những cải tiến đó vào các sản phẩm Copilot trở nên dễ dàng hơn.

Trên lý thuyết, việc di chuyển trông có vẻ đơn giản:

Các công cụ đánh giá hiện có không phải là những lớp bao bọc (wrappers) mỏng. Khi tìm kiếm một thư mục hoặc đọc một phạm vi mã nguồn, chúng có thể trả về các dòng khớp hoặc được yêu cầu cộng với ngữ cảnh mã nguồn xung quanh. Điều đó làm tăng chi phí token, nhưng nó cũng phù hợp với cách các mô hình trước đây thường được hưởng lợi từ việc có ngữ cảnh lân cận được bao gồm tự động.

Ban đầu, chúng tôi hy vọng đây sẽ là một quá trình di chuyển đơn giản: thay thế bộ công cụ này bằng bộ công cụ khác. Nhưng khi chúng tôi kiểm tra các công cụ dùng chung trong các bài kiểm tra ngoại tuyến, tác nhân đánh giá trở nên kém hiệu quả và kém hiệu lực hơn. Chi phí trung bình tăng lên và số lượng nhận xét hữu ích giảm xuống.

Dấu vết (trace) đã tiết lộ một vòng lặp duyệt mã

Các bài kiểm tra đánh giá mã nguồn nội bộ của Copilot rất hữu ích vì chúng cho thấy nhiều điều hơn là chỉ một điểm số cuối cùng. Chúng cho thấy lộ trình mà tác nhân đã thực hiện, bao gồm những công cụ nào được gọi, bao nhiêu kết quả trả về, lỗi xảy ra ở đâu và liệu nó đang thu hẹp phạm vi tìm kiếm đến bằng chứng hay đang mở rộng phạm vi tìm kiếm.

Khi chúng tôi lần đầu thử nghiệm các công cụ Copilot CLI dùng chung trong các bài kiểm tra ngoại tuyến, tác nhân thường hành xử như thể nó đang duyệt một kho lưu trữ thay vì điều tra một pull request. Nó tìm kiếm trên diện rộng, đoán các đường dẫn có khả năng xảy ra, đọc trên diện rộng, tìm thêm những thứ để tìm kiếm và mang theo ngữ cảnh bổ sung đó về phía trước.

Diagram showing the flow before — a simplified illustration of the general-purpose behavior we observed: widening the search, guessing paths, and accumulating context.

Mô hình đó là điều dễ hiểu. Việc khám phá trên diện rộng có thể hữu ích khi nhiệm vụ là "hiểu kho lưu trữ này". Nhưng đó không phải là cách một người đánh giá thường thực hiện đối với một pull request.

Khi tôi đánh giá một pull request, tôi bắt đầu từ phần diff và đặt ra các câu hỏi có mục tiêu:

Tôi không muốn mở một phần lớn của kho lưu trữ trước khi tôi biết mình đang tìm kiếm điều gì. Tôi muốn có ngữ cảnh tối thiểu cần thiết để trả lời câu hỏi, mà không làm quá tải phần đánh giá bằng các đoạn mã không liên quan.

Điều đó quan trọng vì mỗi kết quả công cụ đều trở thành một phần trong ngữ cảnh làm việc của tác nhân. Nội dung tệp bổ sung có thể được mang theo vào quá trình suy luận sau đó, làm tăng chi phí và đôi khi khiến việc đánh giá trở nên kém tập trung. Kết quả công cụ không phải là một bản in dùng một lần; đối với một tác nhân, đó là các token bổ sung nằm lại trong cửa sổ ngữ cảnh.

Các dấu vết đã làm cho sự khác biệt đó trở nên rõ ràng. Các công cụ dùng chung không phải là vấn đề. Các chỉ dẫn đã cung cấp cho tác nhân những bản năng sai lầm để thực hiện một đánh giá hiệu quả và hiệu lực.

Bản thân các công cụ vẫn hoạt động, nhưng các chỉ dẫn của chúng được tinh chỉnh để sử dụng trong Copilot CLI và ngụ ý một quy trình làm việc sai lệch: tác nhân sử dụng grep, glob và view giống như một trợ lý lập trình trên diện rộng thay vì một người đánh giá. Một trợ lý lập trình có thể lập bản đồ toàn bộ khu vực trước khi thực hiện thay đổi để đảm bảo nó không làm hỏng một góc khác của mã nguồn. Mặt khác, một người đánh giá thường bắt đầu từ phần diff, đặt câu hỏi liệu thay đổi đó có gây ra vấn đề hay không, và sau đó tìm kiếm bằng chứng gần nhất, hẹp nhất cần thiết để xác nhận hoặc bác bỏ nó.

Các chỉ dẫn công cụ dành cho trợ lý lập trình chung, giống như những chỉ dẫn được sử dụng bởi Copilot CLI hoặc tác nhân đám mây Copilot, có ý nghĩa đối với một trợ lý tương tác. Một nhà phát triển có thể yêu cầu nó hiểu một kho lưu trữ, lập kế hoạch thay đổi, chỉnh sửa tệp và tiếp tục qua nhiều lượt.

Tính năng đánh giá mã nguồn của Copilot có công việc hẹp hơn: bắt đầu từ phần diff của pull request, thu thập đủ bằng chứng xung quanh để quyết định xem một thay đổi có gây ra vấn đề thực sự hay không và tránh tải ngữ cảnh không cần thiết cho câu hỏi đánh giá đó.

Do đó, rõ ràng là chúng tôi không thể chỉ đơn giản thay thế các công cụ đánh giá mã nguồn Copilot trước đây bằng các công cụ từ Copilot CLI mà không có thêm công việc nhắc lệnh (prompting). Vấn đề trở thành: làm thế nào để chúng tôi thiết kế các chỉ dẫn công cụ sử dụng các công cụ dùng chung này một cách hiệu quả trong môi trường đánh giá mã nguồn?

Viết lại các chỉ dẫn công cụ cho quy trình làm việc của người đánh giá

Các lần lặp tiếp theo đã làm cho hướng dẫn trở nên cụ thể đối với việc đánh giá mã nguồn. Quy trình làm việc mà chúng tôi muốn tính năng đánh giá mã nguồn của Copilot tuân theo là:

Ở dạng đơn giản hóa, đây là hành vi mà chúng tôi đã mã hóa:

Tư thế chung: Sử dụng các công cụ có sẵn để kiểm tra ngữ cảnh kho lưu trữ có thể liên quan.

Hướng dẫn theo hình thức đánh giá: Bắt đầu từ phần diff. Thu hẹp phạm vi trước bằng grep và glob; đọc bằng chứng chính xác bằng view. Nếu grep không tìm thấy ngữ cảnh liên quan, hãy thử lại bằng một tìm kiếm đơn giản hơn. Nếu đường dẫn sai, hãy chuyển sang glob thay vì đoán các đường dẫn lân cận.

Ví dụ, hãy tưởng tượng phần diff thay đổi một trình trợ giúp xác thực (authorization helper) quyết định xem một thao tác có được phép hay không. Một câu hỏi đánh giá liên quan không phải là "hãy cho tôi xem toàn bộ nội dung của mọi tệp gọi trình trợ giúp này". Thay vào đó, nó có thể hẹp hơn: "có bất kỳ trình gọi xử lý yêu cầu nào dựa vào hành vi cũ không?"

Lộ trình dự kiến rất ngắn:

Hướng dẫn cũng thay đổi cách tác nhân phục hồi sau các tìm kiếm thất bại. Nếu một đầu vào khiến grep thất bại, bước tiếp theo tốt hơn là một tìm kiếm đơn giản, đã được sửa lỗi. Nếu một đường dẫn sai, bước tiếp theo tốt hơn là glob, thay vì đoán các đường dẫn lân cận và đọc bất cứ thứ gì tình cờ tồn tại. Điều đó đã thúc đẩy tác nhân tránh để một lỗi công cụ nhỏ biến thành một vòng lặp khám phá lớn hơn.

Diagram showing the flow after: a simplified illustration of the review-shaped behavior the prompt guided toward: stay anchored to the diff, narrow with grep and glob, then read focused ranges with vi

Thay đổi này nhỏ về từ ngữ nhưng lớn về hiệu quả. Nó đã thay đổi nhịp điệu của tác nhân từ "duyệt, đọc, tìm kiếm lại" thành "hỏi, thu hẹp, đọc, quyết định".

Các bài kiểm tra hiệu năng cho phép chúng tôi gỡ lỗi hành vi, không chỉ là điểm số

Bộ công cụ dùng chung đã cung cấp cho chúng tôi các công cụ. Các bài kiểm tra đánh giá mã nguồn nội bộ của Copilot đã cung cấp cho chúng tôi vòng lặp phản hồi.

Chúng tôi có thể chạy các ví dụ đánh giá tương tự, so sánh các dấu vết công cụ, cập nhật các chỉ dẫn và chạy lại. Điều đó cho phép chúng tôi đặt ra các câu hỏi cụ thể:

GitHub CopilotCode ReviewAI AgentQuy trình phát triểnKỹ thuật phần mềm
Đọc bài gốc

Bài viết được AI dịch và tổng hợp tự động từ GitHub Blog. Liên kết bài gốc ở phía trên. AIHOT.vn luôn dẫn nguồn đầy đủ — nếu bạn thấy điểm cần chỉnh sửa, hãy gửi ý kiến tại trang phản hồi.