Xây Dựng Công Cụ Ngăn Chặn Sao Chép Mã Tới ChatGPT
Khi làm việc với ChatGPT, tôi thường cảm thấy mệt mỏi vì phải sao chép từng tệp mã một cách thủ công chỉ để hỏi về mã của mình. Bạn cũng đã trải qua điều này - khi bạn mắc kẹt trong một vấn đề nào đó, bạn dán mã của mình vào, ChatGPT lại yêu cầu xem các import và component cha, rồi bạn lại phải dán thêm một số file khác, và bất chợt bạn đã dành 10 phút chỉ để giới thiệu cho AI về dự án của mình.
Tôi tin rằng phải có một cách tốt hơn. Và tôi đã xây dựng một công cụ như vậy.
Công Cụ Tôi Đã Tạo
Repository Context Packager của tôi là một công cụ dòng lệnh cho phép bạn đóng gói toàn bộ mã nguồn của mình vào một tệp văn bản sạch sẽ, dễ dàng đưa vào bất kỳ cuộc trò chuyện AI nào. Không còn những giải thích rời rạc hay thiếu ngữ cảnh nữa - chỉ cần chạy công cụ và nhận được mọi thứ được định dạng đẹp mắt để AI tiếp nhận.
Đầu Ra Của Công Cụ
Công cụ này sẽ xuất ra:
- Cấu trúc thư mục của dự án của bạn (giống như một cây thư mục đẹp mắt)
- Tất cả các tệp mã của bạn với các khối đánh dấu cú pháp phù hợp
- Thông tin Git nếu bạn muốn (hash commit, nhánh, ai là người chỉnh sửa)
- Một tóm tắt với số lượng tệp và ước lượng token
Xem trên GitHub: [URL của kho lưu trữ của bạn tại đây]
Câu chuyện bắt đầu khi tôi đang làm việc trong một dự án React và liên tục gặp phải những cuộc trò chuyện khó chịu với ChatGPT. Tôi dán một component, nó yêu cầu ngữ cảnh, tôi dán thêm năm tệp nữa, rồi nhận ra rằng tôi quên không bao gồm các tiện ích API... bạn hiểu rồi đấy.
Xây Dựng Công Cụ (Và Những Vấn Đề Gặp Phải)
Tôi quyết định sử dụng TypeScript vì thực sự, JavaScript mà không có kiểu dữ liệu trong một dự án lớn như vậy cảm giác như đang mời gọi rắc rối. Node.js là lựa chọn rõ ràng cho các thao tác trên hệ thống tệp và tích hợp git.
Ý Tưởng Cơ Bản
typescript
// Một lệnh để đóng gói mọi thứ
repo-packager . -o my-code.txt
// Hoặc có thể lọc theo cách thông minh
repo-packager . --include "*.ts,*.jsx" --tokens
Thiết Kế CLI Khó Hơn Bạn Nghĩ
Yêu cầu nói "hỗ trợ nhiều đường dẫn" có vẻ đơn giản cho đến khi bạn nhận ra rằng người dùng có thể làm như sau:
tool .
(thư mục hiện tại)tool file1.js file2.ts
(các tệp cụ thể)tool ./src ./docs
(nhiều thư mục)tool . file.js
(kết hợp)
Tôi đã thử ba cách tiếp cận khác nhau trước khi quyết định xử lý mọi thứ như một mảng:
typescript
// Điều này xử lý tất cả các trường hợp mà không làm tôi mất tâm trí
constructor(paths: string | string[], options = {}) {
this.paths = Array.isArray(paths) ? paths : [paths];
}
Kiểm Tra Thực Tế Hệ Thống Tệp
Đọc tệp có vẻ dễ dàng cho đến khi bạn gặp phải thực tế:
- Còn tệp nhị phân thì sao? (Bỏ qua chúng, nhưng một cách lịch sự)
- Nếu một tệp biến mất trong khi bạn đang đọc nó thì sao? (Bắt lỗi và cảnh báo)
- Thế còn tệp log 500MB? (Cắt ngắn và ghi chú)
- Node_modules với 100k tệp? (Tôn trọng .gitignore, rõ ràng rồi)
Cuối cùng, tôi đã có một cách tiếp cận nhiều lớp sử dụng thư viện glob
:
typescript
const files = await glob(patterns, {
cwd: repoPath,
nodir: true,
ignore: ['node_modules/**', '.git/**', ...gitignorePatterns]
});
Thư viện glob đã cứu tôi khỏi việc phải viết mã duyệt thư mục của riêng mình, điều này có thể dẫn đến rất nhiều vấn đề.
Những Khó Khăn Trong Tích Hợp Git
Lấy thông tin git có vẻ đơn giản - chỉ cần chạy một số lệnh git, đúng không? Chà, không hẳn:
typescript
const commit = execSync('git rev-parse HEAD', options).toString().trim();
Điều này hoạt động rất tốt... cho đến khi ai đó chạy công cụ của bạn trong một thư mục không phải là kho git. Hoặc trong một kho không có commits. Hoặc trên Windows, nơi mà các đường dẫn hoạt động khác. Tôi đã dành quá nhiều thời gian để làm cho điều này trở nên mạnh mẽ, nhưng đó là điều phân biệt giữa "chạy tốt trên máy của tôi" và "thực sự hữu ích."
Những Điều Tôi Thực Sự Học Được
Công Cụ CLI Là Khác Biệt
Xây dựng một công cụ dòng lệnh đúng cách đã dạy tôi những điều mà tôi không mong đợi:
- Chỉ đầu ra thực tế của bạn nên được gửi tới stdout. Thông điệp, cảnh báo, cập nhật tiến độ? Tất cả đều vào stderr.
- Người dùng mong đợi
--help
và--version
hoạt động. Đừng làm họ thất vọng. - Mã thoát là quan trọng. 0 cho thành công, bất kỳ giá trị nào khác cho vấn đề.
- Thông điệp lỗi nên cho người dùng biết điều gì đã sai và họ có thể làm gì để khắc phục.
Thao Tác Tệp Ở Quy Mô Lớn
Tôi đã đọc tệp trước đây, nhưng chưa bao giờ hàng trăm tệp cùng một lúc. Điều này đã dạy tôi:
- Luôn sử dụng async/await cho các thao tác tệp (chặn vòng lặp sự kiện là không lịch sự)
- Bộ nhớ tăng nhanh khi bạn giữ toàn bộ mã nguồn trong RAM
- Quyền truy cập tệp là một vấn đề thực sự mà bạn cần lưu ý
- Xử lý đường dẫn đa nền tảng là phiền phức nhưng cần thiết
Git Là Hơn Cả Kiểm Soát Phiên Bản
Sử dụng các lệnh git trong mã là một sự thức tỉnh. Git không chỉ để lưu trữ công việc của bạn - nó là một cơ sở dữ liệu về lịch sử dự án:
typescript
const author = execSync('git log -1 --pretty=format:\'%an <%ae>\'').toString().trim();
const date = execSync('git log -1 --format=%cd').toString().trim();
Có rất nhiều metadata bị khóa trong các kho git mà hầu hết các công cụ đều bỏ qua.
Sử Dụng Trong Cuộc Sống Thực
Kể từ khi hoàn thành công cụ này, tôi đã sử dụng nó liên tục:
- Gỡ lỗi hành vi kỳ lạ của hook React? Đóng gói toàn bộ cây component và hỏi Claude.
- Chuẩn bị cho việc xem xét mã? Tạo một tệp ngữ cảnh và tự xem xét trước.
- Tham gia một dự án mới? Đóng gói nó và hỏi ChatGPT để giải thích kiến trúc.
Tính năng đếm token đã chứng minh là cực kỳ hữu ích. Biết rằng mã nguồn của tôi có 8.000 token giúp tôi lập kế hoạch các cuộc trò chuyện với ChatGPT tốt hơn.
Kế Hoạch Tương Lai
Tôi có rất nhiều ý tưởng cho nơi có thể phát triển công cụ này:
- Định Dạng Đầu Ra Tốt Hơn: Có thể là HTML với các phần có thể thu gọn, hoặc JSON để các công cụ khác có thể sử dụng.
- Lựa Chọn Thông Minh: Sử dụng một số heuristics cơ bản để gợi ý các tệp nào là phù hợp nhất cho các loại câu hỏi khác nhau.
- Tích Hợp Trực Tiếp: Bỏ qua bước sao chép-dán hoàn toàn - tải trực tiếp lên ChatGPT hoặc Claude APIs.
- Phân Tích Thay Đổi: So sánh các nhánh và làm nổi bật những gì khác biệt, hữu ích cho việc xem xét mã.
Chia Sẻ Thực Tế Với Các Nhà Phát Triển Khác
Một vài điều tôi ước mình biết khi bắt đầu:
- Bắt đầu từ điều đơn giản. Tôi bắt đầu với việc đọc tệp cơ bản và thêm tính năng từng bước một. Cách tiếp cận "mọi thứ một lúc" không bao giờ hiệu quả.
- Kiểm tra trên chính dự án của bạn thường xuyên. Tôi đã sử dụng công cụ này trên các dự án của mình trong quá trình xây dựng, điều này đã phát hiện ra rất nhiều trường hợp ngoại lệ.
- Thông điệp lỗi là tính năng sản phẩm. Khi điều gì đó bị lỗi, một thông điệp lỗi tốt có thể tạo ra sự khác biệt giữa việc người dùng tự sửa chữa hay từ bỏ.
- Tài liệu không phải là tùy chọn. Tôi đã viết README trước khi viết một nửa mã, điều này giúp tôi suy nghĩ về trải nghiệm người dùng.
- Công cụ chỉ tốt khi được áp dụng. Mã tốt nhất trên thế giới không quan trọng nếu mọi người không thể tìm ra cách sử dụng nó.
Tại Sao Điều Này Quan Trọng Với Tôi
Dự án này kết hợp nhiều công nghệ mà tôi muốn cải thiện (TypeScript, thao tác tệp Node.js, thiết kế CLI) trong khi giải quyết một vấn đề thực sự làm tôi khó chịu mỗi ngày. Đó là vị trí ngọt ngào - khi bạn đang học hỏi những điều mới và giải quyết vấn đề cá nhân cùng một lúc.
Điều tuyệt vời nhất là sử dụng nó trong công việc thực tế. Có điều gì đó thật thỏa mãn khi một công cụ bạn xây dựng trở thành một phần trong quy trình làm việc hàng ngày của bạn. Nó không phải là phần mềm cách mạng, nhưng nó tiết kiệm cho tôi thời gian mỗi tuần, và điều đó cộng lại.
Xây dựng các công cụ cho nhà phát triển thật thú vị bởi vì bạn đang xây dựng cho những người nghĩ giống bạn. Họ sẽ thử các trường hợp ngoại lệ kỳ lạ, đọc kỹ thông điệp lỗi của bạn, và nhận thấy khi mọi thứ chỉ hơi bị sai. Điều đó giúp bạn trở thành một lập trình viên tốt hơn khi có những người dùng như vậy.
Hãy Thử Ngay
Nếu bạn đang nghĩ về việc xây dựng các công cụ CLI, hãy bắt đầu với một thứ nhỏ mà làm phiền bạn cá nhân. Các thao tác tệp, xử lý văn bản, tích hợp git - Node.js làm cho tất cả những điều này trở nên dễ tiếp cận, và TypeScript giữ bạn trung thực.
Công cụ của tôi là mã nguồn mở, vì vậy hãy lấy nó và xem nó có hữu ích không. Và nếu bạn xây dựng một thứ gì đó tuyệt vời để giải quyết vấn đề của riêng mình, hãy cho tôi biết - tôi luôn tò mò về những vấn đề mà các nhà phát triển khác đang giải quyết.
GitHub: Repo-Context-Packager. Tôi biết rằng có thể hơi tệ, tôi sẽ làm việc về điều đó sau.
Toàn bộ trải nghiệm này đã nhắc nhở tôi lý do tôi bắt đầu lập trình ngay từ đầu - bạn thấy một cái gì đó có thể hoạt động tốt hơn, và bạn có thể... xây dựng nó. Điều đó không bao giờ cũ.
Có câu hỏi về mã hoặc ý tưởng cải tiến? Liên hệ với tôi tại Clevertag. Tôi luôn vui mừng để nói về các công cụ cho nhà phát triển và thiết kế CLI.