브라우저에서 CAD 에디터를 만들고, LLM에게 사용법을 가르쳤습니다

앱에 물었습니다: "문과 창문이 각각 몇 개 있나요?"

AI는 개수를 답변했습니다. 그러더니 요청하지도 않은 말을 덧붙였습니다:

"참고: D3의 너비가 300mm밖에 되지 않습니다. 문이 잘못 감지되었을 가능성이 높습니다. 확인해 드릴까요?"

AI의 말이 맞았습니다. 제 시스템이 기하학적 형상 중 하나를 30cm짜리 문으로 만들어 버린 것이었습니다. 그 누구도 이를 알아차리지 못했습니다. 모델은 데이터를 읽고 신발 상자보다 좁은 문을 발견한 뒤, 이를 문제로 표시했습니다.

그 순간은 거대한 엔지니어링 과제를 해결한 보람을 느끼게 해주었습니다. AutoCAD DWG 파일을 파싱하고, 수천 개의 무작위 선으로부터 건물 모델을 재구성하며, 2D 에디터를 처음부터 구축하고, 이를 Claude에 연결해야 했습니다.

제가 어떻게 만들었는지 소개합니다.

데이터 문제

DWG 파일에는 벽이 들어있지 않습니다. 선(lines)이 들어있을 뿐입니다. 이 프로젝트에서 흥미로운 모든 일은 이 두 문장 사이의 공간에서 일어납니다.

이 파일들을 처리하기 위해 두 가지 규칙을 따랐습니다:

  • 파서를 서브프로세스(subprocess)로 실행합니다. 30년 된 파서가 충돌하더라도 서버가 죽지 않도록 하기 위함입니다.
  • 파일을 절대 신뢰하지 않습니다. DWG 헤더는 단위에 대해 거짓 정보를 제공하는 경우가 많습니다. 저는 헤더를 무시하고 실제 숫자를 확인하여 정확한 스케일을 찾아냅니다.

추출 파이프라인

선들의 집합을 구조화된 모델로 변환했습니다:

  • 벽은 중심선(centerlines)입니다.
  • 문과 창문은 해당 벽에 스냅(snap)됩니다.
  • 방은 이름과 면적을 가진 다각형(polygons)입니다.

분류를 위해 간단한 트릭을 사용했습니다. 레이어 이름에 대해 부분 문자열 일치(substring matching) 방식을 사용했습니다. 레이어 이름이 "WAND"나 "MAUER"라면 시스템은 그것이 벽임을 인지합니다. 레이어 이름이 없다면 시스템은 기하학적 형상을 통해 추측합니다.

에디터

Canvas 2D 컨텍스트를 사용하여 에디터를 구축했습니다. 속도를 유지하기 위해 세 개의 레이어를 사용했습니다:

  • 레이어 1: 정적 그리드와 원본 선들.
  • 레이어 2: 모델 (벽, 방, 문).
  • 레이어 3: 활성 커서 및 미리보기.

덕분에 벽이 거의 1,000개에 달하는 상황에서도 프레임 레이트를 60 FPS로 유지할 수 있었습니다.

AI 코파일럿

단순히 말만 하는 챗봇을 원하지 않았습니다. 실제로 작동하는 에이전트를 원했습니다. Claude에게 모델을 읽고 편집할 수 있는 13개의 도구(tools)를 부여했습니다.

안전을 위해 세 가지 규칙을 따랐습니다:

  • 단일 쓰기 경로(One write path): AI는 수동 UI와 정확히 동일한 검증된 코드를 사용합니다. UI에서 저장할 수 없다면 AI도 저장할 수 없습니다.
  • 복구 가능한 오류: AI가 맞지 않는 위치에 문을 배치하려고 하면 도구가 오류를 반환합니다. AI는 그 오류를 읽고 다른 위치를 시도합니다.
  • 실행 취소(Undo) 기능: 모든 AI 작업은 하나의 트랜잭션으로 묶입니다. AI가 실수를 하더라도 Ctrl+Z 한 번이면 모든 것이 복구됩니다.

교훈

  • 기하학적 버그는 테스트하지 않은 형상 속에 숨어 있습니다. 직사각형 건물은 쉽습니다. L자형 건물은 모든 것을 망가뜨립니다.
  • 도구를 퍼징(fuzz)하세요. LLM은 퍼저(fuzzer)와 같습니다. 엄격한 코드 경계로 이에 대응해야 합니다.
  • 어려운 부분은 AI가 아닙니다. 데이터 기반(data foundation)입니다. 기하학적 구조가 탄탄했기 때문에 AI 통합 작업은 몇 주가 아닌 며칠 만에 끝날 수 있었습니다.

Source: https://dev.to/arif/i-built-a-cad-editor-in-the-browser-then-taught-an-llm-to-use-it-1l92