EP5. 구조 기반 산출물 생성 실습
💡 "코드 짜줘" 한 마디가 72개 검증 항목이 되기까지
"jsondb를 개발해 줘."
보통의 AI였다면 신나게 "네, 알겠습니다!"를 외치며 수백 줄의 코드를 한 화면에 와르르 쏟아냈을 것입니다. 하지만 Cocrates는 이번에도 우리의 예상을 기분 좋게 빗겨 나갑니다.
🦉 Cocrates: "이
jsondb는 어떤 용도로 쓰실 예정인가요? 아키텍처를 먼저 설계하고, 사용자님께 검토와 승인을 받은 뒤에 안전하게 코드를 생성하겠습니다."
무작정 도끼부터 휘두르지 않고(Do), 설계 도면(Plan)을 먼저 완벽하게 다듬는 것. 이것이 Cocrates가 산출물을 만들어내는 대원칙입니다.
이번 에피소드에서는 "개발해 줘"라는 단 한 문장이 6개의 아키텍처 결정 기록(ADR), 1개의 설계 명세서(Spec), 7개의 소스 파일, 그리고 무려 72개의 검증 항목으로 빌드업되는 경이로운 여정을 따라가 보겠습니다.
🏛️ 1단계. ADR 단계 — AI의 '쉬운 제안'을 무너뜨리는 사용자의 직관
Cocrates와 대화를 나누다 보면 아주 흥미로운 패턴이 발견됩니다. AI는 본능적으로 '자신이 가장 많이 학습한, 가장 구현하기 편하고 쉬운 방식'을 먼저 던진다는 점입니다. 사용자가 중심을 잡지 않으면 AI의 편의주의에 휘둘리기 쉽습니다.
이번 프로젝트에서는 총 3번의 치열한 아키텍처 논쟁(ADR)이 있었습니다.
1️⃣ [ADR 1] 저장 모델 논쟁: "NoSQL이 편해요" vs "직관적인 경로가 필요해"
- AI의 첫 제안: 가장 일반적인 몽고DB 스타일의 'Collection-Document' 구조를 추천했습니다.
- 사용자의 브레이크: "아니, 난 내가 지정한 경로가 그대로 파일명이 되는 Path-Addressable 방식(
Set("episode/e1")→episode/e1.json)이 필요해." - 결과: AI의 고정관념을 깨고 사용자 맞춤형 폴더/파일 경로 매핑 구조로 선회했습니다.
2️⃣ [ADR 2] 아키텍처 논쟁: "단독 라이브러리가 쉽죠" vs "여러 에이전트가 동시에 쓸 거야"
- AI의 첫 제안: 다루기 쉬운 '단일 프로세스용 내부 라이브러리(Library-Only)'로 시작하자고 제안했습니다.
- 사용자의 브레이크: "만약 여러 개의 AI 에이전트 프로세스가 동시에 이 DB에 접근해서 읽고 쓰면 어쩌려고? 이건 Client-Server 구조로 가야 해."
- 결과: Cocrates는 즉시 자신의 실수를 인정하고, REST API 서버(
jsondbd)와 CLI 도구를 포함하는 대형 아키텍처로 도면을 전면 수정했습니다.
3️⃣ [ADR 3] 동시성 모델 논쟁: "통째로 잠글게요" vs "파일별로 세밀하게 잠가줘"
- AI의 첫 제안: 코드 3줄이면 끝나는 'DB 전체 락(DB-level Lock)'을 들고 왔습니다. 하나의 프로세스가 쓸 때 전체 DB를 멈추는 방식입니다.
- 사용자의 브레이크: "서버 환경에서 그건 엄청난 병목이잖아! 다른 파일을 건드릴 때는 락이 안 걸리게 파일별 락(Per-File Mutex)을 설계해 줘."
- 결과:
sync.Map을 활용해 똑똑하게 동시성을 제어하는 고성능 엔진으로 업그레이드되었습니다.
💡 교훈: AI가 "이게 쉽고 좋습니다"라고 제안하는 해결책은 **'지가 만들기 편한 함정'**일 수 있습니다. 실제 사용 맥락과 시나리오를 가장 잘 아는 것은 오직 인간(사용자)뿐입니다.
📝 2단계. Spec 단계 — 도면을 하나로 묶다
치열한 토론 끝에 ADR이 모두 승인되자, Cocrates는 이 결정들을 단 하나의 완벽한 헌법으로 통화합했습니다. 그것이 바로 spec/jsondb.md입니다.
이 명세서는 자체 완결성(Self-Containment)을 갖추고 있어, 이 문서 하나만 읽어도 10개의 REST 엔드포인트 기능, API 시그니처, CLI 명령어 스펙, 심지어 테스트 요구사항까지 한눈에 파악할 수 있도록 촘촘하게 구성되었습니다.
⚡ 3단계. Generation 단계 — 오직 Spec만 보고 달린다
스펙이 확정되자 Cocrates는 spec-driven-generation 모드를 켰습니다. 사용자가 처음에 던진 모호한 프롬프트는 잊고, 오직 우리가 함께 합의한 Spec 문서만을 유일한 법전으로 삼아 코딩을 시작합니다.
- 결과물: 코어 라이브러리 Go 파일 7개, REST 서버 파일, CLI 도구 파일, 그리고 스모크/스키마/동시성을 완벽히 검증하는 단위 테스트 및 통합 테스트 코드까지 단숨에 컴파일 오류 하나 없이(
go build,go vet패스) 생성해 냈습니다.
🔍 4단계. Verification 단계 — 72개의 촘촘한 그물망 검증
코드가 다 짜였다고 해서 축배를 들긴 이릅니다. Cocrates는 곧바로 spec-driven-verification 기능을 발동해, Spec 문서에 적힌 모든 요구사항을 부품 목록(인벤토리)으로 쪼개어 대조하기 시작했습니다.
📊 검증 스코어보드: 총 72개 항목 중 70개 PASS, 1개 FAIL, 1개 검증 불가
완벽해 보였던 코드 숲에서 1개의 디비에이션(Deviation: 스펙과의 차이)과 숨어있던 AI의 침묵의 기본값들이 덜미를 잡혔습니다.
🚨 덜미를 잡힌 결함 (Deviation)
- 스펙 문서:
jsondb schema set /blog/episode→PUT /schema/blog/episode - 실제 코드 결과: 앞의 슬래시가 중복 처리되어
PUT /schema//blog/episode로 이중 슬래시가 붙은 채 요청이 날아감. - 비록 서버가 유연하게 처리해서 굴러는 갔지만, 외부 API 규격 일관성을 깨뜨리는 디테일한 에러를 검증 단계가 아니었다면 놓칠 뻔한 사례입니다.
🤫 AI의 침묵의 기본값 (Undocumented ASR)
Spec 문서가 미처 명시하지 못한 빈틈을 타서, AI가 자기 마음대로 결정해 버린 6가지 암묵적 설계도 발견되었습니다.
- 예를 들어 query parameter를 조합할 때 필수적인 URL 인코딩을 누락했다거나, 데이터를 수정할 때 스키마 재검증을 은근슬쩍 생략한 코드들이 잡혀 올라왔습니다.
💡 교훈: "Spec을 줬으니 코드가 완벽하겠지?"라는 안일한 믿음은 금물입니다. 명시되지 않은 공백은 AI가 임의로 채워버리기 때문에, 반드시 검증(Verification)을 통해 Spec을 계속 보완하는 반복/증분(living document) 주기를 가져가야 합니다.
📝 세 줄 요약
- AI의 '가장 편한 제안'을 의심하세요. 진짜 필요한 비즈니스 맥락과 성능 요건은 사람이 챙겨야 합니다.
- Spec은 살아있는 생명체입니다. 코드를 짜고 검증하는 과정에서 누락된 요구사항을 발견하면 계속 Spec을 업데이트해야 합니다.
- Cocrates의 진가는 정답 출력이 아닙니다. 사용자가 구조적으로 짚고 넘어갈 수 있도록 아키텍처 가이드를 대화로 이끌어주는 페이스메이커 역할에 있습니다.
🎬 다음 편 예고
우리는 Cocrates가 제공하는 든든한 설계 시스템 위에서 산출물을 뽑아내는 전체 사이클을 멋지게 완수했습니다.
그렇다면 이제 한 걸음 더 나아갈 때입니다. 다음 에피소드에서는 남이 만들어 둔 스킬을 쓰는 걸 넘어, "Cocrates 안에서 작동할 새로운 구조적 산출물 생성 스킬(설명문/보고서 자동화 스킬)"을 우리가 직접 Cocrates와 함께 만들어 보는 짜릿한 빌딩 실습을 시작해 보겠습니다!
다음 세션을 맞이하기 전, 여러분 스스로에게 이 한 가지 질문을 무겁게 던져보시기 바랍니다.
"지금까지 AI가 짜준 첫 번째 코드 제안을, 나는 아무 의심 없이 복사·붙여넣기 하진 않았는가?"
이 시리즈는 Cocrates Harness 프레임워크를 소개합니다. Cocrates는 소크라테스식 대화로 사용자가 주도권을 잡고 성장하도록 설계된 에이전트 하네스입니다.