매주 반복되는 고민: '성찰'은 왜 이렇게 힘들까?

매주 대화 훈련 파트너와 함께 상호 코칭을 하며 동기면담(MI)을 연습하는 시간은 나에게 매우 소중하다. 하지만 늘 풀리지 않는 숙제가 있었다. 대화가 끝나고 녹음 파일을 축어록으로 변환해 살펴보는 과정이 너무나 고되었기 때문이다.

어렵게 만든 축어록을 앞에 두고도 "공감이 부족한 것 같아요"라거나 "내가 너무 말을 많이 했네요" 같은 모호한 감상 이상의 피드백을 나누기는 쉽지 않았다. 피드백이 자칫 상대방을 평가하는 것처럼 느껴질까 봐 조심스러워지기도 했고, 정작 중요한 성찰의 포인트는 일상의 바쁨 속에 금세 휘발되곤 했다. 저는 이 '막막함'을 해결하고 싶었다. 대화의 복잡함을 걷어내고, 우리가 무엇을 실험해야 할지 알려주는 명확한 틀이 필요했다.

'Generative Sequence'로 쌓아 올린 나만의 성찰 공간

이 프로젝트를 시작하며 제가 선택한 방법은 한꺼번에 완벽한 서비스를 만드는 것이 아니었습니다. 대신 CLAUDE.md에 정의한 Generative Sequence 원칙에 따라, 시스템의 '생명력'을 한 단계씩 키워나갔다.

처음에는 그저 대화를 기록할 수 있는 '그릇'을 만드는 것에서 시작했다. 이어 외부 툴에서 만든 축어록을 손쉽게 가져오는 기능을 넣었고, 여기에 AI가 특정 관점(Lens)으로 대화를 관찰해 질문을 던져주는 기능을 더했다. 이렇게 차근차근 벽돌을 쌓아 올리듯 구현해 나가는 과정은, 제가 코칭 현장에서 느꼈던 갈증을 하나씩 해소해 나가는 과정이기도 했다.

전율의 순간: MITI 정밀 분석과 연습 카드의 만남

가장 결정적인 순간은 MITI 4.2 정밀 분석(T-013)을 시스템에 이식했을 때 찾아왔다. 동기면담의 전문적인 평가 기준이 AI를 통해 데이터로 치환되어 화면에 뿌려지는 순간, 저는 비로소 "이게 내가 바라던 거구나"라는 확신을 얻었다.

단순히 "잘했다"는 칭찬 대신, 상담자의 역량과 내담자의 반응이 Radar Chart로 그려지며 대화의 역동이 눈앞에 시각화되었다. 특히 감동적이었던 것은 '연습 카드(Practice Cards)'였다. 대화 중 놓쳤던 결정적 순간을 포착해 "이 상황에서 이 대안 문장을 써봤다면 어땠을까요?"라고 제안하는 카드를 뒤집어보며, 저는 평가의 부담에서 벗어나 '실험의 재미'를 발견했다.

다음 상호 코칭이 기다려지는 이유

이제 저와 파트너의 연습은 이전과 전혀 다른 양상을 띠게 될 것이다. 우리는 더 이상 서로를 '평가'하지 않을 것같다. 시스템이 제공하는 구체적인 관찰 지표를 놓고 함께 '연구'한다.

"이번 세션에서는 이 연습 카드에 나온 '열린 질문'을 중점적으로 실험해 볼까요?"라고 제안하며, 대화는 판정으로 닫히는 결과물이 아니라 다음 대화를 여는 풍부한 재료가 된다. 이 시스템은 우리를 더 잘 말하게 만들기보다, 우리의 대화를 더 깊게 만들고 있다.

이 시스템이 우리의 대화 훈련에 더 큰 도움이 되고, 다른 사람들과도 이 시스템을 나누게 될 것이라는 기대가 크다. 이 시스템의 여정은 이제 막 시작되었다.

참고 문서

Dialog Lab : https://github.com/blcktgr73/DialogueLab

요즘 알고 지내는 비개발자들이 Vibe Coding/Agentic Coding에 푹 빠져 사는게 보인다. 나에게도 AI는 내 아이디어를 실현해 주는 구세주와 같다. 하지만 여러 가지 개발을 해보다 보니, 어느 정도 개발이 진행되다 보면 "AI가 왜 답답하게 굴지?" 혹은 "고쳤다는데 왜 똑같은 에러가 나지?" 같은 도돌이표 상황에 빠지게 된다. 새삼, 개발자들이 AI가 만든 코드를 완전히 믿지 못한다는 것도 공감이 가기도 한다.

내 경험을 기반으로 '바이브 코딩(Vibe Coding)'의 한계를 넘어서, 프로젝트를 끝까지 완수하게 만드는 실전 팁을 정리했보았다.

1. AI가 제자리걸음을 할 땐 '피드백'을 요청하자

AI가 비슷한 코드가 너무 오래 걸린다거나, 혹은 문제 수정 상황이 반복되는 느낌이 있다면, 어떻게 하는가? 그렇다면 대화의 주도권을 가져와야 한다. 피드백을 달라고 요청해야 한다.

  • 설명 요청: AI로 생성한 코드가 시간이 오래 걸리는 경우가 종종 있다. 그럼, 세우고 "어떤 동작을 하고 있는지 사용자가 알수 있도록 해줘"라고 해보자. UI로 진행 상황을 표현하기도 하고, Command Line Interface(CLI) 코드라도 중간 진행 사항을 알려준다.
  • 회고 요청: "지금 상황을 설명해줘", "지금까지 시도한 방법들을 요약해줘", 혹은 "왜 실패했는지 네 생각을 말해줘"라고 시켜보자.
  • 관점 전환: "지금 방식 말고 아예 다른 접근 방식 3가지만 제안해 봐"라고 요청하면, AI가 스스로 고정관념에서 벗어나 새로운 길을 찾기도 한다.

계속 같은 상황을 반복시키는 것은 토큰 낭비이기도 하지만, 귀중한 우리의 시간도 낭비하고 있게 된다.

2. AI의 눈과 귀가 되는 상세한 '로그(Log)'

개발자들이 디버깅한다는 이야기를 많이 들어보았을 것이다. 여러 가지 방법이 있지만, 가장 많은 방법이 로그를 확인하는 것이다. 우리도 내 컴퓨터 안에서 무슨 일이 일어나는지 모르지만, AI도 마찬가지이다. 문제가 일어나는 상황을 정확히 전달해야 한다.

  • 로그 추가 요청: 에러 원인을 모를 땐 "어디가 문제인지 알 수 있게 로그(console.log 등)를 추가해 줘"라고 하자.
  • 환경별 대응: 브라우저 콘솔, 서버 터미널, 심지어 모바일 앱에서도 로그를 뽑아 AI에게 먹여주면 정답률이 비약적으로 올라간다.

3. '정책(Policy)'과 '패턴(Pattern)' 문서화

개인적으로는 Claude Code를 초기에 많이 써서, 개발 방법을 CLAUDE.md에 저장해 두고 쓴다. 개발 세션을 시작할 때, 이런 약속들을 상기 시키고 시작한다. 하지만, 시간이 지나가거나 프로젝트가 커지면 AI는 이전에 약속했던 규칙(예: 디자인 스타일, 변수 이름 규칙 등)을 잊어버린다.

  • 규칙 저장소: 반복적으로 지켜야 하는 정책이나 코드 패턴은 별도의 .md 문서(예: POLICY.md)로 정리하자.** 최근에는 LLM을 통해 생성한 결과를 json으로 받을 때, 예외가 많이 생기고 해서 이 부분을 해결하는 부분을 공통코드로 만들었다. 이 때, 패턴 문서를 만들어 AI가 참고하도록 하고 있다.
  • 참조 지시: "새 기능을 짤 때 항상 POLICY.md 문서를 참고해서 작성해 줘"라고 지시하면, 프로젝트의 일관성이 유지되고 나중에 코드를 갈아엎는 불상사를 막을 수 있다. 최근에 pdf를 생성하는 규칙도 반복되니 정책(Policy)라는 이름으로 markdown 문서를 생성하고 참고하게 했다.

4. GitHub 저장소 활용: AI와의 협업에서 '세이브 포인트' 만들기

컴퓨터로 작업하는 사람들이 공동적이면서 기본으로 말하는 작업의 가장 중요한 부분은 백업인 것 같다. 개발자에게 backup에 해당하는 것이 코드 저장소라고 할 수 있다. Agentic Coding에서 코드 저장소(Repository)는 단순히 코드를 보관하는 창고가 아니다. AI와 대화하며 코드를 고치다 보면, 잘 되던 코드가 갑자기 엉망이 되어 "어디서부터 잘못됐지?"라고 자책하게 되는 순간이 온다.

  • Commit은 '세이브'이다: 기능 하나가 성공적으로 구현될 때마다 Commit(기록)을 남기세요. "로그인 기능 구현 완료"라고 적어두면, 나중에 AI가 사고를 쳐도 클릭 한 번으로 가장 완벽했던 상태로 되돌아갈 수 있다.
  • AI에게 과거를 보여주자: "이전 버전에서는 잘 작동했는데 지금은 안 돼. 이전 코드랑 비교해서 뭐가 달라졌는지 분석해 줘"라고 요청할 수 있다. GitHub에 기록된 히스토리는 AI에게 가장 강력한 학습 데이터가 된다.
  • Branch로 실험하기: 새로운 기능을 시도할 때는 기존 코드를 건드리지 말고 '새 가지(Branch)'를 치자. 마음껏 실험하다가 망하면 그냥 삭제하고 원래 가지로 돌아오면 그만이다. 비개발자가 '두려움 없이' 코딩하게 만드는 가장 큰 힘이다.
  • 버전 관리 도구 활용: git의 "터미널 명령어가 어렵다면 앱을 사용해도 좋다. VS Code도 기본적인 git/github 연동은 잘 되는 편이다.

5. Playwright로 '자동 검사기' 세우기

나도 마찬가지이지만, 비개발자가 가장 무서워하는 것은 "하나를 고쳤는데 기존에 잘 되던 기능이 망가지는 것"일 것이다.

  • End to End (E2E) 테스트: Playwright를 사용해 사용자의 클릭과 이동 경로를 테스트 코드로 짜달라고 하자. 명령어 한 줄 혹은 자동화 기법으로 추가 개발한 내용이 기존 동작을 망가뜨리는지 확인할 수 있다.
  • 안전장치: 새 기능을 넣은 후 테스트를 돌려 "기존 기능이 여전히 안전함"을 확인받는 순간, 코딩에 대한 막연한 공포가 자신감으로 바뀌게 된다.

6. GitHub Actions로 '24시간 관리자' 채용하기

위와 같은 E2E 테스트를 내가 직접 테스트를 돌리는 것조차 잊어버릴 수 있다. 이때 GitHub Actions가 해결책이 된다.

  • 자동화: 코드를 올릴 때마다 서버가 자동으로 Playwright 테스트를 실행해 "합격/불합격"을 알려준다.
  • 신뢰도: 시스템이 "이 코드는 안전하다"라고 보증해 주니, AI의 코드를 훨씬 더 믿고 빠르게 수용할 수 있다.

Vercel과 같은 서비스는 github action과도 잘 연계가 되어서, 내가 수정한 사항을 github에 적용하면 자동으로 배포해 준다.

개발의 최종 목표는 '시스템'

단순히 AI에게 코드를 짜달라고 하는 단계를 넘어, 나만의 검증 시스템과 규칙을 갖추게 되면 상용 수준으로 올라가는 기본이다.

  1. 전략 회의: 막힐 땐 AI에게 해결 전략을 묻기.
  2. 철저한 기록: 로그와 정책 문서화로 AI에게 컨텍스트 제공하기.
  3. 자동 검증: Playwright와 GitHub Actions로 안전장치 만들기.

이 시스템만 갖춰지면, 비개발자도 수만 줄의 코드를 가진 복잡한 서비스를 전문가처럼 안정적으로 운영할 수 있는 기본을 갖추게 된다. 이제 AI는 단순한 도구가 아니라, 여러분의 든든한 '엔지니어링 팀'이 될 것이다.

들어가며: 왜 같은 프로젝트를 두 번 만들었나?

Vibe Coding으로 복잡한 요구 사항을 다루어 보려고, GPTers와 유사한 학습 플랫폼을 만들기로 했다. 많은 사람들이 접근하는 방법에 따라서 요구 사항(PRD)를 만들고 단계적 접근 방법 (Iterative Approach)를 따라서 접근했다. 기능을 하나씩 완성해가며 쌓아올리는 방법이다.

 

그런데, 의문이 생겼다. 이 방법이 정말 좋은 것인가?

 

이 때 떠오른 방법이 Christopher Alexander의 Nature Of Order에서 설명하는 생성적인 접근법(Generative Sequence)을 써보고 비교해보고 싶었다. 즉, 구조적 개선을 중심으로 점진적으로 진화시키는 방법이다.

 

결론부터 말하자면, 둘 다 만들어봤다.

 

그리고 그 과정에서 깨달았다. 개발 철학의 차이가 코드 몇 줄보다 훨씬 큰 영향을 미친다는 것을.


Part 1: 두 프로젝트의 탄생

StudyBlog: "완성된 기능을 쌓아가는 방식"

핵심 철학: "작동하는 것부터 만들자"

Phase 1 (MVP)
├── Iteration 1: 프로젝트 초기 설정
├── Iteration 2: 인증 시스템 ✅
├── Iteration 3: 게시물 CRUD ✅
├── Iteration 4: 카테고리 시스템 ✅
└── Iteration 5: UI 개선 ✅

Phase 2
└── Iteration 6: 코드 품질 개선 🔄

결과:

  •  기본 블로그 기능 완벽 작동
  •  Supabase + Drizzle ORM으로 안정적인 DB
  •  다크모드, 반응형 디자인

하지만:

  • 일반적인 블로그와 차별화 포인트 부족
  • AI 기능은 "미래 계획"으로만 존재

StudyBlogGenSeq: "구조를 진화시키는 방식"

핵심 철학: "이 변경이 사용자 경험을 어떻게 개선하는가?"

이 방식은 Christopher Alexander가 건축에서 설명한 원리와 놀랍도록 유사하다.

Alexander는 이렇게 말한다:

 

"만약 당신이 정말로 땅, 부지, 그리고 형성되어가는 건물의 전체성(wholeness)을 따르고, 그 전체성이 자연스럽게 전개되도록 허용한다면—처음의 (그리고 임의적인) 이미지는 점차적으로 상식, 즉 현실과 자리하고 있는 것의 전체성에 자리를 내주게 될 것이다."

 

소프트웨어 개발에서도 마찬가지다. "AI 학습 플랫폼"이라는 초기 이미지에서 출발했지만, 실제로 사용자가 글을 쓰는 과정을 관찰하고, 그들이 겪는 어려움을 이해하면서, 현실이 말해주는 바에 따라 구조가 진화했다.

 

Phase 1: Foundation ✅
Phase 2: AI Editor Core ✅
├── 실시간 문장 개선 (GPT-4o-mini)
├── 자동 태그 생성 (16개 키워드 감지)
├── 템플릿 시스템 (학습경험/프로젝트후기/튜토리얼)
└── Multi-provider AI 아키텍처 (OpenAI/Claude)

Phase 3: Database & Community 🔄
└── LocalStorage → Supabase 전환 예정

결과:

  • 실제로 작동하는 AI 글쓰기 어시스턴트
  •  템플릿으로 초보자도 구조화된 글 작성
  •  2초 후 자동 태그, 8초 후 문장 개선 제안
  • 완전한 Write → Publish → Explore 워크플로우
  •  LocalStorage로 즉시 발행 가능

트레이드오프:

  • AI 비용 지속 발생 ($100-200/월 예상)

Part 2: 철학의 차이가 만든 결과들

1. "무엇을 먼저 만드는가?"

Alexander의 건축 비유를 계속해보자. 그는 원통형 집의 이미지에서 출발한 건축가를 예로 든다.

Iteration 방식 (StudyBlog)은 이렇게 말한다:

  • "원통형 집을 짓기로 했어. 먼저 기초를 완성하고, 그 다음 벽을 세우고, 지붕을 올리고, 마지막에 창문을 내자."
  • 각 단계는 완벽하게 끝나야 다음으로 진행할 수 있다.
  • 이미지가 주도권을 갖는다.

Transformation 방식 (StudyBlogGenSeq)은 이렇게 말한다:

  • "원통형이라는 이미지로 시작했지만, 이 땅의 경사를 보니 다른 형태가 더 자연스럽겠어."
  • "나무의 위치를 보니 창문은 여기에 있어야 해."
  • "전망을 고려하면 현관의 방향이 바뀌어야 해."
  • 현실이 주도권을 갖는다.

Alexander의 말대로:

"점진적으로, 천천히, 단계적으로, 당신의 선행 이미지 속 모든 요소들은 녹아 사라지게 되며, 현실과 상식은 전혀 다른 것을 만들어내게 된다."

 

StudyBlog의 우선순위

1. 인증 → 2. CRUD → 3. 카테고리 → 4. UI → 5. AI(?)

논리: "기본 기능이 완성되어야 AI를 얹을 수 있다"

StudyBlogGenSeq의 우선순위

1. AI 에디터 → 2. 템플릿 → 3. 워크플로우 → 4. DB

논리: "AI가 핵심 차별화 요소다. 먼저 증명하자"

결과의 차이

  • StudyBlog: 안정적이지만 평범한 블로그
  • StudyBlogGenSeq: AI 기능을 완성하고 불확실한 이 부분에 집중이 가능하다.

Part 3: CLAUDE.md - AI 페어 프로그래밍 가이드의 차이

두 프로젝트는 Claude AI와 협업하는 방식도 완전히 달랐다. 그 차이가 CLAUDE.md 파일에 고스란히 담겨있다.

StudyBlog의 CLAUDE.md: "실용적 가이드"

파일명: CLAUDE.md (37줄)

핵심 내용:

# Context Awareness & Code Preservation
- 사용자 정의 코드 구조와 네이밍 보존
- 명시적 지시가 없으면 리팩토링 금지

# Clarity and Traceability
- 생성/수정된 모든 코드에 명확한 설명과 TODO 마커

# Modular Thinking
- 모듈화되고 테스트 가능한 구현
- 유틸 함수, 재사용 가능한 컴포넌트

# Iterative Development
- 작은 테스트 가능한 단계로 분할
- 다음 단계로 진행 전 사용자 확인

# Documentation & Library Integration
- context7 MCP로 최신 문서 검색
- 공식 문서 패턴 우선 사용

특징:

  •  실용적이고 간결함
  •  전통적인 개발 Best Practice
  •  "어떻게 코드를 짜야 하는가"에 집중
  •  라이브러리 통합과 문서화 강조

철학: "Claude는 코딩 도우미"


StudyBlogGenSeq의 CLAUDE.md: "Transformation Agent"

파일명: CLAUDE.md (96줄, StudyBlog의 2.6배)

핵심 내용:

##  목적: Transformation 중심 AI Pair Programming

- **구조적 생명력(Structural Life) 향상**
- **살아있는 구조(Living PRD)**로 진화
- **Transformation 단위 진행** (Iteration이 아님)
- **맥락 보존(Context-preserving)** 개발

##  운영 원칙

### Generative Sequence 기반 개발 루프
1. 맥락 로드: PRD, 기존 코드, Transformation Log 확인
2. Transformation 정의: '작은 구조적 변화 한 가지'
3. 설계 옵션 제안: 2~3개 대안과 트레이드오프
4. 코드 생성/수정: 작은 PR(diff) 단위
5. 맥락 보존 검증: 구조 퀄리티 메트릭 체크
6. 문서 업데이트: Living PRD, Backlog, Transformation Log
7. 후속 Transformation 제안: 다음 단계 후보 제시

##  Transformation 템플릿
- Intent: 구조 개선 목표 (문제-맥락-해결책)
- Change: 변경 내용
- Constraints: 제약 조건
- Design Options: A/B/C - 트레이드오프 포함
- Chosen & Rationale: 선택과 근거
- Acceptance: 테스트/데모 기준
- Impact: API/데이터/UX/문서 영향
- Structural Quality Metric Change: 응집도/결합도 변화
- Follow-ups: 후속 작업

특징:

  •  Christopher Alexander의 철학 반영
  •  "구조적 생명력" 향상이 목표
  •  Iteration이 아닌 Transformation 단위
  •  Living PRD - 문서가 살아 진화함
  •  고객을 "공동 설계자"로 간주

철학: "Claude는 Transformation Agent"


CLAUDE.md 비교표

항목 StudyBlog StudyBlogGenSeq
분량 37줄 96줄 (2.6배)
개발 단위 Iteration Transformation
문서 철학 정적 가이드 Living Document
Claude의 역할 코딩 도우미 Transformation Agent
핵심 개념 Best Practice Structural Life (구조적 생명력)
의사결정 사용자 확인 후 진행 2-3개 옵션 + 트레이드오프 제시
문서화 코드 설명 중심 PRD/TRANSFORMATIONS/BACKLOG 진화
검증 방식 테스트 케이스 구조 퀄리티 메트릭
고객 관점 피드백 제공자 공동 설계자

실제 개발 과정의 차이

StudyBlog 방식 (Iteration)

개발자: "인증 시스템 만들어줘"
Claude: "Supabase Auth 사용하시겠습니까?"
개발자: "응"
Claude: [코드 생성]
개발자: "좋아, 다음은 게시물 CRUD 만들어줘"

특징: 명확하고 빠름, 한 번에 한 가지 완성


StudyBlogGenSeq 방식 (Transformation)

개발자: "사용자가 글을 잘 쓸 수 있게 도와주고 싶어"

Claude (Transformation Agent):
"T-20251003-001: AI 글쓰기 어시스턴트 추가

Intent:
- 초보자도 구조화된 글을 쓸 수 있게 AI 제안 제공
- 사용자 경험의 핵심 차별화 요소

Design Options:
A) OpenAI만 사용 (빠름, 비용 $0.15/1M tokens)
B) Claude만 사용 (고품질 한국어, $3.00/1M tokens)
C) Multi-provider (유연성, Factory Pattern)

트레이드오프:
- A: 빠르지만 한국어 품질 낮음
- B: 품질 좋지만 비용 20배
- C: 복잡하지만 상황별 선택 가능

Chosen: C (Multi-provider)
Rationale:
- 개발 시 Mock 사용 (비용 $0)
- 프로덕션 시 OpenAI/Claude 선택 가능
- 한 Provider 장애 시 Fallback

Impact:
- 사용자: 8초 대기 후 개선안 확인
- 비용: $50/월 (1000 요청)
- 코드: Factory Pattern 추가

Structural Quality Metric:
- 응집도: AI 서비스 레이어 분리 → 향상
- 결합도: Interface로 Provider 격리 → 감소
- 테스트 용이성: Mock으로 API 없이 테스트 가능

Follow-ups:
- T-20251003-002: 요청 캐싱으로 비용 50% 절감
- T-20251003-003: 사용자 피드백 수집 시스템

특징: 느리지만 깊이 있음, 구조적 사고 강제됨


어느 것이 더 나은가?

StudyBlog 방식의 장점

 

  • 빠른 진행: 질문-답변-구현으로 즉시 완성
  •  명확한 목표: 한 번에 한 가지만
  •  낮은 진입 장벽: 전통적인 개발 방식
  •  실용성: Best Practice 즉시 적용

StudyBlogGenSeq 방식의 장점

  • 구조적 사고: 왜, 어떻게, 다음은?
  •  의사결정 기록: Transformation Log로 근거 추적
  •  진화하는 문서: Living PRD가 계속 업데이트
  •  트레이드오프 인식: A vs B vs C를 항상 고려

 


깨달은 것

1. CLAUDE.md는 "개발 철학의 선언문"

  • StudyBlog: "Claude야, 내가 시키는 대로 코드 짜줘"
  • StudyBlogGenSeq: "Claude야, 나와 함께 구조를 진화시켜줘"

2. 같은 AI, 다른 역할

  • 코딩 도우미 Claude: 빠르지만 얕은 협업
  • Transformation Agent Claude: 느리지만 깊은 협업

3. 문서는 "과거 기록" vs "미래 설계도"

StudyBlog:

## Iteration 3
- [x] 게시물 CRUD 완료
- [x] 카테고리 추가

→ "무엇을 했는가"

StudyBlogGenSeq:

## T-20251003-001
Intent: 초보자도 전문가처럼
Options: A/B/C
Chosen: C
Follow-ups: 캐싱, 피드백

→ "왜 이렇게 했는가, 다음은?"

4. 속도 vs 품질의 트레이드오프

  • Iteration 방식: 빠르게 완성 → 나중에 리팩토링 (언제?)
  • Transformation 방식: 천천히 진화 → 구조는 항상 깔끔 (하지만 느림)

결론: 당신의 CLAUDE.md는 어떤가?

이 글을 읽는 당신에게 질문하고 싶다.

당신의 CLAUDE.md는 어떤 철학을 담고 있는가?

  • Claude를 "코딩 도구"로 쓰는가?
  • Claude를 "공동 설계자"로 쓰는가?

빠른 완성이 목표라면 → StudyBlog 방식

  • 37줄의 간결한 가이드
  • Iteration 단위
  • Best Practice 즉시 적용

구조적 진화가 목표라면 → StudyBlogGenSeq 방식

  • 96줄의 Transformation 철학
  • Living PRD
  • 트레이드오프 기반 의사결정

정답은 없다. 하지만 선택은 해야 한다.

그리고 그 선택이 CLAUDE.md에 담겨야 한다.

왜냐하면, CLAUDE.md는 단순한 설정 파일이 아니라, 당신의 개발 철학이 담긴 선언문이기 때문이다.

참고 문서

StudyBlog: https://github.com/blcktgr73/StudyBlog
StudyBlogGenSeq: https://github.com/blcktgr73/StudyBlogGenSeq

📚 PDF 책 읽기 앱: 기능 요약

기능 설명

  • 📖 책 목록 화면 등록된 PDF 책들의 표지를 보여주고, 읽은 비율을 ProgressBar로 표시
  • ➕ 등록 기능 파일 선택(File Picker)으로 PDF를 등록
  • 🗑 삭제 기능 등록된 책을 삭제할 수 있음
  • 📄 책 읽기 화면 선택한 책의 내용을 페이지 단위로 표시, 이전/다음 페이지 이동 가능
  • 🔊 TTS 기능 현재 페이지 내용을 TTS로 읽어줌 (기기 TTS or 온라인 TTS 선택 가능)
  • ⚙️ 설정 메뉴 사용자가 TTS 엔진을 기기용/온라인용으로 선택 가능

🧱 프로젝트 폴더 및 파일 구조 (패키지 기준)

com.example.pdfreader
├── MainActivity.kt                  // 책 목록 UI (RecyclerView)
│
├── adapter
│   └── BookListAdapter.kt          // RecyclerView Adapter
│
├── data
│   ├── Book.kt                     // Room Entity
│   ├── BookDao.kt                  // Room DAO
│   └── BookDatabase.kt             // Room DB 생성
│
├── tts
│   ├── TtsService.kt            // TTS 호출 (기기/온라인 선택)
│   └── OpenAiTts.kt             // Open AI TTS 통신 API
│
├── ui
│   └── SettingsFragment.kt         // TTS 설정 메뉴
│   └── PdfReaderActivity.kt        // PDF 페이지 보기 + TTS
│
└── res
    ├── xml/preferences.xml         // TTS 선택 Preference 정의
    └── values/arrays.xml           // TTS 옵션 배열 정의

🛠️ Empty Project에서 단계별 구현 순서

🔹 1단계: 기본 구성 (Empty Project → 책 목록 화면 만들기)

  • MainActivity.kt 생성
    • RecyclerView 추가하여 등록된 책 표시
    • Book.kt, BookDao.kt, BookDatabase.kt 구성
    • BookListAdapter.kt 작성
    • 책 등록 버튼 → FilePicker 구현
    • PDF 썸네일 추출 (PdfRenderer) → Room에 저장

📦 관련 기술: Room, RecyclerView, PdfRenderer, ActivityResultContracts.OpenDocument

🔹 2단계: 책 읽기 화면 구성

  • PdfReaderActivity.kt 생성
  • PDF 페이지 표시 (AndroidPdfViewer 또는 PdfRenderer)
  • 페이지 이동 버튼 추가 (이전/다음)
  • 읽은 페이지 비율 저장 → Book.progress 업데이트

📦 관련 기술: PdfRenderer, Intent 전달, 상태 저장

🔹 3단계: TTS 기능 연결

  • PdfReaderActivity에서 진행하면, Background 재생이 안됨. Foreground Service를 이용해서 TtsService.kt 생성
  • 현재 페이지의 텍스트 추출 (PdfTextStripper 또는 PdfBox-Android)
  • TextToSpeech 기본 연동
  • 테스트용 더미 온라인 TTS 연동 (나중에 실제 API로 교체 가능)

📦 관련 기술: TextToSpeech, Coroutine, MediaPlayer (온라인 TTS 음성 재생)

🔹 4단계: 설정 화면 구성

  • SettingsFragment.kt 생성
    • preferences.xml에 ListPreference 구성
    • SharedPreferences를 통해 tts_engine 설정값 저장
    • TtsService.kt와 OpenAiTts.kt의 연동

📦 관련 기술: PreferenceFragmentCompat, SharedPreferences, OpenAiTts 연동

📎 참고 라이브러리

라이브러리 기능 링크
AndroidPdfViewer PDF 페이지 표시 https://github.com/barteksc/AndroidPdfViewer
Room 로컬 DB 저장소 https://developer.android.com/training/data-storage/room
TextToSpeech 음성 출력 Android SDK 기본 포함
PdfBox-Android PDF 텍스트 추출 https://github.com/TomRoush/PdfBox-Android
OkHttp 온라인 TTS 호출 시 https://square.github.io/retrofit/

참고링크

https://github.com/blcktgr73/BookPlay
https://www.facebook.com/share/v/162RyBjF7A/

Vibe coding으로 웹 기반의 응용을 많이 만들지만 Android 앱도 만들 수 있다.

 

- PRD 작성: PRD라고 적었지만, Product라기 보다는 기능이 가져야 하는 요구 사항을 정리한다. PRD는 사실 이 보다는 더 넓은 개념에서 제품에 대해 정리한 부분이기는 하다.

- Empy Project 만들기

- PRD 전달하고 코드 생성하기

- 테스트가 가능해지는 시점에서 빌드하면서 Feedback하고 수정

 

PRD 작성

Wireframe

위와 같은 UI Flow 혹은 Wireframe을 손으로 그렸다. 이 부분에 대한 설명은 다음과 같이 했다.

Android로 첨부한 Wireframe의 앱의 PRD를 작성해줘.
- 첫 화면에서는 버튼이 있어서, 클릭하면 Video Picker가 실행이 돼.
- Video Picker에서 비디오를 선택하면, 가로 화면으로 비디오를 재생해줘.
- 비디오 재생 화면의 오른쪽 상단에 X표 버튼이 있어서, 누르면 첫 화면으로 돌아가.
- 첫 화면에서는 기존에 재생한 비디오 목록을 보여줘. 최대 10개까지 보여줘.

 

아래는 생성된 PRD에서 일부 수정한 내용이다. 예를 들면, 단순화 하기 이해 Room DB와 SharedPreference 중에서 후자를 선택해서 단순화 하고, Thumbnail 추출은 MediaExtractor로 변경하였다.

 

# 📄 Product Requirements Document (PRD)

📱 App Name: VideoPlay

## 🎯 목적 (Purpose)
사용자가 휴대폰에 저장된 비디오를 선택해 전체화면(가로모드)으로 재생하고, 최근 재생한 비디오 목록을 쉽게 다시 접근할 수 있도록 하는 Android 앱.

## 🧑‍💻 주요 기능 (Key Features)
1. 홈 화면 (Home Screen)
구성 요소:
[재생 시작 버튼] : 비디오 선택을 위한 버튼
[최근 재생 목록] : 최대 10개의 최근 재생한 비디오 파일 표시

기능:
사용자가 버튼을 누르면 시스템 Video Picker 호출
최근 재생 목록은 가장 최근 것이 상단에 표시되며, 최대 10개 저장
각 목록은 썸네일 + 파일명 표시

2. 비디오 선택 (Video Picker)
Android 시스템의 파일 선택기 사용 (Intent.ACTION_PICK or Intent.ACTION_OPEN_DOCUMENT)
비디오 MIME 타입 필터링 (video/*)
사용자가 선택한 파일 URI를 앱으로 반환

3. 비디오 재생 화면 (Video Player Screen)
가로 화면 고정 (Landscape)
전체 화면 비디오 재생
오른쪽 상단에 [X] 버튼 배치
누르면 재생 중단 및 홈 화면으로 복귀
재생된 파일은 최근 재생 목록에 추가
기존 목록에 이미 있는 경우, 맨 앞으로 이동

10개를 초과하면 가장 오래된 항목 제거

## 🔁 사용자 흐름 (User Flow)
앱 시작
→ 홈 화면 표시

[재생 시작] 버튼 클릭
→ 시스템 Video Picker 실행

비디오 선택
→ 비디오 재생 화면 전환 (가로 모드)

비디오 재생
→ [X] 버튼 클릭 시 홈으로 복귀

홈화면
→ 최근 재생한 목록에 새 항목 반영됨

## 📱 UI 구성 (UI Components)
### 📄 홈 화면
Button - "비디오 선택"
RecyclerView (수직 스크롤)
아이템 구성: 썸네일, 파일명

### 🎞️ 비디오 재생 화면
VideoView or ExoPlayer
전체 화면 (Landscape)
ImageButton (오른쪽 상단) - X 아이콘

### 💾 데이터 저장 (Storage)
최근 재생한 비디오 리스트
최대 10개
SharedPreferences
저장 항목: URI, 파일명, 썸네일 경로(optional)

### ⚙️ 기술 스택 (Tech Stack)
Language: Kotlin
UI Framework: Android View System / Jetpack Compose (선택)
Media Player: ExoPlayer
저장소: SharedPreferences

### 📝 비고 (Notes)
썸네일은 MediaExtractor에서 추출
재생 중 화면 회전은 고정 (android:screenOrientation="landscape")

 

Cursor로 작업

이 후 작업은 Cursor에서 작업하기 위한 준비 작업과 코드 생성 및 테스트 방법이다. 물론, Cursor에서도 CLI로 gradle build하고 adb로 설치하여 테스트하는 것도 가능하겠지만, Android Studio가 이 작업을 GUI로 처리해 주므로 더 편리할 수도 있다.

 

- Android Studio에 빈 Project를 만든다.

- Cursor에서 이 Project Folder를 연다.

- PRD 전달하고 코드 생성하기

- 테스트가 가능해지는 시점에서 빌드하면서 Feedback하고 수정

 

테스트 시점에서는 Android Studio의 logcat의 경우, App과 관련된 log만 필터 하기 때문에 정말 필요한 정보를 Cursor에 피드백하기 좋다. 아래는 완료된 Video Player 구현 데모 영상이다.

 

 

마무리

ChatGPT와 같은 LLM으로 코드를 생성하면서 작업도 충분히 가능하지만, Cursor와 같은 IDE의 경우는 피드백 루프를 단순화 해주어 생산성을 더 높여 준다. 여기서 생성한 코드는 아니지만, 유사한 작업을 한 결과물을 github 링크도 남겨 둔다.

 

https://github.com/blcktgr73/ExoVibe

'Agentic Coding' 카테고리의 다른 글

Claude Code의 확장 메커니즘  (0) 2025.11.01
[Android App] BookPlay: PDF 책읽기  (2) 2025.10.08
Claude Code Meetup@ELUOCNC  (0) 2025.09.21
Claude Code vs Codex  (2) 2025.09.07
[React+Vite+Tailwind v4] Backend 기본 설정 요약  (0) 2025.08.27

 

들어가며

ChatGPT로 계속 Vibe Coding을 했지만, 많은 사람들이 Cursor를 이야기 해서 간단한 실습 예제를 만들어 시도해 본다. 환경 세팅, Open AI 연동을 기본으로 한다. 문제는 전에 풀었던 문제를 풀어 봐서 도구를 새로 익혀 본다.

Cursor를 설정하고, Open AI와 연동하고, 뉴스를 가져와서 요약하는 기능을 Vibe Coding하는 예제까지 만드는 작업을 해보자. 위에서 이야기 한 것과 같이 단계별로 제안해줘.

좋습니다! 그럼 단계별로 Cursor + OpenAI 연동 + 뉴스 요약기 Vibe Coding 실습을 안내해드릴게요.
실습 목표는 다음과 같습니다:

실습 목표:
Cursor에서 OpenAI API를 연동하여 웹에서 뉴스를 가져오고, 자연어 명령으로 요약하는 코드를 작성하고 다듬기

✅ 1단계: Cursor 설정 및 OpenAI API 연동

① Cursor 설치 및 실행

② OpenAI API 키 연동

  1. OpenAI API Key 발급 페이지에서 키 생성
  2. Cursor에서 Ctrl+Shift+PCursor Settings
  3. 왼쪽 사이드바에서 "API Keys" 선택 → OpenAI Key 입력

💡 GPT-4 또는 GPT-4o 모델이 연동되었는지 Chat 창에서 "Which model are you using?" 같은 프롬프트로 확인 가능

✅ 2단계: 뉴스 요약 프로젝트 준비

① 새 폴더 생성

예: news-summarizer
Cursor에서 Open Folder로 열기

② Python 환경 준비

  • main.py 파일 생성
  • 가상환경(optional):
    python -m venv .venv
    source .venv/bin/activate  # 또는 .venv\Scripts\activate (Windows)
    pip install requests openai beautifulsoup4

✅ 3단계: Vibe Coding 시작

🎯 목표: Google 뉴스에서 기사 제목을 수집하고 요약

① 자연어로 명령 (Cursor Chat 창)

Write a Python script to scrape headlines from https://news.google.com and summarize them using OpenAI's API.

Cursor가 아래와 비슷한 코드를 생성할 수 있습니다:

import requests
from bs4 import BeautifulSoup
import openai

openai.api_key = "sk-..."

def get_headlines():
    url = "https://news.ycombinator.com"
    response = requests.get(url)
    soup = BeautifulSoup(response.text, "html.parser")
    headlines = [a.text for a in soup.select(".titleline > a")]
    return "\n".join(headlines)

def summarize(text):
    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{
            "role": "user",
            "content": f"Summarize the following headlines:\n{text}"
        }]
    )
    return response["choices"][0]["message"]["content"]

if __name__ == "__main__":
    text = get_headlines()
    summary = summarize(text)
    print(summary)

② Vibe Coding 실습 포인트

  • "Summarize the following headlines:" → 다양한 프롬프트로 변경해보기:
    • Summarize in 3 bullet points
    • Summarize with a critical tone
    • Translate to Korean and summarize
  • 함수 이름 바꾸기, async 적용 등 리팩터링도 Ctrl+K로 쉽게 가능

마무리 하며

상기 단계로 코드가 생성되지만, 몇번의 iteration을 통해서 에러를 수정할 수 있었다. 조금 더 익숙해질 필요가 있을 것 같다.

1단계 Docker 설치 및 실행

단계별로 접근할 때, 문의를 해본다.

"1단계 부터 해보자."

좋습니다! 1단계: Docker 기본 이해 및 Synology에서 사용법 익히기 단계부터 차근히 시작해보죠.

1단계: Synology NAS에서 Docker 기본 사용법 익히기

1-1. Docker 패키지 설치

  1. DSM(웹관리페이지)에 로그인
  2. 패키지 센터 > 검색창에 Docker 입력
  3. Docker 패키지를 설치
  4. 설치 후 "열기"를 눌러 Docker GUI 실행

1-2. 첫 Docker 이미지 실행 (hello-world or nginx)

(1) Docker에서 이미지 검색 및 다운로드

  • Docker GUI > 레지스트리 탭 클릭
  • nginx 검색 > nginx:latest 선택 후 다운로드

(2) 이미지 실행 (포트 매핑 포함)

  • 이미지 탭 > nginx:latest 선택 > 실행
  • 컨테이너 이름: test-nginx
  • 포트 설정: 로컬 포트: 8080컨테이너 포트: 80
    => 로컬 포트는 설정을 할 수가 없어서 이 부분 분석하는데 시간이 소요되었다.

(3) 결과 확인

  • 브라우저에서 http://NAS_IP:로컬포트 접속
  • nginx Welcome Page가 나오면 성공!

(4) 결과 확인

CLI에서 하면, 로컬 포트도 설정 가능함을 몇 번의 시도로 알 수 있었다.

sudo docker run --name test-nginx2 -p 8081:80 -d nginx

1-3. 컨테이너 관리 실습

  • 컨테이너 탭에서 test-nginx 확인
    • 시작 / 중지 / 재시작 / 로그 보기
    • 중지 후 삭제도 해보세요
  • 볼륨 탭 확인: 아직은 없음 (2단계에서 실습 예정)

1-4. 명령어로도 실행해보기 (선택사항, SSH 접속 필요)

Synology NAS에 SSH 접속이 가능하다면:

docker run --name hello-container hello-world
  • 메시지에 "Hello from Docker!"가 나오면 성공

다음 단계로 넘어가기 전 체크리스트

  • Docker 패키지를 설치했다
  • Docker GUI에서 이미지(nginx)를 다운로드하고 실행해 봤다
  • 브라우저에서 nginx 페이지를 확인했다
  • 컨테이너 시작/중지/삭제를 해봤다

2단계

"단계 2를 해보자."라는 Prompting으로 다음 사항이 제공된다.

✅ 2단계 목표 요약

  1. Python Docker 이미지 다운로드 (python:3.10 권장)
  2. NAS의 공유 폴더를 Docker 컨테이너에 마운트
  3. Python 컨테이너에서 간단한 웹 크롤링 코드 실행 (requests, beautifulsoup4)
  4. 코드 실행 결과를 NAS 폴더에 저장

🔧 준비: NAS에 공유 폴더 하나 만들기 (예: docker-scripts)

Synology DSM > 제어판 > 공유 폴더에서 다음처럼 하나 생성:

  • 이름: docker-scripts
  • 내부 경로 예: /volume1/docker-scripts -> /volume2/backups/scripts를 사용하기로 함.
  • 이후 Python 코드 파일을 여기에 넣고 Docker 컨테이너에서 마운트해서 사용할 예정

✅ Step-by-Step: Docker CLI로 Python 컨테이너 실행

📥 1. Python 이미지 다운로드

sudo docker pull python:3.10

최신 안정 버전으로 3.10을 권장하지만, 필요 시 다른 버전도 가능 (3.11, 3.9 등)

🗂 2. 예제 코드 파일 생성

/volume1/docker-scripts/test.py로 아래 코드를 저장하세요:
-> /volume2/backups/scripts에 저장

# test.py
import requests
from bs4 import BeautifulSoup

res = requests.get("https://example.com") # examples.com으로 변경해서 테스트
soup = BeautifulSoup(res.text, "html.parser")
print("Page title:", soup.title.string)

``

🚀 3. Docker 컨테이너 실행 (NAS 폴더 마운트)

sudo docker run -it --rm \
  --dns=1.1.1.1 \
  -v /volume2/backups/scripts:/app \
  python:3.10 bash

이 명령은:

  • -it: 인터랙티브 터미널
  • --rm: 실행 후 컨테이너 자동 삭제
  • -v: NAS 공유 폴더 /volume2/backups/scripts 를 컨테이너 내부 /app으로 마운트

🧪 4. 컨테이너 내부에서 실행

cd /app
pip install requests beautifulsoup4
python test.py

결과:

Page title: 403

✅ 잘 되었는지 확인 체크리스트

  • python:3.10 이미지 다운로드 성공
  • /volume1/docker-scripts/test.py 파일 생성
  • Docker 컨테이너에서 /app/test.py 실행
  • Page title: 출력 확인

성공했다면 이제 Python 코드도 NAS에서 Docker로 돌릴 수 있게 된 거예요!

ChatGPT를 학습 측면으로 많이 쓰다가 요즘은 Vibe Coding, 즉 개발자가 직접 코드를 작성하기보다는 자연어로 문제를 설명하면 대형 언어 모델(LLM)이 이를 기반으로 코드를 생성해서 활용하는 방식으로 활용도가 하는 증가하고 있다. 이에 대해서 몇 가지 경험들을 공유하기 전에 '들어가기' 측면에서 돌아보며 생각 났던 것을 적어 보려고 한다.

언어로서의 프로그래밍 랭귀지

얼마 전(그래도 2025년 초)에 ChatGPT에게 물었을 때, Tier 1 언어에 다양한 언어가 있다는 것을 본 적 있다. 영어 (English, 가장 자신 있다고 한다), 중국어 (Mandarin), 스페인어 (Spanish), 프랑스어 (French), 독일어 (German), 일본어 (Japanese), 한국어 (Korean)가 포함되어 있다. 특히, 예전에는 한국어로 Prompting을 하면 영어로 번역해서 결과를 가져오고 그 결과를 한글로 번역(심지어 구글 Translator를 쓰는 것도 봤었다)해서 결과를 내었었다. 그래서 그런지, 요즘은 한글로 Prompting을 해도 결과가 아주 좋다. 이 정도라면 언어 학습에 ChatGPT를 안쓰는 것은 바보 같은 일이 되었다고 생각된다. 요즘 영어 학습 시 내가 쓴 글에 대해서 Correct하는데 자주 사용한다.

그렇다면, Computer Language 에서도 Tier 1이 있지 않을까 궁금해서 다음과 같이 물어봤었다. "너는 소프트웨어 개발 전문 Agent야. Vibe coding을 하려는 사용자에게 도움을 줄 때, 가장 자신이 있는 컴퓨터 언어에는 어떤 것들이 있는지 알려줘." ChatGPT는 Python, JavaScript (Node.js & Browser), Processing / p5.js, Rust, Kotlin까지 5개를 이야기 했었다. Gemini는 Python (파이썬), JavaScript (자바스크립트), Java (자바), C++ (씨쁠쁠), C# (씨샵)을 언급했다. 추가로 Swift, Kotlin, PHP, Ruby, Go, TypeScript 등 다양한 현대 프로그래밍 언어에 대해서도 능숙하게 이해하고 코드를 생성하거나 설명할 수 있다고 하긴 했다. 일반 언어 학습도 마찬가지이지만, 이제 프로그래밍 랭귀지 학습도 LLM을 사용하지 않는 것은 좋은 피드백을 놓치는 일인 것이라는게 내 생각이다. 기존 코드 분석이나 내가 작성한 코드의 리뷰도 LLM으로 하면 좋다.

동어 반복이지만, Coding도 어찌 보면 글을 쓰는 일이다. 앞에서 말했듯이 ChatGPT가 좋은 언어 선생인데 활용하지 않는 것은 이상한 일이 되고 있다.

나의 개발 환경

개발을 해보려면, 환경은 중요하다. 사실 많은 개발자들이 Web 기반으로 하고 있어서 Cursor가 유용한 도구이고 Vibe Coding을 할 수 있다. 하지만, 나 같이 Mobile에서 개발을 하고 있거나, 업무 자동화와 같은 것이 유용한 사람도 있다. 이와 같이 개발 환경이 다양할 수 있다.

우선 내가 가지고 있는 환경들을 정리해 보자. 물론, 자신의 환경도 정리해 보고 추가로 확장해 나갈 수도 있겠다. 즉, 개인 프로젝트로 Cloud에 개발해 볼 수도 있는 일이다.

  • 집의 HW: Synology NAS, Laptop, 개인용으로 쓰는 Android Smart Phone이 있다. 뒤에 이야기 하겠지만, NAS가 서버 처럼 동작할 수 있어서 자동화에 활용을 할 수 있다.
  • 회사의 HW에서: Phone/Tablet등이 많고, 개인용 Windows PC도 있다.

SW적 개발 환경은 다음과 같이 이야기 할 수 있다.

  • 언어적으로는 예전에 C/C++을 했지만, 요즘은 살펴 볼 기회가 점점 적어 지고 있다.도리어 Python이 업무 자동화(Web Scrapping)와 AI 관련해서 교육 및 업무 하면서 더 많이 쓰고 있다.
  • Android를 사용해야 하기 때문에 Java/Kotlin도 보게 되는 상황이다.
  • IDE의 측면에서는 Python을 위해서 PyCharm과 Android 개발을 위해서 Android Studio를 사용한다. 일반적인 text editor인 Notepadd++도 사용한다. Linux 환경에 정말 쓸 editor가 없다면 vi를 쓰기도 한다.

이렇게 해야 한다는 것이 아니고 나의 예이다. 내가 가지고 있는 것으로 시작하면 된다. 이런 것을 잘 모르겠다? 그럼 뒤에도 설명하겠지만, 아주 간단한 사용법 부터 익히면 좋겠다.

가장 먼저 할일은? 바로 문제 정의

내가 요즘 담당하고 있는 업무 TPM이고, 개발자가 아니어서 프로그래밍은 눈으로만 보거나 관련된 글을 읽는 것이 다라고 생각하고 살았던 것 같다. Vibe Coding은 생각만 하고 있던 것들을 LLM이 Coding Agent로서 바로 내 옆에 나 대신 코딩을 해주는 전문가가 생긴 것과 마찬가지다.

이렇게 하고 싶은, 하고 싶었던 것들 떠올려 LLM에게 물어 보면 된다.

  • Android 폰의 특정 시간 (시작 시간에서 끝나는 시간 사이) 동안, 사용자가 사용한 Application과 사용한 시간을 측정하고 싶다.
  • 특정 시간에 그날 날씨 예보를 파악해서 사용자에게 Activity를 제안하고 싶다.
  • 매일 뉴스를 찾아서 내가 사용하는 메모 앱(Obsidian)에 요약해서 저장하고 싶다.
  • 관심있는 주식 전망에 대해서 현재 날짜 기준으로 최신 뉴스나 정보를 검색 예상해 준다.
  • Android 폰에서 비디오 재생하는 간단한 Sample 앱을 만들어 보고 싶다.

이러한 것들이 간단하지만 문제 정의의 시작이 될 수 있다. 위의 내용들을 그냥 ChatGPT에 먼저 적고 순차적으로 답변들을 검토하면서 진행해도 큰 문제가 없었다.

Prompting

사실 ChatGPT 같은 경우는 특별히 prompting을 예전처럼 아주 구체적으로 적지 않고, 어설프게 해도 상당히 좋은 결과들이 나온다. 하지만, 몇 번의 시도에서 느낀 것을 적어 본다.

  • 문제 해결의 여러 방법을 제안하고 비교 요청. 이 부분은 Architecturing, Designing 단계로도 볼 수 있다. 즉, 우리가 해결하고자 하는 문제에 대해서 어떤 구조, 어떤 접근 방법이 가능한지 알 수 있다.
  • 작고 쉽게 접근이 가능해야 한다. 여러 제안 중에서 너무 새롭거나 허들이 높다면, 더 세밀하게 나눠봐야 한다. Android Programming을 전혀 해보지 않았다면 Hello World라도 짜보고 접근한다거나, Docker를 전혀 해보지 않은 상태에서 이 방법을 선택하는 것은 너무 어렵다.
  • 이터레이션을 해야 한다. 제안 된 것을 ChatGPT가 실행해 볼 수도 있지만, 그렇지 않은 경우도 많다. 또한, Oudated된 정보를 가지고 있는 경우도 많다. 그렇기 때문에, 제공 받은 코드는 실행을 해봐야 한다. Cursor와 같이 IDE 환경이라면 바로 Deploy도 하고 실행도 해볼 수 있지만, ChatGPT는 그렇지지 않은 환경이라 실행하지 않으면 알기 어렵다.
  • Debugging도 도와 달라고 하면 잘 도와 준다. 분석을 위한 중간 결과물이나 실행 시 중요 정보를 출력하는 Logging이나 Print를 삽입해주기도 한다. 웹 페이지에 접근해서 내용을 가져오는 동작을 의미하는 Web Scrapping이나 Web Crawling의 경우 중간 결과물로 html을 저장하기도 하고 이 저장된 html을 제공하면 디버깅 포인트를 찾기도 한다.

이와 같이 다양한 접근 방법에 대해서 고려하고 작은 스텝으로 진행하면서 실행하여 LLM에게 Feedback하면서 진행하는 것이 유용하다.

마무리 하며

몇 번의 Vibe Coding을 하고 돌아 본 것이라 부족한 부분이 많고 나중에 생각이 바뀔 수도 있겠다. 이후에는 실재 사례들을 정리해 보겠다. 다른 하고 싶은 아이디어들이 떠오른다면, 추가적으로 실행해 볼 수 있겠다. 혹시, 같이 해보고 싶은 아이디어를 제공해 준다면, 함께 시도해 볼 수도...

들어가며..

최근에 Vibe Coding [1,2] 이라는 이야기가 많이 회자되고 있다. 개발자는 구조나 Product에 집중하고 실재 코딩 작업은 LLM에 맞기는 것이라고 한다. VSCode에 통합되어 있는 AI도구인 Cursor에서는 Agent[3]라는 제품도 나와서 이러한 트렌드를 더 가속화 하는 것으로 보인다. Cursor가 이미 IDE와 결함되어 있고, Agent 그리고 Ask 기능을 이미 제공하고 있기 때문에 여기서 설명하는 내용이 이미 필요 없을 수 있다. 하지만, Cursor를 사용하지 않고도 가능하다고 하면 Cursor를 사용하지 못하기 때문에 AI 도구를 이용해서 효과를 내지 못하는 것은 아니라는 것의 반증이기도 할 것 같다.

나의 사례

여기서 다루려는 내용은 아래 내용으로 나누어 볼 수 있다.

  1. 기존에 존재하는 코드를 이해하고 
  2. 우리가 원하는 기능을 어떻게 구현할지 결정하고
  3. 구현하는 코드를 만들어 적용

 

1번은 우리가 이미 구현하고 있는 Android App기준으로 이 부분은 다른 사례에 적용한다면 개발 환경에 따라 다를 수 있을 것 같다. 이 Android App에 대해 분석하는 예는 따로 설명한다[4]. 2번 부터 3번까지의 경우, Android App 기준으로 하나의 예를 가지고 따라가 보자. 물론 상황에 따라 다를 수 있음을 이해하자.

원하는 기능의 구현

이 부분은 필자의 사례이므로 상황에 따라 많이 다를 수 있다. 우리는 사용자가 특정 기간 동안 다른 동작을 해서 주의가 산만해 지는 것을 확인하기 위해 휴대폰에서 특정 앱을 사용하는 것을 모니터링 하는 것을 구현하려고 했다. 이와 관련해서 ChatGPT에 Prompting해 본 결과 중 일부를 살펴 보자.

Prompt: 너는 pytorch 및 tensorflow의 전문가이고, 동영상 처리에 대한 전문가야. Android에 대해서도 잘 알고 있는 전문가야. 휴대폰의 사용자가 휴대폰 사용하는 동안 어떤 어플리케이션을 사용하고 있는지 알아 내는 모듈을 개발하려고해. 이를 알아내는 방법을 여러가지 제안해줘

ChatGPT said:  (7가지를 이야기 했지만, 아래 3가지만 추출)
휴대폰에서 사용자가 어떤 애플리케이션을 사용하는지 알아내는 모듈을 개발하려면 아래와 같은 여러 가지 접근 방법을 고려할 수 있습니다. 각 접근법은 기술적인 제약, 성능, 그리고 보안 문제를 고려해야 합니다.

 

1. Accessibility Services 활용
- 방법: Android의 접근성 서비스(Accessibility Service)를 이용하면 사용자가 현재 활성화된 앱과 상호작용하는 내용을 감지할 수 있습니다.
- 장점: 사용자가 상호작용하는 앱에 대한 정보를 비교적 간단하게 가져올 수 있습니다.
- 단점: 사용자 동의가 필요하며, 민감한 정보를 처리하기 때문에 오용 시 보안 문제가 발생할 수 있습니다.
- 구현:
    1. `AccessibilityService` 클래스 구현.
    2. `onAccessibilityEvent` 메서드에서 앱 사용 데이터를 수집.

 

2. UsageStatsManager 활용
- 방법: Android의 `UsageStatsManager` API를 사용하여 최근에 사용된 애플리케이션 목록 및 사용 시간을 가져올 수 있습니다.
- 장점: 시스템 API를 사용하므로 안정적이고 공식적인 접근 방식.
- 단점: 사용자에게 Usage Access 권한을 별도로 요청해야 합니다.
- 구현:
    1. `UsageStatsManager` 인스턴스 생성.
    2. `queryUsageStats` 메서드로 주어진 기간 동안 사용된 앱의 데이터를 수집.

 

3. Foreground Service 및 Activity Recognition API
- 방법: 포어그라운드 서비스와 Activity Recognition API를 조합하여 현재 활성화된 앱 상태를 모니터링.
- 장점: 백그라운드에서 안정적으로 작동.
- 단점: 높은 배터리 소모 가능성과 앱 승인 절차.
- 구현:
    1. `ActivityManager`로 현재 실행 중인 태스크 정보 확인.
    2. Activity Recognition API로 사용자 동작(예: 걷기, 정지)도 함께 분석.

여기서 도출된 것들 중 유사한 기능을 다른 유관 부서에서 구현한 것을 보아서 문의 시, UsageStatsManager를 사용하는 것을 알았다. 여기서도 동일한 방법으로 접근해 보기로 결정하였다.

구현하는 코드를 만들어 적용

이를 기반으로 Prompting을 하고 관련된 코드를 입수 하여 독립된 Android App 으로 구현 테스트를 진행한다. 다음과 같은 Prompt를 사용하였다.

너는 android application 개발자야. 다음 요구 사항을 만족하는 application을 만들어줘. 추가적으로 필요한 정보가 있다면, 확인하고 제안해줘. 프로그램을 작성하는 순서를 상세히 설명해줘. 
1. MainActivity를 가지고 있어 
2. MainActivity에는 Start 버튼을 가지고 있어. 이 버튼을 클릭하면, 동작 시간을 측정 시작해. 그리고, Start 버튼이 Stop 버튼으로 변경돼. 
3. MainActivity의 Stop 버턴을 클릭하면, 휴대폰에서 사용자가 다른 어플리케이션을 사용한 내용을 정리해서 알려주는 기능을 가지고 있어. 이 부분은 UsageStatsManager에서 사용 이력을 확인할 수 있어.

이 것 기반으로 Android에서 동작하는 Kotlin 코드를 제공한다. 실제로 Android Studio에 코드를 적용하고, 테스트를 한다. 여기서 획득한 Helper 코드의 기본적인 테스트가 완료되어서, 실재 우리 App과 연동해 보고 동작하는 것을 확인하였다. 

마무리하며

간단한 사례이지만, 여기서 의미 있는 부분은 나의 문제를 명확하게 하고 어떻게 해결할지 고민하면서 필요한 요구 사항을 LLM에게 제공하여 동작 가능한 코드를 제공받았다. 개발자의 학습면에서도 좋다고 생각되는 부분은 제공 받은 코드를 통해서 Kotlin에 대해서 학습할 기회를 얻게 된 부분도 부수적인 장점으로 생각된다.


참고 문헌

[1] https://youtu.be/mzomjCHEPpg?si=TJRR-4Er7arf5m-j
[2] https://youtu.be/IACHfKmZMr8?si=rGTS_SlI96HS16no
[3] https://youtu.be/gKCklJOWB6o?si=N95cuv_Nf23Ar8S8
[4] Modern Anroid Application의 구조 이해, https://technical-leader.tistory.com/174

+ Recent posts