So sánh CadQuery và OpenSCAD: Công cụ nào tốt hơn cho CAD do AI tự động thực hiện?

Công nghệ12 tháng 9, 2026·15 phút đọc

Một thử nghiệm có kiểm soát giữa CadQuery và OpenSCAD cho thấy cả hai đều tạo ra được các bộ phận in được, nhưng khác biệt lớn nhất nằm ở cách chúng thất bại. CadQuery báo lỗi rõ ràng và sớm, trong khi OpenSCAD âm thầm thất bại muộn — điều đặc biệt quan trọng khi AI vận hành không có người giám sát.

So sánh CadQuery và OpenSCAD: Công cụ nào tốt hơn cho CAD do AI tự động thực hiện?

ModelRift vốn sử dụng OpenSCAD để tạo mọi mô hình trên nền tảng của mình. Nhưng lựa chọn đó đáng được kiểm tra lại định kỳ, nên nhóm đã thực hiện một so sánh có kiểm soát với đối thủ đáng tin cậy nhất trong lĩnh vực CAD dựa trên mã nguồn: CadQuery, thư viện Python chạy trên nhân B-rep OpenCascade.

Câu hỏi đặt ra rất hẹp: công cụ nào mà một tác nhân AI có thể tự điều khiển để tạo ra chi tiết chính xác, in được và có chức năng, mà không cần ai theo dõi? Việc viết tay bằng công cụ nào dễ chịu hơn không được tính đến.

Sáu tác nhân, ba nhiệm vụ, hai công cụ. Mọi file STL tạo ra sau đó đều được kiểm tra bởi một trình phân tích không tin tưởng vào công cụ nào cả.

Kết quả: cả sáu chi tiết đều in được. Năng lực hoá ra lại là phần nhàm chán nhất của câu trả lời. Điểm khác biệt thực sự nằm ở cách hai công cụ thất bại.

Nhiệm vụ khó nhất trong bộ đề, được cả hai công cụ giải quyết. OpenSCAD bên trái, CadQuery bên phảiNhiệm vụ khó nhất trong bộ đề, được cả hai công cụ giải quyết. OpenSCAD bên trái, CadQuery bên phải

Thiết lập thử nghiệm

Cả sáu lần chạy đều do Claude Opus 5 (ngữ cảnh 1M) điều khiển thông qua Claude Code. Mỗi ô chạy là một tác nhân con đa dụng riêng biệt kế thừa cùng một mô hình, không có trao đổi chéo giữa chúng. Một tác nhân cho mỗi ô, nên một phần độ phân tán bên dưới là do biến động của tác nhân chứ không phải do khác biệt công cụ. Phiên bản công cụ là CadQuery 2.8.0 trên Python 3.14 và OpenSCAD 2026.06.12, cả hai chạy trên máy Mac dòng M.

Phía OpenSCAD chạy trên skill openscad-skill của chính nhóm — kỹ năng tác nhân mà họ công bố và sử dụng nội bộ. Skill này bao gồm quy tắc đặt tên file và phiên bản, vòng lặp QA render-quan sát-sửa lỗi, các preset camera cho preview qua CLI, debug bằng mặt cắt, và cú pháp Customizer.

Với CadQuery, nhóm đã chuyển đổi skill đó từng thao tác một, giữ nguyên cấu trúc và chỉ thay những gì không có tương đương trong OpenSCAD. CadQuery không có trình render qua CLI, nên bản chuyển đổi cần một trình render offscreen nhỏ viết riêng, cùng các chỉ số hợp lệ B-rep thay cho dòng trạng thái CSG. Sau đó cả hai file đều nhận cùng bộ quy tắc thiết kế in 3D — độ dày thành, khe hở và góc nhô — để không bên nào được cung cấp lời khuyên mà bên kia thiếu. Kích thước lần lượt là 12,4 KB cho OpenSCAD và 13,1 KB cho CadQuery.

Một điểm bất đối xứng vẫn còn: file CadQuery mang theo bảng tra cứu API mà file OpenSCAD không cần, vì mô hình đã biết cú pháp OpenSCAD khá tốt. Điều này giúp CadQuery về cú pháp nhưng không giúp gì về hình học.

Mỗi tác nhân bị giới hạn tối đa 12 phiên bản, được yêu cầu không bao giờ giả vờ thành công, và phải báo cáo mọi thất bại kèm nguyên văn thông báo lỗi. Chúng chạy hoàn toàn không giám sát.

Nhóm không tin vào lời tác nhân nói. Mọi STL cuối cùng đều đi qua một trình phân tích đọc trực tiếp file và báo cáo số tam giác, hộp bao, thể tích, độ kín nước, cạnh non-manifold và biên, mặt bị lật, và số thành phần liên thông. Điều này hoá ra quan trọng hơn dự kiến, vì lý do sẽ trình bày bên dưới.

Ba nhiệm vụ

Cả hai tác nhân trong một nhiệm vụ đều nhận cùng một đoạn văn, không có gợi ý riêng cho từng công cụ.

Nhiệm vụ đơn giản T1 là một giá đỡ chữ L gắn tường: hai tấm vuông góc dày 4 mm, hai gân tam giác, hai lỗ khoét chìm cho vít đầu bằng ở góc 90 độ và đường kính đầu 9 mm, hai lỗ trơn, bán kính R3 ở các góc ngoài thẳng đứng, fillet R4 ở góc trong, in được không cần đỡ.

T2 nâng độ khó lên thành vỏ hộp snap-fit hai phần cho bo mạch 50 x 26 mm. Thành dày 2 mm, khe hở khoang 0,4 mm mỗi bên, bốn trụ M2, một khe cắm USB-C 9,5 x 3,5 mm, nắp riêng có gờ viền khe hở 0,2 mm và các chốt snap hoạt động được, năm khe thông gió. Hai phần phải thực sự khớp nhau.

T3 là bài khó nhất: một adapter đầu vòi ren M24x2 với mặt bích lục giác 30 mm across flats, ren xoắn ốc thật dài 12 mm, đầu vòi dài 25 mm mang ba gờ cho ống có đường kính trong 12 mm, và một kênh xuyên suốt 8 mm. Đề bài cấm rõ ràng việc xếp chồng các vòng tròn. Ren phải là hình học xoắn ốc thật.

Kết quả

Tổng hợp qua cả ba nhiệm vụ:

  • Số phiên bản: cả OpenSCAD và CadQuery đều là 11
  • Số dòng mã: OpenSCAD 473, CadQuery 573
  • Lỗi công cụ báo ra: OpenSCAD 2, CadQuery 5
  • Lỗi hình học âm thầm: OpenSCAD 5, CadQuery 4
  • Thời gian tác nhân (giây): OpenSCAD 2061, CadQuery 2406
  • Token tác nhân: OpenSCAD 297k, CadQuery 347k

"Clean" nghĩa là kín nước, một thành phần liên thông, không có cạnh non-manifold hay biên, nằm trên mặt z = 0, được đo từ file chứ không phải do công cụ viết nó báo cáo.

Số vòng lặp hoá ra giống hệt nhau ở 11 phiên bản mỗi bên. Hình dáng tổng thể của nỗ lực cũng vậy. Điều khác biệt là tính chất của các vấn đề mà mỗi tác nhân gặp phải.

T1: Giá đỡ đơn giản

Cả hai đúng, được nhìn từ góc trong để thấy các gân. Khác biệt thị giác nằm ở cách hiểu đề: đề bài để mở kích thước gân và khoảng lùi.

Việc bo tròn bốn góc ngoài phân tách rõ ràng hai mô hình của thế giới. OpenSCAD bo một biên dạng 2D rồi ép đùn, nên thao tác không quan tâm khối rắn được lắp ráp thế nào. CadQuery phải gọi tên bốn cạnh trước, và việc gọi tên mới là phần khó.

OpenSCAD biên dịch hình học đúng ngay lần thử đầu và kết thúc trong hai phiên bản. CadQuery dành khoảng một phần ba thời gian chạy cho một lỗi duy nhất: lệnh .fillet(3.0) thất bại với thông báo BRep_API: command not done — một thông báo không nêu tên cạnh cũng không nêu bán kính. Tác nhân phải tự chia đôi để tìm nguyên nhân, hoá ra là số học: hai fillet R3 không vừa trong bức thành dày 4 mm.

T2: Hai phần phải khớp nhau

Cả hai tác nhân đều suy ra cùng một hộp 54,8 x 30,8 x 25,0 mm từ chuỗi khe hở.

Đây là lúc chuỗi tham số của CadQuery phát huy tác dụng. Thay đổi độ sâu gờ viền làm dịch chuyển đồng thời viền, tấm, khe, rãnh và chốt, vì mỗi kích thước được suy ra chứ không gõ lại hai lần. Kiểu chuỗi kích thước này chính là thứ mà một giao diện tham số tốt phơi ra cho người dùng.

Điều thú vị hơn là cách mỗi bên kiểm tra độ khớp. OpenSCAD in ra các con số để ai đó đọc. CadQuery dùng assert, và quá trình build dừng lại khi assert sai. Một lệnh echo chỉ hữu ích nếu có ai đó đọc nó. Một assert tự làm build thất bại. Với việc tạo tự động không giám sát, khoảng cách đó là phần lớn của câu chuyện.

OpenSCAD cần tám phiên bản so với năm của CadQuery, và ba trong số tám phiên bản đó dành cho việc dọn dẹp boolean chứ không phải thiết kế: dọn các mảnh vụn sinh ra từ các mặt tiếp xúc và trùng nhau.

T3: Ren thật

Bài khó tạo ra kết quả bất ngờ lớn nhất. OpenSCAD hoàn thành trong một phiên bản duy nhất, đúng ngay lần biên dịch đầu, trong 43 ms, không dùng thư viện.

OpenSCAD không có thao tác sweep, nên tác nhân viết đường xoắn ốc bằng số học đỉnh và mặt thô: một biên dạng ISO bốn điểm, 96 mặt cắt mỗi vòng, xuất ra như một polyhedron duy nhất. Trong đoạn mã này hoàn toàn không có lan can bảo vệ. Nếu đảo sai thứ tự quấn, công cụ không nói gì cả.

Tác nhân còn đoán trước được cái bẫy kinh điển của ren trước khi viết dòng nào: một răng ISO kéo dài đúng một bước ren, nên các mặt phẳng chân răng liên tiếp nằm đồng phẳng và phép hợp nhất sẽ hỏng. Nó nhấn chìm biên dạng swept xuống dưới bán kính chân ren để đường xoắn cắt qua lõi thay vì chỉ chạm vào. Đó là lý do phép boolean diễn ra suôn sẻ.

CadQuery diễn đạt cùng hình học đó trong sáu dòng dễ đọc, và phần đó chạy được ngay lần đầu. Nhưng thất bại đến ở dòng cuối cùng, và đây là kết quả đã thay đổi cách nhóm nghĩ về vòng lặp QA.

Lệnh union() âm thầm loại bỏ trụ lõi vì chân ren nằm chính xác trên bán kính lõi. Tiếp xúc chính xác dọc theo một đường xoắn ốc, và OCCT đã bỏ đi một khối rắn mà không nói một lời. Nhìn từ bên ngoài, chi tiết trông hoàn hảo. Tác nhân đọc bốn bản render mà không nhận ra. Thứ phát hiện được là phép đo thể tích: 7065 mm³ trong khi kỳ vọng là 10323 mm³.

Tệ hơn, chi tiết hỏng vẫn báo valid=Truesolids=1. Tăng dung sai boolean lên 1e-3 tạo ra một khối rắn có thể tích âm cũng báo valid=True.

OpenSCAD cũng không vô can ở đây. Trong T2, backend Manifold của nó chứng nhận Status: NoError cho một STL mang 4 cạnh non-manifold và 60 tam giác diện tích bằng không. Báo cáo tự thân của cả hai công cụ đều không phải lời cuối cùng, đó là lý do nhóm tự phân tích từng lưới.

Cả hai đều hoàn thành ren. Các đỉnh răng ở sườn trái lệch nửa bước ren so với sườn phải — dấu hiệu của một đường xoắn ốc đơn khởi thật, và cũng là phép kiểm tra phân biệt ren thật với các vòng xếp chồng.

Ren thật được tạo ra bởi cả hai công cụRen thật được tạo ra bởi cả hai công cụ

Tải các chi tiết

Đây là tám lưới cuối cùng, đúng như các tác nhân xuất ra, không qua dọn dẹp hay sửa chữa gì từ phía nhóm. STL nhị phân, đơn vị mm, định hướng để in với chi tiết nằm trên z = 0.

  • Giá đỡ T1: OpenSCAD 2660 tam giác, CadQuery 4232 tam giác
  • Vỏ hộp T2: OpenSCAD 2944 tam giác, CadQuery 14136 tam giác
  • Nắp hộp T2: OpenSCAD 2960 tam giác, CadQuery 1872 tam giác
  • Adapter ren T3: OpenSCAD 10754 tam giác, CadQuery 13748 tam giác

Cả tám đều kín nước, một thành phần liên thông, không cạnh non-manifold, không cạnh biên và không mặt bị lật. Khe hở giả định in FDM với đầu phun 0,4 mm, nên mỗi cặp T2 khi in ra phải snap khớp được với nhau.

Số lượng tam giác đáng để liếc qua, và không nghiêng về công cụ nào một cách nhất quán. Hộp của CadQuery mang gần năm lần số tam giác của hộp OpenSCAD, trong khi nắp của nó lại ít hơn. Mật độ lưới ở đây phản ánh mức chi tiết bo tròn mà mỗi tác nhân chọn thêm vào, không phải nhân hình học.

Hai phần vỏ hộp snap-fit được tạo ra trong nhiệm vụ T2Hai phần vỏ hộp snap-fit được tạo ra trong nhiệm vụ T2

Những gì nhóm phát hiện

Bản render không phát hiện được gì quan trọng. Đây là kết quả không ngờ tới. Qua sáu lần chạy, hình ảnh chỉ phát hiện các lỗi thô thiển, như bốn trụ gắn bị phép trừ khoang xoá mất, và không phát hiện gì tinh vi. Mọi khiếm khuyết có thể làm hỏng bản in đều được tìm ra bằng con số: một thể tích, một góc, một phép kiểm tra giao thoa. Trong T3, tác nhân OpenSCAD gặp vấn đề ngược lại và suýt bác bỏ hình học đúng, vì một bản render cận cảnh ren trông có vẻ sai.

Các kiểu thất bại đối xứng như ảnh gương. CadQuery thất bại ồn ào và sớm. Thông báo của nó tệ, nhưng một ngoại lệ làm dừng quá trình chạy, và một mô hình bị dừng thì không thể vô tình được xuất bản. OpenSCAD thất bại âm thầm và muộn: trong T2, nó báo không có lỗi và không có cảnh báo qua khoảng 45 lần gọi, trong khi tạo ra các trụ bị xoá, khe đặt sai chỗ, và một file xuất hỏng mà chính nó vừa chứng nhận là sạch. Với việc tạo tự động không giám sát, thành công âm thầm là kiểu thất bại tốn kém hơn.

CadQuery có thể bị chất vấn, OpenSCAD thì không. CadQuery trả lời được các câu hỏi về hình học của chính nó. Tác nhân T1 chứng minh lỗ khoét chìm của mình ở 90 độ và 9 mm bằng cách đọc nửa góc của hình nón từ B-rep, rồi gắn đặc tả vào các assert chạy lại mỗi lần build. OpenSCAD không có cách truy vấn hình học, nên cả hai tác nhân OpenSCAD đều độc lập viết trình phân tích STL nhị phân, lượng mã tương đương chính các mô hình, để đo những gì đã dựng. Nó hoạt động, nhưng chỉ nhìn thấy lưới sau khi xuất, không bao giờ nhìn thấy thiết kế.

Tốc độ nghiêng về OpenSCAD, và điều đó hầu như không quan trọng. Tính toán lại hình học nhanh hơn 30 đến 100 lần, 16 ms so với 1,9 giây. Trong một vòng lặp tác nhân bị chi phối bởi suy luận mô hình, đó là nhiễu. Nó sẽ quan trọng với một customizer trực tiếp hoặc một đợt quét tham số lớn.

Bản render của OpenSCAD không có khái niệm cạnh chi tiết. Sau CSG chỉ còn một mớ tam giác, nên --view=edges vẽ chính phép tam giác hoá chứ không phải đường bao. B-rep của CadQuery biết hai mặt thực sự gặp nhau ở đâu. Vì hình ảnh là kênh phản hồi của tác nhân, đây là một bất đối xứng thực sự trong thiết lập, nên nhóm đã sửa bằng cách render STL đã xuất và tái dựng đường bao từ góc giữa các mặt kề nhau.

Cùng một chi tiết, ba trình render khác nhauCùng một chi tiết, ba trình render khác nhau

Kết luận

Không công cụ nào thắng về đầu ra. Sáu chi tiết sạch, in được, ba từ mỗi bên.

Điều quyết định là khả năng kiểm chứng chứ không phải khả năng diễn đạt, và CadQuery dẫn đầu ở đó với khoảng cách rộng hơn mức mà khác biệt cú pháp gợi ý. Có thể hỏi nhân hình học xem mình vừa dựng cái gì, và assert lên câu trả lời, đáng giá hơn trong vòng lặp tác nhân so với bất kỳ lượng cú pháp tiện lợi nào.

Hình dạng nhiệm vụ quyết định nhiều hơn công cụ. Công việc lăng trụ đơn giản thuộc về OpenSCAD. Hai phần phải khớp nhau thuộc về CadQuery. Ren xoắn ốc — bài trông như được đặt may cho nhân B-rep — lại thuộc về OpenSCAD một cách dứt khoát.

Nếu một pipeline tạo sinh dựa vào ảnh chụp màn hình, nó đang dựa vào kênh duy nhất không phát hiện được gì trong thử nghiệm này. Các assert bằng số là thứ cần bắt buộc: độ dày thành, khe hở, thể tích giao thoa, góc nhô.

Hãy kiểm tra lưới một cách độc lập, vì cả hai chuỗi công cụ đều chứng nhận hình học sai.

Đây cũng là bài học mà benchmark Pantheon rút ra từ một góc khác, nơi Codex trông mạnh trong vòng lặp preview nhưng lại xuất ra một STL có vấn đề hình học. Preview và bản xuất không phải là một. Với bất cứ thứ gì đưa đi in, lưới đã xuất cần có lượt kiểm tra riêng.

Lưu ý về giới hạn thử nghiệm: Một tác nhân cho mỗi ô, nên một phần độ phân tán là do biến động của tác nhân. Thư viện BOSL2 được cố ý không dùng; một lần chạy OpenSCAD có thư viện hỗ trợ nhiều khả năng sẽ thay đổi đáng kể T2 và T3. Cả sáu lần chạy đều diễn ra trước khi có trình render đường bao.

Với ModelRift, nhóm vẫn ở lại với OpenSCAD, và benchmark này làm sắc nét thêm lý do chứ không thay đổi câu trả lời. Lợi thế của CadQuery là thật nhưng chủ yếu nằm ở khả năng kiểm chứng, và kiểm chứng là thứ có thể bổ sung quanh OpenSCAD. Hai thay đổi đã được đưa trở lại skill OpenSCAD đã công bố: trình render cạnh đặc trưng để tác nhân có preview với đường bao chi tiết thật, và một lượt kiểm tra bằng số mà tác nhân phải chạy trước khi được coi là hoàn thành mô hình.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗