
AI 엔지니어가 3시간 동안 진심으로 Replit을 사용해 본 결과: 인터랙티브 아바타 AI 앱
요약
Replit Agent를 활용하여 STT, LLM, TTS 및 3D 아바타 제어 기술을 결합한 인터랙티브 아바타 AI 앱을 3시간 만에 개발한 사례를 소개합니다. 개발자의 기술적 지식과 스펙 주도 방식이 결합되었을 때 AI 에이전트가 얼마나 강력한 생산성을 발휘하는지 보여줍니다.
핵심 포인트
- Replit Agent를 활용한 단시간 고기능 앱 구현 사례
- STT, LLM, TTS 및 Three.js를 결합한 멀티모달 워크플로우
- LLM을 통해 답변 문장과 아바타의 감정/모션을 동시에 생성
- AI 에이전트 활용 시 스펙 주도 개발과 기초 지식의 중요성
AI 엔지니어가 3시간 동안 진심으로 Replit을 사용해 본 결과: 인터랙티브 아바타 AI 앱
서론
생성형 AI를 활용한 개발 도구가 늘어나는 가운데, 자연어로 애플리케이션을 개발할 수 있는 AI 에이전트형 개발 환경이 주목받고 있습니다.
이번에는 Replit Agent를 사용하여, 인터랙티브한 아바타 AI 앱을 약 3시간 만에 개발해 보았습니다.
이번에 개발한 앱은 사용자가 마이크를 향해 말을 걸면, 3D 아바타가 대화 내용에 따른 음성, 표정, 모션으로 응답하는 앱입니다.
처리 흐름은 다음과 같습니다.
- 마이크로부터 사용자의 음성을 취득한다
- STT로 음성을 텍스트화한다
- 인식한 텍스트를 LLM으로 전송한다
- LLM이 사용자에 대한 답변 문장을 생성한다
- LLM이 답변 내용에 적합한 모션을 생성한다
- TTS로 답변 문장을 음성으로 변환한다
- 아바타가 생성된 음성을 재생한다
- 아바타가 응답 내용에 따른 표정이나 모션을 표현한다
단순히 음성으로 답변하는 것만이 아닙니다.
LLM이 대화 내용을 해석하여, 답변 문장뿐만 아니라 아바타가 어떤 표정이나 모션을 표현할지까지 생성합니다.
언뜻 보기에는 꽤 많은 개발 공수가 들어갈 것 같은 앱이지만, 이번에는 Replit Agent와의 대화를 반복함으로써 약 3시간 만에 동작하는 단계까지 구현할 수 있었습니다.
다만, 이 기사에서 전달하고 싶은 것은 Replit Agent를 사용하면 누구나 3시간 만에 똑같은 앱을 만들 수 있다는 이야기가 아닙니다.
단시간에 고기능 앱을 만들 수 있었던 배경에는 다음의 3가지가 있습니다.
- 스펙 주도(Spec-driven)로 개발을 진행한 것
- 처음에는 간단한 기능부터 구현한 것
- 개발자 측에 관련 기술 지식이 있었던 것
구체적으로는 VRM, VRMA, Three.js, three-vrm, STT, TTS, LLM에 관한 지식을 개발 전부터 어느 정도 가지고 있었습니다.
본 기사에서는 어떤 흐름으로 개발했는지, Replit Agent를 어떻게 사용했는지, 그리고 AI 시대의 엔지니어의 가치에 대해 소개합니다.
이번에 만든 것
이번에 개발한 것은 브라우저상에서 동작하는 인터랙티브한 아바타 AI 앱입니다.
사용자가 마이크를 향해 말을 걸면 음성 인식, LLM, 음성 합성, 3D 아바타 제어를 조합하여 응답합니다.
전체 처리 플로우는 다음과 같습니다.
마이크 입력
↓
STT에 의한 음성 인식
...
기술적으로는 주로 다음과 같은 요소들을 조합하고 있습니다.
- React
- TypeScript
- Three.js
- three-vrm
- VRM
- VRMA
- STT
- TTS
- LLM API
- Replit Agent
VRM은 3D 아바타를 다루기 위한 파일 형식입니다.
VRMA는 VRM 아바타를 위한 애니메이션 형식입니다.
Three.js와 three-vrm을 이용함으로써 브라우저상에 VRM 모델을 불러오고, 표정이나 애니메이션을 제어할 수 있습니다.
이번 앱에서는 LLM을 답변 문장 생성에만 이용하고 있는 것이 아닙니다.
LLM에는 답변 문장과 함께 아바타가 실행할 표정이나 모션도 구조화된 형식으로 출력하도록 하고 있습니다.
출력 이미지는 다음과 같습니다.
{
"message": "그것은 매우 좋은 아이디어네요!",
"emotion": "happy",
...
앱 측에서는 이 출력을 바탕으로 다음 처리를 실행합니다.
message를 TTS로 전달하여 음성화한다emotion에 대응하는 표정을 아바타에 반영한다motion에 대응하는 VRMA 애니메이션을 재생한다
이를 통해 아바타는 단순히 답변 문장을 읽어주는 것뿐만 아니라, 대화 내용에 맞는 리액션을 표현할 수 있습니다.
예를 들어, 긍정적인 내용이라면 미소나 고개를 끄덕이는 모션을 선택하고, 신중한 답변에서는 차분한 표정이나 절제된 움직임을 선택합니다.
왜 3시간 만에 만들 수 있었나
이번 개발 시간은 약 3시간입니다.
하지만 Replit Agent가 모든 것을 자동으로 설계하고, 단 한 번의 지시로 완전한 앱을 생성해 준 것은 아닙니다.
단시간에 개발할 수 있었던 이유는 크게 3가지가 있습니다.
1. 스펙 주도로 개발했다
이번 개발에서는 갑자기 코드를 쓰게 하는 것이 아니라, 먼저 앱의 사양을 정리했습니다.
예를 들어, 처음에 다음과 같은 요건을 정의했습니다.
- 브라우저 상에 VRM 아바타를 표시한다
- 사용자는 마이크를 통해 음성 입력이 가능하다
- 입력된 음성을 STT (Speech-to-Text)로 텍스트화한다
- 인식 결과를 LLM (Large Language Model)으로 전송한다
- LLM은 답변 문장을 생성한다
- LLM은 답변 내용에 따른 표정이나 모션을 생성한다
- 답변 문장을 TTS (Text-to-Speech)로 음성화한다
- 아바타가 음성을 재생한다
- 아바타가 지정된 표정과 모션을 재생한다
- 모션은 나중에 추가하거나 교체할 수 있는 구성으로 만든다
중요한 것은, "코드를 써달라"고 의뢰하는 것이 아니라, "어떤 상태가 되면 완성인지"를 먼저 명확히 한 것입니다.
AI 에이전트는 모호한 의뢰에 대해서도 어떻게든 결과물을 생성해 줍니다.
하지만 요구사항이 모호한 상태로 두면, 동작하는 것은 만들어지더라도 기대했던 것과 다르거나 확장하기 어려운 구성이 될 수 있습니다.
이번에는 완성형을 먼저 언어화하고, 그것을 작은 기능 단위로 분해하여 Replit Agent에게 전달했습니다.
스펙을 정의하고, 그 스펙을 충족하도록 구현을 진행하는, 스펙 주도 (Spec-driven) 개발에 가까운 방법입니다.
2. 처음부터 관련 기술에 대한 지식이 있었다
이번에 다룬 기술에 대해, 개발 전부터 일정 수준의 지식을 가지고 있었습니다.
구체적으로는 다음과 같은 지식입니다.
- VRM 모델의 구조
- VRMA를 이용한 애니메이션
- Three.js의 씬 (Scene), 카메라, 라이트, 렌더러
- three-vrm을 사용한 모델 제어
- Expression을 통한 표정 제어
- AnimationMixer를 통한 애니메이션 제어
- STT의 입력 형식과 응답 형식
- TTS를 통한 음성 생성과 재생
- LLM API 호출 방법
- LLM이 JSON 형식으로 출력하게 하는 방법
- 브라우저의 마이크 권한 및 음성 재생 제한
- React 상에서의 비동기 처리 및 상태 관리
이러한 지식이 있었기 때문에, Replit Agent가 생성한 코드에 대해 무엇이 맞고 무엇이 틀린지를 비교적 빠르게 판단할 수 있었습니다.
예를 들어, 모션이 정상적으로 재생되지 않을 경우에도 원인 후보를 즉시 분류할 수 있습니다.
- VRMA 로딩에 실패함
- 모델과 애니메이션의 본 (Bone) 구조가 일치하지 않음
- AnimationMixer가 올바르게 업데이트되지 않음
- 렌더링 루프 내에서 delta time을 전달하지 않음
- 기존 애니메이션이 정지되지 않음
- 모션 이름과 LLM의 출력이 일치하지 않음
- LLM이 존재하지 않는 모션을 생성함
기술 지식이 없는 상태에서는 AI가 생성한 코드가 동작하지 않을 때 어디를 수정해야 할지 판단하기 어려워집니다.
반면, 기술 지식이 있다면 문제 지점을 추측하여 AI에게 구체적인 수정 지시를 내릴 수 있습니다.
AI에게 코드를 쓰게 하는 능력뿐만 아니라, 생성된 코드를 평가하고 방향을 수정하는 능력이 중요합니다.
3. 한 번에 완성하려고 하지 않았다
개발 초기부터 모든 기능을 한 번에 구현하게 한 것은 아닙니다.
처음에는 정말 간단한 기능부터 시작했습니다.
첫 번째 목표는 다음 두 가지뿐입니다.
- 화면에 VRM 아바타를 표시한다
- VRMA 모션을 하나 재생한다
이 단계에서는 음성 입력도, LLM도, 음성 합성도 없습니다.
먼저 Three.js의 씬, 카메라, 라이트, 렌더러를 준비하고 VRM 모델이 정상적으로 표시되는지 확인했습니다.
그다음 VRMA를 로드하여 아바타가 하나의 모션을 재생할 수 있는지 확인했습니다.
그 후 Replit Agent와의 대화를 통해 기능을 단계적으로 추가해 나갔습니다.
Replit Agent와의 개발 진행 방식
실제 개발에서는 다음과 같은 순서로 기능을 추가했습니다.
스텝 1: VRM 아바타를 표시한다
처음에 Replit Agent에게 의뢰한 것은 VRM 모델을 브라우저 상에 표시하는 기능입니다.
이 시점에서는 요구사항을 한정했습니다.
React와 Three.js를 사용하여 브라우저 상에 VRM 모델을 표시해 주세요.
the-vrm을 이용하고, 모델 로딩 처리를 컴포넌트로 분리해 주세요.
이 지시를 통해 Three.js의 기본 구성과 VRM 로딩 처리가 생성되었습니다.
물론 한 번에 완전히 기대한 대로 동작한 것은 아닙니다.
모델의 방향, 카메라 위치, 라이팅, three-vrm의 버전 차이 등은 조정이 필요했습니다.
하지만 토대가 되는 코드는 짧은 시간 안에 준비할 수 있었습니다.
스텝 2: VRMA 모션을 재생한다
다음으로 아바타에 VRMA 형식의 모션을 적용했습니다.
처음에는 아이돌 모션(Idol motion)을 하나 재생할 수 있는 것만을 목표로 삼았습니다.
이 시점에서는 다음과 같은 사항들을 지정했습니다.
- VRMA 파일을 외부 파일로 불러오기
- VRM 모델의 로딩 완료 후 모션 적용하기
- 렌더링 루프(Rendering loop) 내에서 AnimationMixer 업데이트하기
- 향후 여러 개의 모션을 전환할 수 있는 구성으로 만들기
단순히 애니메이션을 재생하는 것에 그치지 않고, 나중에 여러 모션을 추가할 수 있는 구조로 만들었습니다.
예를 들어, 다음과 같은 모션들입니다.
- idle (대기)
- agree (동의)
- happy (행복)
- thinking (생각)
- surprise (놀람)
- apologize (사과)
이 단계에서 앱 측에 모션 이름과 VRMA 파일의 대응표를 갖추게 했습니다.
const motionMap = {
idle: "/motions/idle.vrma",
agree: "/motions/agree.vrma",
...
LLM에는 이 목록에 존재하는 모션만을 출력하도록 설계했습니다.
스텝 3: 텍스트 입력과 LLM 응답을 추가한다
다음으로 텍스트 입력란을 추가하고, 입력 내용을 LLM으로 보내는 기능을 구현했습니다.
이 단계에서는 아직 음성 입력이나 TTS(Text-to-Speech)는 없습니다.
사용자가 텍스트를 입력하면, LLM이 답변 문장을 생성합니다.
여기서는 답변 문장뿐만 아니라, 표정과 모션도 동시에 생성하도록 했습니다.
출력 형식을 미리 정의하고, LLM이 JSON으로 답변하도록 합니다.
{
"message": "그렇군요, 그거 정말 재미있네요.",
"emotion": "happy",
...
LLM이 자유로운 텍스트를 내뱉게 하는 것이 아니라, 앱 측에서 다루기 쉬운 형식으로 제약하는 것이 중요합니다.
또한, 모션에 대해서는 사용할 수 있는 값을 미리 프롬프트(Prompt) 내에서 지정했습니다.
motion에는 다음 중 하나만 지정해 주세요.
- idle
- agree
...
이를 통해 LLM이 존재하지 않는 모션 이름을 생성할 리스크를 줄일 수 있습니다.
스텝 4: 표정과 모션을 LLM의 출력에 연동시킨다
다음으로 LLM이 생성한 emotion과 motion을 아바타의 동작에 반영했습니다.
표정에 대해서는 three-vrm의 ExpressionManager를 이용합니다.
예를 들어, emotion이 happy라면 웃는 얼굴을 설정하고, surprised라면 놀란 표정을 설정합니다.
구현 이미지는 다음과 같습니다.
function applyEmotion(emotion: string) {
expressionManager?.setValue("happy", emotion === "happy" ? 1 : 0);
expressionManager?.setValue(
...
모션에 대해서는 LLM이 반환한 모션 이름을 바탕으로, 대응하는 VRMA를 재생합니다.
await playMotion(response.motion);
applyEmotion(response.emotion);
이를 통해 사용자의 발언 내용에 따라 아바타의 리액션이 바뀌게 되었습니다.
예를 들어, 사용자가 긍정적인 발언을 하면 아바타는 웃으며 고개를 끄덕입니다.
어려운 질문을 받은 경우에는 생각하는 듯한 표정과 모션을 재생합니다.
사과를 포함한 답변에서는 차분한 표정과 사과 모션을 선택합니다.
스텝 5: TTS를 추가한다
다음으로 LLM의 답변 문장을 음성으로 재생하기 위해 TTS를 추가했습니다.
LLM의 message를 TTS API로 전송하고, 반환된 음성 데이터를 브라우저에서 재생합니다.
처리 흐름은 다음과 같습니다.
- LLM으로부터 답변 문장을 가져오기
- 답변 문장을 TTS API로 전송하기
- 음성 데이터 가져오기
- Blob URL 생성하기
- Audio 객체로 음성 재생하기
- 음성 종료 후 리소스 해제하기
음성 합성 자체는 비교적 간단하지만, 브라우저상에서 다룰 때는 몇 가지 주의할 점이 있습니다.
- 음성 형식
- Blob URL 생성
- 음성 재생 시작 타이밍
- 연속 재생 시의 경합(Conflict)
- 재생 종료 시의 리소스 해제
- 사용자 조작 전의 자동 재생 제한
Replit Agent는 기본적인 구현을 생성해 주었지만, 연속해서 대화할 때의 음성 중복이나 오래된 음성의 정지 처리 등은 추가로 수정했습니다.
단계 6: STT를 통한 음성 입력 추가하기
마지막으로, 마이크를 통해 음성을 입력하고 STT (Speech-to-Text)로 텍스트로 변환하는 기능을 추가했습니다.
사용자가 버튼을 누르면 녹음을 시작하고, 다시 한 번 누르면 녹음을 중지합니다.
녹음 데이터는 STT API로 전송되며, 인식 결과가 그대로 LLM (Large Language Model)의 입력값이 됩니다.
녹음 처리 과정에서는 다음과 같은 점들을 Replit Agent와 조정했습니다.
- MediaRecorder 초기화
- 대응하는 MIME 타입 판정
- 녹음 데이터의 Blob화
- STT API로의 전송
- 녹음 중 UI 표시
- 마이크 권한 에러
- 중복 전송 방지
- 녹음 중 버튼 제어
이를 통해 사용자는 키보드를 사용하지 않고도 아바타와 음성으로 대화할 수 있게 되었습니다.
기능은 Replit Agent와의 대화를 통해 단계적으로 늘려나갔다
Replit Agent를 사용한 개발에서는 한 번의 지시로 완성품을 만들게 하기보다, 대화를 거듭하며 단계적으로 개선하는 것이 더 효율적이었습니다.
이번에도 다음과 같은 순서로 기능을 추가했습니다.
- VRM 모델 표시하기
- VRM 애니메이션 모션 1개 재생하기
- 여러 모션을 전환할 수 있도록 하기
- 텍스트 입력 추가하기
- LLM으로부터 답변 문장 가져오기
- LLM이 표정과 모션을 생성하게 하기
- LLM의 출력을 JSON 형식으로 만들기
- 아바타의 표정 전환하기
- 아바타의 모션 전환하기
- TTS (Text-to-Speech)를 통한 음성 재생 추가하기
- STT를 통한 음성 입력 추가하기
- 에러 처리 추가하기
- UI 조정하기
작은 변경을 쌓아감으로써 각 단계에서 동작 확인을 수행할 수 있습니다.
문제가 발생했을 때도 직전에 추가한 기능이 원인이라고 판단하기 쉬워집니다.
반대로 처음부터 모든 기능을 포함한 지시를 내리면, 생성되는 코드량이 늘어나 어디에서 문제가 발생하고 있는지 파악하기 어려워집니다.
AI 에이전트를 사용하는 경우에도 기존의 소프트웨어 개발과 마찬가지로 변경 단위를 작게 유지하는 것이 중요합니다.
AI에게 모션을 너무 자유롭게 생성하게 하지 말 것
이번 앱에서는 LLM이 모션을 생성합니다.
단, LLM이 3D 애니메이션 데이터 그 자체를 생성하는 것은 아닙니다.
미리 준비해 둔 모션 목록 중에서 대화 내용에 적합한 모션 이름을 선택하도록 하고 있습니다.
예를 들어, LLM에는 다음과 같은 선택지를 전달합니다.
사용 가능한 모션:
- idle
- agree
...
LLM은 답변 내용에 따라 이 중에서 적절한 모션을 선택합니다.
{
"message": "조금 확인해 볼게요.",
"emotion": "neutral",
...
이처럼 AI에게 모든 것을 자유롭게 생성하게 하는 것이 아니라, 앱 측에서 선택지를 제한하는 설계가 중요합니다.
제약이 없는 경우, LLM은 존재하지 않는 모션 이름을 반환할 가능성이 있습니다.
예를 들어, wave_happily나 deep_thinking 등 앱에 등록되지 않은 이름을 생성할 수 있습니다.
따라서 다음과 같은 대책을 세웠습니다.
- 사용 가능한 모션을 프롬프트에 명시하기
- JSON Schema나 구조화된 출력 (Structured Output) 이용하기
- 앱 측에서도 모션 이름 검증하기
- 잘못된 값인 경우 idle로 폴백 (Fallback) 하기
const selectedMotion = motionMap[response.motion]
? response.motion
: "idle";
AI를 도입한 앱에서는 AI의 출력을 그대로 신뢰하는 것이 아니라, 앱 측에서 검증하는 것이 중요합니다.
Replit Agent가 특히 뛰어났던 점
이번에 사용해 보면서 특히 편리하다고 느낀 점은 세 가지가 있습니다.
환경 구축이 빠르다
통상적이라면 React 프로젝트 생성, 의존성 추가, 환경 변수 설정, 실행 확인 등에 일정 시간이 소요됩니다.
Replit에서는 개발 환경과 실행 환경이 통합되어 있습니다.
코드 생성 후 즉시 앱을 실행하여 동작을 확인할 수 있습니다.
AI 에이전트형 개발에서는 생성과 확인의 사이클을 짧게 만드는 것이 중요합니다.
Replit은 이 피드백 루프가 매우 짧다고 느꼈습니다.
여러 파일의 수정을 맡기기 쉽다
기능 추가 시에는 하나의 파일뿐만 아니라 여러 컴포넌트나 설정 파일을 변경해야 합니다.
예를 들어, 음성 입력 기능을 추가할 경우 다음과 같은 변경이 필요합니다.
- UI 컴포넌트
- 녹음 처리
- API 호출 처리
- 상태 관리
- 타입 정의
- 에러 표시
Replit Agent는 기존 프로젝트 구조를 참조하면서 여러 파일을 한꺼번에 수정해 줍니다.
단순한 코드 보완이 아니라, 태스크 (Task) 단위로 작업을 맡길 수 있다는 점이 큰 특징입니다.
동작을 확인하며 수정할 수 있음
생성된 코드가 작동하지 않을 경우에도, 에러 내용을 바탕으로 수정을 요청할 수 있습니다.
예를 들어, 다음과 같이 요청할 수 있습니다.
"VRMA를 불러온 후에 모션이 재생되지 않습니다.
AnimationMixer의 업데이트 처리와 렌더링 루프를 확인하여, delta time을 매 프레임 전달하도록 수정해 주세요."
단순히 "작동하지 않는다"라고 전달하는 것이 아니라, 원인의 후보나 수정 방침을 전달함으로써 수정 정밀도를 높일 수 있습니다.
Replit Agent만으로는 어려웠던 점
한편으로, Replit Agent에게만 전부 맡기기 어려운 부분도 있었습니다.
라이브러리 고유의 지식
three-vrm과 같은 전문적인 라이브러리는 버전에 따라 API가 변할 수 있습니다.
AI가 오래된 작성 방식을 생성하는 경우도 있습니다.
따라서 생성된 코드가 현재의 라이브러리 사양에 맞는지 확인할 필요가 있습니다.
VRM과 VRMA 특유의 문제
3D 모델이나 애니메이션에서는 파일마다 다음과 같은 차이가 있습니다.
- 본 (Bone) 구조
- 표정 이름
- 모델의 방향
- 크기
- 원점
- 애니메이션과의 궁합
- VRM 및 VRMA의 버전
코드가 올바르더라도 모델이나 모션 측의 설정에 따라 정상적으로 작동하지 않을 수 있습니다.
이 경우, 문제가 코드에 있는지 아니면 3D 에셋에 있는지 구분할 필요가 있습니다.
LLM의 출력 제어
LLM은 지정한 JSON 형식을 반드시 지킨다는 보장이 없습니다.
또한, 존재하지 않는 표정 이름이나 모션 이름을 생성할 가능성도 있습니다.
따라서 다음과 같은 설계가 필요합니다.
- 출력 형식을 명확하게 지정할 것
- 선택 가능한 값을 제한할 것
- JSON 파싱 (Parsing) 에러를 처리할 것
- 부적절한 값에 대해 폴백 (Fallback) 처리를 할 것
- LLM의 출력을 앱 측에서 검증할 것
브라우저의 음성 제어
브라우저에서는 사용자 조작 없이 음성을 재생할 수 없는 경우가 있습니다.
또한, 마이크 사용에는 사용자의 허가가 필요합니다.
이러한 브라우저 사양과 관련된 문제는 단순히 코드를 생성하는 것만으로는 해결되지 않을 수 있습니다.
앱 전체의 설계 판단
AI는 요청받은 기능을 구현하는 데는 능숙합니다.
반면, 다음과 같은 판단은 인간 측에서 수행해야 합니다.
- 어떤 기능을 우선할 것인가
- 어디까지 만들어야 검증 가능한가
- 모션을 몇 종류 준비할 것인가
- LLM에게 어디까지 판단을 맡길 것인가
- 앱 측에서 어디까지 제약을 둘 것인가
- API 장애 시 어떻게 동작할 것인가
- 장기적인 확장성을 어디까지 고려할 것인가
AI는 구현 속도를 높여주지만, 프로덕트 설계나 기술 설계까지 완전히 대체하는 것은 아닙니다.
AI에게 전달하는 지시의 정밀도가 성과를 좌우한다
이번 개발을 통해 다시 한번 느낀 점은, AI에 대한 지시의 정밀도가 결과물의 품질을 크게 좌우한다는 것입니다.
나쁜 지시의 예는 다음과 같습니다.
"말하는 3D 아바타를 만들어 주세요."
이렇게 해도 어떤 식으로든 앱은 만들어질지 모릅니다.
하지만 사용하는 기술, 구성, 구현 범위, 확장성 등은 AI의 판단에 맡겨지게 됩니다.
반면, 다음과 같이 요청하면 생성되는 코드의 정밀도가 올라갑니다.
"React, TypeScript, Three.js, three-vrm을 사용해 주세요.
VRM 모델을 표시하고, VRMA 형식의 애니메이션을 재생해 주세요.
마이크 음성을 STT로 텍스트화하여 LLM으로 전송해 주세요.
LLM은 답변 문장, 표정 이름, 모션 이름을 JSON 형식으로 반환해 주세요.
모션 이름은 idle, agree, happy, thinking, surprise, apologize 중 하나로 제한해 주세요.
답변 문장을 TTS로 음성화하고, 아바타의 음성, 표정, 모션을 연동해 주세요."
후자의 지시를 만들기 위해서는 구현 대상에 대한 이해가 필요합니다.
즉, AI를 효과적으로 사용하기 위해서 프로그래밍 지식이 불필요해지는 것이 아닙니다.
오히려 설계나 기술 선정의 지식이 중요해집니다.
3시간 만에 만든 것보다, 3시간 동안 판단할 수 있었던 것이 중요하다
이번에 약 3시간 만에 앱을 개발할 수 있었다는 사실 자체는 눈에 보이는 성과입니다.
하지만 정말 중요한 것은, 3시간 내에 많은 기술적 판단을 내릴 수 있었다는 점입니다.
- 어떤 라이브러리로 VRM을 표시할 것인가
- 어떤 타이밍에 VRMA를 로드할 것인가
- 어떻게 여러 모션을 전환할 것인가
- LLM이 어떤 모션을 선택하게 할 것인가
- LLM의 출력을 어떤 형식으로 할 것인가
- 잘못된 출력을 어떻게 처리할 것인가
- STT, LLM, TTS를 어떤 순서로 연동할 것인가
- 음성 재생과 모션 재생을 어떻게 동기화할 것인가
- 어디까지를 이번 검증 범위로 할 것인가
- 어떤 버그를 고치고, 어떤 과제를 뒤로 미룰 것인가
이러한 판단은 Replit Agent가 모두 자동으로 수행한 것이 아닙니다.
AI가 생성한 코드를 보면서, 인간이 설계하고, 평가하며, 수정 방침을 결정합니다.
AI에 의해 단축된 것은 주로 구현, 조사, 수정 시간입니다.
기술적 판단 자체가 불필요해진 것은 아닙니다.
기술 지식이 있을수록 AI의 출력을 빠르게 평가할 수 있다
AI 개발 도구를 사용할 때, 가장 큰 차이가 발생하는 지점은 코드를 쓰는 속도가 아니라 출력을 평가하는 속도라고 느끼고 있습니다.
경험이 있는 엔지니어라면 생성된 코드를 보고 비교적 즉시 다음의 판단을 내릴 수 있습니다.
- 이 API는 오래되었다
- 이 구성으로는 모션 추가가 어렵다
- LLM의 출력값을 제한하는 것이 좋다
- JSON 파싱 에러 처리가 필요하다
- 음성 재생 충돌이 발생할 가능성이 있다
- 이 상태 관리는 너무 복잡해진다
- 이 처리는 컴포넌트에서 분리해야 한다
- 잘못된 모션 이름에 대한 폴백 (Fallback)이 필요하다
- 이 부분은 AI에게 맡기지 않고 직접 고치는 것이 빠르다
이러한 평가 능력이 있음으로써 AI 에이전트와의 대화를 짧게 줄일 수 있습니다.
예를 들어, 단순히 "모션이 움직이지 않습니다"라고 전달하는 대신, 다음과 같이 지시할 수 있습니다.
"VRMA는 로드되었지만, AnimationMixer의 update가 렌더링 루프 내에서 호출되지 않았을 가능성이 있습니다. Clock에서 delta time을 가져와 매 프레임 mixer.update를 실행해 주세요."
문제의 원인과 수정 방침을 구체적으로 전달할 수 있기 때문에 AI의 수정 정밀도도 높아집니다.
AI로 인해 엔지니어의 가치는 떨어지는가
AI가 코드를 작성할 수 있게 되면서, 장래에 엔지니어의 가치가 떨어지지 않을까 하는 의견이 있습니다.
이번에 Replit Agent를 사용해 본 소감은 그 반대입니다.
AI에 의해 뛰어난 엔지니어의 가치는 오히려 올라갈 것이라고 생각합니다.
이유는 AI로 인해 구현 비용이 낮아지는 반면, 다음과 같은 능력이 더욱 중요해지기 때문입니다.
- 요구사항을 정리하는 능력
- 스펙 (Spec)을 정의하는 능력
- 기술을 선정하는 능력
- 설계하는 능력
- 문제를 분해하는 능력
- AI의 출력을 평가하는 능력
- 버그의 원인을 특정하는 능력
- AI의 출력을 안전하게 제어하는 능력
- 보안 및 운영을 고려하는 능력
- 프로덕트로서 성립시키는 능력
AI는 대량의 코드를 짧은 시간 안에 생성할 수 있습니다.
하지만 그 코드가 올바른지, 목적에 맞는지, 안전한지, 유지보수가 가능한지를 판단해야 합니다.
생성되는 코드의 양이 늘어날수록 리뷰와 기술적 판단의 중요성도 커집니다.
엔지니어의 생산성은 수십 배가 된다
이번과 같은 앱을 AI를 사용하지 않고 처음부터 구현한다면, 적어도 며칠에서 몇 주 정도는 필요했을 것이라고 생각합니다.
환경 구축, 라이브러리 조사, VRM 및 VRMA 로드, API 연동, 타입 에러 수정, UI 구현, 디버깅 등 세세한 작업이 대량으로 발생하기 때문입니다.
Replit Agent를 사용함으로써 이러한 작업의 상당 부분을 압축할 수 있었습니다.
- 보일러플레이트 (Boilerplate) 코드 생성
- 컴포넌트 분할
- API 클라이언트 작성
- 타입 정의 작성
- STT, TTS, LLM 연결
- JSON 응답 처리
- 표정 및 모션 제어
- 에러 처리 추가
- UI 조정
- 리팩터링 (Refactoring)
- 라이브러리 도입
- 디버깅 안 제시
엔지니어는 모든 코드를 직접 입력하는 대신 요구사항 정의, 설계, 리뷰, 의사결정에 집중할 수 있습니다.
기술 지식을 가진 엔지니어가 AI를 적절히 사용한다면, 기존과 비교하여 몇 배가 아니라 수십 배의 생산성을 실현할 수 있는 상황도 늘어날 것입니다.
특히 다음과 같은 영역에서는 효과가 클 것이라고 생각합니다.
- PoC (Proof of Concept)
- 데모 앱
- 기술 검증
- 사내 도구
- 신규 사업의 프로토타입
- 고객 제안용 목업 (Mockup)
단, 지식 없이 수십 배가 되는 것은 아니다
주의해야 할 점은 AI를 사용하는 것만으로 자동으로 생산성이 수십 배가 되는 것은 아니라는 사실입니다.
기술 지식이 없는 경우, 생성된 코드가 올바른지 판단할 수 없습니다.
그 결과, 다음과 같은 문제들이 발생합니다.
- 작동하지 않는 코드를 반복해서 다시 생성함
- 임시방편적인 수정을 반복함
- 불필요한 라이브러리가 늘어남
- 코드 구조가 복잡해짐
- LLM이 존재하지 않는 모션 (Motion)을 생성함
- JSON 파싱 (Parsing) 에러를 간과함
- 보안 문제를 놓침
- 한 번은 작동했지만, 이후의 변경으로 인해 망가짐
- AI와의 대화가 길어짐
- 결국 처음부터 다시 만듦
AI는 지식을 완전히 대체하는 것이 아닙니다.
기술 지식을 레버리지 (Leverage) 하기 위한 도구입니다.
지식이 있는 사람일수록 AI에게 올바른 지시를 내리고, 올바른 출력을 선택하며, 불필요한 구현을 버릴 수 있습니다.
따라서 AI 시대에는 기초 지식과 설계 능력의 가치가 더욱 높아질 것이라고 생각합니다.
요약
이번에는 Replit Agent를 사용하여 인터랙티브한 아바타 AI 앱을 약 3시간 만에 개발했습니다.
이번에 구현한 프로세스는 다음과 같습니다.
- 마이크로부터 음성을 가져옴
- STT (Speech-to-Text)로 음성을 텍스트로 변환함
- 텍스트를 LLM으로 전송함
- LLM이 답변 문장을 생성함
- LLM이 표정과 모션을 생성함
- TTS (Text-to-Speech)로 답변 문장을 음성으로 변환함
- 아바타가 음성을 재생함
- 아바타가 응답 내용에 따른 표정이나 모션을 표현함
짧은 시간 안에 고기능 앱을 만들 수 있었던 이유는 Replit Agent의 성능 때문만은 아닙니다.
다음 요소들이 크게 영향을 미쳤습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기