← 메인으로 돌아가기

☕ 바이브 코딩 사례: 커피챗 기능 개발

비개발자의 AI 협업 개발 과정

프로젝트 개요 1단계: 기본 구조 2단계: 기능 추가 3단계: 설계 변경 4단계: UI 개선 최종 결과 배운 점 따라하기
🏠

🎯 프로젝트 개요

목표

IT담당 64명을 4명씩 16개 그룹으로 나누는 커피챗 기능 개발

개발 환경

  • 도구: Amazon Q Developer (Kiro CLI)
  • 기간: 2026-01-07 ~ 2026-01-08 (2일, 실제 작업 약 2시간)
  • 개발자: 비개발자 (인프라 담당)
  • 핵심: 코드를 직접 작성하지 않고, AI와 대화하며 구현

최종 결과물

  • 웹 페이지: 커피챗 페이지
  • 기능: 그룹 생성, 일정 관리, 마스킹, CSV 다운로드
  • Git 커밋: 6개

📸 시작: 조직도 이미지

회사 조직도를 팀별로 캡처한 이미지 11장을 준비했습니다.

coffeechat/data/
├── 01_teams.jpeg
├── 02_IT기획팀.jpeg
├── 03_ERP매입물류팀_파트.jpeg
├── 04_ERP매입물류팀_기준정보발주파트.jpeg
├── 05_ERP매입물류팀_매입물류파트.jpeg
├── 06_ERP판매분석팀_판매.jpeg
├── 07_ERP재무운영팀_파트.jpeg
├── 08_ERP재무운영팀_원가손익.jpeg
├── 09_ERP재무운영팀_재무.jpeg
├── 10_고객플랫폼팀.jpeg
└── 11_아키텍처인프라팀.jpeg

1️⃣ 1단계: 기본 구조 만들기 (30분)

첫 번째 프롬프트

일반적인 접근

프롬프트: "64명을 그룹으로 나눠줘"

데이터: 텍스트로 이름 나열

결과: 단순 랜덤 배치, 팀 정보 누락

실제로 한 것

프롬프트: "이 조직도 이미지들을 보고 64명을 4명씩 그룹으로 나눠줘. 가능한 다양한 팀에서 골고루 선발해줘."

데이터: 조직도 이미지 11장 제공

결과: 팀/직급/역할 정보 포함, 균형잡힌 배치

💡 차이를 만드는 포인트: 구체적인 요구사항 + 시각적 데이터 제공

👩 사용자

"이 조직도 이미지들을 보고 64명을 4명씩 그룹으로 나눠줘. 가능한 다양한 팀에서 골고루 선발해줘."

🤖 AI (Kiro)

  1. 이미지 분석 시작
  2. OCR로 이름, 직급, 팀 정보 추출
  3. JSON 파일 생성: organization.json
  4. Python 알고리즘 작성: coffee_chat_selector.py
  5. 웹 페이지 생성: index.html

생성된 파일

organization.json (일부)

{
  "IT담당": {
    "teams": {
      "IT기획팀": {
        "members": [
          {"name": "유*문", "position": "Chief파트너", "role": "IT기획, AI"},
          {"name": "송창섭", "position": "파트너", "role": "기획업무"},
          {"name": "지형구", "position": "파트너", "role": "IT 예산 관리"}
        ]
      },
      "ERP매입물류팀": {
        "parts": {
          "기준정보/발주": {
            "members": [
              {"name": "송호찬", "position": "파트너"},
              {"name": "이춘식", "position": "파트너"}
            ]
          }
        }
      }
    }
  }
}

coffee_chat_selector.py (핵심 로직)

def generate_groups(members, group_size=4):
    # 팀별로 섞기
    shuffled = shuffle_by_team(members)
    
    # 4명씩 그룹 생성
    groups = []
    for i in range(0, len(shuffled), group_size):
        groups.append(shuffled[i:i+group_size])
    
    return groups

✅ 1단계 완료

  • 조직도 데이터 구조화 (64명)
  • 랜덤 그룹 생성 알고리즘
  • 기본 웹 페이지

2️⃣ 2단계: 기능 추가 및 버그 수정 (40분)

실제 프롬프트 시퀀스

일반적인 접근

버그 발견: "나중에 수정하자"

피드백: 모든 기능 완성 후 한번에

결과: 시간 낭비, 누적된 문제

실제로 한 것

버그 발견: "지금 바로 수정하자"

피드백: 문제 발견 즉시 수정 요청

결과: 빠른 반복, 점진적 개선

💡 차이를 만드는 포인트: 즉각적인 피드백과 빠른 반복

🐛 버그 발견

일반적인 접근

"알고리즘이 맞는지 확인 안 함"

→ 나중에 발견되는 문제

실제로 한 것

"직접 확인: 64명이 다 배치됐나?"

→ 60명만 배치, 4명 누락 즉시 발견

👩 프롬프트 1

"64명 배치가 다 안 되는건 좀 치명적 버그다 수정하자"

→ 알고리즘 분석: 60명만 배치되고 4명 누락

→ 남은 인원 추가 배치 로직 개선

→ Git 커밋: b990064 Fix: 커피챗 64명 전원 배치 알고리즘 수정

🔄 알고리즘 개선 - 3단계 프롬프트

일반적인 접근

"AI가 제시한 첫 알고리즘 그대로 사용"

→ 단순 랜덤 배치

실제로 한 것

"여러 번 개선 요청"

→ 팀 균형 고려 → ERP 제약 추가 → 남은 인원 처리

👩 프롬프트 2

"남은 인원 추가 배치할 때만 ERP 제약을 풀면 안 돼?"

→ 조건부 로직 추가: 남은 인원은 같은 팀 허용

👩 프롬프트 3

"4명으로 그룹 구성하고 남은 인원이 몇명이 돼?"

→ 검증: 64명 ÷ 4 = 16개 그룹, 남은 인원 0명

💡 차이를 만드는 포인트: 단계적으로 문제를 발견하고, 구체적인 해결책을 제시

📝 요구사항 추가

"김*언, 유*문, 임*옥, 유*슬 이 사람은 1그룹으로 픽스하자. 그리고 나머지를 구성하면 되겠어"
# 그룹 1 고정
fixed_group = ['김*언', '유*문', '임*옥', '유*슬']
groups = [fixed_group]

# 나머지 60명 랜덤 배치
remaining = [m for m in members if m.name not in fixed_group]
groups.extend(generate_groups(remaining, 4))

📅 일정 관리

"날짜 입력하고 점심/저녁/티타임 이거 선택하는걸 각 그룹별로 Action 연결할 수 있지?"
<input type="date" id="date-group-1" onchange="saveSchedule('group-1')">
<select id="time-group-1" onchange="saveSchedule('group-1')">
    <option value="점심">점심</option>
    <option value="저녁">저녁</option>
    <option value="티타임">티타임</option>
</select>

🔧 이름 오류 수정

"잠깐, 팀원 이름이 잘 못 되었다는 피드백이.... 아마도 이미지에서 파싱할 때 에러났나봐
이*호 → 이*효
정*호 → 정*효
고*곤 → 고*광

→ OCR 오류 수정

→ organization.json 업데이트

✅ 2단계 완료

  • 64명 전원 배치 알고리즘
  • 그룹 1 고정 기능
  • 마스킹 기능
  • 일정 관리 기능
  • 이름 오류 수정

3️⃣ 3단계: 설계 변경 - 간소화 (20분)

일반적인 접근

설계: "완벽한 시스템을 만들자"

구현: PostgreSQL + API + K8s

결과: 복잡도 증가, 시간 소요

실제로 한 것

설계: "필요한 만큼만 만들자"

구현: localStorage + CSV 다운로드

결과: 간단하고 실용적

💡 차이를 만드는 포인트: 과도한 설계를 과감히 버리는 결단

초기 설계: PostgreSQL + API

👩 사용자

"다른 사람이 일정 저장해도 한 페이지로 동일하게 보이는거지?"

🤖 AI

→ PostgreSQL 테이블 설계

→ FastAPI 서버 코드 작성

→ K8s 배포 준비

설계 변경 결정

"음.. 수정하고, csv 다운 받게 한담에 다시 업로드 하게 하면 많이 번거로울라나?"

"CSV 업로드/다운로드 방식은 번거로울 수 있습니다. PostgreSQL로 실시간 동기화하는게 좋을 것 같습니다."

"아니 설계를 변경하려고, 간소화하고 마무리할래
1. API 구현 없음
2. 로컬에만 저장하고 외부와 공유할 때는 CSV 다운로드해서 줘라"

→ API 서버 코드 제거

→ PostgreSQL 연동 제거

→ localStorage 전용으로 변경

→ CSV 다운로드 기능 강화

제거된 파일

edu/04_scripts/python/
├── coffeechat_api_server.py (삭제)
├── Dockerfile.coffeechat (삭제)
├── create_coffeechat_table.py (삭제)
└── create_coffeechat_groups_table.py (삭제)

edu/04_scripts/k8s/
└── coffeechat-api.yaml (삭제)

Git 커밋

e064c58 refactor: 커피챗 프로젝트 간소화 - API 제거, localStorage + CSV 다운로드로 변경

✅ 3단계 완료

  • 복잡한 API 제거
  • localStorage 전용 저장
  • CSV 다운로드로 공유

4️⃣ 4단계: UI 개선 & 보안 (30분)

🔒 개인정보 보호

일반적인 접근

"개인정보는 항상 숨기기"

→ 사용자도 확인 불편

실제로 한 것

"마스킹 해제 버튼 추가"

→ 외부 크롤링 방어 + 사용자는 확인 가능

💡 차이를 만드는 포인트: 보안과 사용성 모두 고려
"마스킹 해제 버튼을 만들어주까? 그냥은 안 보이게 하고 해제를 눌러야 보이게, 그럼 외부 크롤링도 방어할 수 있지?"
function maskName(name) {
    if (isMasked) {
        if (name.length === 2) {
            return name[0] + '*';
        } else if (name.length >= 3) {
            return name[0] + '*'.repeat(name.length - 2) + name[name.length - 1];
        }
    }
    return name;
}

🎨 UI 재구성

"상단 섹션의 카드들 있지? 그 내용과 가이드 그리고 액션들 이런걸 그냥 하나의 섹션에 분리된 깔끔한 카드들로 모으는게 어때?"

→ 5개 카드 → 2개 카드로 간소화

→ 가이드 카드 (좌측) + 액션 카드 (우측)

🎨 디자인 개선

"테두리만 너무 진하게 하지 말자, 버튼들 색깔도 너무 원색 쓰지 말고 톤 다운된 세련된 전문적인 느낌 나게"
/* 변경 전 */
border: 2px solid #495057;
background: #dc3545; /* 빨강 */
background: #007bff; /* 파랑 */

/* 변경 후 */
border: 1px solid #ced4da;
background: #e57373; /* 부드러운 레드 */
background: #64b5f6; /* 부드러운 블루 */

📖 가독성 개선

일반적인 접근

"개발자 관점의 UI"

→ 작은 글씨, 원색 버튼, 복잡한 레이아웃

실제로 한 것

"실제 사용자(50대 임원) 관점"

→ 큰 글씨, 톤 다운 색상, 간결한 레이아웃

💡 차이를 만드는 포인트: 실제 사용자를 구체적으로 고려
"50대 임원이 보기에 가독성만 좀 향상시켜볼까? 밑에 인원들 보이는 그리드 텍스트가 좀 작은거 같기도 해"
/* 글씨 크기 증가 */
헤더: 11px → 13px
이름: 13px → 16px
직급/팀: 11px → 13px
패딩: 12px → 16px
"직책은 이름 옆에 작게, 팀명은 그 아래 같은 크기"
<!-- 변경 전 -->
<div>홍길동</div>
<div>파트너</div>
<div>IT기획팀</div>

<!-- 변경 후 -->
<div>
    <span style="font-size: 16px">홍길동</span>
    <span style="font-size: 13px">파트너</span>
</div>
<div style="font-size: 13px">IT기획팀</div>

직책 약어

"파트너는 p / Chief 파트너는 cp 이렇게 간략하게"
let shortPosition = member.position;
if (shortPosition.includes('Chief')) {
    shortPosition = 'cp';
} else if (shortPosition.includes('파트너')) {
    shortPosition = 'p';
}

Git 커밋

c6a4dac feat: 커피챗 UI 개선 - 2개 카드로 간소화, 세련된 디자인
3867247 feat: 커피챗 가독성 최종 개선 - 글씨 크기 증가, 직책 약어(cp/p)

✅ 4단계 완료

  • 2개 카드 레이아웃
  • 세련된 디자인 (톤 다운)
  • 50대 가독성 개선
  • 직책 약어 적용

🎉 최종 결과

완성된 기능

개발 통계

⏱️

실제 작업 시간

약 2시간

💬

프롬프트 수

50개+

📝

Git 커밋

6개

📄

파일 생성

23개

핵심 프롬프트 패턴

1. 명확한 요구사항

❌ "그룹 만들어줘"
✅ "64명을 4명씩 그룹으로 나눠줘. 가능한 다양한 팀에서 골고루 선발해줘."

2. 즉각적인 피드백

"64명 배치가 다 안 되는건 좀 치명적 버그다 수정하자"
→ 문제 발견 즉시 수정 요청

3. 설계 변경 결단

"아니 설계를 변경하려고, 간소화하고 마무리할래"
→ 복잡한 API 제거, localStorage로 간소화

4. 사용자 중심 개선

"50대 임원이 보기에 가독성만 좀 향상시켜볼까?"
→ 실제 사용자 고려한 UI 개선

💡 배운 점

비개발자도 할 수 있다

설계는 유연하게

사용자 피드백이 핵심

AI와의 협업 팁

  1. 구체적으로 요청: "그룹 만들어줘" → "64명을 4명씩"
  2. 즉시 피드백: 문제 발견 즉시 수정 요청
  3. 설계 변경 두려워 말기: 더 나은 방법이 있으면 변경
  4. 사용자 중심: 실제 사용자 관점에서 개선

🚀 따라하기

준비물

시작하기

# 1. 프로젝트 폴더 생성
mkdir my-project && cd my-project

# 2. Kiro CLI 실행
q chat

# 3. 첫 프롬프트
"이 데이터를 보고 [목표]를 만들어줘"

성공 포인트

  • ✅ 명확한 요구사항
  • ✅ 즉각적인 피드백
  • ✅ 유연한 설계 변경
  • ✅ 사용자 중심 개선