- Cursor đã thay thế tính năng Git
worktreesphức tạp bằng cáckỹ năngtác nhân dựa trênMarkdown, loại bỏ 15.000 dòng mã và giảm đáng kể công sức bảo trì. - Cách tiếp cận này tận dụng các
tác nhân convàlời nhắcđể tự động hóa việc quản lýworktree, cho phép linh hoạt hơn như hỗ trợ đa kho mã nguồn. - Tuy nhiên, nó đặt ra thách thức về việc giữ
tác nhânđi đúng hướng và giảm khả năng khám phá tính năng, đòi hỏi phải tối ưu hóa liên tục thông quaeValsvàRL.
Replacing 12K LoC with a 200 LoC Skill — David Gomes, Cursor
- Tận dụng LLM cho triển khai tính năng: Thay vì viết mã phức tạp cho các tính năng cấp cao (như quản lý
worktree), hãy sử dụngkỹ năngdựa trênMarkdownđể hướng dẫntác nhânthực hiện công việc, biếnMarkdownthành một dạng "mã nguồn mới". - Kết hợp các
primitiveshiện có: Xây dựng các tính năng mới bằng cách kết hợp cáckỹ năngtác nhân vàtác nhân conđể tạo ra logic phức tạp với ít mã nguồn cốt lõi hơn. - Giảm thiểu chi phí bảo trì: Chuyển đổi các tính năng ít được sử dụng nhưng phức tạp sang
kỹ năngdựa trênMarkdowncó thể giúp loại bỏ hàng nghìn dòng mã, giảm gánh nặng bảo trì. - Cải thiện tính linh hoạt và trải nghiệm người dùng: Việc sử dụng
lệnh slash(như/worktree) giúp người dùng dễ dàng bật tắt tính năng giữa cuộc trò chuyện và hỗ trợ các kịch bản phức tạp hơn như làm việc trên nhiềurepocùng lúc. - Thách thức về độ tin cậy của
mô hình: Cáctác nhâncó thểlệch hướnghoặctạo ảo giác, yêu cầulời nhắcmạnh mẽ (aggressive prompting) và cáclời nhắc hệ thống(system reminders) để giữ chúng trong phạm viworktreeđược chỉ định. - Tối ưu hóa liên tục: Sử dụng
eVals(đánh giá tự động) vàRL(Học tăng cường) để huấn luyện và cải thiện hành vi củamô hình, đặc biệt là cácmô hìnhnội bộ nhưComposer, nhằm tăng cường độ chính xác và độ tin cậy củakỹ năng. - Đánh đổi
khả năng khám phá: Đối với cáctính năng dành cho người dùng chuyên sâu(power user features), chấp nhận việckhả năng khám pháthấp hơn để đổi lấy sự đơn giản hóa trongUIvà giảm chi phí phát triển/bảo trì.
Markdown— Markdown (Mã nguồn định dạng Markdown)skill— kỹ năngworktree— cây làm việcagent— tác nhânsub-agent— tác nhân conprompt— lời nhắccontext— ngữ cảnhdependencies— các phụ thuộcrepo— kho mã nguồn (Repository)implementation— triển khaidiscoverability— khả năng khám pháeVals— hệ thống đánh giá tự động (hoặc viết tắt là eVals)RL(Reinforcement Learning) — Học tăng cườnghallucinate— tạo ảo giác (hoặc "sinh ra ảo giác")aggressive prompting— thúc đẩy lời nhắc tích cực/mạnh mẽ
Giới thiệu: Markdown là Mã nguồn Mới
Chào mọi người, các bạn khỏe không? Cảm ơn vì đã đến hôm nay. Tôi sẽ nói về việc Markdown về cơ bản là mã nguồn mới. Như Tejia đã từng giới thiệu trước, chúng tôi gần đây đã thay thế rất nhiều mã nguồn trong ứng dụng Cursor chỉ bằng Markdown, chỉ bằng một skill. Và trong buổi nói chuyện hôm nay, tôi sẽ chia sẻ một chút về hành trình chuyển đổi từ một tính năng hoàn chỉnh với rất nhiều mã nguồn, nhiều dependencies, nhiều độ phức tạp và tests thành một phiên bản nhẹ nhàng hơn, tinh gọn hơn của cùng một tính năng, nhưng chỉ với một skill duy nhất.
Tổng quan về Git Worktrees trong Cursor
Tuy nhiên, trước khi bắt đầu, tôi phải tóm tắt lại cho các bạn về Git worktrees và cách chúng hoạt động trong Cursor. Nếu bạn chưa từng nghe về worktrees trong Git, chúng thực chất giống như các bản checkout riêng biệt – và xin lỗi vì màn hình rộng – nhưng chúng thực sự là các bản checkout riêng biệt của các repo của bạn, cho phép bạn làm việc song song. Vì vậy, các tác nhân khác nhau có thể làm việc trên cùng một task hoặc trên các task khác nhau cùng một lúc mà không gây trở ngại cho nhau. Nếu bạn chưa bao giờ sử dụng tính năng này trong Cursor trước đây, cách hoạt động là bạn có thể khởi tạo một tác nhân trên một worktree riêng lẻ, và bạn sẽ thấy, ví dụ, cùng một tệp tin trong hai worktrees khác nhau. Bạn có thể thấy chúng trông khác nhau vì tác nhân đang thực hiện một số công việc trên worktree đó, nhưng không phải trên bản checkout chính của bạn. Và bất cứ khi nào tác nhân chạy lệnh, hoặc lint, hoặc bất cứ điều gì nó làm, sẽ được cô lập và giới hạn trong worktree Git đó. Với tính năng này, bạn cũng có thể làm việc song song cùng lúc trên màn hình. Bạn có thể có các grids of agents làm việc cho mình. Và nếu bạn nói, "Này, mở một PR," tác nhân sẽ mở một pull request từ worktree đó với những thay đổi mà nó tạo ra bên trong worktree đó. Và một trong những điều tuyệt vời nhất về tính năng này là nó cho phép bạn giao cùng một task cho các mô hình khác nhau cùng một lúc và sau đó so sánh những gì các mô hình khác nhau thực hiện trên cùng một lời nhắc. Vì vậy, nếu bạn chưa từng nghe về điều này, chúng tôi gọi nó là "Bessavent", và nó thực chất là một cách để bạn có các mô hình khác nhau cạnh tranh trên cùng một task. Và sau đó, bạn thậm chí có thể xem trước các thay đổi nếu đó là một dự án front-end bạn đang làm việc. Bạn có thể so sánh tất cả các implementation trực quan khác nhau và sau đó chọn cái bạn thích.
Thách thức của Phiên bản Cũ
Nếu bạn chưa từng nghe về điều này, tất cả những gì tôi đang nói hôm nay đều được ra mắt vào khoảng tháng 10 năm ngoái, cùng với Cursor 2.0. Và khi chúng tôi lần đầu phát hành nó, nó đi kèm với rất nhiều độ phức tạp. Chúng tôi phải viết tất cả mã nguồn để tạo worktrees, quản lý các worktrees này, đưa chúng vào tác nhân dưới dạng context. Chúng tôi cũng phải đảm bảo rằng các tác nhân được giới hạn phạm vi và cô lập, và chúng không thể thoát ra khỏi worktree mà chúng đang làm việc. Chúng tôi cũng có thứ gọi là setup scripts mà người dùng có thể cấu hình và chạy, và tôi có Cursor chạy chúng bất cứ khi nào một tác nhân bắt đầu hoạt động trên một worktree nhất định. Chúng tôi cũng có judging (vì tôi chưa cho bạn xem điều này trước đây, nhưng có một biểu tượng ngón tay cái hướng lên nhỏ trên một trong các mô hình). Đó chỉ là một judge mà chúng tôi chạy để cho bạn biết implementation nào trông tốt nhất dựa trên các criteria khác nhau. Và sau đó, chúng tôi cũng phải thực hiện một số thay đổi đối với harness và giới thiệu một số system reminders để giúp các tác nhân đi đúng hướng trong các worktrees này. Và cuối cùng, cũng có một số cleanup complexity (độ phức tạp dọn dẹp), bởi vì mọi người thích khởi tạo hàng trăm worktrees này và sau đó disk sizes của họ tăng vọt, và chúng tôi phải giúp họ bằng cách dọn dẹp các worktrees còn sót lại.
Triển khai Mới: Kỹ năng và Tác nhân Con
Trong implementation mới của chúng tôi, cái mà tôi sẽ nói hôm nay, chúng tôi đã có thể loại bỏ hầu hết những điều này. Và thực tế, tôi gần đây đã mở một PR, loại bỏ toàn bộ tính năng này khỏi Cursor, và đó là một sự xóa bỏ mã nguồn lớn – tôi nghĩ khoảng 15.000 dòng mã đã bị xóa. Implementation mới của tính năng gần như tốt bằng phiên bản trước, và nó nhẹ nhàng hơn nhiều về mặt chúng tôi duy trì nó. Và nó thậm chí còn có một số lợi ích so với implementation trước mà tôi sẽ nói hôm nay. Vậy, làm thế nào chúng tôi có thể thay thế toàn bộ một tính năng bằng một skill? Chúng tôi quyết định rằng có hai primitives mà chúng tôi có thể sử dụng để cho phép người dùng Cursor sử dụng worktrees bằng cách đơn giản tận dụng hai primitives: một là agent skills và hai là sub-agents. Vì vậy, cả hai đều là các tính năng hiện có của Cursor. Bạn có thể tìm hiểu thêm về chúng trong docs của chúng tôi. Chúng tôi có một trang dành cho skills và một trang dành cho sub-agents. Chúng tôi nhận ra rằng nếu chúng tôi kết hợp hai điều này lại với nhau, về cơ bản chúng tôi có thể triển khai lại cả tính năng worktrees của Cursor cũng như tính năng "Bessavent" của Cursor, chỉ bằng Markdown. Và đây là một video nhỏ về cách nó hoạt động. Vì vậy, tôi giờ đây, với tư cách là người dùng, có thể nói /worktree, và sau đó tôi sẽ giao cho nó một số task. Tôi sẽ nói, "Sửa lỗi chính tả ở chân trang web." Và tác nhân này sẽ chạy trong một worktree cô lập và thực hiện công việc của nó ở đó. Vì vậy, cách skill được viết thực sự rất đơn giản. Tôi có thể cho bạn thấy hầu hết nó; nó không vừa trên màn hình, nhưng về cơ bản nó là một tập hợp các hướng dẫn nói với mô hình cách tạo worktrees và chạy các setup scripts mà người dùng có thể đã cấu hình, và sau đó duy trì trên bản checkout đó. Chúng tôi muốn đảm bảo rằng khi tác nhân đang hoạt động trên một worktree, nó vẫn ở trong bản checkout đó. Skill "Bessavent" rất tương tự; nó thực ra còn nhỏ hơn. Toàn bộ skill vừa vặn trên màn hình ở đây với phông chữ nhỏ. Và những gì chúng tôi đang làm ở đây là chúng tôi đang hướng dẫn tác nhân cha đi tạo sub-agents cho mỗi mô hình và sau đó khởi tạo một worktree cho mỗi sub-agent, để mỗi tác nhân con tự tạo worktree riêng và làm việc bên trong worktree đó. Và sau đó chúng tôi cũng yêu cầu nó chờ tất cả các sub-agents, và khi chúng hoàn thành, vui lòng cung cấp một số bình luận. Vui lòng cho người dùng biết các implementation khác nhau của các sub-agents khác nhau trông như thế nào. Có thể bạn có thể đánh giá chúng, có thể bạn có thể đưa ra một số phê bình về chúng và có thể bạn có thể giúp người dùng chọn cái nào là tốt nhất. Và vui lòng cung cấp điều đó cho người dùng theo một định dạng ổn định, đẹp mắt hoặc tương tự. Nhưng một lần nữa, nó chỉ khoảng 40 dòng mã và tất cả đều là Markdown. Nó thậm chí không phải là mã nguồn. Và phiên bản trước của điều này có thể là 4.000 dòng mã. Một số cân nhắc mà chúng tôi phải có trong skill này là skill phải cross-platform compatible. Chẳng hạn, chúng tôi có các hướng dẫn dành riêng cho Windows và chúng tôi cũng có các hướng dẫn dành cho Linux và macOS. Chúng tôi cũng hướng dẫn mô hình cha chạy các setup scripts cho mỗi worktree mà người dùng có thể đã cấu hình. Và sau đó đây là phần khó nhất. Chúng tôi sẽ dành một chút thời gian cho phần này trong buổi nói chuyện hôm nay. Chúng tôi phải hướng dẫn mô hình ở lại worktree đó, đúng không? Chúng tôi phải thực sự nói, "Này, đừng bao giờ làm việc bên ngoài cái này và đừng bao giờ thoát ra," đúng không? Và chúng tôi làm điều đó bằng cách aggressive prompting một cách hiệu quả.
Lệnh so với Kỹ năng trong Cursor
Vì vậy, các lệnh mới là /worktree và sau đó /Bessavent để về cơ bản khởi động các tác nhân trong các worktrees cô lập và để khởi động nhiều tác nhân trên cùng một task. Và sau đó chúng tôi cũng có apply worktree và delete worktree để đưa các thay đổi từ worktree phụ sang bản checkout chính của bạn, và delete worktree chỉ làm những gì bạn mong đợi. Một lưu ý nhỏ là đây không thực sự là các skills trong Cursor; chúng thực ra là các lệnh. Nhưng cách các lệnh này hoạt động trong Cursor cực kỳ giống với cách các skills hoạt động, ở chỗ lời nhắc của chúng chỉ được tải vào context nếu người dùng chọn tải chúng. Và lý do duy nhất chúng tôi làm nó dưới dạng lệnh chứ không phải skills là để lời nhắc cho chúng có thể được kiểm soát trong các server của chúng tôi, ở back-end của chúng tôi. Điều này có nghĩa là tôi có thể lặp lại trên các lời nhắc này mà bạn không cần phải cập nhật phiên bản Cursor của mình. Nếu tôi thực hiện một số cải tiến cho các lời nhắc này, lần tới khi bạn sử dụng chúng, bạn sẽ nhận được phiên bản mới nhất của các lời nhắc. Về cơ bản chúng hoạt động giống như skills. Đây là bản demo của skill hoặc lệnh "Bessavent" nơi tôi giao cùng một task cho Kimi, GROQ, Composer, GPT và Opus. Và những gì bạn sẽ thấy là tác nhân cha bắt đầu bằng cách khởi tạo năm sub-agents trên năm mô hình khác nhau mà tôi đã chỉ định, và mỗi tác nhân con sẽ có worktree riêng; mỗi tác nhân con có context riêng. Và sau đó Opus mất nhiều thời gian hơn như mong đợi. Và sau đó, cuối cùng, mô hình cha, theo hướng dẫn, sẽ thực hiện so sánh trên tất cả các sub-agents khác nhau. Nó sẽ nói, "Hai mô hình này về cơ bản đã làm điều tương tự. Mô hình này đã làm điều mà không có mô hình nào khác làm." Và bạn thậm chí có thể nói chuyện với tác nhân cha và bạn có thể nói, "Ồ, tôi thích phần này mà Opus đã làm. Và tôi thích phần này mà GPT đã làm. Bạn có thể ghép chúng lại với nhau không?" Và tác nhân cha sẽ làm điều đó cho bạn.
Ưu điểm của Phiên bản Mới
Vậy, hãy nói về một số pros của implementation mới. Và sau đó tôi sẽ nói về một số cons, một số điều chúng tôi đã mất với refactor này. Vì vậy, pro chính của việc triển khai lại toàn bộ tính năng này dưới dạng một skill là tôi có ít mã nguồn phải duy trì hơn nhiều. Một cách ích kỷ, tôi sẽ dành ít thời gian hơn nhiều để duy trì tính năng này. Và đây là một advanced feature. Chúng tôi không nói về một tính năng được sử dụng bởi 90% người dùng Cursor. Hoàn toàn không. Worktrees là một thứ khá advanced. Và vì vậy, chỉ những power users của Cursor yêu thích việc parallelizing và có những grids of agents này mới sử dụng worktrees. Vì vậy, đây không phải là loại tính năng mà chúng tôi muốn dành nhiều thời gian cho maintenance. Một lợi thế khác là người dùng của chúng tôi giờ đây có thể chuyển sang một worktree giữa chừng một cuộc trò chuyện. Điều đó không thể thực hiện được trước đây. Chúng tôi không muốn làm ô nhiễm prompt UI quá nhiều với tất cả các drop-downs và settings này. Và vì vậy, bây giờ nó chỉ là một slash command, việc người dùng chuyển sang một worktree giữa chừng một cuộc trò chuyện dễ dàng hơn nhiều. Họ có thể bắt đầu nói về điều gì đó và sau đó nếu họ quyết định muốn làm việc trên side, họ có thể làm điều đó với /worktree. Một lợi thế lớn khác là implementation trước đây không hoạt động nếu bạn đang làm việc trên nhiều repo cùng lúc. Vì vậy, rất phổ biến khi có một multi-repo setup nơi có thể front-end và back-end của bạn là các repo riêng biệt. Trong quá khứ, bạn không thể thực hiện worktrees trong loại setup này; nó chỉ bị vô hiệu hóa. Với lệnh /worktree mới, mọi thứ hoạt động tốt. Tác nhân sẽ đảm bảo tạo một worktree trên mỗi repo. Và sau đó nếu bạn mở một PR, nó sẽ mở hai PR, một cho mỗi repo. Nó hoạt động khá tốt. Một lợi thế khác của skill implementation mới là judging experience cuối cùng của việc biết mô hình nào đã làm gì cho "Bessavent" vượt trội hơn nhiều. Tác nhân cha giờ đây có nhiều context hơn về những gì mỗi sub-agents đã làm, và người dùng thậm chí có thể yêu cầu tác nhân ghép nối các phần khác nhau từ các implementation khác nhau, điều mà không thể thực hiện được trước đây trong implementation trước. Bạn phải chọn một sub-agent hoặc một mô hình và chỉ gắn bó với nó.
Nhược điểm của Phiên bản Mới
Bây giờ, hãy nói về một số cons. Và nếu bạn tò mò, chúng tôi có một forums link ở đây, nơi chúng tôi thực sự nhận được một số mixed feedback về implementation mới. Một số người thực sự đã quen với cách hoạt động cũ của tính năng. Và nếu bạn tò mò, bạn có thể vào xem rằng không phải ai cũng hài lòng với sự thay đổi, ít nhất là cho đến bây giờ, nhưng chúng tôi đang theo dõi các vấn đề là gì. Vấn đề số một, rất khó để tác nhân đi đúng hướng. Với cách tiếp cận trước đây của chúng tôi, tác nhân phải đi đúng hướng. Chúng tôi không bao giờ cho phép mô hình chạm vào bất kỳ tệp nào bên ngoài worktree của nó. Việc nó làm như vậy là không thể về mặt vật lý. Bây giờ, chúng tôi đang tin tưởng mô hình. Vì vậy, bạn có thể nói đó là một chút trust-based, bởi vì chúng tôi về cơ bản đang nói, "Này, hoạt động trên thư mục này," và sau đó, kiểu như, "cầu trời phù hộ, xin đừng quên điều này." Và đặc biệt trong các phiên làm việc dài, rất có thể mô hình sẽ quên nơi nó nên hoạt động.
Nhược điểm hiện tại
Đôi khi các mô hình, đặc biệt là những mô hình kém nhất, sẽ tạo ra "ảo giác" (hallucinate) hoặc trở nên mất kiểm soát (haywire) và bắt đầu làm những điều không nên. Nhưng chúng tôi đang khắc phục điều này. Một nhược điểm khác là nó có cảm giác chậm hơn vì bạn thấy tác nhân tạo ra work tree và bạn thấy điều đó trong đoạn chat của mình. Thực tế nó không chậm hơn, nhưng có cảm giác như tác nhân đang lãng phí thời gian làm những việc lẽ ra phải được thực hiện trước.
Khả năng khám phá tính năng
Chúng tôi cũng đang xem xét một số cải tiến ở đây. Cuối cùng, tính năng này giờ đây khó tìm hơn nhiều. Trước đây, mỗi khi bạn mở Cursor, bạn có một trình đơn thả xuống hiển thị tùy chọn chạy tác vụ này cục bộ, trên đám mây (Claude) hay trong work tree. Giờ đây, toàn bộ trình đơn thả xuống đó đã biến mất. Vì vậy, nếu bạn muốn sử dụng work tree, bạn phải biết tính năng này tồn tại để có thể gõ /work tree. Do đó, khả năng khám phá (discoverability) hơi kém hơn. Nhưng như tôi đã đề cập trước đây, đây là một tính năng dành cho người dùng chuyên sâu (power user feature) mà chúng tôi chấp nhận việc nó ít được khám phá hơn nói chung.
Cải thiện kỹ năng Tác nhân
Vậy làm thế nào chúng ta có thể cải thiện kỹ năng này? Như tôi đã đề cập, vấn đề lớn nhất hiện nay là tác nhân không phải lúc nào cũng đi đúng hướng. Có hai cách chúng tôi sẽ cải thiện điều này. Một là với eVals và sau đó sử dụng các eVals đó để cải thiện lời nhắc, và cách còn lại là thông qua RL (Học tăng cường) và huấn luyện (training). Tại Cursor, chúng tôi huấn luyện mô hình riêng của mình có tên Composer. Đối với Composer 2, phiên bản nhẹ nhất của mô hình này, chúng tôi không có bất kỳ tác vụ RL nào với các lời nhắc này. Chúng tôi không có bất kỳ tác vụ nào trong số hàng nghìn tác vụ mà chúng tôi đã sử dụng cho RL thực sự hoạt động trong loại môi trường (environment) này. Vì vậy, chúng tôi đang nỗ lực thêm một loạt các tác vụ này vào quy trình RL (RL pipeline) của mình để đến khi chúng tôi ra mắt Composer 3, 4 hoặc 5, ít nhất mô hình của chúng tôi sẽ tốt hơn nhiều trong việc này. Rõ ràng, chúng tôi không thể cải thiện các mô hình mà các công ty khác đã phát triển, nhưng chúng tôi đã chia sẻ phản hồi với tất cả các phòng thí nghiệm (labs) và nhà cung cấp mô hình (model providers) khác về loại vấn đề này.
Tối ưu hóa bằng eVals
Và đối với eVals, tôi đã làm việc trên một số eVals cho tính năng này và đây thực sự là lần đầu tiên của tôi – hoặc không phải lần đầu tiên, nhưng tôi đang ở giai đoạn khá sớm trong hành trình viết eVals của mình. Và tôi thực sự rất ngạc nhiên rằng nếu bạn sử dụng một công cụ như Brain Trust (và xin cảm ơn Brain Trust, họ đã rất hữu ích), việc viết các loại eVals này thực sự rất, rất dễ dàng. Bạn không cần phải biết hầu hết bất cứ điều gì về eVals và bạn chỉ cần đưa lời nhắc cho tác nhân; nó sẽ làm mọi thứ cho bạn. Về cơ bản, điều tôi đang làm là tôi khởi động Cursor CLI. Nó là headless (không giao diện), vì vậy nó rất tuyệt cho eVals. Và sau đó tôi có hai bộ tính điểm (scorers): một cái kiểm tra xem mô hình có thực hiện bất kỳ công việc nào trong work tree của nó như mong đợi hay không, và một cái khác là ngược lại, tức là mô hình có thực hiện bất kỳ công việc nào trong primary checkout – nơi nó không nên làm việc. Cho đến nay, các eVals mà tôi đã chạy khá đơn giản, vì vậy tôi thực sự chưa thể mô phỏng các phiên (sessions) cực kỳ dài, đó là lúc các mô hình bắt đầu hoạt động kém hơn. Nhưng ngay cả đến nay, tôi đã hiểu rằng không phải tất cả các mô hình đều giỏi như nhau trong việc này. Ví dụ, HIKU, một mô hình nhỏ hơn, kém thông minh hơn, rất thường xuyên lệch hướng (deviate) và bắt đầu làm việc trong primary checkout. Nhưng các mô hình khác mà tôi đã thử nghiệm, chẳng hạn như Composer và GROK, lại hoạt động tốt hơn nhiều. Vì vậy, tôi vẫn phải cải thiện eVals nhiều hơn để làm cho chúng phức tạp hơn. Nhưng hy vọng là ngay khi tôi có thể bắt đầu tìm thấy các mô hình (patterns) ở đây, tôi thực sự có thể cải thiện các lời nhắc.
Hướng phát triển tiếp theo
Và một điều nữa chúng ta có thể làm là đưa ra các lời nhắc hệ thống (system reminders) tốt hơn cho các mô hình, hướng dẫn chúng đi đúng hướng và không lệch hướng khỏi work tree mà chúng được cho là phải làm việc. Được rồi, vậy tiếp theo là gì? Điều đầu tiên là chúng tôi thực sự sẽ lùi lại một bước nhỏ ở đây và sẽ có một triển khai work tree (work tree implementation) đầy đủ và tự nhiên (native) hơn trong cửa sổ tác nhân Cursor (Cursor agent window) mới. Nếu bạn đã theo dõi, chúng tôi gần đây đã công bố Cursor 3.0. Một phần của 3.0 là một giao diện tác nhân (agentic interface) hơn cho viết mã (coding), nơi bạn vẫn có thể chỉnh sửa mã (edit code) và vẫn có thể xem mã (see code), nhưng UI (Giao diện người dùng) và UX (Trải nghiệm người dùng) được tối ưu hóa hơn nhiều xung quanh tác nhân và giao diện trò chuyện (chat interface). Chúng tôi tin rằng loại giao diện này là nơi phù hợp cho một triển khai work tree đúng đắn. Loại người có nhiều khả năng thực hiện nhiều song song hóa cục bộ (local parallelization) thường là cùng một loại người có nhiều khả năng sử dụng loại UI này. Vì vậy, chúng tôi đang lùi lại một bước nhỏ và xây dựng một triển khai work tree đúng đắn, tự nhiên hơn, không quá tác nhân (agentic) trong UI mới.
Giải pháp song song hóa thay thế
Ngoài ra, chúng tôi đang cải thiện kỹ năng như tôi đã đề cập thông qua công việc liên tục về eVals và sau đó là RL cùng các công việc huấn luyện khác. Cuối cùng, chúng tôi thực sự đang tìm hiểu các cơ chế song song hóa (parallelization primitives) khác không phải là Git work tree. Nếu bạn đã sử dụng Git work tree, bạn có thể biết rằng chúng có thể hơi chậm khi tạo và cũng tốn nhiều dung lượng đĩa (disk space) trên máy tính của bạn. Và cuối cùng, chúng chỉ hoạt động với kho lưu trữ Git (Git repos). Vì vậy, nếu bạn đang sử dụng thứ gì đó khác ngoài Git, thực sự không có cơ chế song song hóa cục bộ nào trong Cursor. Trong tương lai gần, chúng tôi hy vọng sẽ chia sẻ thêm về điều này, nhưng chúng tôi đang tìm kiếm một số giải pháp khác cho song song hóa cục bộ không liên quan đến Git và không liên quan đến Git work tree. Vâng, hãy theo dõi để biết thêm. Cảm ơn tất cả các bạn đã đến buổi nói chuyện hôm nay. Tôi chắc rằng nhiều bạn có câu hỏi và tôi sẽ có mặt cả ngày. Hãy cứ tìm tôi bất cứ lúc nào và tôi rất vui được trò chuyện với bất kỳ ai. Cảm ơn.
TL;DR
- Cursor đã thay thế tính năng Git
worktreesphức tạp bằng cáckỹ năngtác nhân dựa trênMarkdown, loại bỏ 15.000 dòng mã và giảm đáng kể công sức bảo trì. - Cách tiếp cận này tận dụng các
tác nhân convàlời nhắcđể tự động hóa việc quản lýworktree, cho phép linh hoạt hơn như hỗ trợ đa kho mã nguồn. - Tuy nhiên, nó đặt ra thách thức về việc giữ
tác nhânđi đúng hướng và giảm khả năng khám phá tính năng, đòi hỏi phải tối ưu hóa liên tục thông quaeValsvàRL.
Điểm chính
- Tận dụng LLM cho triển khai tính năng: Thay vì viết mã phức tạp cho các tính năng cấp cao (như quản lý
worktree), hãy sử dụngkỹ năngdựa trênMarkdownđể hướng dẫntác nhânthực hiện công việc, biếnMarkdownthành một dạng "mã nguồn mới". - Kết hợp các
primitiveshiện có: Xây dựng các tính năng mới bằng cách kết hợp cáckỹ năngtác nhân vàtác nhân conđể tạo ra logic phức tạp với ít mã nguồn cốt lõi hơn. - Giảm thiểu chi phí bảo trì: Chuyển đổi các tính năng ít được sử dụng nhưng phức tạp sang
kỹ năngdựa trênMarkdowncó thể giúp loại bỏ hàng nghìn dòng mã, giảm gánh nặng bảo trì. - Cải thiện tính linh hoạt và trải nghiệm người dùng: Việc sử dụng
lệnh slash(như/worktree) giúp người dùng dễ dàng bật tắt tính năng giữa cuộc trò chuyện và hỗ trợ các kịch bản phức tạp hơn như làm việc trên nhiềurepocùng lúc. - Thách thức về độ tin cậy của
mô hình: Cáctác nhâncó thểlệch hướnghoặctạo ảo giác, yêu cầulời nhắcmạnh mẽ (aggressive prompting) và cáclời nhắc hệ thống(system reminders) để giữ chúng trong phạm viworktreeđược chỉ định. - Tối ưu hóa liên tục: Sử dụng
eVals(đánh giá tự động) vàRL(Học tăng cường) để huấn luyện và cải thiện hành vi củamô hình, đặc biệt là cácmô hìnhnội bộ nhưComposer, nhằm tăng cường độ chính xác và độ tin cậy củakỹ năng. - Đánh đổi
khả năng khám phá: Đối với cáctính năng dành cho người dùng chuyên sâu(power user features), chấp nhận việckhả năng khám pháthấp hơn để đổi lấy sự đơn giản hóa trongUIvà giảm chi phí phát triển/bảo trì.
Từ vựng
Markdown— Markdown (Mã nguồn định dạng Markdown)skill— kỹ năngworktree— cây làm việcagent— tác nhânsub-agent— tác nhân conprompt— lời nhắccontext— ngữ cảnhdependencies— các phụ thuộcrepo— kho mã nguồn (Repository)implementation— triển khaidiscoverability— khả năng khám pháeVals— hệ thống đánh giá tự động (hoặc viết tắt là eVals)RL(Reinforcement Learning) — Học tăng cườnghallucinate— tạo ảo giác (hoặc "sinh ra ảo giác")aggressive prompting— thúc đẩy lời nhắc tích cực/mạnh mẽ
Nội dung chi tiết
Giới thiệu: Markdown là Mã nguồn Mới
Chào mọi người, các bạn khỏe không? Cảm ơn vì đã đến hôm nay. Tôi sẽ nói về việc Markdown về cơ bản là mã nguồn mới. Như Tejia đã từng giới thiệu trước, chúng tôi gần đây đã thay thế rất nhiều mã nguồn trong ứng dụng Cursor chỉ bằng Markdown, chỉ bằng một skill. Và trong buổi nói chuyện hôm nay, tôi sẽ chia sẻ một chút về hành trình chuyển đổi từ một tính năng hoàn chỉnh với rất nhiều mã nguồn, nhiều dependencies, nhiều độ phức tạp và tests thành một phiên bản nhẹ nhàng hơn, tinh gọn hơn của cùng một tính năng, nhưng chỉ với một skill duy nhất.
Tổng quan về Git Worktrees trong Cursor
Tuy nhiên, trước khi bắt đầu, tôi phải tóm tắt lại cho các bạn về Git worktrees và cách chúng hoạt động trong Cursor. Nếu bạn chưa từng nghe về worktrees trong Git, chúng thực chất giống như các bản checkout riêng biệt – và xin lỗi vì màn hình rộng – nhưng chúng thực sự là các bản checkout riêng biệt của các repo của bạn, cho phép bạn làm việc song song. Vì vậy, các tác nhân khác nhau có thể làm việc trên cùng một task hoặc trên các task khác nhau cùng một lúc mà không gây trở ngại cho nhau. Nếu bạn chưa bao giờ sử dụng tính năng này trong Cursor trước đây, cách hoạt động là bạn có thể khởi tạo một tác nhân trên một worktree riêng lẻ, và bạn sẽ thấy, ví dụ, cùng một tệp tin trong hai worktrees khác nhau. Bạn có thể thấy chúng trông khác nhau vì tác nhân đang thực hiện một số công việc trên worktree đó, nhưng không phải trên bản checkout chính của bạn. Và bất cứ khi nào tác nhân chạy lệnh, hoặc lint, hoặc bất cứ điều gì nó làm, sẽ được cô lập và giới hạn trong worktree Git đó. Với tính năng này, bạn cũng có thể làm việc song song cùng lúc trên màn hình. Bạn có thể có các grids of agents làm việc cho mình. Và nếu bạn nói, "Này, mở một PR," tác nhân sẽ mở một pull request từ worktree đó với những thay đổi mà nó tạo ra bên trong worktree đó. Và một trong những điều tuyệt vời nhất về tính năng này là nó cho phép bạn giao cùng một task cho các mô hình khác nhau cùng một lúc và sau đó so sánh những gì các mô hình khác nhau thực hiện trên cùng một lời nhắc. Vì vậy, nếu bạn chưa từng nghe về điều này, chúng tôi gọi nó là "Bessavent", và nó thực chất là một cách để bạn có các mô hình khác nhau cạnh tranh trên cùng một task. Và sau đó, bạn thậm chí có thể xem trước các thay đổi nếu đó là một dự án front-end bạn đang làm việc. Bạn có thể so sánh tất cả các implementation trực quan khác nhau và sau đó chọn cái bạn thích.
Thách thức của Phiên bản Cũ
Nếu bạn chưa từng nghe về điều này, tất cả những gì tôi đang nói hôm nay đều được ra mắt vào khoảng tháng 10 năm ngoái, cùng với Cursor 2.0. Và khi chúng tôi lần đầu phát hành nó, nó đi kèm với rất nhiều độ phức tạp. Chúng tôi phải viết tất cả mã nguồn để tạo worktrees, quản lý các worktrees này, đưa chúng vào tác nhân dưới dạng context. Chúng tôi cũng phải đảm bảo rằng các tác nhân được giới hạn phạm vi và cô lập, và chúng không thể thoát ra khỏi worktree mà chúng đang làm việc. Chúng tôi cũng có thứ gọi là setup scripts mà người dùng có thể cấu hình và chạy, và tôi có Cursor chạy chúng bất cứ khi nào một tác nhân bắt đầu hoạt động trên một worktree nhất định. Chúng tôi cũng có judging (vì tôi chưa cho bạn xem điều này trước đây, nhưng có một biểu tượng ngón tay cái hướng lên nhỏ trên một trong các mô hình). Đó chỉ là một judge mà chúng tôi chạy để cho bạn biết implementation nào trông tốt nhất dựa trên các criteria khác nhau. Và sau đó, chúng tôi cũng phải thực hiện một số thay đổi đối với harness và giới thiệu một số system reminders để giúp các tác nhân đi đúng hướng trong các worktrees này. Và cuối cùng, cũng có một số cleanup complexity (độ phức tạp dọn dẹp), bởi vì mọi người thích khởi tạo hàng trăm worktrees này và sau đó disk sizes của họ tăng vọt, và chúng tôi phải giúp họ bằng cách dọn dẹp các worktrees còn sót lại.
Triển khai Mới: Kỹ năng và Tác nhân Con
Trong implementation mới của chúng tôi, cái mà tôi sẽ nói hôm nay, chúng tôi đã có thể loại bỏ hầu hết những điều này. Và thực tế, tôi gần đây đã mở một PR, loại bỏ toàn bộ tính năng này khỏi Cursor, và đó là một sự xóa bỏ mã nguồn lớn – tôi nghĩ khoảng 15.000 dòng mã đã bị xóa. Implementation mới của tính năng gần như tốt bằng phiên bản trước, và nó nhẹ nhàng hơn nhiều về mặt chúng tôi duy trì nó. Và nó thậm chí còn có một số lợi ích so với implementation trước mà tôi sẽ nói hôm nay. Vậy, làm thế nào chúng tôi có thể thay thế toàn bộ một tính năng bằng một skill? Chúng tôi quyết định rằng có hai primitives mà chúng tôi có thể sử dụng để cho phép người dùng Cursor sử dụng worktrees bằng cách đơn giản tận dụng hai primitives: một là agent skills và hai là sub-agents. Vì vậy, cả hai đều là các tính năng hiện có của Cursor. Bạn có thể tìm hiểu thêm về chúng trong docs của chúng tôi. Chúng tôi có một trang dành cho skills và một trang dành cho sub-agents. Chúng tôi nhận ra rằng nếu chúng tôi kết hợp hai điều này lại với nhau, về cơ bản chúng tôi có thể triển khai lại cả tính năng worktrees của Cursor cũng như tính năng "Bessavent" của Cursor, chỉ bằng Markdown. Và đây là một video nhỏ về cách nó hoạt động. Vì vậy, tôi giờ đây, với tư cách là người dùng, có thể nói /worktree, và sau đó tôi sẽ giao cho nó một số task. Tôi sẽ nói, "Sửa lỗi chính tả ở chân trang web." Và tác nhân này sẽ chạy trong một worktree cô lập và thực hiện công việc của nó ở đó. Vì vậy, cách skill được viết thực sự rất đơn giản. Tôi có thể cho bạn thấy hầu hết nó; nó không vừa trên màn hình, nhưng về cơ bản nó là một tập hợp các hướng dẫn nói với mô hình cách tạo worktrees và chạy các setup scripts mà người dùng có thể đã cấu hình, và sau đó duy trì trên bản checkout đó. Chúng tôi muốn đảm bảo rằng khi tác nhân đang hoạt động trên một worktree, nó vẫn ở trong bản checkout đó. Skill "Bessavent" rất tương tự; nó thực ra còn nhỏ hơn. Toàn bộ skill vừa vặn trên màn hình ở đây với phông chữ nhỏ. Và những gì chúng tôi đang làm ở đây là chúng tôi đang hướng dẫn tác nhân cha đi tạo sub-agents cho mỗi mô hình và sau đó khởi tạo một worktree cho mỗi sub-agent, để mỗi tác nhân con tự tạo worktree riêng và làm việc bên trong worktree đó. Và sau đó chúng tôi cũng yêu cầu nó chờ tất cả các sub-agents, và khi chúng hoàn thành, vui lòng cung cấp một số bình luận. Vui lòng cho người dùng biết các implementation khác nhau của các sub-agents khác nhau trông như thế nào. Có thể bạn có thể đánh giá chúng, có thể bạn có thể đưa ra một số phê bình về chúng và có thể bạn có thể giúp người dùng chọn cái nào là tốt nhất. Và vui lòng cung cấp điều đó cho người dùng theo một định dạng ổn định, đẹp mắt hoặc tương tự. Nhưng một lần nữa, nó chỉ khoảng 40 dòng mã và tất cả đều là Markdown. Nó thậm chí không phải là mã nguồn. Và phiên bản trước của điều này có thể là 4.000 dòng mã. Một số cân nhắc mà chúng tôi phải có trong skill này là skill phải cross-platform compatible. Chẳng hạn, chúng tôi có các hướng dẫn dành riêng cho Windows và chúng tôi cũng có các hướng dẫn dành cho Linux và macOS. Chúng tôi cũng hướng dẫn mô hình cha chạy các setup scripts cho mỗi worktree mà người dùng có thể đã cấu hình. Và sau đó đây là phần khó nhất. Chúng tôi sẽ dành một chút thời gian cho phần này trong buổi nói chuyện hôm nay. Chúng tôi phải hướng dẫn mô hình ở lại worktree đó, đúng không? Chúng tôi phải thực sự nói, "Này, đừng bao giờ làm việc bên ngoài cái này và đừng bao giờ thoát ra," đúng không? Và chúng tôi làm điều đó bằng cách aggressive prompting một cách hiệu quả.
Lệnh so với Kỹ năng trong Cursor
Vì vậy, các lệnh mới là /worktree và sau đó /Bessavent để về cơ bản khởi động các tác nhân trong các worktrees cô lập và để khởi động nhiều tác nhân trên cùng một task. Và sau đó chúng tôi cũng có apply worktree và delete worktree để đưa các thay đổi từ worktree phụ sang bản checkout chính của bạn, và delete worktree chỉ làm những gì bạn mong đợi. Một lưu ý nhỏ là đây không thực sự là các skills trong Cursor; chúng thực ra là các lệnh. Nhưng cách các lệnh này hoạt động trong Cursor cực kỳ giống với cách các skills hoạt động, ở chỗ lời nhắc của chúng chỉ được tải vào context nếu người dùng chọn tải chúng. Và lý do duy nhất chúng tôi làm nó dưới dạng lệnh chứ không phải skills là để lời nhắc cho chúng có thể được kiểm soát trong các server của chúng tôi, ở back-end của chúng tôi. Điều này có nghĩa là tôi có thể lặp lại trên các lời nhắc này mà bạn không cần phải cập nhật phiên bản Cursor của mình. Nếu tôi thực hiện một số cải tiến cho các lời nhắc này, lần tới khi bạn sử dụng chúng, bạn sẽ nhận được phiên bản mới nhất của các lời nhắc. Về cơ bản chúng hoạt động giống như skills. Đây là bản demo của skill hoặc lệnh "Bessavent" nơi tôi giao cùng một task cho Kimi, GROQ, Composer, GPT và Opus. Và những gì bạn sẽ thấy là tác nhân cha bắt đầu bằng cách khởi tạo năm sub-agents trên năm mô hình khác nhau mà tôi đã chỉ định, và mỗi tác nhân con sẽ có worktree riêng; mỗi tác nhân con có context riêng. Và sau đó Opus mất nhiều thời gian hơn như mong đợi. Và sau đó, cuối cùng, mô hình cha, theo hướng dẫn, sẽ thực hiện so sánh trên tất cả các sub-agents khác nhau. Nó sẽ nói, "Hai mô hình này về cơ bản đã làm điều tương tự. Mô hình này đã làm điều mà không có mô hình nào khác làm." Và bạn thậm chí có thể nói chuyện với tác nhân cha và bạn có thể nói, "Ồ, tôi thích phần này mà Opus đã làm. Và tôi thích phần này mà GPT đã làm. Bạn có thể ghép chúng lại với nhau không?" Và tác nhân cha sẽ làm điều đó cho bạn.
Ưu điểm của Phiên bản Mới
Vậy, hãy nói về một số pros của implementation mới. Và sau đó tôi sẽ nói về một số cons, một số điều chúng tôi đã mất với refactor này. Vì vậy, pro chính của việc triển khai lại toàn bộ tính năng này dưới dạng một skill là tôi có ít mã nguồn phải duy trì hơn nhiều. Một cách ích kỷ, tôi sẽ dành ít thời gian hơn nhiều để duy trì tính năng này. Và đây là một advanced feature. Chúng tôi không nói về một tính năng được sử dụng bởi 90% người dùng Cursor. Hoàn toàn không. Worktrees là một thứ khá advanced. Và vì vậy, chỉ những power users của Cursor yêu thích việc parallelizing và có những grids of agents này mới sử dụng worktrees. Vì vậy, đây không phải là loại tính năng mà chúng tôi muốn dành nhiều thời gian cho maintenance. Một lợi thế khác là người dùng của chúng tôi giờ đây có thể chuyển sang một worktree giữa chừng một cuộc trò chuyện. Điều đó không thể thực hiện được trước đây. Chúng tôi không muốn làm ô nhiễm prompt UI quá nhiều với tất cả các drop-downs và settings này. Và vì vậy, bây giờ nó chỉ là một slash command, việc người dùng chuyển sang một worktree giữa chừng một cuộc trò chuyện dễ dàng hơn nhiều. Họ có thể bắt đầu nói về điều gì đó và sau đó nếu họ quyết định muốn làm việc trên side, họ có thể làm điều đó với /worktree. Một lợi thế lớn khác là implementation trước đây không hoạt động nếu bạn đang làm việc trên nhiều repo cùng lúc. Vì vậy, rất phổ biến khi có một multi-repo setup nơi có thể front-end và back-end của bạn là các repo riêng biệt. Trong quá khứ, bạn không thể thực hiện worktrees trong loại setup này; nó chỉ bị vô hiệu hóa. Với lệnh /worktree mới, mọi thứ hoạt động tốt. Tác nhân sẽ đảm bảo tạo một worktree trên mỗi repo. Và sau đó nếu bạn mở một PR, nó sẽ mở hai PR, một cho mỗi repo. Nó hoạt động khá tốt. Một lợi thế khác của skill implementation mới là judging experience cuối cùng của việc biết mô hình nào đã làm gì cho "Bessavent" vượt trội hơn nhiều. Tác nhân cha giờ đây có nhiều context hơn về những gì mỗi sub-agents đã làm, và người dùng thậm chí có thể yêu cầu tác nhân ghép nối các phần khác nhau từ các implementation khác nhau, điều mà không thể thực hiện được trước đây trong implementation trước. Bạn phải chọn một sub-agent hoặc một mô hình và chỉ gắn bó với nó.
Nhược điểm của Phiên bản Mới
Bây giờ, hãy nói về một số cons. Và nếu bạn tò mò, chúng tôi có một forums link ở đây, nơi chúng tôi thực sự nhận được một số mixed feedback về implementation mới. Một số người thực sự đã quen với cách hoạt động cũ của tính năng. Và nếu bạn tò mò, bạn có thể vào xem rằng không phải ai cũng hài lòng với sự thay đổi, ít nhất là cho đến bây giờ, nhưng chúng tôi đang theo dõi các vấn đề là gì. Vấn đề số một, rất khó để tác nhân đi đúng hướng. Với cách tiếp cận trước đây của chúng tôi, tác nhân phải đi đúng hướng. Chúng tôi không bao giờ cho phép mô hình chạm vào bất kỳ tệp nào bên ngoài worktree của nó. Việc nó làm như vậy là không thể về mặt vật lý. Bây giờ, chúng tôi đang tin tưởng mô hình. Vì vậy, bạn có thể nói đó là một chút trust-based, bởi vì chúng tôi về cơ bản đang nói, "Này, hoạt động trên thư mục này," và sau đó, kiểu như, "cầu trời phù hộ, xin đừng quên điều này." Và đặc biệt trong các phiên làm việc dài, rất có thể mô hình sẽ quên nơi nó nên hoạt động.
Nhược điểm hiện tại
Đôi khi các mô hình, đặc biệt là những mô hình kém nhất, sẽ tạo ra "ảo giác" (hallucinate) hoặc trở nên mất kiểm soát (haywire) và bắt đầu làm những điều không nên. Nhưng chúng tôi đang khắc phục điều này. Một nhược điểm khác là nó có cảm giác chậm hơn vì bạn thấy tác nhân tạo ra work tree và bạn thấy điều đó trong đoạn chat của mình. Thực tế nó không chậm hơn, nhưng có cảm giác như tác nhân đang lãng phí thời gian làm những việc lẽ ra phải được thực hiện trước.
Khả năng khám phá tính năng
Chúng tôi cũng đang xem xét một số cải tiến ở đây. Cuối cùng, tính năng này giờ đây khó tìm hơn nhiều. Trước đây, mỗi khi bạn mở Cursor, bạn có một trình đơn thả xuống hiển thị tùy chọn chạy tác vụ này cục bộ, trên đám mây (Claude) hay trong work tree. Giờ đây, toàn bộ trình đơn thả xuống đó đã biến mất. Vì vậy, nếu bạn muốn sử dụng work tree, bạn phải biết tính năng này tồn tại để có thể gõ /work tree. Do đó, khả năng khám phá (discoverability) hơi kém hơn. Nhưng như tôi đã đề cập trước đây, đây là một tính năng dành cho người dùng chuyên sâu (power user feature) mà chúng tôi chấp nhận việc nó ít được khám phá hơn nói chung.
Cải thiện kỹ năng Tác nhân
Vậy làm thế nào chúng ta có thể cải thiện kỹ năng này? Như tôi đã đề cập, vấn đề lớn nhất hiện nay là tác nhân không phải lúc nào cũng đi đúng hướng. Có hai cách chúng tôi sẽ cải thiện điều này. Một là với eVals và sau đó sử dụng các eVals đó để cải thiện lời nhắc, và cách còn lại là thông qua RL (Học tăng cường) và huấn luyện (training). Tại Cursor, chúng tôi huấn luyện mô hình riêng của mình có tên Composer. Đối với Composer 2, phiên bản nhẹ nhất của mô hình này, chúng tôi không có bất kỳ tác vụ RL nào với các lời nhắc này. Chúng tôi không có bất kỳ tác vụ nào trong số hàng nghìn tác vụ mà chúng tôi đã sử dụng cho RL thực sự hoạt động trong loại môi trường (environment) này. Vì vậy, chúng tôi đang nỗ lực thêm một loạt các tác vụ này vào quy trình RL (RL pipeline) của mình để đến khi chúng tôi ra mắt Composer 3, 4 hoặc 5, ít nhất mô hình của chúng tôi sẽ tốt hơn nhiều trong việc này. Rõ ràng, chúng tôi không thể cải thiện các mô hình mà các công ty khác đã phát triển, nhưng chúng tôi đã chia sẻ phản hồi với tất cả các phòng thí nghiệm (labs) và nhà cung cấp mô hình (model providers) khác về loại vấn đề này.
Tối ưu hóa bằng eVals
Và đối với eVals, tôi đã làm việc trên một số eVals cho tính năng này và đây thực sự là lần đầu tiên của tôi – hoặc không phải lần đầu tiên, nhưng tôi đang ở giai đoạn khá sớm trong hành trình viết eVals của mình. Và tôi thực sự rất ngạc nhiên rằng nếu bạn sử dụng một công cụ như Brain Trust (và xin cảm ơn Brain Trust, họ đã rất hữu ích), việc viết các loại eVals này thực sự rất, rất dễ dàng. Bạn không cần phải biết hầu hết bất cứ điều gì về eVals và bạn chỉ cần đưa lời nhắc cho tác nhân; nó sẽ làm mọi thứ cho bạn. Về cơ bản, điều tôi đang làm là tôi khởi động Cursor CLI. Nó là headless (không giao diện), vì vậy nó rất tuyệt cho eVals. Và sau đó tôi có hai bộ tính điểm (scorers): một cái kiểm tra xem mô hình có thực hiện bất kỳ công việc nào trong work tree của nó như mong đợi hay không, và một cái khác là ngược lại, tức là mô hình có thực hiện bất kỳ công việc nào trong primary checkout – nơi nó không nên làm việc. Cho đến nay, các eVals mà tôi đã chạy khá đơn giản, vì vậy tôi thực sự chưa thể mô phỏng các phiên (sessions) cực kỳ dài, đó là lúc các mô hình bắt đầu hoạt động kém hơn. Nhưng ngay cả đến nay, tôi đã hiểu rằng không phải tất cả các mô hình đều giỏi như nhau trong việc này. Ví dụ, HIKU, một mô hình nhỏ hơn, kém thông minh hơn, rất thường xuyên lệch hướng (deviate) và bắt đầu làm việc trong primary checkout. Nhưng các mô hình khác mà tôi đã thử nghiệm, chẳng hạn như Composer và GROK, lại hoạt động tốt hơn nhiều. Vì vậy, tôi vẫn phải cải thiện eVals nhiều hơn để làm cho chúng phức tạp hơn. Nhưng hy vọng là ngay khi tôi có thể bắt đầu tìm thấy các mô hình (patterns) ở đây, tôi thực sự có thể cải thiện các lời nhắc.
Hướng phát triển tiếp theo
Và một điều nữa chúng ta có thể làm là đưa ra các lời nhắc hệ thống (system reminders) tốt hơn cho các mô hình, hướng dẫn chúng đi đúng hướng và không lệch hướng khỏi work tree mà chúng được cho là phải làm việc. Được rồi, vậy tiếp theo là gì? Điều đầu tiên là chúng tôi thực sự sẽ lùi lại một bước nhỏ ở đây và sẽ có một triển khai work tree (work tree implementation) đầy đủ và tự nhiên (native) hơn trong cửa sổ tác nhân Cursor (Cursor agent window) mới. Nếu bạn đã theo dõi, chúng tôi gần đây đã công bố Cursor 3.0. Một phần của 3.0 là một giao diện tác nhân (agentic interface) hơn cho viết mã (coding), nơi bạn vẫn có thể chỉnh sửa mã (edit code) và vẫn có thể xem mã (see code), nhưng UI (Giao diện người dùng) và UX (Trải nghiệm người dùng) được tối ưu hóa hơn nhiều xung quanh tác nhân và giao diện trò chuyện (chat interface). Chúng tôi tin rằng loại giao diện này là nơi phù hợp cho một triển khai work tree đúng đắn. Loại người có nhiều khả năng thực hiện nhiều song song hóa cục bộ (local parallelization) thường là cùng một loại người có nhiều khả năng sử dụng loại UI này. Vì vậy, chúng tôi đang lùi lại một bước nhỏ và xây dựng một triển khai work tree đúng đắn, tự nhiên hơn, không quá tác nhân (agentic) trong UI mới.
Giải pháp song song hóa thay thế
Ngoài ra, chúng tôi đang cải thiện kỹ năng như tôi đã đề cập thông qua công việc liên tục về eVals và sau đó là RL cùng các công việc huấn luyện khác. Cuối cùng, chúng tôi thực sự đang tìm hiểu các cơ chế song song hóa (parallelization primitives) khác không phải là Git work tree. Nếu bạn đã sử dụng Git work tree, bạn có thể biết rằng chúng có thể hơi chậm khi tạo và cũng tốn nhiều dung lượng đĩa (disk space) trên máy tính của bạn. Và cuối cùng, chúng chỉ hoạt động với kho lưu trữ Git (Git repos). Vì vậy, nếu bạn đang sử dụng thứ gì đó khác ngoài Git, thực sự không có cơ chế song song hóa cục bộ nào trong Cursor. Trong tương lai gần, chúng tôi hy vọng sẽ chia sẻ thêm về điều này, nhưng chúng tôi đang tìm kiếm một số giải pháp khác cho song song hóa cục bộ không liên quan đến Git và không liên quan đến Git work tree. Vâng, hãy theo dõi để biết thêm. Cảm ơn tất cả các bạn đã đến buổi nói chuyện hôm nay. Tôi chắc rằng nhiều bạn có câu hỏi và tôi sẽ có mặt cả ngày. Hãy cứ tìm tôi bất cứ lúc nào và tôi rất vui được trò chuyện với bất kỳ ai. Cảm ơn.