Dây cương hiệu quả cho các tác nhân chạy dài hạn
Khi các tác nhân AI ngày càng có năng lực hơn, các nhà phát triển đang yêu cầu chúng đảm nhận những nhiệm vụ phức tạp kéo dài hàng giờ, thậm chí hàng ngày. Tuy nhiên, việc khiến các tác nhân duy trì tiến độ ổn định qua nhiều cửa sổ ngữ cảnh vẫn là một bài toán mở.
Thách thức cốt lõi của các tác nhân chạy dài là chúng phải làm việc trong các phiên rời rạc, và mỗi phiên mới bắt đầu mà không có ký ức về những gì đã xảy ra trước đó. Hãy tưởng tượng một dự án phần mềm với các kỹ sư làm việc theo ca, nơi mỗi kỹ sư mới đến mà không nhớ gì về ca trước. Vì cửa sổ ngữ cảnh có giới hạn và hầu hết các dự án phức tạp không thể hoàn thành trong một cửa sổ duy nhất, các tác nhân cần một cách để kết nối giữa các phiên lập trình.
Chúng tôi đã phát triển một giải pháp hai phần để cho phép **Claude Agent SDK** hoạt động hiệu quả qua nhiều cửa sổ ngữ cảnh: một **tác nhân khởi tạo** thiết lập môi trường trong lần chạy đầu tiên và một **tác nhân lập trình** được giao nhiệm vụ tạo ra tiến độ gia tăng trong mỗi phiên, đồng thời để lại các tạo phẩm rõ ràng cho phiên tiếp theo. Bạn có thể tìm thấy các ví dụ mã trong **quickstart** đi kèm.
Claude Agent SDK là một bộ công cụ tác nhân đa năng, mạnh mẽ, thành thạo trong lập trình cũng như các nhiệm vụ khác yêu cầu mô hình sử dụng công cụ để thu thập ngữ cảnh, lập kế hoạch và thực thi. Nó có các khả năng quản lý ngữ cảnh như nén, cho phép tác nhân làm việc trên một nhiệm vụ mà không làm cạn kiệt cửa sổ ngữ cảnh. Về mặt lý thuyết, với thiết lập này, một tác nhân có thể tiếp tục thực hiện công việc hữu ích trong một khoảng thời gian tùy ý.
Tuy nhiên, nén thôi là chưa đủ. Ngay cả một mô hình lập trình tiên tiến như Opus 4.5 chạy trên Claude Agent SDK trong một vòng lặp qua nhiều cửa sổ ngữ cảnh cũng sẽ không thể xây dựng một ứng dụng web chất lượng sản xuất nếu chỉ được cung cấp một lời nhắc cấp cao, chẳng hạn như "xây dựng một bản sao của claude.ai."
Các thất bại của Claude biểu hiện qua hai mô hình. Đầu tiên, tác nhân có xu hướng cố gắng làm quá nhiều cùng một lúc—về cơ bản là cố gắng hoàn thành ứng dụng trong một lần. Điều này thường dẫn đến việc mô hình hết ngữ cảnh giữa chừng khi triển khai, khiến phiên tiếp theo phải bắt đầu với một tính năng chưa hoàn thiện và không có tài liệu. Tác nhân sau đó phải đoán những gì đã xảy ra và dành nhiều thời gian để cố gắng làm cho ứng dụng cơ bản hoạt động trở lại. Điều này xảy ra ngay cả với tính năng nén, vốn không phải lúc nào cũng truyền đạt các hướng dẫn rõ ràng hoàn hảo cho tác nhân tiếp theo.
Một mô hình thất bại thứ hai thường xảy ra sau đó trong dự án. Sau khi một số tính năng đã được xây dựng, một phiên bản tác nhân sau đó sẽ nhìn quanh, thấy rằng đã có tiến triển và tuyên bố công việc đã hoàn thành.
Điều này phân rã vấn đề thành hai phần. Đầu tiên, chúng ta cần thiết lập một môi trường ban đầu đặt nền tảng cho **tất cả** các tính năng mà một lời nhắc nhất định yêu cầu, điều này giúp tác nhân làm việc từng bước và từng tính năng. Thứ hai, chúng ta nên hướng dẫn mỗi tác nhân tạo ra tiến độ gia tăng hướng tới mục tiêu của nó, đồng thời để lại môi trường ở trạng thái sạch sẽ khi kết thúc.
Kết thúc một phiên làm việc. "Trạng thái sạch" ở đây có nghĩa là loại mã phù hợp để hợp nhất vào nhánh chính: không có lỗi lớn, mã được sắp xếp gọn gàng và có tài liệu đầy đủ, và nhìn chung, một nhà phát triển có thể dễ dàng bắt đầu làm việc trên một tính năng mới mà không cần phải dọn dẹp một mớ hỗn độn không liên quan trước.
Khi thử nghiệm nội bộ, chúng tôi đã giải quyết những vấn đề này bằng một giải pháp gồm hai phần:
Ý tưởng chính ở đây là tìm cách để các agent nhanh chóng hiểu được trạng thái công việc khi bắt đầu với một cửa sổ ngữ cảnh mới, điều này được thực hiện với tệp claude-progress.txt cùng với lịch sử git. Cảm hứng cho những thực hành này đến từ việc biết những kỹ sư phần mềm hiệu quả làm gì hàng ngày.
Trong hướng dẫn prompting Claude 4 đã cập nhật, chúng tôi đã chia sẻ một số phương pháp hay nhất cho quy trình làm việc đa cửa sổ ngữ cảnh, bao gồm cấu trúc harness sử dụng "một prompt khác cho cửa sổ ngữ cảnh đầu tiên". "Prompt khác" này yêu cầu agent khởi tạo thiết lập môi trường với tất cả ngữ cảnh cần thiết mà các agent mã hóa trong tương lai sẽ cần để làm việc hiệu quả. Ở đây, chúng tôi cung cấp một phân tích sâu hơn về một số thành phần chính của một môi trường như vậy.
Để giải quyết vấn đề agent tạo ra một ứng dụng một lần hoặc coi dự án đã hoàn thành sớm, chúng tôi đã yêu cầu agent khởi tạo viết một tệp toàn diện về các yêu cầu tính năng, mở rộng dựa trên prompt ban đầu của người dùng. Trong ví dụ claude.aiclone, điều này có nghĩa là hơn 200 tính năng, chẳng hạn như "người dùng có thể mở một cuộc trò chuyện mới, nhập truy vấn, nhấn Enter và thấy phản hồi AI." Tất cả các tính năng này ban đầu được đánh dấu là "thất bại" để các agent mã hóa sau này có một bản phác thảo rõ ràng về chức năng đầy đủ trông như thế nào.
Chúng tôi yêu cầu các agent mã hóa chỉ chỉnh sửa tệp này bằng cách thay đổi trạng thái của trường passes, và chúng tôi sử dụng các hướng dẫn mạnh mẽ như "Không thể chấp nhận việc xóa hoặc chỉnh sửa các bài kiểm tra vì điều này có thể dẫn đến chức năng bị thiếu hoặc có lỗi." Sau một số thử nghiệm, chúng tôi đã quyết định sử dụng JSON cho việc này, vì mô hình ít có khả năng thay đổi hoặc ghi đè không phù hợp lên các tệp JSON so với các tệp Markdown.
Với scaffolding môi trường ban đầu này, lần lặp tiếp theo của agent mã hóa sau đó được yêu cầu chỉ làm việc trên một tính năng tại một thời điểm. Cách tiếp cận gia tăng này hóa ra lại rất quan trọng để giải quyết xu hướng của agent làm quá nhiều thứ cùng một lúc.
Khi làm việc gia tăng, điều cần thiết là mô hình phải để lại môi trường ở trạng thái sạch sau khi thực hiện thay đổi mã. Trong các thử nghiệm của chúng tôi, chúng tôi thấy rằng cách tốt nhất để đạt được hành vi này là yêu cầu mô hình commit tiến trình của nó vào git với các thông điệp commit mô tả và viết tóm tắt tiến trình của nó trong một tệp tiến trình. Điều này cho phép mô hình sử dụng git để hoàn tác các thay đổi mã xấu và khôi phục các trạng thái hoạt động của cơ sở mã.
Những cách tiếp cận này cũng tăng hiệu quả, vì chúng loại bỏ nhu cầu agent phải đoán những gì đã xảy ra và dành thời gian để cố gắng làm cho ứng dụng cơ bản hoạt động trở lại.
Một điểm tinh tế...
Một chế độ thất bại chính mà chúng tôi quan sát được là xu hướng của Claude đánh dấu một tính năng là hoàn thành mà không kiểm tra đúng cách. Nếu không có lời nhắc rõ ràng, Claude có xu hướng thực hiện các thay đổi mã và thậm chí kiểm tra bằng unit test hoặc lệnh `curl` với máy chủ phát triển, nhưng sẽ không nhận ra rằng tính năng đó không hoạt động từ đầu đến cuối.
Trong trường hợp xây dựng một ứng dụng web, Claude chủ yếu làm tốt việc xác minh các tính năng từ đầu đến cuối khi được nhắc rõ ràng sử dụng các công cụ tự động hóa trình duyệt và thực hiện tất cả kiểm tra như một người dùng thực tế.
Việc cung cấp cho Claude những loại công cụ kiểm tra này đã cải thiện đáng kể hiệu suất, vì agent có thể xác định và sửa các lỗi không rõ ràng từ mã nguồn.
Một số vấn đề vẫn còn tồn tại, như hạn chế về khả năng thị giác của Claude và các công cụ tự động hóa trình duyệt khiến việc xác định mọi loại lỗi trở nên khó khăn. Ví dụ, Claude không thể nhìn thấy các modal cảnh báo gốc của trình duyệt thông qua Puppeteer MCP, và các tính năng phụ thuộc vào các modal này thường có nhiều lỗi hơn.
Với tất cả những điều trên, mỗi coding agent được yêu cầu chạy qua một loạt các bước để định hướng, một số khá cơ bản nhưng vẫn hữu ích:
Cách tiếp cận này giúp Claude tiết kiệm một số token trong mỗi phiên vì nó không phải tìm cách kiểm tra mã. Nó cũng giúp yêu cầu agent khởi tạo viết một script init.sh có thể chạy máy chủ phát triển, và sau đó chạy một bài kiểm tra từ đầu đến cuối cơ bản trước khi triển khai một tính năng mới.
Trong trường hợp bản sao claude.ai, điều này có nghĩa là agent luôn khởi động máy chủ phát triển cục bộ và sử dụng Puppeteer MCP để bắt đầu một cuộc trò chuyện mới, gửi một tin nhắn và nhận phản hồi. Điều này đảm bảo rằng Claude có thể nhanh chóng xác định nếu ứng dụng bị hỏng và sửa ngay lập tức bất kỳ lỗi hiện có nào. Nếu agent thay vào đó bắt đầu triển khai một tính năng mới, nó có thể sẽ làm vấn đề trở nên tồi tệ hơn.
Với tất cả những điều này, một phiên điển hình bắt đầu với các tin nhắn trợ lý sau:
Các chế độ thất bại của agent và giải pháp
Điều này lại


