쏟아지는 소식을 첫 장면으로 보여주는 L-Proof AI 홈페이지.

L-Proof AI 홈페이지를 리디자인했습니다. 월요일과 목요일 아침 9시에 보내는 AI 브리핑 서비스인데, 이번에는 글의 내용보다 그 글을 처음 만나는 화면을 고쳤습니다.

시작은 전전회사 팀장님에게 들은 피드백이었습니다. 저는 글에는 자신이 있다고 했는데, 홈페이지가 눈에 들어오지 않으면 누가 구독하겠느냐는 이야기를 들었습니다.

생각해보니 맞는 말이었습니다. 원고는 계속 다듬으면서 홈페이지는 비교적 쉽게 만들어둔 상태였습니다. 어떤 서비스인지, 어떤 기준으로 글을 쓰는지 설명은 있었지만, 처음 들어온 사람이 그 설명을 읽고 싶어지는지는 별개의 문제였습니다.

제작 과정을 눈으로 보여줄 수 없을까

L-Proof에는 자료를 모으고 원문을 확인해 원고를 작성한 뒤, 다른 AI로 검토하고 제가 최종적으로 확인해 발행하는 과정이 있습니다.

이 과정을 홈페이지에서도 전달하고 싶었습니다. 처음에는 단계별로 설명하면 되겠다고 생각할 수 있지만, 방문자가 그 설명을 끝까지 읽는다는 보장은 없었습니다. 이미 AI 소식을 전달하는 사이트는 많은데, 제 홈페이지까지 들어와서 제작 방식부터 공부해줄 이유도 없고요.

그래서 질문을 바꿨습니다. 글을 자세히 읽지 않아도, 스크롤하면서 이 서비스가 어떤 과정을 거치는지 알 수 있게 만들 수는 없을까.

하나의 이야기를 시각적으로 풀어내려면 어떤 장치가 필요한지 고민하며 인터넷에서 여러 사례를 찾아봤습니다. 그중 스크롤에 따라 카메라가 움직이고, 같은 대상을 다른 거리와 각도에서 보여주면서 이야기가 이어지는 방식이 눈에 들어왔습니다.

처음에는 화면이 멋있다는 생각이 먼저 들었습니다. 그런데 계속 살펴보니 카메라가 어디에 가까워지는지, 언제 멈추는지, 다음 장면으로 넘어갈 때 무엇이 이어지는지가 중요했습니다. 화면에 무언가를 많이 넣는 것만으로는 같은 느낌이 나지 않았습니다.

L-Proof에서는 쏟아지는 소식이 출발점이 될 수 있겠다고 생각했습니다. 수많은 종이 사이로 들어가 한 장의 원고에 가까워지고, 그 원고가 채워지고 검토되는 과정을 따라가면 어떨까. 완성된 원고가 메일로 전달될 때까지 시선이 이어지면, 제작 과정을 길게 설명하지 않아도 되겠다는 생각이었습니다.

스크롤에 따라 원고 작성부터 검수, 사람의 승인, 메일 전달까지 이어지는 흐름.

원하는 장면을 설명하는 일이 생각보다 어려웠다

구현에는 AI를 활용했습니다. 다만 제가 원하는 경험이 바로 나오지는 않았습니다.

설명을 줄여달라고 하면 문장을 정리하고, 과정을 보여달라고 하면 단계별 카드와 제목을 배치했습니다. 3D를 넣어도 구도가 고정돼 있으면 제가 기대한 흐름과는 달랐습니다. 화면이 입체적으로 바뀌었는데도 여전히 설명을 읽어야 무슨 일이 일어나는지 알 수 있었습니다.

작업 중에는 이런 말도 했습니다.

왜 사람이 글을 읽을 거라고 생각하는 거야?

제작 단계를 소개하는 문구가 있다는 것과, 제작 과정이 눈앞에서 일어나는 것은 달랐습니다.

특히 검수 장면에서 그 차이가 컸습니다. 종이 위에 검수한다는 설명을 붙이거나 밑줄과 말풍선을 넣어도, 종이 자체에서 변화가 느껴지지 않으면 제가 원한 장면이 되지 않았습니다. 검토 전후에 무엇이 달라졌는지 보여야 했습니다.

그래서 요청도 점점 구체적으로 바뀌었습니다. 본문을 따라 내려가면 빈 여백이 드러나고, 그곳에 검토한 내용이 써지는 식으로 설명했습니다. 그런데 그 방식 역시 글자를 읽어야 의미를 파악하게 될 수 있었습니다. 무엇을 보여주려는지는 설명할 수 있는데, 실제 화면에서는 충분히 전달되지 않는 일이 반복됐습니다.

이걸 제가 이렇게까지 설명해야 하나 싶은 순간도 있었습니다. 반복해서 교정하던 시안을 인수인계 문서로 정리하고, 다른 AI 작업으로 이어가기도 했습니다. 같은 요구를 계속 덧붙이기보다, 어디서 의도가 어긋났는지 정리할 필요가 있었습니다.

장면마다 무엇이 바뀌는지부터 다시 정했다

다시 잡은 기준은 글자를 읽지 못해도 장면의 변화가 구분되는가였습니다.

멀리서 보면 수많은 종이가 쏟아집니다. 그 안으로 카메라가 들어가면 종이들이 사라지고 한 장이 남습니다. 빈 원고에 내용이 채워지고, 일부 줄은 잘려 나가고, 해석이 더해집니다. 이어서 검수하는 빛과 붉은 교정 부호가 나타납니다.

이렇게 양과 크기, 빛과 색의 변화를 먼저 정하니 각 장면에서 무엇을 강조해야 하는지가 더 분명해졌습니다.

검수 장면에서는 빛의 이동과 붉은 교정 표시로 원고의 변화를 보여줬다.

도구 이름도 역할 이름으로 바꿨습니다. 방문자가 제가 쓰는 AI 제품들을 알고 있다고 가정할 필요가 없었습니다. 작성자 AI, 검수자 AI, 최종 발행을 승인하는 사람으로 구분하면 과정에 집중할 수 있었습니다.

버린 연출도 있습니다. 종이를 접어 봉투에 넣고 날려 보내는 시도를 했는데, 접히는 면과 형태가 어색했습니다. 메일 전달을 표현하겠다고 넣은 동작이 오히려 눈에 걸렸습니다. 결국 봉투 접기는 빼고, 카메라가 승인된 종이 안으로 들어가 메일 지면으로 이어지도록 바꿨습니다.

승인 도장도 스크롤에 매달려 천천히 내려오기만 하면 힘이 없었습니다. 일정 지점까지는 스크롤을 따라오되, 그 지점을 넘으면 실제 시간으로 찍히도록 했습니다. 같은 스크롤 연출 안에서도 모든 동작을 똑같이 처리할 필요는 없었습니다.

완성된 장면 하나만 보고 판단하지 않으려고도 했습니다. 앞 장면에서 다음 장면으로 넘어가는 도중에 무엇이 보이는지 확인했습니다. 착지하는 종이가 바닥에 잘려 보이는 문제처럼, 정지 화면만 봤다면 놓쳤을 부분도 그 과정에서 수정했습니다.

운영 화면으로 옮기면서 챙긴 것들

현재 홈페이지는 쏟아지는 소식에서 시작해 원고 작성, 검수, 사람의 승인, 메일 전달로 이어집니다. 이후에는 실제 발행물과 구독 영역을 볼 수 있습니다.

승인된 원고를 따라 들어가면 메일 지면으로 이어진다.

연출에 관심이 없는 사람은 바로 구독 영역으로 이동할 수 있게 했습니다. 서비스 설명과 운영자 소개는 About 페이지로 분리했습니다. 홈페이지를 구경하러 온 사람과 필요한 정보만 확인하려는 사람을 함께 생각해야 했습니다.

움직임을 줄이는 기능과 3D 화면을 표시할 수 없는 환경의 대체 화면도 준비했습니다. 다만 실제 휴대폰과 저사양 PC에서의 체감은 계속 살펴볼 부분입니다.

원고에 쓰인 제목과 발췌문은 실제 발행물에서 가져왔습니다. 교정 표시와 승인 도장은 제작 과정을 설명하기 위한 연출입니다. 실제 원고가 화면 속 순서와 모양 그대로 편집됐다는 뜻은 아니므로, 홈페이지에도 그 점을 밝혔습니다.

기억에 남지만 조금 느리다는 피드백

리디자인한 사이트를 공유한 뒤 이런 반응을 받았습니다.

효과는 멋있고 기억에 남을 것 같은데, 조금 더 빨랐으면 좋겠다.

제가 보여주고 싶었던 장면은 전달됐지만, 보는 사람이 느끼는 속도에는 조정할 부분이 있었습니다.

연출을 만든 입장에서는 각 장면에 의미가 있으니 충분히 보여주고 싶었습니다. 하지만 처음 들어온 사람에게는 다음 내용으로 가기 위해 계속 스크롤해야 하는 구간일 수도 있었습니다.

피드백을 받은 뒤 스크롤 거리와 장면별 배분을 바로 수정했습니다. 기존에는 약 15화면 분량의 스크롤을 사용했는데, 이를 약 8.9화면 기준으로 줄였습니다. 큰 모니터에서는 화면 높이 때문에 이동 거리가 과도하게 늘어나지 않도록 상한도 뒀습니다.

전체를 같은 비율로 빠르게 돌린 것은 아닙니다. 장면 사이를 이동하는 구간은 압축하고, 원고가 작성되거나 검수되는 것처럼 변화가 중요한 구간에는 필요한 여유를 남겼습니다. 너무 오래 끌지도, 무슨 일이 일어났는지 모를 정도로 빨리 지나가지도 않게 호흡을 다시 잡았습니다.

이 변경도 현재 운영 화면에 반영돼 있습니다. 수정 후 모두에게 적절한 속도가 됐다고 단정할 수는 없지만, 피드백에서 지적한 답답함을 구체적인 조정으로 연결할 수 있었습니다.

이번 작업에서 남은 것

이번 리디자인에서는 제가 무엇을 원하는지 설명하는 것만큼, 나온 결과에서 무엇이 어긋났는지 짚는 일이 중요했습니다.

처음에는 멋있는 스크롤 화면을 만들고 싶다는 생각이 컸습니다. 작업하다 보니 어느 장면에서 무엇이 바뀌어야 하는지, 방문자가 어디를 보게 할지, 어떤 동작은 빼는 편이 나은지를 계속 판단하게 됐습니다.

AI에게 맡긴 뒤에도 제가 해야 할 일이 꽤 많았습니다. 결과가 돌아올 때마다 직접 스크롤해보고, 의도와 다르면 다시 설명하고, 어색한 부분은 고치거나 버렸습니다. 공개한 뒤에는 다른 사람이 느끼는 속도를 듣고 다시 조정했습니다.

처음 받은 피드백은 홈페이지가 눈에 들어오지 않는다는 것이었습니다. 리디자인 후에는 기억에 남지만 조금 느리다는 이야기를 들었습니다. 고쳐야 하는 문제가 달라졌고, 그다음 수정도 할 수 있었습니다.

지금의 홈페이지는 그 과정을 거쳐 나온 결과입니다. 앞으로도 실제로 보는 사람들의 반응을 들으면서 다듬어보려고 합니다.

L-Proof AI 홈페이지 둘러보기

L-Proof-AI — AI가 모으고, 사람이 증명합니다

코딩 에이전트와 LLM 소식을 원문과 직접 테스트로 검증해 보내는 개발자 브리핑.

l-proof-ai.xyz

'코딩이야기' 카테고리의 다른 글

IF 카카오 ai 컨퍼런스 1일차 정리 노트  (12) 2024.10.22

지난 글에서는 AI와 FilmCraft를 이용해 영상 제작 과정을 자동화하기 시작한 이야기를 정리했다.

처음에는 간단한 영상 하나를 만드는 것부터 시작했지만, 현재는 대본 승인과 완성본 검수를 제외한 제작 과정과 유튜브 비공개 업로드까지 자동화할 수 있게 됐다.

실제로 역사 콘텐츠를 다루는 프로젝트에서는 세 편의 에피소드를 제작했다.

그런데 세 편까지 만들어보고 나니 조금 고민되는 문제가 생겼다.

영상은 정상적으로 만들어지는데, 정작 화면에 사람이 거의 등장하지 않는 것이다.

역사적인 사건을 설명하는 콘텐츠인데 대부분의 장면이 지도와 문서, 숫자, 텍스트 애니메이션으로 구성되어 있었다.

내용을 전달하는 데 문제가 있는 것은 아니었다.

다만 역사 속 인물이 등장해 대사를 하거나 행동하는 장면이 조금 더 있었다면, 시청자들이 이야기에 몰입하기 좋지 않았을까?

처음에는 영상 생성 API의 비용을 줄이려고 했던 선택이었는데, 실제로 결과물을 만들어보니 그 선택이 콘텐츠의 표현 방식까지 제한하고 있었다.

이번 글에서는 영상 생성 API의 비용을 줄이기 위해 어떤 기준을 세웠고, 실제로 적용해보니 어떤 문제가 나타났는지 정리해보려고 한다.

1. 영상 생성 API가 생각보다 비쌌다

처음 영상 자동화를 구상했을 때는 생성형 영상 API를 적극적으로 활용할 생각이었다.

대본을 작성하고 장면별 프롬프트를 만든 다음, API로 영상을 생성해 이어 붙이는 구조다.

하지만 실제로 비용을 계산해보니 조금 부담스러웠다.

당시 검토한 Gemini 영상 생성 구성에서는 8초짜리 영상 하나를 생성하는 데 약 1달러를 예상했다.

물론 이 금액은 당시 선택한 모델과 생성 조건에 따른 견적이다. 모든 Gemini 영상 모델에 동일한 가격이 적용된다는 뜻은 아니다.

문제는 영상 한 편이 8초로 끝나지 않는다는 것이다.

1분짜리 영상에서 여러 장면을 생성형 영상으로 채우면 그만큼 호출 횟수도 늘어난다.

게다가 생성한 영상이 항상 원하는 결과로 나오는 것은 아니다.

인물의 동작이 어색하거나, 장면의 구도가 예상과 다르거나, 앞뒤 영상에서 등장인물의 모습이 달라지는 등의 문제가 생길 수 있다.

그러면 다시 생성해야 한다.

처음 계산할 때는 영상 한 편에 필요한 생성 횟수만 생각했는데, 실제 제작에서는 수정과 재생성까지 고려해야 했다.

하루에 한 편씩 제작한다고 가정하고 월간 비용을 계산해보니, 선택한 생성 조건과 재시도 횟수에 따라 한 달에 수십만 원이 발생할 가능성도 있었다.

물론 영상이 실제로 수익을 내고 있다면 이야기가 달라진다.

하지만 지금은 자동화 시스템이 제대로 동작하는지 확인하는 단계였다.

아직 콘텐츠의 반응도 충분히 검증하지 않았는데, 테스트할 때마다 영상 생성 API 비용이 발생하는 것은 부담스러웠다.

그래서 우선 편당 유료 생성 비용의 상한을 정하고, API를 호출하기 전에 예상 비용과 필요한 장면을 확인하도록 했다.

초기 제작 설정에서 잡은 상한은 편당 6달러였다.

이것도 적정 제작비를 검증해서 얻은 수치라기보다는, 실험 과정에서 예상하지 못한 과금을 막기 위해 설정한 제한에 가까웠다.

2. 그래서 Gemini를 사용하는 기준을 엄격하게 만들었다

처음 생각한 해결책은 단순했다.

코드로 만들 수 있는 장면은 코드로 만들고, 코드로 표현하기 어려운 장면에만 영상 생성 API를 사용하자.

예를 들어 역사적 사건의 발생 지역을 지도에서 보여주는 장면이 있다고 생각해보자.

굳이 AI에게 지도가 움직이는 영상을 생성하도록 요청할 필요는 없었다.

지도 이미지 위에 카메라 이동 효과를 적용하면 된다.

연도가 바뀌거나 숫자가 증가하는 장면도 마찬가지다.

텍스트와 그래픽을 코드로 생성한 다음 애니메이션을 적용하면 충분하다.

반면 여러 사람이 움직이거나 복잡한 행동을 하는 장면이라면 코드로 직접 구현하는 것이 오히려 비효율적일 수 있다.

그래서 이런 장면에서만 Gemini 영상 생성 API를 활용하도록 했다.

이 판단을 매번 직접 내리는 대신 제작 하네스에 규칙으로 넣었다.

여기서 말하는 하네스는 AI가 작업할 때 따르는 지침, 역할별 스킬, 실행 도구, 검증 절차 등을 묶어놓은 구조다.

단순히 AI에게 영상을 만들어달라고 요청하는 것이 아니라, 어떤 순서로 작업하고 어떤 조건에서 도구를 사용할지 정해두는 것이다.

당시 비용과 관련해 세운 원칙은 대략 다음과 같았다.

  • 코드 기반 연출을 우선 검토한다.
  • 생성형 영상이 반드시 필요한 경우에만 유료 API를 선택한다.
  • 유료 요청 전에는 장면과 예상 비용을 확인한다.
  • 전체 제작비가 설정한 상한을 넘지 않도록 한다.
  • 생성한 영상의 길이와 실제 음성 길이가 다를 경우 불필요한 재생성을 피한다.

이렇게 하면 AI가 영상 한 편을 만들면서 필요 이상으로 유료 API를 호출하는 일을 줄일 수 있을 것 같았다.

그리고 실제로 이 규칙은 상당히 강하게 적용됐다.

3. 11개 장면 중 Gemini를 쓰는 장면이 사라졌다

역사 콘텐츠의 새로운 에피소드를 제작하면서 흥미로운 일이 있었다.

당시 대본은 총 11개 장면으로 구성되어 있었다.

지도에서 시작해 역사적 기록을 보여주고, 사건의 전개를 설명한 다음 결말로 이어지는 방식이었다.

처음에는 이 중 한 장면에 Gemini 영상 생성을 사용하는 구성이 제안됐다.

눈보라가 몰아치는 성문을 표현하는 장면이었다.

나머지 10개 장면은 지도, 문서, 텍스트와 그래픽 애니메이션으로 처리하도록 설계됐다.

예상한 유료 영상 생성 비용은 약 1달러였다.

그런데 콘티를 살펴보면서 생각이 조금 달라졌다.

눈보라 속 성문 정도라면 이미지와 그래픽을 조합해서도 표현할 수 있지 않을까?

그래서 Gemini를 반드시 사용해야 하는 장면에만 적용하라고 기준을 더 엄격하게 요청했다.

그 결과 이번 에피소드에서 Gemini를 사용하는 장면은 0개가 됐다.

유료 영상 생성 없이 모든 장면을 구성할 수 있도록 제작 방향이 바뀐 것이다.

당시에는 꽤 만족스러웠다.

적어도 자동화 파이프라인을 검증하는 데 필요한 영상 생성 비용을 크게 줄일 수 있었기 때문이다.

그런데 이후 제작된 콘텐츠들을 다시 살펴보면서 다른 문제가 눈에 들어오기 시작했다.

4. 그런데 영상에 사람이 거의 안 나온다

세 편의 에피소드를 제작하면서 화면 구성을 살펴보니, 코드 기반으로 표현할 수 있는 장면이 대부분을 차지하고 있었다.

지도에 특정 지역을 표시한다.

문서에서 중요한 문장을 강조한다.

숫자가 증가하거나 감소한다.

연표가 움직인다.

이런 장면들이다.

내용을 전달하는 데는 충분히 활용할 수 있는 표현 방식이었다.

특히 역사 자료나 기록을 소개하는 콘텐츠에서는 문서와 지도가 중요한 시각 자료이기도 하다.

그런데 계속 이런 화면이 나오다 보니 뭔가 아쉬웠다.

역사 속 인물이 직접 등장해 말을 하거나 행동하는 장면이 거의 없었던 것이다.

예를 들어 어떤 장수가 성문을 열라고 명령하는 사건을 소개한다고 생각해보자.

문서에 남아 있는 기록을 강조하고, 성문이 열리는 모습을 그래픽으로 표현하는 방법도 있다.

하지만 장수가 등장하고, 명령하는 모습을 보여주고, 주변 인물들이 반응하는 장면을 연출한다면 이야기를 조금 더 극적으로 전달할 수 있지 않을까?

물론 생성형 영상에 인물이 등장한다고 해서 무조건 더 재미있는 영상이 되는 것은 아니다.

오히려 어색한 동작이나 부자연스러운 연출이 몰입을 방해할 수도 있다.

다만 적어도 지금의 제작 방식은 그런 연출을 충분히 시도하지 않고 있었다.

왜 그럴까?

원인을 생각해보니 내가 하네스에 설정해둔 기준과 연결되어 있었다.

영상 생성 API를 반드시 사용해야 하는가?

이 질문으로 장면을 판단하도록 했기 때문이다.

AI 입장에서는 코드로 대체할 수 있는 장면이라면 굳이 유료 API를 사용할 이유가 없었다.

그리고 대부분의 역사적 사건은 지도와 문서, 텍스트만으로도 어느 정도 설명할 수 있다.

결국 하네스는 내가 정한 규칙을 잘 따르고 있었다.

문제는 그 규칙을 적용해서 만들어진 결과물이 내가 기대했던 영상과 조금 달랐다는 것이다.

5. 하네스가 잘못 작동한 것은 아니었다

처음에는 하네스를 잘못 설정했다고 생각했다.

그런데 다시 생각해보니 조금 다른 문제였다.

처음 하네스를 설계할 때 가장 중요하게 생각했던 것은 자동화 흐름을 검증하고 제작 비용을 줄이는 일이었다.

그 목적에서는 기존 규칙이 합리적이었다.

불필요한 영상 생성을 줄이고, 코드로 처리할 수 있는 장면을 최대한 활용하도록 했기 때문이다.

실제로 전체 제작 과정도 작동했고, 여러 편의 영상을 만들 수 있었다.

그런데 이제는 상황이 달라졌다.

자동화가 가능한지는 어느 정도 확인했다.

다음으로 확인하고 싶은 것은 이 방식으로 만든 콘텐츠가 시청자에게 얼마나 재미있고 몰입감 있게 전달되는가였다.

그런 관점에서는 영상 생성 API를 최소한으로 사용하는 것이 항상 좋은 선택은 아니었다.

단순히 정보를 전달하는 장면과 이야기의 중요한 순간을 보여주는 장면은 다르게 취급할 필요가 있었다.

예를 들어 사건이 발생한 장소를 알려주는 지도는 코드로 만들어도 충분할 수 있다.

하지만 인물이 중요한 결정을 내리거나 서로 대화를 나누는 장면에서는 영상 생성 API를 사용하는 편이 더 좋은 연출을 만들 가능성이 있다.

물론 아직 그 효과를 검증한 것은 아니다.

직접 만들어보고, 기존 영상과 비교하고, 시청자 반응까지 확인해야 알 수 있는 일이다.

그래도 적어도 기존의 기준을 그대로 유지하는 것이 최선이라고 생각하지는 않게 됐다.

비용을 줄이기 위한 규칙이 결과물의 표현 범위까지 제한하고 있었기 때문이다.

6. 처음부터 완벽한 하네스를 만들 수 있을까?

이번 작업을 하면서 하네스에 대해서도 생각이 조금 달라졌다.

처음에는 작업 절차와 규칙을 상세하게 작성해두면 AI가 원하는 결과물을 안정적으로 만들어줄 수 있을 거라고 생각했다.

물론 규칙을 잘 정리하는 것은 중요하다.

실제로 하네스를 구성하면서 이전에 발견한 문제를 다음 제작에 반영할 수 있었고, 여러 AI가 동일한 기준을 참고하도록 만들 수도 있었다.

하지만 규칙을 아무리 자세하게 작성하더라도 실제 결과물이 어떻게 나올지는 만들어보기 전까지 알기 어렵다.

특히 영상처럼 정답이 명확하지 않은 작업에서는 더 그렇다.

기술적으로 정상적인 결과물과 내가 만족하는 결과물은 다를 수 있다.

AI가 지침을 정확하게 지켰는데도 기대했던 영상이 나오지 않을 수 있다는 뜻이다.

그렇다면 처음부터 완벽한 하네스를 만드는 것이 가능할까?

지금은 조금 어렵지 않을까 싶다.

물론 이미 잘 구축된 하네스를 가져와 활용하는 방법도 있다.

기존 프로젝트를 Clone해서 정해진 제작 방식에 맞게 콘텐츠를 만들면 초기 구축 시간을 줄일 수 있다.

반대로 하네스가 지원하는 표현 방식에 맞춰 콘텐츠 자체를 기획할 수도 있다.

예를 들어 문서와 지도 애니메이션에 특화된 제작 시스템이라면, 처음부터 그런 화면이 잘 어울리는 콘텐츠만 제작하는 방법이다.

이런 방식이 오히려 효율적일 수도 있다.

하지만 내가 만들고 싶은 영상의 형태가 따로 있다면 이야기가 달라진다.

그때는 기존 하네스를 그대로 사용하는 것보다 원하는 결과물에 맞게 수정하는 과정이 필요하다.

그리고 그 수정 기준은 결국 실제로 영상을 만들어보면서 발견하게 되는 것 같다.

이번에도 처음에는 비용을 줄이는 규칙이 중요했다.

하지만 실제 영상을 세 편까지 제작해보니, 이제는 인물의 등장과 행동을 더 적극적으로 표현할 필요가 있겠다는 판단으로 바뀌었다.

하네스를 잘못 만들었다기보다, 처음에 세운 기준이 실제 제작 경험을 통해 바뀐 것에 가깝다.

7. 그래서 하네스를 다시 수정하려고 한다

이제 Gemini 영상 생성 API를 사용하는 기준을 조금 바꿔보려고 한다.

기존에는 코드로 표현할 수 있는지를 먼저 판단했다.

앞으로는 장면이 영상에서 어떤 역할을 하는지를 먼저 살펴보도록 할 생각이다.

판단 기준기존 방식변경하려는 방식

우선순위 API 비용 최소화 영상의 전달력과 비용을 함께 고려
장면 선택 코드로 만들 수 있으면 코드 사용 장면의 서사적 역할부터 판단
인물 연출 필요할 때만 검토 중요한 행동·대화 장면에서 적극 검토
Gemini 사용 코드로 대체하기 어려운 경우 생성형 영상이 연출에 실질적인 가치를 더하는 경우
비용 관리 유료 호출 최소화 장면별 예상 비용과 전체 예산 관리

그렇다고 모든 장면을 생성형 영상으로 만들 생각은 아니다.

지도나 연도, 문서처럼 코드로 표현하는 편이 적절한 화면은 계속 기존 방식을 사용할 예정이다.

반면 이야기의 전환점이나 인물이 직접 행동하는 장면에서는 생성형 영상을 활용하는 방법을 적극적으로 검토하려고 한다.

특히 역사 속 인물이 대사하는 장면이라면 단순히 TTS로 내용을 읽는 것보다, 인물이 실제로 말하는 것처럼 연출했을 때 어떤 차이가 있는지도 확인하고 싶다.

물론 여기에는 새로운 문제가 생길 수 있다.

인물의 모습이 장면마다 달라질 수도 있고, 음성과 입 모양을 맞추는 작업이 필요할 수도 있다.

유료 영상 생성 횟수가 늘어나면 제작비도 증가할 것이다.

또 당시 인물이 실제로 했던 말과 콘텐츠를 위해 재구성한 대사를 구분하는 문제도 중요하다.

결국 기존에 줄였던 비용과 복잡성이 다시 늘어날 가능성이 있다.

하지만 이번에는 그 비용을 무조건 없애는 대신, 어디에 사용하는 것이 효과적인지 확인해보려고 한다.

기존 방식으로 제작한 영상도 그대로 게시할 생각이다.

어떤 판단으로 어떤 결과물이 나왔는지 확인할 수 있는 사례이기도 하고, 새로운 방식이 실제로 더 나은 결과를 만드는지 비교할 기준이 될 수 있기 때문이다.

다만 영상 몇 편의 조회수만으로 제작 방식의 우열을 판단하기는 어려울 것 같다.

소재나 게시 시점에 따른 차이도 있을 수 있으니, 앞으로는 조회수뿐 아니라 시청 지속 시간과 이탈 구간 같은 지표도 함께 살펴볼 생각이다.

아직 변경한 기준의 성과가 검증된 것은 아니다.

지금은 새로운 제작 방향을 정하고 하네스를 수정하려는 단계다.

8. 마무리하며

이번 작업은 영상 생성 API의 비용을 줄이고 싶어서 시작했다.

자동화 시스템을 검증하는 단계에서 매번 유료 영상을 생성하는 것은 부담스러웠고, 코드로 처리할 수 있는 작업을 최대한 분리하는 것이 합리적이라고 생각했다.

그리고 그 판단은 실제로 자동화 파이프라인을 구축하는 데 도움이 됐다.

하지만 세 편의 영상을 만들어보니 새로운 문제가 보였다.

영상은 만들어지고 있었다.

자동화도 작동했다.

그런데 비용을 줄이는 데 집중한 나머지, 시청자가 더 재미있게 볼 수 있을지도 모르는 장면들까지 너무 쉽게 코드 기반 연출로 대체하고 있었다.

이 경험을 통해 하네스를 바라보는 생각도 조금 달라졌다.

하네스는 한번 잘 만들어두면 끝나는 설정 파일이 아니라, 실제 결과물을 보면서 계속 조정해야 하는 제작 기준에 가까운 것 같다.

물론 이미 잘 만들어진 하네스를 그대로 활용하는 방법도 있고, 그 구조에 맞춰 콘텐츠를 기획하는 방법도 있다.

그런 방식이 더 빠르고 효율적인 경우도 분명히 있을 것이다.

하지만 내가 원하는 결과물이 그 구조와 다르다면, 결국 직접 제작하면서 기준을 수정하는 과정이 필요하다.

이번에는 비용을 아끼기 위해 만든 규칙이 예상하지 못한 방향으로 콘텐츠의 모습을 바꿨다.

이제는 그 규칙을 조금 느슨하게 만들어보려고 한다.

그렇다고 비용 최적화를 포기하는 것은 아니다.

처음에는 영상 생성 API를 얼마나 적게 사용할 수 있는지가 중요했다면, 이제는 어떤 장면에 비용을 쓰는 것이 가치 있는가를 고민하는 단계로 넘어온 것이다.

그리고 이것이 실제로 더 나은 결과로 이어질지는 아직 모른다.

비용만 늘어나고 시청자 반응에는 큰 차이가 없을 수도 있다.

반대로 몇 개의 인물 장면을 추가하는 것만으로도 영상의 분위기가 상당히 달라질 수도 있다.

그것도 직접 만들어보고 비교해봐야 알 수 있을 것 같다.

일단 자동화 시스템이 작동한다는 사실은 확인했다.

이제는 그 시스템이 어떤 영상을 만들도록 해야 할지 조금 더 고민해보려고 한다.

다음에는 이 제작 과정에서 Codex와 Claude Code를 함께 사용하면서 겪었던 문제와, 서로 다른 AI가 같은 하네스를 활용하도록 구조를 바꾼 과정을 정리해보려고 한다.


2026년 11월 1일까지의 개인 영상 자동화 프로젝트 경험을 바탕으로 작성했습니다. 본문의 API 비용은 당시 검토한 생성 조건에 따른 예상치이며, 실제 청구액이나 모든 모델의 가격을 의미하지 않습니다. 변경하려는 하네스의 영상 품질 및 시청자 반응 개선 효과는 아직 검증되지 않았습니다.

최근 유튜브 쇼츠를 자동으로 제작하는 개인 프로젝트를 진행하고 있다.

하나는 동아시아 역사의 흥미로운 사건을 소개하는 프로젝트고, 다른 하나는 고사성어를 두 캐릭터의 만담 형식으로 풀어내는 채널이다.

처음에는 AI가 대본을 작성하고, 영상과 음성을 생성한 다음 유튜브에 업로드하는 구조를 생각했다.

요즘 영상 생성 AI의 성능이 상당히 좋아졌으니, API만 잘 연결하면 생각보다 간단하게 만들 수 있지 않을까 싶었다.

그런데 실제로 영상 생성 API의 비용을 알아보니 조금 고민이 생겼다.

몇 초짜리 영상을 만드는 데도 비용이 발생하고, 원하는 결과가 나오지 않으면 다시 생성해야 한다.

한 편을 만드는 것은 큰 부담이 아닐 수 있다.

하지만 하루에 한 편씩 꾸준히 제작하고, 그 과정에서 여러 번 테스트하고 수정한다면 이야기가 달라진다.

계산에 사용한 모델과 재생성 횟수에 따라 차이는 있겠지만, 욕심을 덜어내도 비용이 한 달에 27만 원을 넘기는 것은 우스운 일이 아닐 수도 있었다.

무엇보다 이번 프로젝트에서 내가 먼저 확인하고 싶었던 것은 영상 생성 AI가 얼마나 좋은 영상을 만들어주는지가 아니었다.

AI가 기획부터 영상 제작, 검수, 업로드까지 이어지는 작업을 얼마나 자동화할 수 있는지 확인하는 것이었다.

그렇다면 모든 장면을 굳이 영상 생성 API로 만들 필요가 있을까?

이런 생각으로 다른 제작 방법을 찾아보기 시작했다.

먼저 현재 상태부터 이야기하면, 두 프로젝트 중 하나는 대본 승인과 완성본 검수라는 두 번의 사람 개입을 제외하고, 콘텐츠 조사부터 영상 제작과 유튜브 비공개 업로드까지 이어지는 자동화 파이프라인을 구축했다.

실제로 이 시스템을 통해 제작한 영상도 유튜브에 게시하고 있다.

다만 처음부터 이런 구조를 만든 것은 아니다.

영상 생성 API의 비용을 계산하고, 로컬 영상 편집 도구를 테스트하고, AI가 할 수 있는 작업과 그렇지 않은 작업을 구분하면서 조금씩 방향을 바꿨다.

이번 글부터 그 과정에서 겪었던 시행착오를 정리해보려고 한다.

1. 영상 생성과 영상 편집은 다른 문제였다

처음에는 영상 제작을 하나의 작업으로 생각했다.

하지만 실제로 필요한 기능을 나눠보니 서로 다른 작업이 꽤 많았다.

  • 대본에 맞는 이미지와 그래픽 제작
  • 이미지의 위치와 크기 변경
  • 카메라 이동과 확대·축소
  • 자막과 음성의 시간 동기화
  • 장면 전환과 효과음 삽입
  • 최종 영상 렌더링

여기서 모든 작업에 생성형 영상 AI가 필요한 것은 아니었다.

예를 들어 역사적 사건의 연도를 표시하거나, 지도에서 특정 지역으로 카메라가 이동하는 장면을 생각해봤다.

이런 화면은 이미지와 텍스트의 위치를 코드로 제어해도 충분히 구현할 수 있을 것 같았다.

반면 사람이 걷거나 전투를 벌이는 등 복잡한 움직임을 자연스럽게 표현하려면 이야기가 조금 다르다.

그렇다면 단순한 장면은 코드로 만들고, 복잡한 움직임이 꼭 필요한 경우에만 영상 생성 API를 사용하는 방법도 가능하지 않을까?

다만 이것도 어디까지나 가설이었다.

코드로 장면을 만들 수 있다는 것과 실제로 볼 만한 영상이 나온다는 것은 별개의 문제이기 때문이다.

그래서 우선 자동으로 영상을 편집하고 출력할 수 있는 도구부터 확인하기로 했다.

2. FilmCraft를 확인해봤다

이번에 선택한 도구는 FilmCraft였다.

FilmCraft는 로컬에서 실행되는 영상 편집기로, CLI와 MCP를 통해 외부 프로그램이나 AI 에이전트가 편집 기능을 호출할 수 있다.

내가 사용한 환경에서는 FilmCraft 0.15.0이 설치되어 있었고, Claude Code로 실제 설치된 프로그램의 기능을 조사했다.

확인된 명령 목록은 711개였다.

시퀀스 생성, 타임라인 배치, 그래픽 삽입, 키프레임 제어, 오디오 믹싱, 자막 처리, 영상 내보내기 등의 명령이 포함되어 있었다.

물론 명령이 711개 있다고 해서 모든 기능을 원하는 방식으로 사용할 수 있다는 의미는 아니다.

실제로 실행할 수 있는지, 결과물의 품질은 어떤지 확인하는 과정이 필요했다.

우선 간단한 그래픽 영상을 만들어볼 수 있는지부터 살펴봤다.

구조는 대략 다음과 같았다.

AI 에이전트
    ↓
대본 / 장면 데이터
    ↓
코드로 이미지와 그래픽 생성
    ↓
FilmCraft CLI 또는 MCP
    ↓
타임라인 조립 / 효과 적용
    ↓
MP4 출력

전체 제작 과정에서 사용하는 도구와 역할도 나누어봤다.

도구담당 역할활용 방식

FilmCraft 영상 편집 및 조립 장면 배치, 키프레임, 전환, 오디오 믹싱, 자막, MP4 출력
Claude Code / Codex 제작 과정 제어 조사, 대본과 콘티 작성, 스크립트 실행, 검증 작업 조율
Python / Pillow 코드 기반 화면 제작 지도, 문서, 텍스트 그래픽, 도트 캐릭터와 프레임 생성
ImageGen 정지 이미지 생성 배경 및 시각 자료 제작
Gemini 영상 API 복잡한 움직임 생성 코드로 표현하기 어려운 장면에 선택적으로 사용
Azure Speech TTS 한국어 음성 합성 내레이션과 캐릭터별 음성 생성
FFmpeg 영상·오디오 후처리 미디어 변환, 영상 검사, 편집 기능 보완
MCP / CLI 도구 연결 AI 에이전트가 FilmCraft의 기능을 호출
Harness / Skills 제작 절차 표준화 조사, 대본, 렌더링, 검수 절차 및 사용 규칙 재사용

여기에 정리한 도구가 모든 영상에서 빠짐없이 실행되는 것은 아니다.

콘텐츠에 따라 필요한 도구가 달라지고, 초기에는 일부 기능이 설계 단계에 있기도 했다.

이 구조에서 AI는 영상의 모든 프레임을 직접 생성하는 것이 아니다.

필요한 장면을 설계하고, 코드와 편집 도구를 이용해 결과물을 만드는 역할에 가깝다.

개인적으로는 이쪽이 이번 프로젝트의 목적에 더 잘 맞았다.

같은 장면을 여러 번 수정하더라도 매번 영상 생성 API를 호출할 필요가 없고, 자막이나 타이밍 같은 요소를 코드로 조정할 수 있기 때문이다.

3. 도트 애니메이션을 만들려다 발견한 문제

고사성어를 다루는 채널은 고정된 도트 캐릭터 두 명이 대화하는 방식으로 기획했다.

매번 캐릭터를 새로 생성하는 대신, 최초에 만든 캐릭터를 재사용하면서 표정과 동작만 바꾸는 구조다.

그래서 도트 그래픽을 코드로 만들고 확대하는 방법을 확인했다.

초기 설계는 180×320 크기로 장면을 만든 다음, 이를 6배 확대해 1080×1920 영상으로 사용하는 방식이었다.

그런데 여기서 예상하지 못한 문제가 하나 나왔다.

FilmCraft에서 저해상도 도트 이미지를 그대로 확대하면 경계가 흐려졌다.

도트 그래픽은 픽셀의 경계가 선명해야 하는데, 확대 과정에서 보간이 적용되면서 의도한 느낌과 달라지는 것이다.

처음에는 단순히 확대하면 될 줄 알았다.

하지만 도트 그래픽에서 확대 방식은 생각보다 중요한 문제였다.

그래서 방법을 조금 바꿨다.

FilmCraft에 작은 이미지를 넣고 확대하는 대신, 이미지 제작 단계에서 최근접 이웃 보간(Nearest Neighbor)으로 미리 확대하기로 했다.

그렇게 만든 PNG를 FilmCraft에서 원래 크기로 배치하니 도트의 경계가 선명하게 유지되는 것을 확인했다.

문제가 해결되긴 했지만 조금 재미있었다.

영상 편집기를 이용해 도트 애니메이션을 만들겠다고 시작했는데, 처음 확인한 문제는 애니메이션이 아니라 이미지 확대 방식이었다.

덕분에 화면을 어떤 도구에서 만들어야 하는지도 조금 명확해졌다.

도트 화면 자체는 전용 렌더러에서 만들고, FilmCraft는 장면 조립과 영상 편집을 담당하도록 역할을 나누는 편이 낫겠다고 판단했다.

다만 이 결과는 도트 확대 방식에 대한 검증이었다.

이것만으로 캐릭터의 움직임이나 표정 변화까지 자동으로 만들어낼 수 있다는 의미는 아니었다.

그 부분은 별도로 확인해야 했다.

4. 실제로 짧은 영상을 만들어봤다

기능 목록만 확인해서는 감이 잘 오지 않았다.

그래서 별도로 간단한 영상 테스트도 진행했다.

마침 가지고 있던 애니메이션 전투 장면의 스케치가 있어서, 이를 채색한 다음 짧은 액션 영상처럼 연출해보기로 했다.

원하는 것은 단순했다.

두 장면을 연결하고, 카메라를 확대하거나 흔들면서 타격 순간에 효과를 넣어보는 것이었다.

Codex에서 이미지 생성 기능을 사용해 장면을 준비하고, FilmCraft의 MCP 명령으로 타임라인을 구성했다.

실제로 사용한 작업은 다음과 같았다.

  • 이미지를 타임라인에 배치
  • 키프레임으로 위치와 확대 비율 변경
  • 타격 순간에 짧은 플래시 삽입
  • 장면 전환과 화면 흔들림 조정
  • MP4로 내보내기

결과적으로 720×1280 해상도, 30fps, 135프레임의 영상을 생성했다.

길이는 4.5초였다.

FilmCraft의 내보내기 결과에는 렌더링 처리 시간 약 3.26초가 기록됐다.

출력된 MP4를 다시 불러와 파일을 확인하는 과정까지 진행했다.

짧은 영상이었지만, AI가 편집 명령을 호출해 실제로 영상 파일을 만드는 과정이 작동한다는 점은 확인할 수 있었다.

다만 별도의 FFmpeg 검증은 당시 로컬 실행 환경 오류로 완료하지 못했다.

그렇다고 여기서 모든 문제가 해결된 것은 아니었다.

5. 그런데 이건 애니메이션이 아니잖아?

완성된 결과물을 보고 처음에는 꽤 괜찮다고 생각했다.

스케치가 채색된 장면으로 바뀌고, 카메라가 움직이면서 타격 효과도 들어갔다.

그런데 다시 보니 내가 원했던 애니메이션과는 차이가 있었다.

인물이 움직이는 것이 아니라 이미지가 움직이고 있었다.

캐릭터의 팔이나 무기가 프레임마다 다른 자세로 움직이는 것이 아니라, 준비된 이미지를 확대하고 이동시키는 방식이었다.

영상으로서의 움직임은 있지만 캐릭터 자체의 움직임은 없는 셈이다.

그래서 Codex에게 물어봤다.

"그럼 인물과 무기가 프레임마다 움직이는 완전한 애니메이션도 가능해?"

답변은 조금 달랐다.

현재 연결된 이미지 생성 기능과 FilmCraft만으로는 원하는 수준의 연속 동작을 바로 생성하기 어렵다는 것이었다.

FilmCraft는 이미 존재하는 이미지와 영상을 편집하고 움직임을 연출할 수 있지만, 그것만으로 복잡한 캐릭터 동작을 자동으로 만들어주지는 않는다.

이 부분은 처음부터 구분했어야 하는 문제였다.

키프레임으로 카메라를 이동시키는 것과 캐릭터 자체를 프레임마다 움직이게 하는 것은 구현 방법부터 다르다.

이후에는 프로젝트에 이미 준비되어 있던 Gemini 영상 생성 흐름도 다시 확인했다.

재미있게도 Codex가 처음에는 연결된 영상 생성 수단이 없다고 설명했는데, 실제 저장소에는 이미 Gemini API를 호출하는 코드가 있었다.

프로젝트에 구현된 기능과 현재 세션에 직접 연결된 도구를 혼동한 것이었다.

AI가 기존 프로젝트를 충분히 확인하지 않고 현재 사용할 수 있는 기능만으로 판단하면 이런 일이 생길 수도 있겠다는 생각이 들었다.

어쨌든 이 테스트로 구분할 수 있는 것은 명확해졌다.

카메라 움직임과 간단한 그래픽 연출은 코드와 편집 도구로 처리할 수 있다.

하지만 복잡한 인물 동작까지 같은 방법으로 자연스럽게 표현하기는 어렵다.

그 부분은 별도의 애니메이션 로직을 구현하거나 영상 생성 도구를 이용해야 한다.

6. 그러면 영상 생성 API를 쓰는 게 낫지 않을까?

물론 그럴 수도 있다.

오히려 제작하려는 영상에 따라서는 생성형 영상 API를 사용하는 편이 훨씬 합리적일 것 같다.

예를 들어 실제 사람처럼 자연스럽게 움직이는 캐릭터나 복잡한 전투 장면을 표현한다면, 코드로 직접 애니메이션을 만드는 데 들어가는 시간이 훨씬 클 수도 있다.

내가 코드 기반 제작을 선택한 이유는 이것이 영상 제작의 더 우수한 방법이라고 생각했기 때문이 아니다.

당시 영상 생성 API의 비용이 생각보다 만만치 않았고, 여러 편을 계속 제작하기 전에 자동화 흐름 자체를 검증하고 싶었기 때문이다.

이번 프로젝트에서 확인하고 싶었던 것은 다음과 같았다.

AI가 대본을 작성하면 장면 데이터를 만들 수 있는가?

장면 데이터를 바탕으로 화면을 자동 구성할 수 있는가?

음성과 자막을 합쳐 영상으로 출력할 수 있는가?

그리고 이 과정을 반복 실행할 수 있는가?

이 질문에 답하기 위해 모든 장면을 고품질 영상 생성 API로 만들 필요는 없었다.

오히려 테스트 과정에서 영상 생성 API를 계속 호출한다면, 실제 콘텐츠의 품질을 검증하기도 전에 비용부터 늘어날 수 있었다.

그래서 복잡한 장면은 일단 미뤄두고, 코드로 구현할 수 있는 화면부터 만들어보기로 했다.

이 방식에도 단점은 있다.

원하는 애니메이션을 직접 구현해야 하고, 코드 기반 연출만으로는 표현할 수 있는 장면에 한계가 있다.

또 영상 생성 비용을 아끼더라도 이를 위한 개발 시간과 AI 에이전트 사용 비용은 별도로 발생한다.

따라서 단순히 API 호출 비용이 적다는 이유만으로 전체 제작비가 더 저렴하다고 단정할 수는 없다.

지금은 이 구조가 현재 실험 목표에 더 적합하다고 판단한 정도가 맞을 것 같다.

실제로 두 프로젝트도 같은 제작 방식을 사용하지 않는다.

역사적 사건을 소개하는 영상은 지도와 문서, 연도, 인물 관계 등을 코드로 표현할 수 있는 경우가 많다.

반면 고정 캐릭터가 대화하는 영상에서는 매번 새로운 장면을 생성하기보다 캐릭터 에셋을 재사용하는 것이 더 중요했다.

그래서 전자는 필요한 장면에 한해 영상 생성 API를 사용하는 방식을 검토하고, 후자는 유료 영상 생성 API를 사용하지 않는 방향으로 설계했다.

어느 쪽이 더 좋은 방식이라고 단정하기는 어렵다.

콘텐츠의 형태도 다르고, 지금 해결하려는 문제도 다르기 때문이다.

7. FilmCraft를 사용하면서 확인한 것

초기에 확인한 기능 중에는 흥미로운 결과도 있었다.

간단한 4초 영상의 내보내기 테스트에서는 약 4.07초가 걸렸다.

또한 여러 편집 명령을 개별적으로 실행하는 것보다 배치로 실행하는 방식이 훨씬 빨랐고, 측정한 조건에서는 명령당 처리 속도에 약 60배 차이가 났다.

이 결과를 모든 영상 작업에 일반화할 수는 없다.

복잡한 효과나 고해상도 영상이 추가되면 렌더링 시간이 달라질 수 있고, 실제 제작에서는 이미지 준비와 음성 생성 시간도 포함해야 한다.

그래도 자동화 도구로서 사용할 가능성을 확인하기에는 유용했다.

반대로 한국어 음성 같은 부분에서는 제약도 발견했다.

FilmCraft의 내장 TTS는 확인 당시 영어만 지원했기 때문에, 한국어 내레이션과 캐릭터 대화에는 외부 음성 생성 도구가 필요했다.

결국 모든 기능을 FilmCraft 하나로 해결하는 구조는 아니었다.

화면은 코드로 만들고, 한국어 음성은 외부 TTS로 생성하고, FilmCraft에서 이 요소들을 조립하는 방식으로 역할을 분리해야 했다.

이렇게 보면 자동화 시스템은 특정 도구 하나를 잘 사용하는 문제가 아니었다.

각 도구가 잘하는 작업과 그렇지 않은 작업을 나누고, 결과물을 다음 단계로 전달하는 구조를 만드는 문제에 가까웠다.

그리고 처음에는 별도로 생각하지 않았던 문제도 있었다.

바로 AI 에이전트마다 사용할 수 있는 도구가 다르다는 점이다.

Codex에서 사용하던 이미지 생성 기능이 Claude Code에서는 동일한 방식으로 제공되지 않았고, FilmCraft의 실시간 MCP 연결 상태도 서로 달랐다.

같은 프로젝트를 읽는다고 해서 두 AI가 동일한 작업을 바로 실행할 수 있는 것은 아니었다.

반면 Python 스크립트나 검증 도구처럼 프로젝트 안에 파일로 존재하는 기능은 상대적으로 공유하기 쉬웠다.

이런 차이도 이후 제작 절차를 정리할 때 고려해야 했다.

8. 결국 유튜브 비공개 업로드까지 연결했다

처음 FilmCraft를 테스트했을 때는 4.5초짜리 영상을 만드는 것도 하나의 검증 과제였다.

하지만 프로젝트를 계속 진행하면서 실제 콘텐츠 제작에 필요한 작업들을 하나씩 연결했다.

소재를 조사하고, 대본을 작성하고, 장면별 콘티를 만들고, 음성과 자막을 생성한 다음 영상으로 조립하는 과정이다.

여기에 제작 결과를 검사하는 절차와 유튜브 비공개 업로드까지 연결했다.

현재 역사 콘텐츠를 제작하는 프로젝트에서는 다음과 같은 흐름으로 작업하고 있다.

새로운 에피소드 제작 요청
    ↓
기존 에피소드 및 중복 여부 확인
    ↓
역사 소재 조사 / 사료 교차 검증
    ↓
대본 및 장면별 콘티 작성
    ↓
[사용자: 대본 승인]
    ↓
장면별 시각 자료 제작
    ↓
음성 / 자막 / 영상 조립
    ↓
자동 검증 및 결과물 생성
    ↓
[사용자: 완성본 검수]
    ↓
유튜브 비공개 업로드
    ↓
공개 여부 및 시점은 직접 결정

여기서 사람이 개입하는 지점은 의도적으로 남겨두었다.

첫 번째는 대본 승인이다.

역사 콘텐츠에서는 사실관계도 중요하지만, 어떤 내용을 전달할지와 어떤 방식으로 이야기를 풀어갈지도 중요하다.

AI가 자료를 조사하고 대본을 작성하더라도 최종적으로 어떤 이야기를 만들지는 직접 확인하고 싶었다.

두 번째는 완성본 검수다.

코드로 영상의 길이나 자막 위치, 파일 형식 등을 검사할 수는 있다.

하지만 영상이 실제로 재미있는지, 연출이 어색하지 않은지, 전달하려는 내용이 제대로 느껴지는지는 단순한 자동 검사만으로 판단하기 어렵다.

그래서 완성본을 직접 확인하는 절차를 유지했다.

이 두 단계의 확인을 제외하면 나머지 제작 과정과 비공개 업로드는 자동화된 흐름으로 실행할 수 있게 됐다.

물론 문제가 생겼을 때 수정하거나 다시 검증하는 작업까지 완전히 사라졌다는 뜻은 아니다.

실제로 유튜브에 자막을 등록하는 과정에서는 자동 생성 자막에 역사 용어와 숫자 오류가 있어 준비한 자막 파일로 교체한 적도 있었다.

또 대본의 예상 길이와 실제 음성 길이가 달라지거나, 모바일 화면에서 자막이 지나치게 길어지는 문제도 발견했다.

이런 문제는 해당 작업만 수정하고 끝내기보다 다음 제작에서도 반복되지 않도록 검증 규칙과 제작 절차에 반영하는 방향으로 정리했다.

결국 초기에는 영상 하나를 출력하는 방법을 확인했다면, 지금은 여러 단계로 구성된 제작 절차가 실제로 연결되어 동작하는 상태까지 발전한 셈이다.

다만 자동화 파이프라인을 구현했다는 사실이 곧 지속적으로 좋은 콘텐츠를 만들 수 있다는 의미는 아니다.

영상의 품질과 시청자의 반응, 장기적인 제작 비용은 별도로 확인해야 한다.

9. 마무리하며

처음에는 AI로 유튜브 쇼츠를 자동 제작하는 것이 생각보다 간단할 거라고 생각했다.

그런데 실제로 도구를 조사하고 테스트해보니 영상 생성과 영상 편집, 캐릭터 애니메이션은 서로 다른 문제였다.

FilmCraft로 영상을 만드는 데는 성공했지만, 그것이 내가 원하는 모든 움직임을 만들 수 있다는 의미는 아니었다.

또 하나의 편집 도구에 모든 기능을 맡기기보다 여러 도구의 역할을 분리하는 편이 현재 목적에 더 적합했다.

그렇게 제작 과정을 조금씩 연결한 결과, 현재는 사람의 대본 승인과 완성본 검수를 제외한 제작 및 비공개 업로드 과정을 자동화할 수 있게 됐다.

그렇다고 이 방식이 모든 영상 제작에 적합하다고 생각하지는 않는다.

영상 생성 API를 더 적극적으로 활용했다면 훨씬 자연스럽고 화려한 결과물을 만들 수 있었을지도 모른다.

반대로 코드 기반 제작을 고집하다 보면 직접 구현하고 유지해야 할 부분이 많아져 오히려 비효율적일 수도 있다.

다만 이번에는 높은 영상 품질 자체보다, 비용을 통제하면서 전체 제작 과정이 실제로 작동하는지 확인하는 것이 우선이었다.

그리고 그 목표에 대해서는 의미 있는 결과를 얻었다고 생각한다.

개인적으로 이번 작업에서 흥미로웠던 부분은 처음에 생각했던 방식과 실제로 구현한 방식이 꽤 달라졌다는 점이다.

처음에는 영상 생성 AI를 잘 연결하면 될 거라고 생각했다.

하지만 실제로는 영상 생성 API를 언제 사용하지 않을지 결정하고, 코드와 로컬 도구로 처리할 수 있는 작업을 분리하면서 자동화 구조를 만들어갔다.

새로운 기술을 사용할 수 있다고 해서 반드시 모든 곳에 사용할 필요는 없었다.

현재 해결하려는 문제에 적합한 방법을 선택하는 것이 더 중요했다.

물론 아직 확인할 것은 남아 있다.

지금은 실제로 자동화된 시스템을 통해 콘텐츠를 제작하고 있지만, 장기간 운영했을 때에도 품질과 비용을 유지할 수 있을지는 더 지켜봐야 한다.

영상 한 편을 만드는 데 사용하는 API 비용뿐 아니라, AI 에이전트의 작업 비용과 수정에 드는 시간도 함께 고려해야 한다.

그리고 자동으로 제작한 영상이 실제 시청자에게 얼마나 매력적으로 느껴지는지는 또 다른 문제다.

자동화 시스템을 만들었다는 것과, 그 시스템으로 지속 가능한 콘텐츠를 운영할 수 있다는 것은 다른 이야기다.

일단 첫 번째 목표였던 제작 과정의 자동화는 상당 부분 달성했다.

이제는 실제 운영을 통해 이 방식이 얼마나 효율적인지 확인할 차례다.

다음에는 영상 생성 API의 비용을 실제 제작 단위로 계산하면서, 어디에 돈을 쓰고 어디에서 아낄지를 고민했던 과정을 조금 더 자세히 정리해보려고 한다.


2026년 11월 1일까지의 개인 개발 환경과 제작 실험을 바탕으로 작성했습니다. 본문의 성능 수치는 제한된 테스트 결과이며, 실제 운영 환경이나 다른 영상 제작 조건에서 동일한 결과를 보장하지 않습니다. 영상 생성 API 비용과 장기적인 제작 효율은 별도로 검증할 예정입니다.

최근 개인 프로젝트를 진행하면서 Claude Code, Codex, ChatGPT 등 여러 AI 도구를 함께 사용하고 있다.

도구마다 강점이 다르다 보니 상황에 맞춰 사용하고 있는데, 프로젝트가 늘어나면서 조금씩 번거로운 문제가 생기기 시작했다.

AI마다 알고 있는 프로젝트의 맥락이 다르다는 것이다.

어떤 세션에서는 이미 해결한 문제를 다른 세션에서는 처음부터 다시 설명해야 했다. 이전에 합의했던 설계 원칙을 모르는 AI가 기존 코드와 다른 방식으로 구현하거나, 오래된 문서를 기준으로 현재 상태를 설명하는 일도 있었다.

처음에는 프롬프트나 인수인계 문서를 조금 더 잘 작성하면 해결할 수 있을 거라고 생각했다.

그런데 여러 프로젝트를 오가다 보니 단순히 설명을 잘하는 문제는 아니라는 생각이 들었다.

결국 AI가 바뀔 때마다 맥락을 다시 전달하는 것이 아니라, AI들이 공통으로 참조할 수 있는 지식을 별도로 관리하는 편이 낫지 않을까?

이런 생각으로 로컬 기반의 개인 Wiki를 구축하기 시작했다.

이번 글은 그 과정에서 어떤 기술을 선택했고, 실제로 효과가 있었는지, 그리고 예상하지 못했던 어떤 문제가 발견됐는지를 정리한 기록이다.

1. AI가 기억하는 내용은 어디까지 믿을 수 있을까?

여러 AI를 함께 사용하는 과정에서 기억에 남는 사례가 있다.

기존에 Tailwind를 사용하던 프로젝트의 메인 페이지를 새로 구현하도록 AI에 요청한 적이 있었다.

Figma 디자인과 애니메이션 요구사항을 전달했는데, 결과물을 확인해 보니 기존 프로젝트와 다르게 styled-components를 사용하고 있었다.

당장 화면을 구현하는 데 문제가 있는 것은 아니었다.

다만 프로젝트의 다른 컴포넌트와 스타일링 방식이 달라지면 이후 코드를 수정하거나 재사용할 때 불필요하게 복잡해질 수 있다고 판단했다.

결국 기존 Tailwind 방식으로 다시 정리하고, Tailwind만으로 표현하기 어려운 애니메이션은 별도의 CSS 클래스로 처리했다.

이후에는 AI가 코드를 수정하거나 생성하기 전에 비슷한 역할의 기존 컴포넌트와 페이지를 먼저 살펴보도록 작업 지침을 보완했다.

이 경험에서 중요했던 것은 특정 CSS 기술의 우열이 아니었다.

AI가 현재 작업에 집중하는 동안 프로젝트 전체에서 지켜야 할 원칙을 놓칠 수 있다는 점이었다.

그 원칙이 다른 AI 세션에 전달되지 않는다면 비슷한 문제가 반복될 수도 있었다.

서로 다른 프로젝트가 같은 정보를 공유해야 한다면?

개인적으로는 오래전부터 구상해 온 하나의 창작 세계관을 소설과 게임이라는 서로 다른 매체로 확장하는 작업도 진행하고 있다.

두 프로젝트는 공통 설정을 공유하지만, 매체의 특성에 따라 일부 표현이나 구현 방식은 달라질 수 있다.

여기서도 비슷한 고민이 생겼다.

어떤 설정이 공식적으로 확정된 내용인지, 아직 아이디어 단계인지, 특정 매체에서만 적용하는 각색인지 구분할 필요가 있었다.

이를 여러 AI 세션에 나누어 전달하면서 작업한다면 이전 결정이 누락되거나 서로 다른 설정을 기준으로 결과물이 만들어질 위험이 있다.

소프트웨어 프로젝트에서도 같은 구조의 문제가 나타난다.

공통으로 유지해야 하는 규칙이 있고, 프로젝트마다 다른 구현이 있으며, 시간이 지나면서 기존 결정이 변경되기도 한다.

그렇다면 필요한 것은 단순히 긴 인수인계 문서가 아니라, 확정된 정보와 프로젝트별 해석, 변경의 역사를 구분해 관리하는 지식 기반이라고 생각했다.

2. 처음부터 거대한 RAG 시스템을 만들 필요는 없었다

개발자 커뮤니티에서 개인 로컬 Wiki를 구축하고 여러 AI 도구와 연동해 활용한다는 사례를 접했다.

마침 내가 겪고 있던 문제와도 연결되는 부분이 많았다.

다만 처음부터 모든 과거 대화를 수집하거나, 로컬 LLM과 벡터 데이터베이스를 붙여 거대한 지식 시스템을 만들 생각은 없었다.

과거의 모든 기록을 완벽하게 복원하는 것은 작업 범위도 너무 컸고, 무엇보다 그 과정에서 잘못된 정보를 확정된 사실로 가져올 위험도 있었다.

그래서 이번에는 현재를 기준점으로 삼기로 했다.

주요 프로젝트의 현재 상태와 최근에 확정한 결정만 먼저 정리하고, 이후 발생하는 활동과 판단을 지속적으로 기록하는 방식이다.

초기에 정한 요구사항은 비교적 단순했다.

  • 프로젝트별 현재 상태와 의사결정 이력을 구분한다.
  • 중요한 지식에는 출처와 확인 시점을 남긴다.
  • AI가 제안한 내용과 승인된 내용을 구분한다.
  • Claude Code 외의 다른 AI도 접근할 수 있어야 한다.
  • 매번 전체 문서를 읽히는 대신 필요한 정보만 조회한다.

특히 이번 Wiki는 별도의 판매용 제품이 아니라 내 개발 환경을 지원하는 내부 인프라다.

따라서 기능을 많이 넣는 것보다 실제로 유지하고 사용할 수 있는 구조를 만드는 데 집중했다.

3. Markdown, SQLite, MCP로 시작한 구조

초기 구현에서는 Markdown과 Git을 지식 원본으로 사용하고, Node.js 내장 SQLite를 검색 색인에 활용했다.

Wiki에 저장할 데이터는 출처가 다른 여러 종류의 지식이다.

프로젝트 현황, 설계 결정, 테스트 결과, 문서, 현재 유효한 사실, 과거에 사용했던 표현 등이 포함된다.

이 정보를 AI가 동일한 방식으로 소비할 수 있도록 CLI를 만들고 MCP 서버를 연결했다.

현재 구현된 주요 기능은 다음과 같다.

기능역할

hw validate 지식 구조와 승인 상태 등의 유효성 검사
hw search 지식 검색
hw show 문서 원문 조회
hw timeline 시간순 변경 기록
hw brief 프로젝트별 현재 상태와 주요 맥락 요약
hw ingest 지원 대장 등 기존 데이터 가져오기
MCP 서버 외부 AI 세션에서 Wiki 기능 호출
정적 HTML 뷰 프로젝트 허브, 검색, 타임라인, 관계 그래프

웹 화면은 현재 탐색을 위한 정적 스냅샷 형태다.

문서를 직접 편집하는 기능까지 웹에 구현하지는 않았다. 데이터 수정과 검증, 승인 기능은 기존 파일과 CLI를 중심으로 관리한다.

이렇게 하면 편집 UI를 위해 별도의 상태 동기화 구조를 추가하지 않아도 된다.

한국어 검색은 어떻게 처리할까?

초기에는 검색 방식부터 비교했다.

실제 문서 177개와 검색 질의 30개를 이용해 네 가지 검색 방식을 시험했다.

그 결과, 공백을 제거한 문자열에 trigram 검색을 적용하고 두 글자 이하의 질의에는 LIKE를 사용하는 방식이 준비한 평가 세트에서 가장 좋은 재현율을 기록했다.

평가 항목결과

평가 문서 177개
질의 30개
비교한 검색 방식 4가지
기본 방식 재현율 81.5%
선택한 방식 재현율 100%

기본 방식에서는 조사가 붙은 검색어를 놓치는 문제가 있었다.

물론 여기서 재현율 100%라는 것은 평가에 사용한 30개 질의에서 원하는 결과를 찾았다는 뜻이지, 모든 한국어 검색이 완벽하다는 의미는 아니다.

하지만 현재 문서 규모와 사용 목적에서는 더 복잡한 검색 시스템을 당장 도입할 이유가 충분하지 않았다.

그래서 벡터 검색과 로컬 LLM 기반 의미 검색은 일단 보류했다.

기능을 추가할 수 있다는 이유만으로 추가하지 않기로 했다.

4. 검색보다 먼저 해결해야 했던 문제: 무엇을 사실로 볼 것인가?

초기 데이터를 정리하는 과정에서 예상보다 많은 불일치를 발견했다.

그중 일부는 실제 오류였지만, 일부는 서로 다른 목적의 문서에서 발생한 정상적인 차이였다.

예를 들어 하나의 경험이라도 작성 목적에 따라 강조하는 부분이 달라질 수 있다.

기술적인 의사결정을 설명하는 문서에서는 구현 과정이 중요하지만, 외부에 제출하는 소개 자료에서는 해당 경험이 어떤 문제를 해결했는지가 더 중요할 수 있다.

따라서 특정 문서에 정보가 빠져 있다는 이유만으로 모순이라고 판단해서는 안 된다.

반대로 과거에 작성한 문서에 잘못된 내용이 존재할 수도 있다.

그 문서가 실제로 사용됐다는 사실과, 문서에 적힌 내용이 현재도 정확하다는 사실은 서로 다르다.

이 문제를 해결하기 위해 데이터를 세 가지 개념으로 분리했다.

Canonical Facts

현재 확인된 기준 사실이다.

실제 프로젝트의 구현 내용이나 사용자가 확인한 경력 사실처럼, 다른 문서를 작성할 때 기준으로 삼을 정보가 여기에 해당한다.

Contextual Representations

목적이나 대상에 맞게 기준 정보를 선별하고 표현한 결과다.

특정 프로젝트의 소개 문서나 외부 제출 자료처럼 같은 사실을 서로 다른 관점에서 설명할 수 있다.

Historical Snapshots

특정 시점에 실제로 사용했던 문서의 원본이다.

이후 오류가 발견되더라도 해당 문서를 과거에 사용했다는 기록까지 변경하지 않는다.

대신 현재 확인된 사실과 정정 기록을 연결한다.

이 구분은 단순한 문서 정리를 넘어, AI가 서로 다른 출처를 읽었을 때 무엇을 기준으로 판단해야 하는지를 정의하는 데 필요했다.

5. AI의 잘못된 분석이 다른 AI에게 전달된 사례

Wiki 설계 과정에서 실제로 흥미로운 문제가 발생했다.

Claude Code가 기존 자료를 분석하면서 회사 이름의 식별자가 일관되지 않다고 보고했다.

나는 그 분석을 다른 AI에게 전달했고, 다른 AI도 이를 데이터 모델의 문제로 받아들였다.

그런데 이후 실제 필드를 다시 검토해 보니 최초 판단이 잘못됐다는 사실이 드러났다.

표시용 이름과 이미 정규화된 식별자를 혼동한 것이었다.

실제로 개선해야 할 부분은 다른 데이터 목록에 식별자가 누락되어 있거나, 서로 다른 플랫폼의 동일한 항목을 연결하지 못하는 문제였다.

결과적으로 AI의 잘못된 최초 분석이 다른 AI의 판단 근거로 전달된 것이다.

이 과정을 보면서 단순히 출처를 저장하는 것만으로는 부족하다는 생각이 들었다.

어떤 결론이 왜 만들어졌고, 무엇을 근거로 수정됐는지도 추적할 수 있어야 했다.

그래서 기존의 잘못된 판단을 조용히 덮어쓰기보다 정정 이벤트로 남겼다.

이후에는 지식의 승인 상태도 별도로 검증하도록 했다.

실제로 첫 검증에서는 승인 기록 없이 확정 상태로 표시된 노트 등 여러 위반 사항이 발견됐다.

검증기가 이를 찾아내면서 데이터 구조를 바로잡을 수 있었다.

이번 작업에서 가장 의미 있었던 경험 중 하나는, Wiki를 구축하는 과정에서 발생한 오류 자체가 Wiki에 기록할 첫 번째 지식이 되었다는 점이다.

6. 실제 A/B 테스트: Wiki가 토큰을 줄여줄까?

기능이 어느 정도 갖춰진 뒤에는 원천 문서를 직접 읽는 방법과 Wiki를 사용하는 방법을 비교했다.

시험에는 별도의 Claude Code 서브에이전트를 활용했다.

질문과 정답 기준은 실험 전에 파일로 등록했다.

평가 조건은 다음과 같다.

조건 A — 원천 문서 직접 조회

기존 프로젝트 저장소와 관련 문서, 기록 파일을 직접 탐색한 뒤 질문에 답한다.

조건 B — Wiki 조회

Wiki CLI를 통해 필요한 정보를 조회하고 질문에 답한다.

두 조건에 동일한 13개 질문을 제공했다.

질문은 현재 프로젝트 상태, 과거 결정, 판단 근거, 기록의 기준일, 다른 프로젝트에서 사용한 해결 방식 등으로 구성했다.

기록에 없는 사실을 질문해 AI가 내용을 임의로 만들어내는지도 확인했다.

결과

평가 항목A: 원천 문서B: Wiki

정확한 답변 10 13
부분 정답 3 0
지어낸 답변으로 분류된 건수 0 0
동일 원천으로 답변 가능한 9문항 9/9 9/9
사용 토큰 235,242 101,097
A 대비 토큰 사용량 100% 43%

이번 평가에서는 Wiki를 사용한 조건 B가 원천 문서 방식보다 약 57% 적은 토큰을 사용했다.

정확한 답변 수도 B가 더 많았다.

하지만 이를 곧바로 Wiki의 검색 방식이 더 정확하다는 의미로 해석할 수는 없었다.

전체 13개 질문 중 일부는 Wiki에만 반영된 최신 사용자 정정 정보를 필요로 했다.

반면 두 조건이 모두 접근할 수 있는 원천 정보만 필요한 9개 질문에서는 A와 B가 모두 정답을 기록했다.

따라서 이번 시험에서 확인한 성과는 동일한 정보로 답변할 수 있는 질문에서 정확도를 유지하면서 전체 토큰 사용량을 줄였다는 것에 가깝다.

또한 처음 설정했던 목표는 원천 문서 방식 대비 20% 이하의 토큰 사용량이었다.

실제 결과는 43%였으므로 목표를 달성하지 못했다.

이후 현실적인 다음 목표를 35% 이하로 조정했다. 아직 그 수치를 달성한 것은 아니다.

실험의 한계

이번 평가에서 답변은 완전히 블라인드로 채점하지 못했다.

근거에 문서 경로나 Wiki의 ID가 포함되어 있어 어느 조건의 답변인지 구분할 수 있었기 때문이다.

또한 사용한 질문은 13개에 불과하며, 평가에 활용한 문서와 질문도 현재 프로젝트에 맞춰져 있다.

따라서 이번 결과를 다른 프로젝트나 모든 AI 작업에 일반화하기는 어렵다.

다만 초기 시스템의 문제를 찾기 위한 실험으로서는 충분히 유용했다.

7. Wiki가 항상 더 좋은 답을 주는 것은 아니었다

A/B 평가에서 가장 흥미로웠던 부분은 전체 점수보다 개별 질문의 차이였다.

사례 A: 과거 문서의 잘못된 내용을 현재 사실로 받아들임

조건 A는 과거에 사용했던 문서를 읽으면서, 이후 정정된 정보를 반영하지 못한 사례가 있었다.

반면 조건 B는 기준 사실과 과거 문서를 구분해 관리하고 있어 올바른 정보를 선택했다.

이는 검색 결과에 출처가 있다는 사실만으로 그 내용이 신뢰할 만하다고 판단해서는 안 된다는 것을 보여준다.

문서를 정확하게 찾는 것과 그 문서의 내용을 현재의 사실로 채택하는 것은 다른 문제다.

사례 B: Wiki의 요약이 최신 기록을 놓침

반대로 조건 A가 더 잘 답한 질문도 있었다.

운영 중인 개인 프로젝트의 최근 기록에 미완료된 자동화 작업이 남아 있었는데, Wiki의 프로젝트 브리프에는 해당 최신 기록이 충분히 반영되지 않았다.

원문을 직접 읽은 A는 미완료 상태를 확인했다.

하지만 B는 요약된 프로젝트 상태를 참고하면서 일부 정보를 추론에 의존했다.

이 사례는 Wiki가 오래된 요약을 전달하면 최신 원문보다 불리해질 수 있다는 문제를 보여줬다.

이를 개선하기 위해 브리프에서 최근 갱신 문서를 함께 표시하도록 수정했다.

프로젝트의 현재 상태를 요약하더라도, 그 요약보다 최신인 기록이 존재한다면 AI가 이를 확인할 수 있어야 한다고 판단했기 때문이다.

8. 프로젝트마다 흩어진 지식을 연결하기 시작했다

A/B 평가 중 특정 질문에서 Wiki 조건이 같은 주제의 자료를 여러 번 검색하는 문제가 있었다.

원인을 살펴보니 중복 요청 방지와 관련된 기술적 판단이 여러 프로젝트에 흩어져 있었다.

프로젝트별 문서는 존재했지만 공통으로 재사용할 지식은 별도로 정리되어 있지 않았던 것이다.

그래서 관련 프로젝트에서 출처가 확인된 내용을 모아 하나의 공통 지식 노트를 작성했다.

다만 AI가 작성한 노트이므로 처음에는 승인 대기 상태로 남겼다.

이 과정에서 처음 구상했던 Wiki의 또 다른 목적이 드러났다.

프로젝트마다 별도의 기록을 남기는 것에서 그치지 않고, 여러 프로젝트에서 반복된 문제와 해결 경험을 연결해 재사용할 수 있어야 한다는 것이다.

아직 실제 개발 과정에서 재사용 효과가 얼마나 있는지는 확인하지 못했다.

하지만 적어도 검색 과정에서 발견한 비효율을 데이터 구조의 개선으로 연결하는 첫 사례가 되었다.

9. 지금까지 구현한 것과 앞으로 필요한 것

현재는 로컬 Wiki를 구축하고 MCP 연동까지 완료했다.

검색, 현재 상태 조회, 의사결정 히스토리, 출처 추적, 지식 제안과 승인, 그래프 탐색 등을 사용할 수 있다.

하지만 다른 AI 세션에서 작업한 내용이 아무런 개입 없이 자동으로 수집되고 학습되는 시스템은 아직 아니다.

현재 구현한 것은 여러 AI가 공통 지식을 조회하고, 새로운 지식을 제안할 수 있는 기반이다.

다음에는 개발 과정에서 발생한 중요한 결정과 구현 결과를 어떻게 수집할지 검토하려 한다.

그렇다고 모든 채팅 메시지를 무조건 저장하고 싶지는 않다.

개발 과정에서는 검토하다가 폐기한 아이디어도 있고, AI가 잘못 이해한 내용도 있고, 아직 검증하지 않은 추론도 나온다.

이것들이 모두 공식 지식으로 확정된다면 오히려 정보의 품질이 떨어질 수 있다.

따라서 자동 수집을 구현하더라도 수집, 제안, 검증, 승인 과정을 구분하는 원칙은 유지할 생각이다.

또한 현재 검색에서 해결되지 않는 문제가 확인되지 않은 이상 의미 검색이나 벡터 데이터베이스를 무리하게 추가하지는 않으려 한다.

10. 마무리하며

이번 작업은 원래 여러 AI에게 같은 맥락을 반복해서 설명하는 것이 번거로워서 시작했다.

그런데 실제로 자료를 정리하고 비교 실험까지 해보니 생각보다 해결해야 할 문제가 많았다.

AI가 이전 결정을 기억하지 못하는 것도 문제였지만, 잘못된 내용을 현재 사실로 받아들이거나 서로 다른 목적의 자료를 같은 기준으로 해석하는 것도 문제였다.

그리고 Wiki를 구축한다고 이런 문제가 자동으로 사라지는 것은 아니었다.

요약된 정보가 오래되면 최신 기록을 놓칠 수 있고, 출처가 있는 문서라도 사실이 잘못되어 있을 수 있었다.

그래서 이번 프로젝트에서 중요하게 생각하게 된 것은 검색 자체보다도 어떤 지식을 신뢰하고, 어떤 판단을 변경했으며, 그 근거가 어디에 있는지 추적할 수 있는 구조였다.

이번 초기 평가에서는 Wiki 사용 조건이 원문 직접 조회보다 약 57% 적은 토큰을 사용했다.

다만 실험 규모가 작고, 데이터 최신성에 차이가 있었으며, 처음 목표했던 토큰 사용량에도 미치지 못했다.

그럼에도 개인적으로는 만족스러운 출발이었다.

이제는 새로운 AI 세션을 시작할 때마다 내가 무엇을 했고 왜 그렇게 결정했는지 다시 설명하는 대신, 그 정보를 참조할 수 있는 기반이 생겼기 때문이다.

앞으로 개발하는 제품들이 원하는 성과를 내지 못하거나 중간에 방향을 바꾸더라도, 그 과정에서 얻은 판단과 검증 결과까지 사라지지는 않았으면 한다.

AI가 나를 얼마나 오래 기억하느냐보다, AI가 참고할 지식을 내가 얼마나 정확하게 관리할 수 있느냐.

지금은 그쪽이 더 중요한 문제처럼 느껴진다.

앞으로 실제 개발과 창작 작업에서 사용하면서 발견하는 문제들도 계속 기록해 볼 생각이다.


2026년 10월 25일 개인 개발 환경에서 진행한 초기 구현과 평가를 바탕으로 작성했습니다. 본문의 성능 수치는 제한된 평가 조건에서 얻은 결과이며, 다른 환경에서의 성능이나 지속적인 생산성 개선을 보장하지 않습니다.



업데이트 (2026-11-02)

본문은 작성 당시 기록으로 그대로 두고, 이후 달라진 점만 덧붙인다.

- 토큰 목표: 같은 13문항을 두 번 더 측정했다. 정확도는 13/13을 유지했지만 토큰은 원천 문서 대비 39%에서 멈춰 35% 목표를 달성하지 못했다. Wiki 출력은 전체 토큰의 약 16%였고, 나머지는 대부분 에이전트 자체 비용이었다.

- 작업 단위 측정: 실제로 맡길 법한 작업 3개를 작업마다 새 에이전트로 다시 비교했다. 채점 항목 14개 중 Wiki 조건은 14개, 원천 문서 조건은 12개를 맞혔다. 토큰은 71%로 새 목표 40%에 미달했다. 측정 후 빈 에이전트의 고정 비용(약 5만 토큰)을 빼는 기준으로 바꾸니 36%였다. 판정 기준을 측정 뒤에 바꾼 결과이고, 작업 3개의 작은 표본이다.

- 방향 변경: 토큰 수치를 낮추기 위한 최적화는 중단했다. 이제 측정은 큰 변경 뒤 정확도가 떨어지지 않았는지 확인하는 데만 쓰고, 개선은 실제 사용에서 드러난 누락과 오답을 기준으로 한다. Wiki의 목적도 AI나 세션이 바뀌어도 결정과 근거를 잇는 것으로 분명히 했다.

- 기록 수집: 본문에서 검토하겠다고 쓴 수집은 hw digest로 시작했다. 마지막 갱신 이후의 커밋과 문서, 승인 대기 항목을 보여 주면 에이전트가 기록을 제안하고 승인은 내가 한다. 대화 전문은 수집하지 않는다.

오늘은 로컬 LLM을 직접 서비스에 붙여보는 실험을 해봤습니다.

요즘 로컬 LLM이나 여러 모델을 역할별로 나눠 사용하는 구조에 대해 이런저런 이야기를 많이 듣고 있기도 했고, 저도 실제로 한 번 돌려봐야 어느 정도인지 감이 올 것 같았습니다.

마침 제가 만들고 있는 서비스 중에 실험하기 적당한 게 하나 있었습니다.

‘오늘 얼마 먹어도 돼?’

사용자가 하루 동안 먹은 음식을 그냥 평소 말하듯 입력하면 기록하고, 오늘 얼마나 더 먹을 수 있는지 보여주는 작은 서비스입니다.

예를 들면 이런 식입니다.

“아침에 계란 두 개 먹었어.”

“아까 먹은 바나나 취소해줘.”

“오늘 얼마나 더 먹어도 돼?”

이 서비스에서는 사용자의 문장을 받으면 먼저 이게 음식 추가인지, 수정인지, 삭제인지, 상태를 묻는 건지 등을 판단합니다.

현재는 이 판정을 Jev라는 외부 모델에 맡기고 있습니다.

문득 이런 생각이 들었습니다.

이 정도의 짧은 문장 분류라면 굳이 외부 모델을 호출하지 않고 작은 로컬 LLM으로 처리해도 되지 않을까?

그래서 직접 테스트해보기로 했습니다.


일단 모델부터 설치하지는 않았다

처음에는 Ollama를 설치하고 모델부터 실행하면 될 거라고 생각했습니다.

그런데 실제 코드를 다시 살펴보니 먼저 해야 할 게 있었습니다.

현재 앱에서 AI가 정확히 무엇을 하고 있는지를 분리하는 일이었습니다.

확인해보니 생각보다 구조가 명확했습니다.

LLM은 사용자의 의도를 판단합니다.

반면 음식 이름과 양을 해석하고, 칼로리를 조회하고, 실제 기록을 추가하거나 수정하는 작업은 코드가 처리하고 있었습니다.

즉 대략 이런 구조였습니다.

사용자 입력
→ AI가 의도 판단
→ 코드가 명령 결정
→ 음식 데이터 조회
→ 실제 기록 처리

이 구조라면 실험하기 상당히 좋았습니다.

기존 로직을 거의 건드리지 않고 판정기만 로컬 모델과 비교해볼 수 있기 때문입니다.

그래서 바로 로컬 모델을 실제 기능으로 넣지 않고 세 가지 모드를 만들었습니다.

off

기존 시스템 그대로 사용합니다.

shadow

기존 Jev의 판단을 실제 결과로 사용하면서, 같은 문장을 로컬 LLM에게도 보내 결과만 비교합니다.

active

로컬 모델의 결과가 일정 조건을 만족하면 사용하고, 그렇지 않으면 기존 Jev로 다시 보냅니다.

그리고 production에서는 무조건 off가 되도록 막았습니다.

지금 목적은 새 기능을 만드는 것이 아니라 이게 정말 쓸 만한지 확인하는 것이었기 때문입니다.


테스트 데이터도 만들었다

그냥 몇 문장 던져보고

“오, 잘 되는데?”

라고 끝내면 의미가 없을 것 같았습니다.

그래서 로컬 라우터용으로 67개의 테스트 케이스를 만들었습니다.

예를 들면 이런 문장들입니다.

“아침에 계란 두 개 먹었어.”

“점심 김치찌개랑 밥.”

“아까 먹은 바나나 취소해줘.”

“나 오늘 얼마나 더 먹어도 돼?”

“배고프다.”

“오늘 운동했는데 더 먹어도 돼?”

여기에 오타, 줄임말, 조사가 빠진 문장, 음식 여러 개가 들어간 문장, 애매한 표현들도 섞었습니다.

그리고 정확도만 보는 게 아니라

  • 평균 응답 시간
  • p95 응답 시간
  • JSON 파싱 실패
  • timeout
  • confidence
  • 기존 Jev와의 일치율
  • 실제로 외부 호출을 얼마나 줄일 수 있는지

까지 같이 측정하게 만들었습니다.


그런데 갑자기 Jev가 바보가 됐다

실험 중간에 조금 당황스러운 일이 있었습니다.

기존 Jev에

“아침에 계란 두 개 먹었어.”

를 넣었는데 confidence가 이상하게 낮게 나오기 시작했습니다.

“오늘 얼마나 남았어?”

같은 문장도 엉뚱하게 음식 추가로 판단했습니다.

기존 테스트에서 intent 정확도가 90% 중반대였기 때문에 갑자기 모델 성능이 크게 떨어진 것처럼 보였습니다.

혹시 서비스 쪽 모델이 바뀐 건가 싶어서 baseline을 다시 측정했습니다.

결과는 정상이었습니다.

기존 측정: 93.3%
오늘 측정: 95.0%

모델 버전도 같았습니다.

그럼 뭐가 문제였을까.

결국 범인은 AI가 아니라 Windows Git Bash의 한글 인코딩이었습니다.

curl 명령에서 한글을 직접 body에 넣었더니 UTF-8이 아니라 CP949 바이트로 서버에 전달되고 있었습니다.

즉 모델은 제가 쓴 한국어를 본 게 아니라 깨진 문자열을 보고 있었던 겁니다.

UTF-8 파일로 body를 저장한 뒤 --data-binary로 다시 보내니 정상적으로 confidence 1.00이 나왔습니다.

AI 성능 테스트를 하다가 인코딩 문제를 잡게 될 줄은 몰랐습니다.

그래도 덕분에 테스트 방법까지 문서에 남겨두었습니다.


드디어 로컬 모델을 돌려봤다

PC에는 RTX 2060 SUPER 8GB가 있습니다.

Ollama를 설치하고 우선 작은 모델 두 개부터 테스트했습니다.

  • EXAONE 3.5 2.4B
  • Qwen 2.5 3B

결과는 조금 아쉬웠습니다.

둘 다 intent 정확도가 **79.4%**였습니다.

기존 Jev는 같은 데이터에서 **98.4%**였습니다.

심지어 코드 기반 mock router도 84.1%였습니다.

속도도 예상과 달랐습니다.

EXAONE 2.4B 평균 약 358ms.

Qwen 3B 평균 약 431ms.

Jev는 약 213ms였습니다.

로컬에서 GPU로 직접 돌리는데 외부 모델보다 느렸습니다.

그리고 더 큰 문제가 하나 있었습니다.

두 작은 모델 모두 맞는 답이든 틀린 답이든 거의 무조건 confidence를 0.9 이상으로 줬습니다.

틀리면서도

“나 이거 95% 확신해.”

라고 하는 셈입니다.

이 상태에서는 confidence threshold를 안전장치로 사용할 수도 없습니다.


마지막으로 7B까지 해봤다

그래도 작은 모델만 보고 결론을 내리기는 아쉬웠습니다.

그래서 Qwen 2.5 7B까지 받아서 한 번 더 테스트했습니다.

모델 크기는 약 4.7GB.

RTX 2060 SUPER에서도 100% GPU로 실행됐습니다.

결과는 확실히 좋아졌습니다.

EXAONE 2.4B
79.4%

Qwen 3B
79.4%

Qwen 7B
88.9%

Jev
98.4%

7B 정도가 되니 작은 모델과는 차이가 꽤 났습니다.

confidence도 처음으로 조금 의미가 생겼습니다.

confidence 0.9 이상인 답만 보면 정확도가 92.7%였습니다.

그리고 현재 설정해둔 0.85 threshold와 수정·삭제 요청 fallback 규칙을 적용하면 실제 Local 결과를 사용하게 되는 43건에서는 43건 모두 정답이었습니다.

이 부분은 꽤 인상적이었습니다.

작은 로컬 모델도 조건을 잘 걸면 일부 작업 정도는 충분히 맡길 수 있겠다는 생각이 들었습니다.

하지만 문제가 하나 남았습니다.

속도입니다.

Qwen 7B 평균 응답 시간은 약 593ms.

p95는 1초 정도였습니다.

Jev는 평균 약 214ms였습니다.

그리고 모델이 GPU 메모리에서 내려간 상태에서 첫 요청을 보내면 로딩에 약 4.2초가 걸렸습니다.


그래서 비용도 계산해봤다

그러면 느리더라도 API 비용을 크게 줄일 수 있다면 사용할 이유가 있을 수 있습니다.

현재 구조대로라면 Qwen 7B가 Jev 호출의 약 68% 정도를 대신할 수 있었습니다.

그런데 Jev 비용을 계산해보니 60건 호출에 약 0.003달러 수준이었습니다.

요청 1,000건을 기준으로 계산해도 로컬 모델로 줄일 수 있는 비용이 몇 센트 수준입니다.

반면 production은 Vercel에 올라가 있습니다.

로컬 모델을 실제 서비스에 사용하려면 별도의 GPU 서버를 운영해야 합니다.

그러면 상황이 이상해집니다.

몇 센트를 아끼기 위해 GPU 서버와 새로운 인프라를 추가해야 합니다.

사용자는 응답을 더 늦게 받습니다.

정확도도 기존 시스템보다 낮습니다.

결론이 꽤 명확해졌습니다.


그래서 안 쓰기로 했다

처음 이 작업을 시작할 때 목표는 로컬 LLM을 도입해보는 것이었습니다.

그런데 하루 동안 테스트한 결과는 반대였습니다.

지금 이 서비스에는 로컬 LLM을 도입하지 않는 것이 더 낫다.

현재의 Jev가 더 정확합니다.

더 빠릅니다.

비용도 이미 충분히 쌉니다.

운영해야 할 인프라도 적습니다.

로컬 LLM이 나빠서라기보다는 현재 문제에 이미 더 적합한 도구가 있었던 것에 가깝습니다.

그래서 실험 코드는 기본값 off 상태로 남겨두고, production에서는 사용하지 않기로 했습니다.


그래도 오늘 실험은 꽤 마음에 들었다

예전 같았으면 새로운 기술이 보이면

“이걸 어디에 넣어볼까?”

부터 생각했을 것 같습니다.

오늘은 조금 달랐습니다.

직접 붙여보고,

테스트셋을 만들고,

속도를 재고,

정확도를 비교하고,

비용까지 계산한 다음,

안 쓰는 쪽을 선택했습니다.

새로운 기술을 도입하는 것 자체가 개발의 목적은 아니니까요.

그리고 또 하나 알게 된 것도 있습니다.

2~3B 정도의 작은 모델에서는 아직 제가 원하는 판정 품질이 나오지 않았지만, 7B쯤 되니 꽤 재미있는 수준까지 올라왔습니다.

조금 더 좋은 GPU나 다른 워크로드라면 결과가 또 달라질 수도 있을 것 같습니다.

그래서 오늘의 결론은 이렇게 남겨두려고 합니다.

로컬 LLM 도입은 실패했다.

라고 쓰기보다는,

로컬 LLM을 도입하지 않을 근거를 얻었다.

정도가 더 정확할 것 같습니다.

이런 실험은 꽤 재미있습니다.

+ Recent posts