
Gemini를 그만두고 Claude로 바꿨더니 코드가 190행이 되었다
요약
Gemini를 활용한 Google Drive API 기반의 복잡한 시스템을 Claude를 이용한 로컬 파일 쓰기 방식으로 전환하여 코드를 190행으로 대폭 축소한 사례를 다룹니다. 공식 API의 복잡성 대신 OS의 동기화 기능을 활용하여 아키텍처를 단순화하고 관심사를 분리하는 설계의 중요성을 강조합니다.
핵심 포인트
- 공식 API 사용이 반드시 최적의 아키텍처를 보장하지는 않음
- Claude를 활용해 복잡한 인증 절차를 로컬 파일 입출력으로 대체
- OS의 클라우드 동기화 기능을 활용하여 시스템 복잡도 감소
- 핵심 로직과 주변 인프라(동기화 등)를 분리하는 설계의 중요성
지난번, 「기억은 저장하는 것이 아니라, 생성하는 것이다」라는 설계에 관한 글을 썼다. 소재만을 NDJSON으로 남기고, 의미는 문맥에 맞춰 매번 생성하게 하는——그런 외부 뇌의 설계론이었다.
이 기사는, 그 설계를 쌓아 올렸던 토대에 관한 이야기다. 더 정확히는, 반년에 걸쳐 구축한 토대를 어제 거의 버린 이야기다. 버렸다고 해도 좋다. 남은 코드는 그 시점에서 190행이었다.
기술의 잔혹함과 아름다움이 공존하는 이야기를 하려 한다.
결론——공식 API보다, 로컬로의 직접 쓰기가 승리했다
먼저 결론을 적는다. Google의 AI (Gemini)보다, 타사의 AI (Claude)가 Google Drive를 더 심플하게 다룰 수 있었다.
반년 전쯤, 나는 「사고를 Google Drive에 저장하는 외부 뇌 시스템」을 만들고 있었다. 당시의 파트너는 Gemini였고, 저장 경로는 다음과 같았다. Drive API로 인증을 통과하고, 브릿지(중계 프로세스)를 실행하고, 가상 환경 (venv)을 활성화하고, JSON을 구성하여 던지고, 클라우드 측의 동기화를 기다린다. 모듈은 십수 개의 파일로 나뉘어 있었고, 서비스 계정의 JSON 키와 폴더 ID의 공유 설정이 전제였다. 그것을 차근차근 쌓아 올리고 있었다.
그것이 어제, 190행의 로컬 쓰기 스크립트 한 개로 대체되었다. 외부 라이브러리는 제로(0).
Gemini의 속박——「공식성」이 아키텍처를 규정한다
왜 Gemini를 사용하면 복잡해졌는가. 원인은 모델의 똑똑함이 아니라, 공식성에 있었다는 것이 나의 견해다.
Gemini는 Google의 정통 혈통이다. 그렇기에 Google Drive를 「정식 API」라는 절차로 호출한다는 전제로 발상이 짜인다. 인증을 통과하고, 요청을 보내고, 무거운 동기화를 기다린다. 이 경로는 견고하며 권한 관리도 올바르다. 다만, 그 위에 올라가는 코드는 필연적으로 인증, 재시도(Retry), 토큰 관리, 브릿지라는 주변 장치들을 떠안게 된다.
여기서 작용하는 것은 툴이 가진 「올바른 사용법」이라는 인력이다. 공식 API가 존재하면 그것을 사용하는 것이 정답처럼 보인다. 정답처럼 보이는 쪽으로 맞춰가다 보면, 아키텍처는 API의 편의에 따라 비대해진다. 이를 이 기사에서는 공식성의 함정이라고 부르기로 하겠다. 수단의 정통함이 목적(사고를 한 줄 남기는 것)에 비해 과도한 것이다.
관심의 소재——Claude는 Drive를 「보지 않았다」
반면 Claude는 Google의 화려한 API를 처음부터 보지 않았다. 눈앞에 있었던 것은 「로컬의 공유 폴더」뿐이었고, 그곳에 Python 스크립트로 직접 파일을 썼다.
질문을 던지는 방식이 달랐다. 「Drive API를 어떻게 올바르게 호출할 것인가」가 아니라, 「사고를 한 줄, 확실하게 파일에 추가하려면 무엇이 필요한가」였다. 후자에 답한다면 필요한 것은 표준 라이브러리의 파일 입출력뿐이다. 그리고——Drive 동기화라는 거대한 인프라는 「OS에 상주하는 Google Drive 클라이언트에게 통째로 맡긴다」는 한 수로 사라졌다. 로컬에 쓰면 나머지는 OS가 알아서 클라우드로 동기화한다. 앱은 그 존재를 몰라도 된다.
본가라고 할 수 있는 Google의 AI가 본가 창고에 물건을 넣고 빼는 정식 절차 때문에 고군분투하고 있는 옆에서, 남의 집 아이가 뒷문으로 순식간에 짐을 옮겨 날랐다. 아이러니하지만 설계로서는 이쪽이 옳다. 관심사를 동기화라는 타자의 책무로부터 분리했기 때문이다.
왜 순식간에 이식할 수 있었나——핵심과 주변의 분리
이 부분이 이 기사에서 가장 쓰고 싶은 점이다.
190행으로의 수렴은 솔직히 말하면 「패배 인정(미련)」에서 시작되었다. 반년의 고생이 이것으로 끝난다면 그 시간은 무엇이었나, 하고. 하지만 냉정하게 되돌아보면, 순식간에 이식할 수 있었던 것은 우연이 아니라 첫 설계가 올바르게 분리되어 있었기 때문이었다.
시스템을 두 개의 층으로 나누어 생각하고 있었다.
설계의 핵심: SSOT (Single Source of Truth)는 journal_by_day/의 NDJSON 이벤트 열이라는 것. 쓰기는 반드시 게이트(원자적 쓰기 + 스키마 검증)를 통할 것. 기존 레코드는 수정·삭제하지 않을 것 (append-only). 인덱스류는 거기서 전체를 재생성할 수 있는 파생물일 것.
주변 인프라: 그것을 실제로 어디에, 어떻게 영속화할 것인가. Drive API인가, 로컬 파일인가, 라는 구현의 선택.
Gemini 시절에 비대해졌던 것은 후자(주변 인프라)뿐이었다. 전자(핵심)는 저장소가 무엇이든 변하지 않는다. 그래서 Drive 연계라는 주변부를 통째로 버려도, 핵심은 그대로 새로운 토대 위에 올라탈 수 있었다.
토대가 썩어 있었다면, 환경이 변하는 순간 시스템 전체가 붕괴했을 것이다. Drive 부분을 망설임 없이 버릴 수 있었다는 것 자체가 설계의 승리였다. 여기서 이끌어낼 수 있는 일반 원칙은 다음과 같다——이식성(Portability)은 영리한 구현이 아니라, 핵심(Core)과 주변부(Periphery)의 분리에서 태어난다. 이론(핵심)만 독립되어 있다면, 과거의 구현은 모두 버릴 수 있다. 그것이 강점이라고 생각한다.
무엇이 바뀌었나——4단계에서 1단계로
체감상 가장 컸던 것은 저장이라는 행위 자체의 단계(Steps)다.
이전(Gemini + Drive API)의 저장 플로우:
- 브릿지(Bridge)를 기동한다
- 가상 환경(venv)을 활성화한다
- JSON을 수동으로 구성하여 붙여넣는다
- Drive로의 동기화를 기다린다
현재(Claude + 로컬)의 저장 플로우:
- Claude에게 "저장해줘"라고 말한다
터미널은 필요 없다. 인증 정보 설정도 필요 없다(애초에 Drive API를 사용하지 않는다). 그 외에는 대화하는 것만으로 사고 내용이 로컬의 NDJSON에 기록되고, Google Drive 클라이언트가 백그라운드에서 알아서 동기화한다.
저장의 내용은 이것뿐이다. 락(Lock)을 걸고, 직전의 해시(Hash)를 읽고, 레코드를 구성하여 추가하고, 인덱스를 업데이트한다.
with journal_lock(mirror_base):
prev_hash = get_prev_hash(mirror_base) # 직전 레코드의 hash
record_obj = build_record(author, prev_hash, record)
...
각 레코드는 prev_hash → hash의 SHA256 체인으로 연결된다. 단 한 건이라도 변조나 결손이 있으면 체인이 끊겨 감지할 수 있다.
{
"id": "abc123def456",
"t_utc": "2026-07-06T00:09:16.515454Z",
...
Drive API, 인증, 브릿지, 가상 환경——그것들이 담당하던 일은 모두 "OS에 맡기기" 혹은 "애초에 필요 없음"으로 환원되었다.
190행, 그 이후
솔직히 보충해 두자면, 이 "190행"은 전환한 당일의 숫자다. 지금 같은 스크립트를 세어보면 약 280행으로 성장해 있다(실제 코드 기준 213행).
늘어난 것은 기능이 아니라 **견고성(Robustness)**이다. 전체 쓰기를 임시 파일을 경유한 원자적 교체(os.replace) 방식으로 바꾸고, 추가할 때마다 fsync로 디스크에 확실히 기록하며, 동일 머신 내의 경합을 배타적 락(Exclusive Lock)으로 직렬화하고, 도중에 프로세스가 종료되어도 본체 파일이 깨지지 않도록(Torn line을 구조적으로 만들지 않도록) 했다. 다시는 반복하고 싶지 않은 사고로부터 배운 줄(Line)들이다.
하지만 본질은 변하지 않았다. 의존 라이브러리는 여전히 제로. 단일 파일. 표준 라이브러리뿐. 십수 개의 모듈 + Drive API + 서비스 계정(Service Account)이라는 구(舊) 아키텍처와는 비교할 수 없는 가벼움을 유지하고 있다. 행수가 190에서 280으로 늘어난 것 자체가 오히려 건전한 징후라고 생각한다. 늘어난 한 줄 한 줄이 영리함이 아닌 내구성을 사고 있는 것이다.
과거의 정답이 부채가 된다
이 사건을 개인적인 실패담으로 끝내고 싶지 않다. 여기에는 개발자라면 누구나 직면하는 일반적인 구조가 있기 때문이다.
반년 동안 Drive API, 브릿지, venv, JSON 붙여넣기라는 경로를 만들어냈다. 당시에는 그것이 정답이었다. 그 환경에서, 그 도구들로 외부 뇌를 성립시키기 위해서는 필요한 복잡함이었다. 그것이 환경의 변화——로컬 폴더에 직접 쓸 수 있는 AI 에이전트의 등장——에 의해 하룻밤 사이에 부채(Debt)로 변했다.
"과거의 정답"에 매달리면 기술의 진화 그 자체에 뒤처지게 된다. 하지만 반대로 말하면, 핵심과 주변부를 분리해 두었다면 진화가 왔을 때 주변부만 교체하여 갈아탈 수 있다. 과거의 정답을 부채로 만들지 않고 자산인 채로 버릴 수 있느냐는 그 분리 설계에 달려 있다.
어제 시작했더라면 오늘 할 수 있었을 텐데——그런 감각은 솔직히 아직 사라지지 않는다. 하지만 그것은 능력이나 판단의 문제가 아니었다. 기술 진화의 타이밍과 나의 시도가 아주 조금 어긋났을 뿐이다. 그리고 어긋났던 반년 동안 구축한 설계의 핵심이, 오늘 이 순간의 이식(Porting)을 가능하게 했다. 그러므로 헛되지 않았다고 단언할 수 있다.
마치며
도구는 변한다. 동기화 메커니즘도, 인증 방식도, 영리한 AI의 이름도 변한다. 변하지 않는 것은 무엇을 유일한 정답으로 삼고, 무엇을 파생물로 보며, 어디에서 양자를 나눌 것인가 하는 설계의 핵심(Core)뿐이다.
도구는 버려진다. 설계는 남는다.
남을 수 있도록 분리해 두라.
이전 글 「기억은 저장하는 것이 아니다——AI 외부 뇌의 설계」의 후속 편이다.
토론 (Discussion)

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기