0
0
Lập trình
NM

Kinh Nghiệm Phát Triển Dựa Trên Spec: Xây Dựng Ứng Dụng Coxy

Đăng vào 4 ngày trước

• 11 phút đọc

Kinh Nghiệm Phát Triển Dựa Trên Spec: Xây Dựng Ứng Dụng Coxy

Giới Thiệu

Trong thời đại công nghệ hiện nay, phát triển phần mềm không chỉ là việc viết mã mà còn là một quy trình tổng thể bao gồm việc lập kế hoạch, thiết kế và thực hiện. Trong bài viết này, tôi sẽ chia sẻ về kinh nghiệm của mình khi áp dụng phương pháp phát triển dựa trên đặc tả (spec-driven development) để xây dựng ứng dụng Coxy, một phiên bản hoàn thiện của dự án copilot-proxy trước đây. Tôi sẽ trình bày lý do tại sao tôi quyết định viết lại dự án, chiến lược phát triển của mình, cũng như những bài học quý giá mà tôi đã học được trong quá trình này.

Tại Sao Tôi Viết Lại Dự Án Copilot-Proxy

Giới Hạn Kỹ Thuật Của Dự Án Gốc

Dự án copilot-proxy ban đầu được xây dựng bằng SolidStart, một lựa chọn có vẻ tốt nhưng đã tạo ra nhiều thách thức:

  • Vấn Đề Về Độ Trưởng Thành Của Framework: SolidStart nhẹ và hiệu suất cao, nhưng hệ sinh thái của nó không trưởng thành bằng Next.js. Tôi đã tốn nhiều thời gian để gỡ lỗi quy trình xây dựng và làm việc quanh những hạn chế của framework thay vì tập trung vào các tính năng.
  • Vấn Đề Kiến Trúc Monolithic: Tôi đã kết hợp phần frontend và backend trong một mã nguồn duy nhất, ban đầu có vẻ hiệu quả nhưng nhanh chóng trở nên rối rắm. Khi các tính năng quản lý proxy trở nên phức tạp hơn, việc duy trì sự tách biệt rõ ràng giữa logic API và các thành phần UI trở nên khó khăn.
  • Cảm Giác Phát Triển Không Liên Tục: Quy trình xây dựng không thể đoán trước, quản lý phụ thuộc phức tạp và quy trình phát triển cảm thấy bị phân mảnh.

Cơ Hội Cho Phát Triển Dựa Trên Spec

Ngoài việc giải quyết các hạn chế kỹ thuật, tôi muốn thử nghiệm phương pháp phát triển dựa trên đặc tả. Phương pháp này hứa hẹn nhiều lợi ích:

  • Định Nghĩa Yêu Cầu Rõ Ràng trước khi viết mã.
  • Hợp Tác Tốt Hơn Với AI thông qua các đặc tả có cấu trúc.
  • Kiến Trúc Dễ Duy Trì Hơn với các quyết định đã được tài liệu hóa.
  • Cách Tiếp Cận Hệ Thống Để Phát Triển Tính Năng giúp giảm thiểu việc mở rộng phạm vi.

Việc viết lại đã tạo ra cơ hội hoàn hảo để áp dụng những phương pháp này từ đầu, thay vì cố gắng thêm chúng vào mã nguồn hiện có.

Chiến Lược Phát Triển Dựa Trên Spec

Triết Lý Lấy Quy Trình Làm Trung Tâm: Tránh Khóa Công Cụ

Chiến lược cốt lõi của tôi tập trung vào tối ưu hóa quy trình phát triển thay vì lựa chọn công cụ. Triết lý này nhằm tránh khóa công cụ với các công cụ AI cụ thể như Cursor hay Claude Code, có thể giới hạn tính linh hoạt khi các công cụ mới xuất hiện.

Các nguyên tắc chính tôi đã thiết lập:

  • Tôi xác định quy trình, công cụ sẽ thích nghi để phục vụ quy trình.
  • Tài liệu điều khiển việc thực hiện, không phải ngược lại.
  • Đặc tả không phụ thuộc vào công cụ cho phép chuyển đổi giữa các trợ lý AI.
  • Kiến trúc mô-đun hỗ trợ các phương pháp phát triển khác nhau.

Cách tiếp cận này có nghĩa là đầu tư thời gian vào việc thiết kế quy trình từ đầu, biết rằng tôi có thể tối ưu hóa lựa chọn công cụ sau mà không cần cấu trúc lại toàn bộ quy trình phát triển.

Lợi Ích Của Phát Triển Lấy Quy Trình Làm Trung Tâm

Cách tiếp cận lấy quy trình làm trung tâm đã mang lại ba lợi ích chính: kiến trúc sạch hơn thông qua việc lập kế hoạch trước, gỡ lỗi nhanh hơn với các quy trình có hệ thống, và dễ dàng chuyển đổi công cụ khi có các tùy chọn tốt hơn xuất hiện.

Triển Khai: Từ Kiến Trúc Đến Tính Năng

Nx Monorepo: Cấu Trúc Dự Án Có Thể Mở Rộng

Tôi đã chọn Nx làm nền tảng cho kiến trúc của Coxy, chủ yếu để đạt được sự tách biệt rõ ràng giữa frontend và backend mà dự án copilot-proxy gốc gặp phải.

Các quyết định kiến trúc chiến lược:

Copy
coxy/
├── apps/
│   ├── frontend/                # Frontend Next.js
│   ├── backend/                 # Backend Nest.js
│   └── frontend-e2e/            # Kiểm thử end-to-end
├── libs/
│   ├── shared/              # Tiện ích đa nền tảng
│   ├── ui/                  # Thư viện thành phần React
│   ├── logger/              # Ghi log trung tâm
│   └── types/               # Định nghĩa TypeScript
└── ...

Tại sao cấu trúc này hoạt động cho Coxy:

  • Ranh giới rõ ràng giữa UI quản lý proxy và logic API.
  • Thư viện chia sẻ loại bỏ việc sao chép mã giữa các ứng dụng.
  • Triển khai độc lập cho dịch vụ frontend và backend.
  • Nền tảng có thể mở rộng hỗ trợ kiến trúc microservices trong tương lai.

Tối Ưu Hóa Công Cụ: Biome Thay Cho ESLint/Prettier

Tôi đã thay thế ESLint và Prettier bằng Biome để có hiệu suất tốt hơn và cấu hình đơn giản hơn. Biome đã giảm độ phức tạp của thiết lập xuống 70%, cải thiện thời gian xây dựng và yêu cầu ít phụ thuộc hơn để quản lý. Việc di chuyển rất đơn giản với các lợi ích về hiệu suất ngay lập tức.

Phát Triển Dựa Trên Spec: Tài Liệu USER_STORY.md

Theo các nguyên tắc phát triển dựa trên đặc tả, tôi đã tạo các tài liệu USER_STORY.md toàn diện cho mỗi tính năng của Coxy. Những tài liệu này trở thành nền tảng cho tất cả các hoạt động phát triển.

Ví dụ về quản lý cấu hình proxy:

Copy
# User Story 1: Điểm Cuối Proxy Tương Thích Với OpenAI

Là một nhà phát triển sử dụng các công cụ tương thích với OpenAI, tôi muốn gửi yêu cầu đến một máy chủ proxy chuyển tiếp chúng tới GitHub Copilot để tôi có thể sử dụng GitHub Copilot thông qua các giao diện tương thích với OpenAI hiện có.

## Tiêu Chí Chấp Nhận (EARS):
- **Giả sử** một yêu cầu hợp lệ tương thích với OpenAI, **khi** gửi đến `/chat/completions`, **thì** chuyển tiếp đến API của GitHub Copilot.
- **Giả sử** một khoá API không hợp lệ, **khi** thực hiện yêu cầu, **thì** trả về `401 Unauthorized`.
- **Giả sử** một yêu cầu sai định dạng, **khi** gửi đến proxy, **thì** trả về `400 Bad Request` với lỗi xác thực.
- **Nơi** hệ thống hoạt động như một proxy trong suốt giữa các khách hàng OpenAI và GitHub Copilot.

---

# User Story 2: Bảng Điều Khiển Quản Trị

Là một quản trị viên hệ thống, tôi muốn có một giao diện quản trị để theo dõi và cấu hình proxy để tôi có thể quản lý việc sử dụng API, xem nhật ký và cấu hình các thiết lập.

## Tiêu Chí Chấp Nhận (EARS):
- **Giả sử** xác thực quản trị, **khi** truy cập `/admin`, **thì** hiển thị bảng điều khiển với thống kê sử dụng.
- **Giả sử** các yêu cầu proxy, **khi** xảy ra, **thì** ghi lại chúng để quản trị viên xem xét.
- **Giả sử** có thay đổi cấu hình, **khi** được gửi qua bảng điều khiển quản trị, **thì** cập nhật hành vi của proxy.
- **Nơi** quyền truy cập quản trị được bảo vệ bằng xác thực.

Hướng Dẫn Prompt Hệ Thống Toàn Dự Án: Ràng Buộc Phát Triển

Tôi đã tạo một prompt hệ thống toàn diện phục vụ như cả ràng buộc và hướng dẫn phát triển cho sự hỗ trợ của AI trong toàn bộ dự án:

Copy
# Prompt Hệ Thống Tái Cấu Trúc Dự Án Nx

## 1. Persona
Bạn là một kiến trúc sư phần mềm cao cấp và chuyên gia Nx với kinh nghiệm sâu sắc trong quản lý monorepo, tối ưu hóa phụ thuộc và tái cấu trúc quy mô lớn. Bạn có kiến thức sâu sắc về:
- Kiến trúc workspace Nx và các thực tiễn tốt nhất
- Hệ sinh thái TypeScript/JavaScript và công cụ
- Mô hình thiết kế micro-frontend và thư viện
- Tối ưu hóa xây dựng và quản lý đồ thị phụ thuộc
- Chiến lược di chuyển mã cho monorepos

## 2. Tuyên Bố Nhiệm Vụ
Phân tích và tái cấu trúc mã trong một workspace Nx để cải thiện khả năng bảo trì, hiệu suất và tuân thủ các thực tiễn tốt nhất của Nx trong khi vẫn bảo tồn chức năng và giảm thiểu thay đổi gây hỏng.

## 3. Bối Cảnh
Bạn đang làm việc trong một monorepo Nx có thể chứa:
- Nhiều ứng dụng (React, Angular, Node.js, v.v.)
- Các thư viện và tiện ích chung
- Các phụ thuộc phức tạp giữa các dự án
- Cấu hình xây dựng và công cụ hiện có
- Các quy ước và tiêu chuẩn mã hóa của nhóm
- Các quy trình CI/CD phụ thuộc vào cấu trúc hiện tại

Quy Trình Phát Triển Hỗ Trợ AI

Hướng Dẫn Prompt LLM Cấu Trúc

Tôi đã phát triển một cách tiếp cận hệ thống để tạo các prompt cụ thể cho từng tính năng sử dụng "Hướng Dẫn Prompt LLM Cấu Trúc". Quy trình này bao gồm:

  1. Phân Tích USER_STORY.md để trích xuất các yêu cầu chính.
  2. Cung cấp Hướng Dẫn Prompt LLM Cấu Trúc cho Claude để tinh chỉnh.
  3. Tạo các prompt cụ thể cho từng tính năng phù hợp với nhu cầu quản lý proxy.
  4. Kiểm Tra Các Prompt Trên Các Công Cụ AI Khác Nhau để đảm bảo tính nhất quán.

Chiến Lược Triển Khai AI Đa Công Cụ

Tôi đã sử dụng Rovo Dev và Gemini CLI làm công cụ triển khai chính, được chọn vì các mô hình LLM hiện đại và mức quota miễn phí hào phóng của chúng.

Quy trình phát triển:

  1. Xem Lại Kế Hoạch: AI tạo kế hoạch triển khai dựa trên USER_STORY.md.
  2. Xác Thực Kiến Trúc: Xem xét thủ công đảm bảo sự phù hợp với cấu trúc Nx.
  3. Triển Khai Từng Bước: Tạo mã với sự giám sát thường xuyên của con người.
  4. Giải Quyết Lỗi: Gỡ lỗi có hệ thống với sự hỗ trợ của AI.

Bài Học Rút Ra: Những Gì Hoạt Động Và Những Gì Không

Những Gì Hoạt Động Tốt

  • Hiểu biết từ trên xuống đã biến đổi cách tiếp cận phát triển của tôi. Phát triển dựa trên đặc tả buộc tôi phải suy nghĩ có hệ thống về yêu cầu và kiến trúc trước khi triển khai, dẫn đến các quyết định tốt hơn và các tính năng gắn kết hơn.
  • AI đã phát hiện ra những điều chưa biết trong quá trình lập kế hoạch. Khi tạo các đặc tả quản lý proxy, AI đã xác định các trường hợp biên, những cân nhắc về bảo mật và tối ưu hóa hiệu suất mà tôi chưa nghĩ đến.
  • Các đặc tả có cấu trúc thúc đẩy nhanh quá trình phát triển. Các tài liệu USER_STORY.md toàn diện đã cho phép các công cụ AI tạo mã ban đầu chất lượng cao hơn.

Những Thách Thức Cần Thích Ứng

  • Chuyển đổi công cụ tạo ra gánh nặng tinh thần. Quản lý các công cụ AI khác nhau yêu cầu năng lượng mà đáng lẽ tôi có thể dành cho phát triển. Tôi đã học được cách nhóm các nhiệm vụ tương tự trong các công cụ duy nhất.
  • Tài liệu trở thành một dự án riêng. Tổ chức các đặc tả và prompt yêu cầu thời gian và cách tiếp cận có hệ thống.
  • Chi phí tăng nhanh. Quota của các công cụ AI đôi khi bị cạn kiệt nhanh hơn dự kiến.

Kết Luận: Phát Triển Cùng AI, Không Đầu Hàng Trước Nó

Việc xây dựng Coxy với phát triển dựa trên đặc tả đã dạy tôi rằng sự hợp tác với AI hoạt động tốt nhất khi con người duy trì quyền sở hữu kiến trúc trong khi tận dụng AI để tăng tốc độ thực hiện. Thay vì giao hoàn toàn quyền kiểm soát cho các công cụ AI, cách tiếp cận dựa trên đặc tả đã giúp tôi phát triển cùng với khả năng của AI.

Câu Hỏi Thường Gặp

1. Phát triển dựa trên đặc tả là gì?
Phát triển dựa trên đặc tả là phương pháp lập kế hoạch và phát triển phần mềm bằng cách xác định rõ ràng các yêu cầu trước khi viết mã.

2. Tại sao nên sử dụng phương pháp này?
Phương pháp này giúp tăng cường sự hợp tác giữa con người và AI, đảm bảo tính nhất quán và tăng tốc độ phát triển.

3. Có những công cụ nào hỗ trợ phát triển dựa trên đặc tả?
Có nhiều công cụ hỗ trợ như Rovo Dev, Gemini CLI và các công cụ AI khác có thể giúp tạo mã dựa trên đặc tả.

Kêu Gọi Hành Động

Nếu bạn đang tìm kiếm cách cải thiện quy trình phát triển của mình, hãy thử áp dụng phương pháp phát triển dựa trên đặc tả. Hãy theo dõi những cập nhật mới nhất từ chúng tôi để có thêm nhiều kiến thức bổ ích!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào