4일 만에 프로덕션 시스템을 만드는 시대
Obie Fernandez의 Nexus 프로젝트 완전 분석
프롤로그: 30년 경력 개발자가 목격한 진짜 패러다임 전환
“내가 이번 주에 경험하고 있는 것은 내가 본 그 어떤 변화와도 진정으로 다르다.”
30년 경력의 베테랑 개발자 Obie Fernandez의 이 선언은 가볍게 들을 말이 아니다. 그는 성공적인 스타트업을 만들었고, 베스트셀러 기술서를 집필했으며, Fortune 500 기업들을 컨설팅했고, 수많은 기술 물결이 왔다가 사라지는 것을 지켜봤다. 그 중 일부를 적절한 시점에 포착한 것이 그의 경력을 지금의 위치로 끌어올렸다. 그는 또한 실제로는 아니었던 “패러다임 전환”과 사그라든 “혁명”도 목격했다.
그런 그가 2025년 크리스마스와 새해 사이, 단 4일 만에 13,000줄 가까운 프로덕션 수준의 조직 지식 관리 시스템을 구축했다. 그것도 CTO로서의 정규 업무를 병행하면서. 이것은 과장이 아니라 커밋 기록, 타임스탬프, 프로덕션 배포로 증명되는 사실이다.
이 문서는 Fernandez의 개발 과정을 일별로 추적하고, 기술적 선택의 배경을 분석하며, AI 시대 소프트웨어 개발의 본질적 변화가 무엇인지 탐구한다.
제1부: 문제 정의와 결단
1.1 조직 지식의 증발 문제
Fernandez와 그의 팀 ZAR는 Claude Code 세션에서 수백 시간을 보냈다. 깊은 기술 작업, 결정, 아키텍처 토론, 버그 해결. 그런데 트랜스크립트는 사라진다. 다음 세션은 백지에서 시작한다.
이것은 Claude Code만의 문제가 아니다. Slack 대화도 마찬가지다. Linear 코멘트도. GitHub PR 토론도. 모든 귀중한 조직 지식이 끊임없이 증발하고 있었다.
전통적인 개발은 아티팩트를 남긴다 - 설계 문서, ADR(Architecture Decision Records), 위키 페이지, 주석이 달린 코드. 하지만 Claude Code와 페어 프로그래밍할 때, 아티팩트는 대화 그 자체다. 결정은 대화 속에 살아있다. 그리고 터미널을 닫는 순간, 그 지식은 사라진다.
규모를 생각해보라. Fernandez의 팀은 주당 수백 건의 Claude Code 세션을 실행한다. 각각에는 결정, 학습, 아키텍처 토론, 디버깅 통찰이 담겨 있다. 여기에 수십 개의 Slack 스레드, Linear 티켓 코멘트, GitHub PR 리뷰 대화를 곱하면? 엄청난 양의 조직 지식을 생성하면서도 체계적으로 보존하는 것은 전혀 없다.
1.2 2026년의 비전: 자율 AI 에이전트를 위한 조직 메모리
Fernandez가 원했던 것은 단순한 지식 저장소가 아니었다. 2026년에 구축하고자 하는 고급/자율 AI 에이전트들이 활용할 수 있는 조직 메모리였다.
모든 트랜스크립트, 모든 스레드, 모든 토론을 수동적으로 수집하여 쿼리 가능한 조직 메모리로 추출하는 시스템. 단순히 원문을 저장하는 것이 아니라 실제로 이해하는 시스템. 결정을 추출하고, 학습을 추출하고, 충돌을 추출하고, 코딩 어시스턴트가 탐색할 수 있는 시맨틱 그래프를 구축하는 것.
흥미롭게도, 이것은 Fernandez가 2005년부터 관심을 가져온 주제였다.
1.3 RAG vs. 직접 구축: 경쟁 우위의 재정의
RAG 솔루션을 사면 되지 않나? 오픈소스를 쓰면 되지 않나? 실제로 그가 원하는 것과 정확히 같은 것을 작업하는 스타트업이 수십 개는 있을 것이다. 전통적인 엔터프라이즈 지식 관리 플랫폼들도 있다 - 통합 비용, 컨설턴트, 수개월의 구현 기간을 감안하면 최소 6자리 수 비용이 들 것이다.
Fernandez의 대답: “씨발, 그딴 건.”
그는 4일 만에 만들었다.
개념 증명이 아니다. 데모가 아니다. 인증, 시맨틱 검색, 에이전트 액세스를 위한 MCP 서버, 주요 SaaS 플랫폼을 위한 웹훅 통합, 포괄적인 테스트 커버리지를 갖춘 프로덕션 준비 시스템이다. 배포되었고, 통합되었으며, 월요일부터 회사 전체에서 사용할 준비가 되었다. 거의 13,000줄의 코드.
더 흥미로운 점: Nexus를 만드는 것이 그 주의 주된 업무도 아니었다. 그는 ZAR의 새 CTO였고, 새해 전날과 새해 당일(방해받지 않는 시간의 사치를 누릴 수 있었던)을 제외하고는 정상적인 삶과 업무 책임을 병행하면서 Nexus를 만들었다. 회의. Slack 스레드. 프로덕션 코드 작성. 코드 리뷰. 계획. 채용. 일상적인 일들. Nexus는 틈새 시간에, 오후에, 다른 의무 사이에 만들어낼 수 있는 몰입 상태의 폭발 속에서 일어났다.
제2부: 왜 오픈소스하지 않는가 - 경쟁 우위의 재정의
2.1 오픈소스 복음 전도사의 불편한 깨달음
Fernandez의 경력은 오픈소스로 만들어졌다. 그는 Rails 초창기부터 기여했다. 수백만 번 다운로드된 gem들을 작성했다. 그는 문자 그대로 “The Rails Way” 프랜차이즈를 집필했고, 8개 에디션에 걸쳐 세대를 거쳐온 Rails 개발자들을 위한 베스트 프랙티스를 체계화하는 데 도움을 줬다. 그는 20년 동안 코드를 자유롭게 공유하는 것을 전도했다.
그런데 왜 Nexus를 GitHub에 공개하지 않고 블로그에 글을 쓰는가?
불편한 깨달음 때문이다: 킬러 소프트웨어가 이렇게 빠르게 개발될 수 있고, 적절한 사람이 적절한 도구를 가지면, 그리고 에이전트 도움 덕분에 그 소프트웨어를 유지하는 것이 사실상 무료인 시대에는… 오픈소싱이 예전과 같은 의미를 갖지 않는다. 적어도 이 프로젝트에는.
2.2 복제 장벽의 붕괴
Nexus는 그의 회사에 진정한 경쟁 우위를 나타낸다. 시장에서 차별화할 수 있는 종류의 인프라다.
예전에는 이런 것을 만드는 것이 너무 비싸고 시간이 많이 걸려서 사내에서 만들 생각조차 하지 않았다. (Shopify가 아니라면 말이다.) 어쨌든 미친/바보 같이 시도했다면, 오픈소싱하는 것이 전략적으로 의미가 있었다. 커뮤니티 기여, 버그 수정, 평판을 얻을 수 있고, 경쟁자들이 따라잡으려면 수개월의 노력이 필요하다는 것을 알면서. 복제 장벽이 충분히 높아서 공유하는 것이 의미가 있었다.
지금은? 씨발, 안 된다…
만약 내가 오늘 Nexus를 오픈소스한다면, Claude Code를 가진 거의 누구나 그것을 포크하고, 커스터마이즈하고, 내일 오후까지 배포할 수 있다. 내 경쟁 우위는 몇 시간 만에 증발할 것이다. 이것은 과장이 아니다. Fernandez는 Claude Code를 사용하여 복잡한 코드베이스를 가져와서 한 세션에서 상당히 수정했다. 한 번에 앉아서 Python 라이브러리를 Ruby로 다시 작성했다. 복제 장벽이 무너졌다.
2.3 오픈소스의 미래: 기초 vs. 전략적 애플리케이션
절망하지 마라. Fernandez는 Claude Code가 오픈소스의 종말이라고 생각하지 않는다.
기초 라이브러리, 프로토콜, 도구는 여전히 오픈 협업으로부터 엄청나게 이익을 얻는다. Ruby 생태계, JavaScript 생태계, PostgreSQL과 Redis 같은 인프라 도구… 모두 공유 개발의 혜택을 계속 받을 것이다.
하지만 전략적 우위를 나타내는 맞춤형 사내 애플리케이션의 경우? 계산법이 극적으로 바뀌었다.
이것은 소프트웨어 경제학의 근본적인 전환이다. 개발 비용이 극적으로 떨어지면, 희소성의 원천이 이동한다. 코드 자체는 덜 귀중해진다. 독특한 통찰력, 도메인 전문성, 전략적 적용은 더 귀중해진다.
2.4 회의론자들에 대한 답변: 증거가 여기 있다
Fernandez가 이 글을 쓰는 또 다른 이유는 온라인에서 회의론자들을 계속 보기 때문이다: “좋아, AI 보조 개발이 그렇게 혁명적이라면, 프로젝트는 어디 있어? 증거는 어디 있어?”
함의는 Fernandez 같은 사람들이 단지 과대광고를 하고 있다는 것, “vibe coding”이 실질적인 것을 생산하지 못한다는 것, 생산성 향상을 과장하거나 장난감 프로젝트를 만들고 프로덕션 시스템이라고 부른다는 것이다.
여기 증거가 있다. 실제 프로젝트, 실제 커밋, 실제 타임스탬프, 실제 프로덕션 배포가 있다. 따라와라. 무엇이 만들어졌는지, 언제 만들어졌는지, 실제로 얼마나 걸렸는지 보여줄 것이다.
제3부: Nexus는 실제로 무엇을 하는가
3.1 시스템 아키텍처: 포괄적 개요
추상적인 “지식 관리” 설명은 범위를 전달하지 못한다. 실제 시스템을 살펴보자.
Nexus는 조직 지식 추출 서비스다. 핵심 워크플로우:
1. 입력 레이어 - 보편적 수집
- Claude Code 훅: 세션이 끝날 때 자동으로 실행
- Slack Events API를 통한 Slack 스레드
- PR 토론을 위한 GitHub 웹훅
- 이슈 코멘트를 위한 Linear 웹훅
- API를 통한 수동 제출
2. 처리 레이어 - LLM 추출 각 트랜스크립트를 분석하여 구조화된 지식을 추출:
- 내려진 결정
- 배운 교훈
- 관련된 사람들
- 논의된 주제
- 충돌과 모순
3. 저장 레이어 - 이중 패러다임
- RDF 그래프 (Oxigraph): 시맨틱 트리플로 모든 것을 저장. 진실의 원천은 그래프지, Postgres가 아니다.
- 벡터 임베딩 (pgvector): 전체 지식 베이스에 걸친 시맨틱 유사성 검색 가능
4. 쿼리 레이어 - 다중 인터페이스
- 웹 UI: 사람이 세션을 탐색하고, 온톨로지를 탐색하고, 시맨틱하게 검색하고, 충돌을 관리
- MCP 서버: 그래프를 AI 에이전트에 노출하여 Claude가 코딩 세션 중에 조직 메모리를 직접 쿼리
- REST API: 프로그래밍 방식의 액세스, HTML/JSON/TXT 형식 지원
3.2 기술 스택: 현대적이고 야심찬 선택
Ruby 4.0과 Rails 8 (edge) 출시되지 않은 최신 버전을 사용. 왜? Claude가 재치 있게 설명할 수 있기 때문이다. Rails 8의 Solid* gems(SolidQueue, SolidCache, SolidCable)는 Redis 의존성을 제거한다. 관리할 인프라가 하나 줄었다.
PostgreSQL with pgvector 일차 관계형 데이터베이스이면서 동시에 시맨틱 검색을 위한 벡터 저장소. pgvector 확장은 일반 데이터와 함께 768차원 임베딩을 저장하고 유사성 연산자로 쿼리할 수 있게 한다. Pinecone이나 Weaviate 같은 별도의 인스턴스가 필요 없다.
Oxigraph SPARQL 지원을 갖춘 Rust 기반 RDF 트리플 저장소. 지식 그래프를 실제로 작동하게 만드는 것이다. 추출된 지식의 모든 조각은 SPARQL의 전체 능력으로 쿼리할 수 있는 시맨틱 트리플이 된다.
예시 쿼리: “Sarah가 인증에 대해 내린 모든 결정을 찾아라” → 단일 SPARQL 쿼리.
Raix OpenRouter를 통한 LLM 오케스트레이션을 위한 Fernandez 자신의 gem. 추출 파이프라인을 위한 프롬프트 구성, 응답 파싱, 오류 처리를 담당한다.
GitHub OAuth 웹 UI와 API를 위한 인증. 모든 사람이 GitHub 계정을 가지고 있으므로 가입 마찰이 없다.
제4부: 일별 개발 일지 - 커밋이 말하는 것
Day 1: 12월 29일 - 최초 체크포인트
시간: 늦은 오전부터 저녁까지
커밋: 1개의 주요 체크포인트
추가된 줄: ~6,000줄
첫 실제 체크포인트는 중부 표준시 오후 5시 47분에 올라왔다. 늦은 오전부터 작업했지만, 일관성 있고 작동하는 것이 있을 때까지 체크포인트하지 않았다.
136개 파일. 6,000줄. 오타가 아니다.
이 수준의 AI 보조 개발을 경험하지 못한 사람들에게 Claude Code의 힘을 제대로 설명하기는 어렵다. Fernandez는 6,000줄을 타이핑하지 않았다. 6,000줄을 지시했다. 원하는 것을 설명하고, Claude가 제안한 것을 검토하고, 방향을 수정하고, 통합하고, 테스트했다. 키보드에서의 실제 문자 입력은 아마도 그것의 10%였을 것이다. 하지만 설계 결정은? 아키텍처는? 그것은 모두 Fernandez였고, 설명하는 것을 실제로 구현할 수 있는 AI와의 빠른 대화를 통해 다듬어졌다.
4.1 TDD: AI 개발의 닻
이것을 지속 가능하게 만든 것은 TDD였다. 테스트 주도 개발. 대부분의 기능에 대해 Fernandez는 Claude Code가 자신과 함께 red-green-refactor 사이클을 따르도록 고집했다. 먼저 실패하는 테스트를 작성하고, 가장 간단한 구현으로 통과시키고, 테스트를 녹색으로 유지하면서 리팩터링한다.
이것은 단순한 방법론적 순수주의가 아니었다. TDD는 AI 보조 개발에서 결정적인 기능을 수행했다: 개발자를 루프 안에 유지했다.
수천 줄의 코드 생성을 지시할 때, 무엇이 만들어지고 있는지 실제로 이해하도록 강제하는 메커니즘이 필요하다. 테스트가 바로 그 강제 기능이다. 이해하지 못하는 것에 대해 의미 있는 테스트를 작성할 수 없다. 그리고 의도 자체를 이해하지 못하면 테스트가 의도를 올바르게 포착하는지 확인할 수 없다.
Fernandez는 자신의 글 “Ruby Was Ready From the Start”에서 이를 더 광범위하게 다뤘지만, 짧은 버전은: TDD는 의도를 지속적으로 검증하는 유일한 개발 프로세스다. 기계가 작동하는 것처럼 보이는 코드의 끝없는 변형을 생성할 수 있을 때, 소프트웨어가 의도한 대로 작동하는지 아는 유일하게 신뢰할 수 있는 방법은 의도를 테스트로 인코딩하고 그 테스트를 항상 실행하는 것이다.
4.2 첫날의 핵심 컴포넌트
추출 파이프라인 Nexus의 핵심은 DistillTranscript 서비스다. 원시 트랜스크립트 텍스트를 받아 구조화된 지식을 생성한다:
- 세션 식별: 트랜스크립트 내용에서 결정론적 ID 생성 (중복 및 업데이트 감지)
- LLM 추출: 결정, 학습, 참여자, 주제를 추출하는 신중하게 제작된 프롬프트로 트랜스크립트를 LLM에 전송
- 응답 처리: LLM이 JSON 반환
- 중복 제거: 이 세션을 이미 처리했는지 확인하고, 그렇다면 새 내용만 처리
- RDF 변환: 구조화된 JSON을 시맨틱 트리플로 변환
- 저장: Oxigraph에 트리플 작성
프롬프트 엔지니어링이 중요했지만 많은 시간이 걸리지 않았다. LLM은 “결정” 대 “학습”으로 간주되는 것, 참여자를 식별하는 방법, 너무 세분화되거나 너무 모호하지 않은 의미 있는 주제를 추출하는 방법을 이해해야 한다. Claude가 한 번에 해냈다.
RDF 스키마 Claude가 조직 지식을 위한 맞춤형 온톨로지를 설계했다:
1
2
3
4
5
6
7
8
9
10
11
12
nx:Session a rdfs:Class ;
rdfs:label "Session" ;
rdfs:comment "A conversation or transcript session from any source" .
nx:Decision a rdfs:Class ;
rdfs:label "Decision" ;
rdfs:comment "An architectural, strategic, or implementation decision" .
nx:Learning a rdfs:Class ;
rdfs:label "Learning" ;
rdfs:comment "An insight, lesson learned, or piece of knowledge discovered" .
모든 세션, 결정, 학습은 타입화된 관계를 가진 그래프의 노드가 된다. 결정은 nx:madeIn 세션에서. 세션은 nx:hasTopic 개념을. 사람은 nx:proposedDecision 결정을. 그래프 구조는 전통적인 관계형 저장소로는 불가능한 쿼리를 가능하게 한다.
Claude Code 훅 첫날 가장 유용한 기능 중 하나가 도착했고 그 순간부터 도그푸딩할 수 있게 했다: 자동 트랜스크립트 캡처.
Claude Code는 다양한 라이프사이클 포인트에서 실행되는 훅을 지원한다. Fernandez는 다음과 같은 Stop 훅을 만들었다:
- 세션에서 전체 대화 트랜스크립트 캡처
- Nexus API 엔드포인트로 POST
- 인증 자동 처리
모든 Claude Code 세션이 이제 자동으로 조직 메모리가 된다. 수동 노력이 필요 없다. 트랜스크립트가 추출되고, 결정과 학습이 추출되며, 모든 것이 쿼리 가능해진다.
대화형 지식 쿼리 SPARQL을 작성하도록 요구하는 대신(솔직히 말해서 아무도 원하지 않는다), Fernandez는 대화형 인터페이스를 구축했다. 일반 영어로 질문하면 LLM이 그것을 SPARQL로 번역하고, 쿼리를 실행하고, 결과를 설명한다.
KnowledgeQueryAssistant 서비스가 이것을 오케스트레이트한다:
- 질문 분석: 사용자가 무엇을 묻는지 이해
- 스키마 인식: 그래프에 어떤 엔티티 타입과 속성이 존재하는지 알기
- SPARQL 생성: 자연어 질문을 유효한 쿼리로 번역
- 실행: Oxigraph에 대해 쿼리 실행
- 결과 설명: 인간이 읽을 수 있는 형식으로 결과 제시
진짜 유용하다. “우리가 인증에 대해 내린 결정은 무엇인가?”가 SPARQL 쿼리가 되고, 쿼리는 일치하는 트리플을 반환하며, 어시스턴트가 대화식으로 제시한다: “인증과 관련된 3개의 결정을 찾았습니다. 가장 최근의 것은 ‘사용자 인증에 GitHub OAuth 사용’으로, 어제 만들어졌습니다…”
웹 UI 첫날에도 Fernandez는 탐색 가능한 인터페이스를 원했다. 초기 UI는 이미 꽤 완전한 기능을 갖췄다:
- 세션 목록: 생성된 제목과 요약과 함께 수집된 모든 트랜스크립트 보기
- 결정 뷰: 근거와 함께 추출된 모든 결정 탐색
- 학습 뷰: 추출된 모든 학습 탐색
- 문의: 시연 목적 및 기능 검증을 위해
첫날은 핵심 아키텍처를 확립했다. 트랜스크립트 입력, LLM 추출, RDF 저장, 쿼리 가능한 지식. 기초는 견고했다. 이후의 모든 것은 반복과 향상이었다.
Day 2: 12월 30일 - 델타 문제와 정제
커밋: 5개
테마: 프로덕션에서 실제로 작동하게 만들기
둘째 날은 현실과 직면하는 것이었다. 초기 시스템은 짧은 트랜스크립트에는 아름답게 작동했다. 하지만 Claude Code 세션은 몇 시간 동안 실행될 수 있다. 트랜스크립트는 수천 줄로 늘어난다. 그리고 시스템을 구축한 방식대로라면, 트랜스크립트가 제출될 때마다 전체를 다시 처리했다.
데모에는 괜찮다. LLM 토큰 비용을 지불하고 응답을 기다릴 때는 괜찮지 않다.
4.3 델타 추출의 도입
통찰은 간단했다: 각 트랜스크립트에서 얼마나 처리했는지 추적하고 새 내용만 추출한다. 하지만 구현하려면 전체 파이프라인을 재고해야 했다.
새로운 접근법:
- 콘텐츠 오프셋 추적: 각 세션에 대해 얼마나 처리했는지의 문자 오프셋 저장
- 델타 추출: 트랜스크립트 업데이트가 도착하면 마지막 오프셋 이후의 내용만 추출
- 증분 추출: 새 내용만 LLM에 전송
- 추가 전용 저장: 새 결정과 학습이 기존 세션에 추가되지, 교체되지 않음
- 메타데이터 보존: 세션 제목과 요약은 첫 추출에서만 나옴
이것은 프로덕션 소프트웨어를 데모와 구분하는 종류의 아키텍처 결정이다.
새로운 서비스 객체(KnowledgeDeduplicator, KnowledgeQuery) 추출, 세션 식별 방법 재고, 동일한 트랜스크립트가 다른 길이로 여러 번 제출될 때 멱등성 보장이 필요했다.
TDD 원칙이 여기서 필수적임을 입증했다. 전체 트랜스크립트 처리에서 델타 기반 처리로 리팩터링하는 것은 모든 이음새에서 미묘한 버그를 도입할 수 있었다. 하지만 원래 동작에 대한 포괄적인 스펙이 있었기 때문에, Fernandez는 자신 있게 리팩터링할 수 있었다. 내부를 변경하고, 스펙을 실행하고, 모든 것이 여전히 작동하는지 확인한다. 그런 다음 델타 특정 동작에 대한 새 스펙을 추가한다. red-green-refactor 사이클은 잠재적으로 위험한 아키텍처 변경을 안전하게 느끼게 했다.
이것은 Fernandez가 수십 년의 익스트림 프로그래밍 실천에서 내재화한 정확한 패턴이다: 테스트는 두려움을 해소한다. 새 코드를 만나거나 상당한 변경을 해야 할 때, 물건을 깨뜨릴까 걱정하며 조심스럽게 다가가지 않는다. 작은 단계로 이동하고, 시스템이 거의 항상 테스트를 통과하도록 유지하고, 리팩터링을 시도하고 기분이 좋지 않으면 되돌릴 수 있다는 것을 안다. 그 안전망은 단지 기술적인 것이 아니다. 탐색하려는 의지를 바꾼다.
그건 그렇고, 델타 알고리즘을 도입하고 위에서 설명한 전체 리팩터링은 약 30분이 걸렸다.
4.4 액션 아이템 기능 제거
Fernandez는 둘째 날 자신의 시스템에 대해 중요한 것을 배웠다: 액션 아이템은 노이즈였다.
초기 설계는 세 가지 유형의 지식을 추출했다: 결정, 학습, 그리고 액션 아이템. 논리적으로 보였다. 확실히 트랜스크립트에는 사람들이 추적해야 할 액션 아이템이 포함되어 있을 것이다.
LLM은 충실하게 그것들을 추출했다. “데이터베이스 스키마를 업데이트해야 함.” “인증 흐름에 테스트를 추가해야 함.” “문서를 업데이트하는 것을 기억하라.” 각 세션에서 수십 개의 액션 아이템.
문제는? 누군가 그것들을 볼 때쯤이면 거의 항상 오래된 것이었다. Claude Code 세션은 즉각적인 구현을 포함한다. Nexus가 “데이터베이스 스키마를 업데이트해야 함”을 추출할 때쯤이면 데이터베이스 스키마는 이미 업데이트되어 있었다. 액션 아이템은 유용한 정보가 아니라 역사적 노이즈였다.
결정과 학습은 지속되지만 액션 아이템은 만료된다. Fernandez는 전체 기능을 제거했다: 11개 파일 변경, 8개 삽입(+), 132개 삭제(-).
추가된 것보다 더 많은 줄이 삭제되었다. 좋은 신호다. 작동하지 않는 기능을 제거하려는 의지가 중요하다. 기능을 계속 축적하는 것은 쉽다. 무언가가 유용하지 않다는 것을 인정하고 그것을 자르는 것은 더 어렵다.
4.5 사소한 수정들
다른 커밋들은 버그 수정과 정제였다:
- 사용자 추적: 세션을 제출한 API 사용자와 적절히 연결
- URI 도메인 수정: Claude가 여러 곳에서 zar.app 대신 zar.com을 온톨로지에 환각했다. 쉬운 수정, 기존 데이터를 수정하는 rake 작업 포함
- 세션 중복 제거 엣지 케이스: 두 세션이 동일한 내용을 가지고 있지만 다른 메타데이터를 가진 경우 처리 등
다시 말해, 일반적인 소프트웨어 개발 일들이지만, 50배 속도로 일어나고 있다.
Day 3: 12월 31일 - 폭발
커밋: 18개
추가된 줄: ~3,000+
테마: 프로덕션 준비 기능
새해 전날. 대부분의 사람들은 파티를 계획하거나 술을 마시고 있다. Fernandez는 몰입 상태에 있다. 다음날 CTO로서의 첫 전사 회의가 있었고 작업을 데모하고 싶었다. 이제 본격적으로 시작할 시간이다.
이날은 절대적으로 가득 찼다. 18개의 커밋. 여러 주요 기능. 능력별로 분류해보자.
4.6 RESTful 지식 API
우선: 모든 것에 대한 적절한 REST 엔드포인트. 초기 시스템에는 기본 뷰가 있었지만 실제 API에 가까운 것은 아무것도 없었다. 셋째 날이 그것을 바꿨다.
세션, 결정, 학습 모두 전체 RESTful 엔드포인트를 가진 자체 컨트롤러를 얻었다:
1
2
3
4
5
6
GET /sessions # 모든 세션 나열
GET /sessions/:id # 세션 세부 정보 표시
GET /decisions # 모든 결정 나열
GET /decisions/:id # 결정 세부 정보 표시
GET /learnings # 모든 학습 나열
GET /learnings/:id # 학습 세부 정보 표시
각 엔드포인트는 여러 형식을 지원한다:
- HTML: 사람이 탐색하기 위해
- JSON: API 소비자를 위해
- TXT: LLM 소비를 위해
텍스트 형식 엔드포인트는 특별한 언급을 받을 가치가 있다. AI 에이전트가 /decisions.txt를 요청하면 깔끔한 토큰 효율적인 표현을 얻는다:
1
2
3
4
5
6
7
8
9
# Decision: Use PostgreSQL with pgvector for semantic search
Rationale: Keeps vector storage in the same database as other data, simplifying the stack.
Session: 9cafca33-cb1c-49c4-8696-d8be97871356
Date: 2026-01-01
# Decision: Implement delta distillation
Rationale: Full re-processing is too expensive for long transcripts.
Session: bf6dd8f-1f2b-4f8c-8c81-c3551f2fb368
Date: 2025-12-30
HTML 크러프트 없음. JavaScript 없음. 탐색 크롬 없음. 그냥 지식, 기계 소비를 위해 포맷되었다. 이것은 에이전트가 API를 소비하는 세상을 위해 구축할 때 중요한 종류의 것이다.
4.7 GitHub OAuth + API 키 시스템
이 시스템에는 귀중한 지식이 저장될 것이다. 인증 없이 배포할 수 없었으므로 그것이 다음이었다. Fernandez는 GitHub OAuth를 선택했다. 왜냐하면 회사의 모든 사람이 GitHub 계정을 가지고 있기 때문이다. 가입 마찰 없음, 비밀번호 관리 없음, 이메일 검증 흐름 없음.
가장 어려운 부분은 CLI 도구를 위한 디바이스 인증 흐름이었다.
Claude Code 훅은 어떻게든 인증해야 하지만 브라우저가 없는 터미널에서 실행된다. 설치된 MCP 서버와 인증 상태를 공유하는 방법을 찾을 수 없었다. 해결책: 브라우저를 자동으로 여는 간소화된 디바이스 흐름.
흐름 작동 방식:
- 훅이
POST /device/authorize호출 - 서버가 디바이스 코드와 검증 URL 반환
- 훅이 브라우저를 검증 페이지로 자동으로 엶 (macOS의
open또는 Linux의xdg-open사용) - Nexus 인증 페이지를 보고 검증 클릭
- 아직 로그인하지 않았다면 GitHub OAuth로 리디렉션
- 한편 훅은 백그라운드에서
/device/token을 폴링 - 권한을 부여하면 서버가 API 토큰 반환
- 훅이
~/.config/nexus/api_key.<hostname>에 보안 권한으로 토큰 저장
UX는 매끄럽다: 첫 실행 시 브라우저가 팝업되고, 권한 부여를 클릭하면 완료. 이후 세션은 캐시된 토큰을 사용하여 자동으로 인증한다.
4.8 배포 인프라
Fernandez는 이것을 가능한 한 빨리 프로덕션에서 실행하고 싶었다. localhost만이 아니다. Render를 대상 플랫폼으로 선택했지만 Claude는 Fernandez가 관습에 얽매이지 않는 접근법을 취했다고 말한다: 모든 것을 번들로 묶는 단일 Docker 컨테이너.
컨테이너에 포함된 것:
- pgvector를 가진 PostgreSQL 17: 임베디드 데이터베이스, 관리 서비스 아님
- Oxigraph: RDF 트리플 저장소도 임베디드
- Rails + Puma: 웹 애플리케이션
- SolidQueue worker: 백그라운드 작업 처리
네 가지 프로세스 모두 Overmind, Procfile 기반 프로세스 매니저가 관리한다. 하나의 컨테이너, /data의 하나의 영구 디스크 마운트, 모든 것이 자체 포함된다.
왜 모든 것을 번들로? 단순성. 여러 서비스 조정 없음. 관리 데이터베이스 가격 없음. 앱과 데이터베이스 간 네트워크 지연 없음. 작은 팀으로 확장할 수 있는 사이드 프로젝트에 완벽하다. 그것을 넘어 확장해야 한다면 데이터베이스를 분리하는 것은 간단하다.
커밋은 또한 다음을 추가했다:
- GitHub Actions 워크플로: main에 푸시할 때 자동 배포
- CI 파이프라인: 배포 전 실행되는 RSpec 테스트, 나쁜 커밋 차단
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
name: Deploy to Render
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: bundle exec rspec
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- name: Deploy to Render
uses: johnbeynon/render-deploy-action@v0.0.8
with:
service-id: $
api-key: $
needs: test 줄이 중요하다. 테스트 스위트가 통과하지 않으면 배포가 일어나지 않는다. 그리고 처음부터 TDD를 해왔기 때문에 그 테스트 스위트는 상당했다.
셋째 날까지 스펙은 다음을 포괄했다:
- 다양한 트랜스크립트 형식을 가진 전체 추출 파이프라인
- RDF 변환 및 SPARQL 쿼리 실행
- 중복 제거 로직 및 델타 처리
- 웹 및 API 모두를 위한 인증 흐름
- 대화형 쿼리 어시스턴트
- 신원 해결을 위한 엣지 케이스
TDD 원칙은 Fernandez가 자신감을 가지고 지속적 배포를 실천할 수 있게 하는 데 배당금을 지불하고 있었다.
Day 4: 1월 1일 - 새해, 새로운 능력
커밋: 29개
병합된 PR: 12개
테마: 지능적으로 만들기
새해 복 많이 받으세요! 일반 사람들이 축하 행사에서 회복하고 있는 동안, Fernandez는 MCP 서버를 구축하고 있었다. 1월 1일의 커밋 로그를 돌아보면, 어떻게 모든 것을 맞췄는지 솔직히 모르겠다.
4.9 온톨로지 브라우저
RDF는 자기 기술적이기 때문에 강력하다. 스키마 자체가 데이터다. 인스턴스를 쿼리하는 것처럼 온톨로지를 쿼리할 수 있다.
Fernandez는 사용자(그리고 에이전트)가 어떤 엔티티 타입이 존재하는지, 어떤 속성을 가지고 있는지, 어떻게 쿼리하는지 탐색할 수 있도록 UI를 통해 노출하고 싶었다.
PR #19가 온톨로지 브라우저를 제공했다:
- 엔티티 타입의 시각적 그리드: Session, Decision, Learning, Conflict, Person, Agent, Project, Concept, User, ExternalResource. 각 카드는 타입 이름, 설명, 속성 개수, 인스턴스 총계를 보여준다.
- 세부 뷰: 모든 타입을 클릭하여 전체 속성 목록, 다른 타입과의 관계, 예제 SPARQL 쿼리 보기
- 다운로드 가능한 Turtle 형식: 다른 도구에서 사용하기 위한 전체 온톨로지 정의 내보내기
- JSON API 엔드포인트: 에이전트가 쿼리하기 전에 프로그래밍 방식으로 스키마 탐색
이것은 사소해 보일 수 있지만 발견 가능성에 중요하다. 새로운 지식 시스템에 도착하면 그 모양을 이해해야 한다. 어떤 종류의 것들이 저장되어 있는가? 어떻게 관련되어 있는가? 무엇을 쿼리할 수 있는가? 온톨로지 브라우저가 그것을 제공한다.
4.10 신원 해결
이날의 큰 PR 중 하나는 근본적인 문제를 다뤘다: 이 세션에 누가 참여하는가?
트랜스크립트가 “Sarah가 PostgreSQL을 사용하기로 결정했다”고 언급하면, 시스템은 Sarah가 실제 사람임을 이해해야 한다. 그녀를 그녀가 참여한 다른 세션에 연결해야 한다. “Sarah가 관련된 결정은 무엇인가?” 같은 쿼리를 가능하게 해야 한다.
이것은 여러 구성 요소를 요구했다:
- 새로운 RDF 엔티티 타입: 인간을 위한
nx:Person, AI 어시스턴트를 위한nx:Agent. 둘 다 참여자지만 다른 처리가 필요하다. IdentityResolver서비스: 트랜스크립트에서 이름이나 이메일을 가져와 정규 Person 레코드로 해결. 변형 처리: “Sarah,” “Sarah Chen,” “sarah@company.com”이 모두 같은 사람으로 해결되어야 한다. 퍼지 매칭과 이메일 기반 식별 사용.- 귀속 추적: 추출 프롬프트가 이제 “참여자”뿐만 아니라 구체적인 귀속 추출: 누가 이 결정을 제안했는지, 누가 이 학습을 발견했는지, 누가 토론에 기여했는지.
- 사람 UI: 신원을 탐색하고 병합하는
/people엔드포인트. 때때로 시스템이 수동 통합이 필요한 중복 Person 레코드를 생성한다.
신원 해결자는 AI 이름에 대해서도 똑똑하다. “Claude,” “Claude Code,” “Assistant,” “GPT-4,” “Copilot”은 모두 에이전트로 올바르게 분류되지, 사람이 아니다. 이것은 AI 어시스턴트에 대한 Person 레코드를 실수로 생성하는 것을 방지한다.
4.11 pgvector를 사용한 시맨틱 검색
SPARQL은 강력하지만 정확하다. 특정 술어와 값을 쿼리한다. 정확히 일치하는 것을 되돌려준다.
개념적 유사성을 원한다면? “인증과 관련된 지식 찾기”는 표면화해야 한다:
- OAuth에 대한 결정
- API 키에 대한 토론
- 세션 관리에 대한 학습
- 보안 관련 충돌
- 그들 중 어느 것도 문자 그대로 “인증”이라는 단어를 포함하지 않더라도.
PR #21이 벡터 유사성 검색을 추가했다:
- pgvector 확장: pgvector 확장을 가진 PostgreSQL은 고차원 벡터를 저장하고 쿼리할 수 있다. 별도의 벡터 데이터베이스가 필요 없다.
- 임베딩 생성: Gemini의 임베딩 모델(OpenRouter를 통해) 사용, 각 결정과 학습이 의미를 포착하는 768차원 벡터로 변환된다.
RdfEntity모델: RDF 저장소의 엔티티를 미러링하고 벡터 임베딩을 추가하는 PostgreSQL 테이블. 지식이 추출되면 각 엔티티는 임베딩 생성을 위해 큐에 들어간다.SemanticSearch서비스: 자연어 쿼리를 받아 임베드하고 벡터 공간에서 가장 가까운 일치를 찾는다.
1
2
3
4
5
6
7
8
9
class SemanticSearch
def search(query, limit: 10)
query_embedding = EmbeddingService.embed(query)
RdfEntity
.nearest_neighbors(:embedding, query_embedding, distance: "cosine")
.limit(limit)
.map { |entity| enrich_with_rdf_data(entity) }
end
end
지식이 추출되면 각 결정과 학습이 임베딩 생성을 위해 자동으로 큐에 들어간다. 그래프는 벡터 인덱스와 동기화 상태를 유지한다.
4.12 충돌 감지
지식 시스템은 모순을 축적한다. 이것은 불가피하다. 두 세션이 반대 결정을 기록할 수 있다:
- 세션 A: “모바일 클라이언트에 REST API를 사용하기로 결정”
- 세션 B: “모바일 클라이언트에 GraphQL을 사용하기로 결정”
또는 서로 직접 모순되는 학습:
- 학습 1: “캐싱이 성능을 40% 향상시켰다”
- 학습 2: “캐싱이 일관성 문제를 일으켜 제거되었다”
일관성을 조용히 품는 대신, Nexus는 이제 이것들을 명시적으로 표면화한다.
PR #22가 Conflict 엔티티 타입을 추가했다:
- 비동기 충돌 감지: 각 추출 후 백그라운드 작업이 잠재적 충돌을 스캔한다. 임베딩을 사용하여 의미론적으로 유사한 항목을 찾은 다음 LLM에게 프롬프트하여 실제로 충돌하는지 평가한다.
- 상태 추적: 충돌은 다음과 같을 수 있다: 열림, 조사 중, 해결됨. 각 상태 변경은 타임스탬프와 함께 추적된다.
- 우선순위 수준: 모든 충돌이 동등하지 않다. 아키텍처 결정 간의 모순은 코드 스타일에 대한 상충되는 선호도보다 더 중요하다.
4.13 엔티티 브라우저
온톨로지 브라우저는 스키마를 보여준다. 하지만 실제 데이터는? 인스턴스 자체를 탐색하고 검색할 수 있어야 한다.
PR #25와 #27이 엔티티 탐색을 추가했다:
/entities엔드포인트: 타입 필터링으로 모든 엔티티 탐색. 모든 결정을 보여줘. 모든 학습을 보여줘. 모든 충돌을 보여줘.- 검색: 정확한 텍스트 검색과 시맨틱 유사성 검색 모두. “인증”을 문자 그대로 언급하는 엔티티를 찾거나 인증과 개념적으로 관련된 엔티티를 찾는다.
- 개별 엔티티 뷰: 모든 엔티티의 모든 속성과 관계를 보기 위해 클릭.
- 온톨로지 뷰의 개수: 온톨로지 브라우저가 이제 각 타입의 인스턴스가 몇 개인지 보여준다.
4.14 MCP 서버
MCP(Model Context Protocol)는 AI 에이전트에 도구를 노출하기 위한 Anthropic의 표준이다. Nexus에 MCP 서버를 임베딩함으로써 모든 AI 에이전트가 조직 지식 베이스를 직접 쿼리할 수 있다.
이것이 가능하게 하는 것을 생각해보라. 기능 구현을 시작하기 전에 Claude는 Nexus를 확인하도록 구성될 수 있다: “이 팀이 인증 패턴에 대해 내린 결정이 있는가?” 아키텍처 변경을 제안하기 전에 쿼리할 수 있다: “이 코드베이스에서 캐싱에 대해 우리가 가진 학습은 무엇인가?”
PR #30이 다섯 가지 도구로 MCP 서버를 구현했다:
1. nexus_ontology: 타입, 속성, 예제 쿼리와 함께 전체 스키마 가져오기. 탐색의 시작점이다.
2. nexus_type: 특정 엔티티 타입에 대한 상세 정보 가져오기. “Decision 엔티티에 대해 알려줘.”
3. nexus_recent: 최근 세션, 결정, 학습 또는 충돌 가져오기. “마지막 10개 결정은 무엇이었는가?”
4. nexus_query: 임의의 SPARQL 쿼리 실행. 찾고 있는 것을 아는 에이전트를 위해.
5. nexus_search: 시맨틱 벡터 유사성 검색. “데이터베이스 성능과 관련된 지식 찾기.”
도구들은 HATEOAS 스타일의 점진적 발견을 따른다. 각 응답에는 다음에 무엇을 쿼리할지에 대한 힌트가 포함된다. 에이전트는 nexus_ontology로 시작하여 스키마를 이해한 다음 특정 타입으로 드릴다운하고 특정 인스턴스를 쿼리할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
Agent: nexus_ontology()
→ 반환: 설명과 예제 쿼리가 있는 모든 타입
힌트: "상세한 Decision 속성을 위해 nexus_type('Decision') 사용"
Agent: nexus_type(type_name: "Decision")
→ 반환: 속성, 관계, 예제 쿼리
힌트: "최근 결정을 보려면 nexus_recent(type: 'Decision') 사용"
Agent: nexus_recent(type: "Decision", limit: 5)
→ 반환: 전체 세부 정보가 있는 5개의 가장 최근 결정
힌트: "더 구체적인 쿼리를 위해 SPARQL과 함께 nexus_query() 사용"
MCP 서버는 Nexus가 아는 모든 것에 대한 읽기 액세스를 제공한다. 조직 메모리는 더 이상 웹 UI를 탐색하는 인간만을 위한 것이 아니다. 에이전트가 소비하는 인프라이며, 이것이 처음부터의 목표였다.
29개의 커밋. 12개의 병합된 PR. 1월 1일에. 여전히 믿을 수 없다.
Days 5-6: 1월 2-3일 - 수문 열기
커밋: ~10개
테마: 보편적 수집
Fernandez는 금요일 전사 회의에서 시스템을 성공적으로 데모했다. 사람들은 흥분했다. 그도 흥분했다. 시스템은 강력했지만 Claude Code 세션만 캡처했다. 시작 부분에서 언급한 다른 모든 지식 소스는 어떤가? GitHub PR 토론. Slack 스레드. Linear 이슈. 비엔지니어는? 비전은 모든 곳에서의 수동적 수집이었다, 맞지? 마법의 시간이다.
4.15 보편적 웹훅 프로세서
PR #33이 핵심 잠금 해제였다. 모든 SaaS 플랫폼을 위한 맞춤형 통합을 구축하는 대신, Fernandez는 AI를 사용하여 모든 JSON 페이로드를 이해하고 변환하는 보편적 웹훅 엔드포인트를 구축했다:
1
POST /webhooks/:source
GitHub 웹훅을 여기로 지정. Linear 웹훅을 여기로. Slack 이벤트 구독을 여기로. Notion 웹훅을 여기로. JSON을 POST할 수 있는 모든 서비스가 지식 소스가 될 수 있다.
WebhookProcessor 서비스:
- 원시 JSON 페이로드 수신: 구조에 대한 가정 없음
- LLM 분석: Gemini 3 Flash를 사용하여 이것이 어떤 종류의 웹훅인지 이해하고 의미 있는 내용 추출
- 트랜스크립트 변환: 웹훅을 기존 추출 파이프라인이 Claude Code에서 오는 것처럼 처리할 수 있는 “트랜스크립트” 형식으로 변환
- 작업 큐잉: 백그라운드 처리를 위해 추출 작업 큐에 넣기
아름다운 부분은 우아한 저하다:
- Slack: 관련 내용을 찾을 위치를 아는 특정 추출기로 최적화된 처리 받음
- 그 외 모든 것: LLM이 JSON 구조를 분석하고 의미 있는 내용을 추출하기 위해 최선의 노력
- 어떤 무작위 내부 도구가 웹훅을 보내는가? 페이로드 어딘가에 의미 있는 텍스트 내용이 있는 한 Nexus는 지식을 추출하려고 시도할 것이다.
4.16 Slack 통합
Slack은 단순한 웹훅보다 더 깊은 통합을 받을 자격이 있었다. 그곳에서 많은 조직 토론이 일어나기 때문이다.
PR #34가 추가했다:
- Slack Events API 핸들러: 메시지, 반응, 스레드 업데이트를 위한 실시간 이벤트 처리
SlackThreadCollector: 전체 컨텍스트와 함께 전체 스레드 가져오기 및 포맷. 스레드가 추출되면 트리거 메시지만이 아니라 전체 대화를 캡처- 임계값 필터링: 모든 Slack 메시지가 보존할 가치가 있는 것은 아니다. 기본값은 자동 수집 전에 최소 3개의 답글 또는 2명의 참여자가 필요. 실질적인 토론을 캡처하는 동안 많은 캐주얼한 “좋아요”(ok, lol 등)를 필터링.
- ID 해결: Slack은 사용자에게 U09RS4298TY, 채널에 C01234ABCDE 같은 내부 ID를 사용한다. LLM은 이제 이것들을 인간이 읽을 수 있는 이름으로 해결하는 도구를 가지고 있다. “U09RS4298TY가 말했다…“가 “Obie Fernandez가 말했다…“가 된다.
임계값 필터링이 중요하다. Slack은 엄청난 양의 콘텐츠를 생성한다. 필터링 없이는 “좋아요”와 “감사합니다!”를 하루에 수천 번 추출하는 데 비용을 지불하게 될 것이다.
4.17 RDF 속성으로서의 메타데이터
최종 아키텍처 조각: 세션이 웹훅에서 시작되면 메타데이터가 쿼리 가능해진다.
PR #44가 웹훅 기반 세션을 위한 새로운 RDF 속성을 추가했다:
nx:sourceUrl: 원래 리소스로 돌아가는 링크. GitHub PR 토론의 경우 PR로 링크. Slack 스레드의 경우 Slack의 스레드로 링크.nx:resourceType: 이것이 어떤 종류의 외부 리소스에서 왔는가: pull_request, issue, slack_thread, linear_issue 등.nx:eventType: 세션을 트리거한 것: pr_opened, pr_reviewed, issue_commented, message_posted.nx:significance: 영향 분류: low, medium, high. 웹훅 프로세서는 참여자 수, 토론 길이 또는 명시적 마커 같은 요인을 기반으로 중요성을 평가할 수 있다.
이제 쿼리할 수 있다:
1
2
3
4
5
6
7
8
PREFIX nx: <https://nexus.zar.app/ontology#>
SELECT ?session ?title ?url WHERE {
?session a nx:Session ;
nx:resourceType "pull_request" ;
nx:significance "high" ;
nx:title ?title ;
nx:sourceUrl ?url .
}
“지난 달의 GitHub PR에서 모든 높은 중요성 결정을 보여줘.” RDF 그래프는 지식이 어디에서 왔는지 알고 있다, 무엇을 포함하는지만이 아니라.
제5부: 숫자가 말하는 것
5.1 코드 메트릭스
이 블로그 포스트의 세부 사항에도 불구하고, Fernandez는 여전히 관련된 작업의 표면만 긁고 있다고 느낀다.
코드:
- app, lib, spec 디렉토리에 걸쳐 ~12,800줄의 코드
- 다양한 엔드포인트를 처리하는 20개 이상의 컨트롤러
- Person, RdfEntity, Inquiry, DeviceAuthorization 등을 포함한 10개 이상의 모델
- 추출, 변환, 검색, 충돌 감지, 신원 해결을 위한 15개 이상의 서비스
- 10개의 고유한 타입과 23개의 속성을 가진 Nexus 온톨로지의 완전한 기능을 갖춘 첫 번째 초안
- RSpec으로 포괄적인 테스트 커버리지 (247개 예제)
- Claude Code, Github, Slack, Linear와의 작동하는 통합
인프라:
- CI/CD를 갖춘 Render의 전체 배포 인프라
- GitHub OAuth 및 API 키를 사용한 프로덕션 준비 인증
- 에이전트 통합을 위한 MCP 서버
- 모든 SaaS 플랫폼을 위한 보편적 웹훅 수집
타임라인: 12월 29일부터 1월 3일까지. 4 작업일이라고 하자.
5.2 이것이 의미하는 것
Fernandez는 경력에서 많은 소프트웨어를 구축했다. 그는 상당한 소프트웨어 배달 컨설팅 조직을 소유하고 운영했다. 프로젝트가 일반적으로 얼마나 걸리는지 알고 있고 비용도 안다. “작동하는 데모”와 “프로덕션 시스템”의 차이를 안다.
Claude Code가 이번 주에 할 수 있게 한 것은 점진적 개선이 아니다. 범주적 변화다.
Nexus 같은 시스템을, 솔로 개발자가 “옛날” 방식으로 구축하면 몇 개월이 걸린다. 다음 각 항목은 최소 1-2주가 걸릴 것이며, 산만함이 거의 없는 동기 부여된 엔지니어를 가정한다.
- RDF/SPARQL 접근법 연구 및 스파이크
- 스키마와 온톨로지 설계
- 수집 파이프라인 구축
- 프롬프트 엔지니어링으로 추출 구현
- 인증 및 권한 부여 추가
- 웹 UI 구축
- 배포 인프라 설정
- 벡터 임베딩으로 시맨틱 검색 추가
- MCP 서버 구축
- 모든 것을 철저히 테스트
- 나타나는 수백 가지 엣지 케이스 처리
그것은 최소 13주의 집중 개발이다. 4-5개월이라고 하자. 그리고 그것도 관련 기술을 아는 경험 많은 개발자와 함께. 이것은 다른 배달 가능한 기능 작업이 있는 일반적인 엔지니어에게는 실행 가능한 사이드 프로젝트가 아니다. 바쁜 CTO의 경우? 그래, 맞아.
그런데 Fernandez는 크리스마스와 새해 사이의 시간에 그것을 했고, 여전히 정규 업무, 강아지 산책, 휴가 활동을 위한 시간이 있었다. 레버리지는 터무니없다. (물론 일부 작업은 이발소에서 휴대폰의 Claude Code에서 이루어졌다.)
5.3 숙련된 개발자를 대체하는 것이 아니다
이것은 숙련된 개발자를 대체하는 것이 아니다. Fernandez의 아키텍처 판단, 도메인 지식, 제품 직관은 모든 단계에서 필수적이었다. Claude Code는 Nexus를 혼자 만들 수 없었다. 독자 여러분이 Claude Code의 도움으로도 며칠 만에 Nexus를 만들 수 있을 가능성은 매우 낮다.
AI 코딩 에이전트는 Fernandez의 회사 요구, 기존 인프라, 특정 패턴에 대한 선호도를 자동으로 이해하지 못한다. 하지만 Fernandez도 혼자서는 이렇게 빨리 만들 수 없었다.
절대. 일어나지. 않았을. 것이다.
제6부: 개발 경험의 질적 전환
6.1 전통적 개발의 리듬
생산성 측정은 이런 방식으로 작업하는 데 관련된 질적 차이를 포착하지 못한다. 전통적인 개발은 특정한 리듬을 가지고 있다. 무엇을 만들고 싶은지 생각한다. 타이핑을 시작한다. 문제에 부딪히고, 디버깅하고, 문서를 참조하고, Stack Overflow를 검색한다. 테스트를 작성한다. 리팩터링한다. 각 단계는 시간이 걸리고, “문제에 대해 생각하기”와 “기계적으로 솔루션 구현하기” 사이의 컨텍스트 전환에는 인지적 오버헤드가 있다.
6.2 AI 보조 개발: 오버헤드의 붕괴
AI 보조 개발은 그 오버헤드를 붕괴시킨다. Fernandez는 거의 전체 시간을 “문제에 대해 생각하기” 모드에 머문다. 무언가를 구현해야 할 때, 설명한다. 문서가 필요할 때, 요청한다. 문제에 부딪히면 증상을 설명하고 디버깅 제안을 받는다.
사실, 현재 작업 흐름 밖의 새로운 것을 생각하면 어떻게 할까? 예전에는 이슈를 기록했다. 이제는 Claude Code에서 & 접두사를 사용하여 원격 인스턴스를 시작하고 생각한 것을 작업하게 한다.
Fernandez는 “코딩이 작업에서 가장 흥미롭지 않은 부분이 될 때 무슨 일이 일어나는가”에서 이 전환을 반영했고, 이것은 최근 엄청나게 바이럴했다. 그의 경험 수준에 있는 사람에게는 실제 코드 타이핑이 오래전에 무언가를 가르치는 것을 멈췄다.
6.3 시니어 사고: AI가 대체하지 않는 것
지적 작업은 첫 줄이 작성되기 전에 일어난다: 문제 공간 이해, 수십 년의 경험에서 패턴 인식, 추상화 수준에 대한 판단 호출, 변경의 폭발 반경 평가, 무언가가 일반적이어야 하는지 특정적이어야 하는지 느끼기.
그것이 AI가 대체하지 않는 “시니어 사고”다. AI가 대체하는 것은 그러한 결정을 작동하는 코드로 기계적으로 번역하는 것이다. 그리고 솔직히? 그 번역은 항상 지루한 부분이었다.
6.4 페어 프로그래밍의 새로운 차원
경험은 매우 유능하고 매우 빠른 동료와의 페어 프로그래밍에 더 가깝다. 절대 지치지 않고 모든 API를 속속들이 안다. Fernandez는 여전히 모든 결정을 내리고 있다. 여전히 아키텍처에 책임이 있다. 하지만 기계적인 부분은 타이핑 속도 대신 대화 속도로 일어난다.
제7부: 한국 개발 생태계에 대한 시사점
7.1 기술 주권과 경쟁 우위
Fernandez의 경험은 한국의 기업들과 개발자들에게 중요한 질문을 던진다.
Sovereign AI와 내부 도구: KT, POSCO, Naver 같은 한국 기업들이 자체 AI 역량을 구축하고 있다. Nexus 같은 도구는 이러한 노력을 가속화할 수 있다. 조직 지식을 효과적으로 관리하고 활용하는 능력은 AI 경쟁에서 핵심 차별화 요소가 될 것이다.
복제 장벽의 재정의: 전통적으로 한국 기업들은 대규모 R&D 투자와 긴 개발 기간으로 경쟁 우위를 구축했다. AI 시대에는 복제 장벽이 낮아졌다. 경쟁 우위는 코드 자체가 아니라 독특한 도메인 지식, 데이터, 그리고 그것을 활용하는 전략적 통찰력에서 나올 것이다.
7.2 개발자 교육의 재설계
코딩에서 아키텍처로: 한국의 코딩 부트캠프와 대학 교육은 주로 코딩 기술에 초점을 맞춘다. AI 시대에는 아키텍처 사고, 시스템 설계, AI 활용 능력이 더 중요하다. 교육 과정을 재설계해야 한다.
TDD의 새로운 중요성: Fernandez의 경험이 보여주듯, TDD는 AI 시대에 더욱 중요해진다. 한국 개발 문화에서 TDD 채택이 상대적으로 낮은 것은 재고되어야 할 수 있다.
실전 프로젝트: 이론보다 실전 프로젝트 경험이 더 중요해진다. Nexus 같은 실제 프로덕션 시스템을 구축하는 경험이 교육의 핵심이 되어야 한다.
7.3 오픈소스 전략의 재평가
한국 개발자 커뮤니티는 전통적으로 오픈소스 기여보다는 소비에 더 치중해왔다. Fernandez의 통찰은 이것에 새로운 관점을 제공한다.
기초 도구는 오픈소스: PostgreSQL, Redis, Rails 같은 기초 도구와 라이브러리는 여전히 오픈소스 협업의 혜택을 받는다. 한국 개발자들의 이러한 영역에서의 기여는 계속 가치가 있다.
전략적 애플리케이션은 클로즈드: 하지만 회사의 핵심 경쟁 우위를 나타내는 애플리케이션은 오픈소스하지 않는 것이 더 전략적일 수 있다. 특히 AI로 복제하기 쉬운 시대에는.
7.4 스타트업 생태계의 변화
빠른 MVP에서 빠른 프로덕션으로: 한국 스타트업들은 전통적으로 긴 개발 기간과 큰 초기 투자를 요구했다. Nexus 같은 사례는 4일 만에 프로덕션 준비 시스템을 만들 수 있음을 보여준다. 이는 스타트업 생태계를 근본적으로 바꿀 수 있다.
1인 개발자의 역량: Fernandez는 CTO 업무를 병행하면서도 이것을 만들었다. AI 시대에는 작은 팀, 심지어 1인 개발자도 이전에는 큰 팀이 필요했던 시스템을 만들 수 있다. 한국의 독립 개발자들에게는 엄청난 기회다.
VC 투자 기준의 변화: 스타트업 투자자들은 “얼마나 빨리 만들 수 있는가”보다 “무엇을 만들 것인가, 왜 만들 것인가”에 더 초점을 맞춰야 할 것이다. 기술 구현 능력보다 시장 통찰력과 도메인 전문성이 더 중요한 차별화 요소가 된다.
7.5 기업 문화의 적응
실패 허용 문화: Fernandez는 액션 아이템 기능을 과감하게 제거했다. 빠른 실험과 빠른 실패가 가능한 환경이 AI 시대에는 더 중요하다. 한국 기업의 전통적인 신중함과 완벽주의는 재고될 필요가 있다.
문서화 vs. 대화: Nexus는 대화를 조직 지식으로 변환한다. 한국 기업의 전통적인 문서 중심 지식 관리는 대화 중심, AI 보조 지식 관리로 전환될 수 있다.
결정 투명성: Nexus는 모든 결정과 근거를 추적한다. 이것은 한국 기업 문화에서 종종 불투명한 의사결정 과정에 대한 새로운 접근법을 제시한다.
7.6 언어와 도구 생태계
한국어 지원: Nexus 같은 도구가 한국 기업에서 효과적으로 사용되려면 한국어 지원이 필수적이다. Slack 스레드, Linear 코멘트, PR 토론이 한국어로 이루어질 때도 효과적으로 지식을 추출할 수 있어야 한다.
한국형 도구: 글로벌 도구(Claude Code, GitHub)를 사용하되, 한국 기업의 특수한 요구에 맞춘 통합과 커스터마이징이 필요하다. Naver Works, Kakao Work 같은 한국형 협업 도구와의 통합도 고려되어야 한다.
결론: 새로운 개발의 시대
경쟁 우위의 원천 이동
Fernandez의 Nexus 프로젝트는 단순한 기술 성과가 아니다. 이것은 소프트웨어 개발 경제학의 근본적인 전환을 보여주는 사례 연구다.
코드를 빠르게 생성하는 능력이 상품화되면서, 경쟁 우위의 원천이 이동하고 있다:
- 과거: 코드 작성 능력, 대규모 개발 팀, 긴 개발 기간
- 현재: 아키텍처 사고, 도메인 전문성, AI 활용 능력, 전략적 통찰력
개발자 역량의 재정의
AI 시대의 개발자는:
- 아키텍트: 시스템을 설계하고 트레이드오프를 평가
- 전략가: 무엇을 만들지, 왜 만들지 결정
- 오케스트레이터: AI 도구들을 효과적으로 조율
- 검증자: AI가 생성한 것을 평가하고 개선
- 도메인 전문가: 깊은 비즈니스 이해를 코드로 번역
원칙을 가지고 오라
Fernandez의 마지막 메시지는 명확하다:
“당신의 원칙을 가지고 오라. 당신의 테스트를 가지고 오라. 당신의 판단을 가지고 오라. AI는 속도를 제공한다. 당신은 방향을 제공한다. 함께, 당신은 혼자서는 만들 수 없는 것을 만든다.”
이것은 AI가 개발자를 대체한다는 이야기가 아니다. AI가 개발자를 증강시키고, 가능성의 영역을 확장하고, 창의성과 전략적 사고를 위한 더 많은 공간을 만든다는 이야기다.
4일 만에 프로덕션 시스템을 만드는 시대가 왔다. 문제는 “가능한가?”가 아니라 “무엇을 만들 것인가, 왜 만들 것인가, 어떻게 그것을 전략적 우위로 전환할 것인가”다.
Fernandez는 증거를 제공했다. 이제 우리 차례다.
작성 일자: 2026-01-10