
Codex가 나의 첫 네이티브 Mac 앱을 빌드하고 테스트하게 해보았다
요약
Codex를 활용하여 네이티브 Mac 앱을 빌드, 설치, 테스트하는 실험 과정을 다룹니다. 단순 코드 작성을 넘어 권한 설정 및 물리적 오디오 실행까지 수행하는 AI의 주도적인 개발 능력을 보여줍니다.
핵심 포인트
- Codex를 통해 Swift 앱 빌드부터 설치, macOS 권한 설정까지 자동화 가능
- 코드 체크 통과 후에도 실제 앱 실행 및 테스트를 수행하는 높은 주도성 확인
- Computer Use 기능을 활용한 마이크 권한 설정 및 클립보드 검증 프로세스 수행
첫 번째 공개 Billie Flow 빌드가 출시되었고, 중단 없이 실행되었으며, 서명 확인(signature check)을 통과했고, 소스 및 모델을 찾을 수 있었습니다. 하지만 재설치 시 새로운 사용자에게 설정(Settings) 창이 나타나지 않았는데, 이는 로컬 워커(local worker)를 설치할 수 있는 가시적인 방법이 없음을 의미했습니다.
프로세스는 정상적이었습니다. 하지만 앱은 사용할 수 없는 상태였습니다.
그 간극이 바로 나의 로컬 받아쓰기(dictation) 실험에서 가장 유용하다고 느끼는 부분입니다. 나는 Codex가 리포지토리(repository)의 범위를 훨씬 넘어서 작업하도록 허용했습니다. Codex는 나의 첫 네이티브 Mac 앱을 빌드하고, 설치하고, macOS 권한 인터페이스(permission surfaces)를 조작하며, 물리적 오디오를 실행하고, 클립보드(clipboard)를 검사했습니다. 흥미로운 실패 사례들은 코드 체크가 통과(green)된 이후에도 Codex가 계속 작업을 진행했기 때문에 나타났습니다.
설치된 앱을 테스트하는 것이 작업의 성격을 바꾸었다
내가 Billie Flow를 시작한 이유는 Wispr Flow를 사용하고 있었고, 이 유용한 루프를 로컬에서 실행할 수 있을지 궁금했기 때문입니다. 나를 이끌었던 것은 단순한 호기심이었습니다. 정말로 가능할까?
이것이 대체재가 되도록 의도한 것은 아니었습니다. Wispr Flow는 여전히 사용할 만큼 충분한 가치를 제공합니다. 나는 개인용 버전을 만들 수 있는지 보고 싶었을 뿐이었고, 그 후에는 내가 Codex를 얼마나 깊게 관여시켰는지에 대해 훨씬 더 큰 흥미를 느끼게 되었습니다.
5.6 버전에서는 말 그대로 무언가를 작성하고, 빌드하고, 의존성(dependencies)을 설치하고, 테스트까지 할 수 있었습니다. 이 프로젝트에서 "테스트"란 결국 설치된 Swift 앱을 열고, Computer Use를 통해 마이크 권한 설정을 진행하며, 글로벌 단축키를 누른 뒤 결과 텍스트가 클립보드에 도달하는지 확인하는 것을 의미했습니다.
어느 순간, 나는 그것이 작동하기를 기다리며 누워 있었는데 스피커에서 음성이 나오기 시작했습니다. Billie Flow는 그 음성을 녹음하고 전사(transcribe)했습니다. 무엇이 그 음성을 만들어냈는지는 모르기에, 이 관찰을 더 깔끔한 기술적 주장으로 만들지는 않겠습니다. 다만 5.5 버전이었다면 이 정도의 주도성을 보이지 않았을 것이라고 생각했던 기억이 나지만, 이는 통제된 비교라기보다는 인상에 가깝습니다.

글로벌 단축키(Global shortcut)는 누르고 있는 동안에만 기록됩니다. 단축키를 떼면 임시 오디오가 로컬 처리(local processing)를 위해 제출됩니다.
물리적인 실행은 결국 클립보드에 비어 있지 않은 텍스트가 남고, 앱과 워커(worker)가 정상적으로 작동하며, 새로운 충돌(crash)이 발생하지 않고, 남겨진 임시 녹음 파일도 없이 완료되었습니다.

이것은 로컬 인식(local recognition)과 가벼운 정리(light cleanup)가 완료된 후 설치된 앱에서 보이는 최종 상태입니다.
예상했던 모델은 유용하지 않았습니다
앱 작업은 모델 결정과 함께 시작되었습니다. 제 머릿속에는 오디오 기능이 있는 Gemma 12B 경로가 있었지만, 그 가정을 바탕으로 구축하기 전에 동일한 35.3초 분량의 음성 메모를 여러 로컬 인식 경로를 통해 실행해 보았습니다.
또한 저는 음성 인식(speech recognition)을 정리(cleanup) 작업과 분리하여 유지했습니다. 그렇지 않으면 정리 모델이 인식기(recogniser)가 이미 잘못 파악한 중요한 이름들을 보존하면서도 전사(transcript)를 다듬어버릴 수 있기 때문입니다.
Gemma는 258.79초 만에 메모를 완료했고 중첩된 청크(overlapping chunk) 주변에서 표류했습니다. MLX Whisper large-v3-turbo는 약 3.68초 만에 가장 유용한 인식을 생성했고, 그 후 Qwen2.5 1.5B가 선택된 가벼운 정리 단계를 약 0.62초 만에 실행했습니다.
제가 처음에 생각했던 모델은 정답이 아니었습니다. 두 개의 더 작은 모델이 이 앱을 위해 더 빠르고 유용한 결과를 만들어냈습니다. 이는 의도적으로 좁게 설정된 결과입니다. 이는 한 대의 기기에서 수행된 하나의 메모일 뿐이며, 모든 인식 경로가 여전히 적어도 하나의 중요한 프로젝트 용어를 놓쳤기 때문입니다. Billie Flow 모델 분석 전체 보고서에는 다른 분기, 타이밍 및 어휘 실패 사례들이 포함되어 있습니다.
세 가지 다른 종류의 녹색 실패 (green failure)
설정(Settings) 창이 나타나지 않았던 것만이 교체 설치(replacement-install) 단계에서 발견된 유일한 문제는 아니었습니다.
정리(Cleanup) 과정은 고정된(pinned) MLX 라이브러리가 구식 인자(obsolete argument)를 전달받으면서 조용히 원시 인식(raw recognition) 방식으로 폴백(fallback)되고 있었습니다. 워커 요청(worker request)은 성공을 반환했지만, UI는 실제로 일어나지 않은 정리를 수행했다고 주장했습니다. 마지막 설정 확인(setup check) 또한 앱이 완료를 등록하기 전에 종료될 수 있었고, 이로 인해 설정이 검증(verification) 단계에서 멈춰버리는 현상이 발생했습니다.
이전의 마이크 테스트에서는 첫 번째 오디오 버퍼에서 액터 격리(actor-isolation) 충돌이 발생했고, 이어서 변환된 WAV를 쓰는 동안 포맷 불일치(format mismatch)가 노출되었습니다. 이것들은 동일한 버그의 다섯 가지 버전이 아니었습니다. 이 문제들은 Swift 동시성(concurrency), Core Audio, 고정된 Python 의존성(dependency), 프로세스 생명주기(process lifecycle), 그리고 가시적인 macOS 프레젠테이션(presentation)을 가로질러 발생했습니다.
Codex는 각 실패가 발생한 레이어(layer)를 끝까지 추적해 나갔습니다. 이제 릴리스 게이트(release gate)는 실행 중인 프로세스나 성공적인 응답을 충분한 증거로 간주하는 대신, 실제 첫 실행 창이 나타나는지, 그리고 경고 없는 정리가 이루어지는지를 확인합니다.
명확한 경계가 있는 공개 개념 증명 (Proof of Concept)
소스 코드와 설치 테스트를 거친 v0.2.1 빌드는 공개되어 있습니다. 원하신다면 Billie Flow를 사용하셔도 좋지만, 누군가 사용하든 말든 저는 크게 상관하지 않습니다.
설치(Install)를 선택하기 전까지는 어떤 큰 작업도 시작되지 않습니다. 또한, 이 개념 증명(proof of concept)은 Apple Silicon 및 macOS 26 환경에서의 영어 음성으로 제한됩니다.
경계는 명확합니다: Apple Silicon, macOS 26, 영어 인식, 그리고 약 3.5 GB의 동의된 런타임 (runtime) 및 모델 설정이 필요합니다. 설정 이후의 추론 (Inference)은 로컬에서 이루어지지만, 설정 과정에서는 여전히 Python 의존성 (dependencies)과 고정된 모델들을 다운로드합니다. 이 앱은 애드혹 (ad-hoc) 서명되었으며 공증 (notarised)되지 않았고, 업데이트 프로그램, App Store 출시, 호환성 보장 또는 지원 계획도 없습니다. 이 정도 수준을 위해 Apple Developer Programme 멤버십을 가입할 생각은 전혀 없습니다.
Billie Flow가 모든 사람이 이미 사용 중인 소프트웨어를 다시 만들 필요가 있다는 점을 시사하는 것은 아닙니다. 다만, 이 루프 (loop)의 놀라울 정도로 훌륭한 개인용 버전을 이제는 빠르게 만들 수 있다는 것을 보여줍니다. 제가 여전히 가장 기이하게 기억할 부분은 이것입니다: Codex가 마이크를 테스트해야 한다고 결정하고 스피커에서 음성이 나오기 시작할 때, 그저 누워 있었던 순간 말입니다. 그것은 정말 정말 인상적이었습니다.
제가 작성하거나 만든 것에 대해 이야기하고 싶으신가요? 연락하기.
이 기사는 billiem.uk의 원문 기사를 AI의 도움을 받아 각색하였습니다. 원문 기사는 발행 전 검토를 거쳤습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기