Differences between revisions 2 and 4 (spanning 2 versions)
Revision 2 as of 2025-12-29 21:42:57
Size: 9320
Editor: 정수
Comment:
Revision 4 as of 2025-12-30 10:00:27
Size: 8065
Editor: 정수
Comment:
Deletions are marked like this. Additions are marked like this.
Line 8: Line 8:
== The Story: The Migration Script Trap == == The Story 1: The Migration Script Trap (Programming) ==
Line 10: Line 10:
한 주니어 개발자가 레거시 DB를 새로운 시스템으로 마이그레이션하는 스크립트를 짜고 있었다.
"95%는 완료됐어요. 그런데 나머지 5% 데이터가 문제입니다."
한 주니어 개발자가 레거시 DB를 새로운 시스템으로 마이그레이션하는 스크립트를 짜고 있었다. "95%는 완료됐어요. 그런데 나머지 5% 데이터가 문제입니다." 그는 수백 줄의 복잡한 예외 처리 코드를 가리켰다. "50건 정도의 데이터가 형식이 제멋대로라 이걸 자동으로 보정하는 알고리즘을 짜고 있어요. 3일째 이것만 하고 있네요." 시니어가 답했다. "50건 고치는 데 직접 하면 30분이면 돼. 네가 짠 그 복잡한 코드를 유지보수하는 비용은 3년이 갈 거고. 자동화의 목적은 '100% 자동'이 아니라 '시간 절약'이야." 주니어는 복잡한 코드를 다 지우고 에러 로그만 남겼다. 마이그레이션은 그날 오후에 끝났다.
Line 13: Line 12:
그는 모니터를 가리켰다. 수백 줄의 복잡한 정규표현식과 예외 처리 코드였다.
"이 데이터들은 인코딩이 깨졌거나 형식이 제멋대로예요. 이걸 자동으로 보정하려고 휴리스틱 알고리즘을 짜고 있는데, 예외가 계속 나와서 코드가 점점 복잡해지네요. 3일째 이것만 하고 있어요."
Line 16: Line 13:
시니어가 물었다. "그 5%가 몇 건이나 되지?" == The Story 2: The Perfect Garden (Ordinary Life) ==
Line 18: Line 15:
"전체 10만 건 중 50건 정도요." 민수와 하나는 각자 마당에 '정원'을 가꾸고 있다.
Line 20: Line 17:
"그럼 그냥 스크립트가 그 50건을 `error.log` 파일로 뱉게 하고, 우리가 엑셀로 열어서 눈으로 보고 고치면 안 될까?" '''민수의 정원 (The 100% Perfectionist):'''
민수는 정원에 잡초가 단 하나도 있는 것을 용납하지 못한다. 그는 매일 아침부터 저녁까지 핀셋을 들고 아주 작은 풀 한 포기까지 뽑아낸다. "완벽한 정원을 만들어야 해." 하지만 민수는 잡초를 뽑느라 정작 꽃에 물을 주거나 나무를 가꿀 시간이 없었다. 민수의 정원은 잡초는 없었지만, 주인은 지쳐버렸고 꽃들도 생기를 잃었다.
Line 22: Line 20:
주니어는 멍한 표정을 지었다. "수동으로요? 하지만... 자동화 스크립트잖아요."

"50건 고치는 데 30분이면 돼. 네가 짠 그 복잡한 코드를 유지보수하는 비용은 3년이 갈 거고. 자동화의 목적은 '100% 자동'이 아니라 '시간 절약'이야."

주니어는 복잡한 코드를 다 지우고, 에러 로그를 남기는 코드 5줄을 넣었다. 마이그레이션은 그날 오후에 끝났다.
'''하나의 정원 (The 95% Pragmatist):'''
하나는 큰 잡초들만 눈에 띌 때 솎아낸다. "95% 정도만 깔끔하면 충분해. 남은 5%의 작은 풀들은 자연스러운 풍경의 일부라고 생각하자." 하나는 잡초 뽑기에 쏟을 에너지를 아껴 새로운 꽃을 심고 나무를 전정했다. 하나의 정원은 완벽하게 매끈하지는 않았지만, 항상 꽃이 피어있고 생명력이 넘쳤다. 마지막 5%의 완벽함에 집착하지 않을 때 더 큰 가치를 돌볼 수 있음을 하나는 알고 있었다.
Line 31: Line 26:
당신은 반복적인 작업을 자동화하거나 도구를 만들고 있다.
처음 90~95%의 케이스를 처리하는 것은 쉽고 빨랐다. 하지만 남은 소수의 엣지 케이스 (Edge Case), 불규칙한 데이터, 주관적 판단이 필요한 부분들이 발목을 잡는다.
당신은 반복적인 작업을 자동화하거나 도구를 만들고 있다. 처음 90~95%의 케이스를 처리하는 것은 쉽고 빨랐다. 하지만 남은 소수의 엣지 케이스 (Edge Case), 불규칙한 데이터, 주관적 판단이 필요한 부분들이 발목을 잡는다.
Line 46: Line 40:

자동화의 비용 곡선은 선형이 아니라 지수적다.
자동화의 비용 곡선은 선형이 아니라 지수적입니다.
Line 51: Line 44:

마지막 5%는 보통 규칙성이 없거나, 문맥 파악이 필요하거나, 외부 요인에 의존다. 이를 코드로 해결하려면 배보다 배꼽이 더 커다.
마지막 5%는 보통 규칙성이 없거나, 문맥 파악이 필요하거나, 외부 요인에 의존합니다. 이를 코드로 해결하려면 배보다 배꼽이 더 커집니다.
Line 55: Line 47:

마지막 5%까지 처리하려고 억지로 끼워 맞춘 로직은 매우 취약 (Brittle)다. 데이터 형식이 조금만 바뀌어도 스크립트 전체가 깨다.
결과적으로 "완전 자동화" 도구는 신뢰를 잃고, 아무도 쓰지 않게 다.
마지막 5%까지 처리하려고 억지로 끼워 맞춘 로직은 매우 취약(Brittle)합니다. 데이터 형식이 조금만 바뀌어도 스크립트 전체가 깨집니다. 결과적으로 "완전 자동화" 도구는 신뢰를 잃고, 아무도 쓰지 않게 됩니다.
Line 65: Line 55:

먼저 질문하. '''"이것은 사람의 개입 없이 돌아가야 하는가 (Unattended)?"'''

 1. '''YES (e.g., CI/CD Pipeline, Nightly Backup)'''
  *
이때는 100% 자동화가 필수다.
  * 사람이 자는 동안 돌아가야 하므로, 실패하면 안 된다.
  * '''해결책:''' 범위를 좁히거나,
입력을 엄격하게 통제해서 100%를 달성하라.

 2. '''NO (e.g., Migration, Report Gen, Code Gen)'''
  *
사람이 실행 버튼을 누르고 결과를 기다리는 도구라면?
  * '''해결책:'''
95%까지만 해주고, "나머지는 네가 확인해"라고 넘겨라.
먼저 질문하십시오. '''"이것은 사람의 개입 없이 돌아가야 하는가 (Unattended)?"'''
 1. '''YES (e.g., CI/CD Pipeline):''' 이때는 100% 자동화가 필수입니다. 입력을 엄격하게 통제하여 100%를 달성하십시오.
 2. '''NO (e.g., Migration, Report Gen):''' 사람이 실행 버튼을 누르는 도구라면 95%까지만 해주고 "나머지는 네가 확인해"라고 넘기는 것이 현명합니다.
Line 78: Line 60:

가장 강력한 패턴은 '''"기계가 초안을 잡고 (Draft), 사람이 검수/완료 (Finalize)하는 것"'''다.

* '''데이터 정리:''' 기계가 확실한 것만 처리하고, 애매한 것은 "검토 필요" 폴더로 다.
* '''코드 생성:''' 기계가 보일러플레이트를 짜주고, 핵심 로직은 사람이 채운다.
 * '''번역/요약:''' AI가 초벌 번역을 하고, 사람이 다듬는다.

이것은 100% 자동화보다 훨씬 만들기 쉽고, 유연하며, 결과물의 품질도 높다.
가장 강력한 패턴은 '''"기계가 초안을 잡고(Draft), 사람이 검수/완료(Finalize)하는 것"'''입니다.
 * 기계가 확실한 것만 처리하고, 애매한 것은 "검토 필요" 폴더로 뺍니다. 이것은 100% 자동화보다 훨씬 만들기 쉽고 유연하며 결과물의 품질도 높습니다.
Line 88: Line 64:

노력 대비 효과 그래프에서 기울기가 꺾이는 지점 (Knee)에서 멈춰라.
* 1시간 투자해서 90% 자동화 → OK.
 * 10시간 더 투자해서 95% 자동화 → 글쎄?
 * 100시간 더 투자해서 99% 자동화 → '''STOP.'''

남은 작업이 수동으로 10분 내외라면, 자동화를 멈추는 것이 경제적다.
노력 대비 효과 그래프에서 기울기가 꺾이는 지점(Knee)에서 멈추십시오. 남은 작업이 수동으로 10분 내외라면, 자동화를 멈추는 것이 경제적입니다.
Line 97: Line 67:

자동화를 포기하는 대신, '''수작업을 편하게 만들어라.'''

 * ❌ "이 50건은 알아서 찾아서 고치세요." (불친절)
 * ✅
"처리 못한 50건은 `review_needed.csv`에 저장했습니다. 열어서 `fixed` 컬럼만 채우고 다시 돌리세요." (친절한 반자동)
자동화를 포기하는 대신, 수작업을 편하게 만드십시오. "처리 못한 50건은 `review_needed.csv`에 저장했습니다. 열어서 확인하고 다시 돌리세요" 같은 친절한 반자동 시스템을 지향하십시오.
Line 107: Line 73:
표준 서식은 자동 처리하고, 이상한 서식이 발견되면 경고를 띄우고 멈추는 시스템. 사람이 1분만 개입하면 복잡한 파서 없이도 보고서를 완성할 수 있다.
Line 108: Line 75:
 * '''상황:''' 여러 팀의 엑셀 파일을 취합해 일일 보고서를 만든다. 영업팀 엑셀 서식이 매일 조금씩 바뀐다.
 * '''100% 시도:''' 모든 가능한 서식 변형을 처리하는 파서 작성 → 매일 깨짐.
 * '''95% 접근:''' 표준 서식은 자동 처리. 이상한 서식이 발견되면 "영업팀 파일 확인 필요" 경고 띄우고 멈춤. 사람이 열어서 표준 서식으로 복붙하고 다시 실행.
 * '''결과:''' 개발 1주일 → 2시간. 스트레스 제로.

=== Example 2: CI/CD Pipeline (The Exception) ===

 * '''상황:''' 배포 파이프라인.
 * '''95% 접근:''' "가끔 테스트가 실패하지만 재시도하면 되니까 넘어갑시다." → '''절대 안 됨.'''
 * '''이유:''' 파이프라인은 Unattended System이다. 신뢰성이 100%여야 한다.
 * '''해결:''' Flaky Test (오락가락하는 테스트)를 고치거나 제거해서 100% 신뢰성을 확보해야 한다. 여기서는 타협하면 안 된다.

=== Example 3: Code Migration Tool ===

 * '''상황:''' Java 코드를 Kotlin으로 변환.
 * '''100% 시도:''' 완벽한 문법 변환기 작성.
 * '''95% 접근:''' `IntelliJ`의 "Convert Java File to Kotlin" 기능. 완벽하지 않음. 변환 후 빨간 줄(에러)이 뜬다. 개발자가 5분 만에 수정.
 * '''교훈:''' 완벽한 변환기가 없어도 생산성은 10배 올라간다.
=== Example 2: Code Migration Tool ===
Java 코드를 Kotlin으로 바꿀 때 IDE의 자동 변환 기능을 쓴 뒤, 빨간 줄(에러)이 뜨는 몇 군데만 개발자가 직접 수정하는 방식. 완벽한 변환기보다 10배 빠르다.
Line 131: Line 82:
개발자들의 강박이다. "수동=악". 하지만 '''일회성 작업'''이나 '''비용이 높은 작업'''에서는 수동이 최선이다. 자동화 자체가 목적이 아니라, '''문제 해결'''이 목적임을 기억하라. 자동화 자체가 목적이 아니라 '''문제 해결'''이 목적임을 기억하십시오. 일회성 작업이나 비용이 높은 작업에서는 수동이 최선일 때가 많습니다.
Line 134: Line 85:
그 정규식 하나가 당신의 코드를 '유지보수 불가능한 괴물'로 만드는 마지막 지푸라기일 수 있다.

=== Confusing Frequency ===
1년에 한 번 하는 일을 100% 자동화하느라 3일을 쓴다? 그냥 1시간 수동으로 하는 게 낫다. (XKCD의 자동화 시간표를 참고하라)
그 정규식 하나가 당신의 코드를 유지보수 불가능한 괴물로 만드는 마지막 지푸라기일 수 있습니다.
Line 142: Line 90:
'''WorkingFirst''' - 일단 95%라도 작동하게 만들어라. 완벽을 기하다가 0%에 머물지 마라.

'''
ArtisanMind''' - 어디서 멈출지 아는 것이 장인의 감각다. 기계적 완벽함보다 실용적 가치를 본다.

'''
TinyExperiment''' - 5%를 자동화하는 게 얼마나 걸릴지 작게 실험해보고, 견적이 안 나오면 포기하라.

'''
TwoWorlds''' - 문제 공간 (비용 절감)을 생각하면 95%가 답이다. 해결 공간 (기술적 챌린지)에 갇히면 100%에 집착한다.
 * '''[[WorkingFirst]]''' - 일단 95%라도 작동하게 만드십시오. 완벽을 기하다가 0%에 머물지 마십시오. ''순서''
 * '''[[ArtisanMind]]''' - 어디서 멈출지 아는 것이 장인의 감각입니다. 기계적 완벽함보다 실용적 가치를 보십시오. ''정신''
 * '''[[TinyExperiment]]''' - 5%를 자동화하는 게 얼마나 걸릴지 작게 실험해보고, 견적이 안 나오면 포기하십시오. ''탐색''
 * '''[[ComplexityTaming]]''' - 95%에서 멈추는 것은 시스템의 복잡성을 관리하는 핵심 전략입니다. ''조절''
Line 153: Line 97:
The95PercentRule을 잘 적용하고 있다는 신호:

* '''도구가 단순하다:''' 코드가 짧 이해하기 쉽다.
 * '''예외 처리가 명확하다:''' "이건 못 하니까람이세요"라고 명확히 알려준다.
 * '''스트레스가 없다:''' 엣지 케이스 때문에 밤새 디버깅하 않는다.
 * '''유연하다:''' 프로세스가 바뀌어도 코드를 갈아엎을 필요가 없다.
 * '''사용자가 만족한다:'''
"완벽하진 않은데, 내 일의 90%를 줄여줘서 너무 편해."
 * 도구가 단순하 코드가 짧 이해하기 쉽다.
 * 예외 처리가 명확하용자가 당황 않는다.
 * 엣지 케이스 때문에 밤새 디버깅하 스트레스가 사라진다.
 * "완벽하진 않은데 내 일의 90%를 줄여줘서 너무 편해"라는 피드백을 듣는다.
Line 167: Line 107:
마지막 5%는 악마가 사는 곳다. 그곳에 들어가지 마.
대신 그 5%를 위한 '''아름다운 수동 인터페이스'''를 열어둬라.

그것이 기계와 인간이 조화롭게 협업하는 방법다.
마지막 5%는 악마가 사는 곳입니다. 그곳에 들어가지 마십시오. 대신 그 5%를 위한 '''아름다운 수동 인터페이스'''를 열어두십시오. 그것이 기계와 인간이 조화롭게 협업하는 방법입니다.

The95PercentRule

주니어 개발자들을 위한 패턴 언어 - 마지막 5%의 자동화를 포기하고 단순함을 선택하는 지혜

The Story 1: The Migration Script Trap (Programming)

한 주니어 개발자가 레거시 DB를 새로운 시스템으로 마이그레이션하는 스크립트를 짜고 있었다. "95%는 완료됐어요. 그런데 나머지 5% 데이터가 문제입니다." 그는 수백 줄의 복잡한 예외 처리 코드를 가리켰다. "50건 정도의 데이터가 형식이 제멋대로라 이걸 자동으로 보정하는 알고리즘을 짜고 있어요. 3일째 이것만 하고 있네요." 시니어가 답했다. "50건 고치는 데 직접 하면 30분이면 돼. 네가 짠 그 복잡한 코드를 유지보수하는 비용은 3년이 갈 거고. 자동화의 목적은 '100% 자동'이 아니라 '시간 절약'이야." 주니어는 복잡한 코드를 다 지우고 에러 로그만 남겼다. 마이그레이션은 그날 오후에 끝났다.

The Story 2: The Perfect Garden (Ordinary Life)

민수와 하나는 각자 마당에 '정원'을 가꾸고 있다.

민수의 정원 (The 100% Perfectionist): 민수는 정원에 잡초가 단 하나도 있는 것을 용납하지 못한다. 그는 매일 아침부터 저녁까지 핀셋을 들고 아주 작은 풀 한 포기까지 뽑아낸다. "완벽한 정원을 만들어야 해." 하지만 민수는 잡초를 뽑느라 정작 꽃에 물을 주거나 나무를 가꿀 시간이 없었다. 민수의 정원은 잡초는 없었지만, 주인은 지쳐버렸고 꽃들도 생기를 잃었다.

하나의 정원 (The 95% Pragmatist): 하나는 큰 잡초들만 눈에 띌 때 솎아낸다. "95% 정도만 깔끔하면 충분해. 남은 5%의 작은 풀들은 자연스러운 풍경의 일부라고 생각하자." 하나는 잡초 뽑기에 쏟을 에너지를 아껴 새로운 꽃을 심고 나무를 전정했다. 하나의 정원은 완벽하게 매끈하지는 않았지만, 항상 꽃이 피어있고 생명력이 넘쳤다. 마지막 5%의 완벽함에 집착하지 않을 때 더 큰 가치를 돌볼 수 있음을 하나는 알고 있었다.

Context

당신은 반복적인 작업을 자동화하거나 도구를 만들고 있다. 처음 90~95%의 케이스를 처리하는 것은 쉽고 빨랐다. 하지만 남은 소수의 엣지 케이스 (Edge Case), 불규칙한 데이터, 주관적 판단이 필요한 부분들이 발목을 잡는다.

일상적인 상황:

  • "이것만 자동화하면 완벽한데..."라며 며칠을 보낸다.
  • 예외 처리를 위해 메인 로직보다 더 큰 if-else 블록을 만든다.

  • 자동화 도구를 만들었는데, 너무 복잡해서 동료들이 쓰기 어려워한다.
  • "완전 자동화"라는 로망에 사로잡혀 있다.

Problem

마지막 5%를 자동화하는 비용은 종종 나머지 95%를 합친 것보다 비싸다. 이를 무리하게 자동화하려다 시스템의 복잡도가 폭발하고 유지보수가 불가능해진다.

The Complexity Curve

자동화의 비용 곡선은 선형이 아니라 지수적입니다.

  • 0% → 80% 자동화: 매우 쉬움 (Happy Path)
  • 80% → 95% 자동화: 적당한 노력 (Common Edge Cases)
  • 95% → 100% 자동화: 엄청난 비용 (Chaos, Human Judgment)

마지막 5%는 보통 규칙성이 없거나, 문맥 파악이 필요하거나, 외부 요인에 의존합니다. 이를 코드로 해결하려면 배보다 배꼽이 더 커집니다.

The Fragility of 100%

마지막 5%까지 처리하려고 억지로 끼워 맞춘 로직은 매우 취약(Brittle)합니다. 데이터 형식이 조금만 바뀌어도 스크립트 전체가 깨집니다. 결과적으로 "완전 자동화" 도구는 신뢰를 잃고, 아무도 쓰지 않게 됩니다.

Solution

의도적으로 불완전한 자동화 (Semi-Automation)를 선택하라. 기계가 잘하는 95%는 기계에게, 사람이 잘하는 5%는 사람에게 맡겨라.

Principle 1: Distinguish the Goal

먼저 질문하십시오. "이것은 사람의 개입 없이 돌아가야 하는가 (Unattended)?"

  1. YES (e.g., CI/CD Pipeline): 이때는 100% 자동화가 필수입니다. 입력을 엄격하게 통제하여 100%를 달성하십시오.

  2. NO (e.g., Migration, Report Gen): 사람이 실행 버튼을 누르는 도구라면 95%까지만 해주고 "나머지는 네가 확인해"라고 넘기는 것이 현명합니다.

Principle 2: The Human-in-the-Loop Pattern

가장 강력한 패턴은 "기계가 초안을 잡고(Draft), 사람이 검수/완료(Finalize)하는 것"입니다.

  • 기계가 확실한 것만 처리하고, 애매한 것은 "검토 필요" 폴더로 뺍니다. 이것은 100% 자동화보다 훨씬 만들기 쉽고 유연하며 결과물의 품질도 높습니다.

Principle 3: Stop at the "Knee of the Curve"

노력 대비 효과 그래프에서 기울기가 꺾이는 지점(Knee)에서 멈추십시오. 남은 작업이 수동으로 10분 내외라면, 자동화를 멈추는 것이 경제적입니다.

Principle 4: Make the Manual Part Easy

자동화를 포기하는 대신, 수작업을 편하게 만드십시오. "처리 못한 50건은 review_needed.csv에 저장했습니다. 열어서 확인하고 다시 돌리세요"와 같은 친절한 반자동 시스템을 지향하십시오.

Real Examples

Example 1: The Daily Report

표준 서식은 자동 처리하고, 이상한 서식이 발견되면 경고를 띄우고 멈추는 시스템. 사람이 1분만 개입하면 복잡한 파서 없이도 보고서를 완성할 수 있다.

Example 2: Code Migration Tool

Java 코드를 Kotlin으로 바꿀 때 IDE의 자동 변환 기능을 쓴 뒤, 빨간 줄(에러)이 뜨는 몇 군데만 개발자가 직접 수정하는 방식. 완벽한 변환기보다 10배 빠르다.

Common Pitfalls

"But Manual Work is Bad!"

자동화 자체가 목적이 아니라 문제 해결이 목적임을 기억하십시오. 일회성 작업이나 비용이 높은 작업에서는 수동이 최선일 때가 많습니다.

"I Can Fix This with One More Regex..."

그 정규식 하나가 당신의 코드를 유지보수 불가능한 괴물로 만드는 마지막 지푸라기일 수 있습니다.

Connection to Other Patterns

  • WorkingFirst - 일단 95%라도 작동하게 만드십시오. 완벽을 기하다가 0%에 머물지 마십시오. 순서

  • ArtisanMind - 어디서 멈출지 아는 것이 장인의 감각입니다. 기계적 완벽함보다 실용적 가치를 보십시오. 정신

  • TinyExperiment - 5%를 자동화하는 게 얼마나 걸릴지 작게 실험해보고, 견적이 안 나오면 포기하십시오. 탐색

  • ComplexityTaming - 95%에서 멈추는 것은 시스템의 복잡성을 관리하는 핵심 전략입니다. 조절

Signs of Success

  • 도구가 단순하고 코드가 짧아 이해하기 쉽다.
  • 예외 처리가 명확하여 사용자가 당황하지 않는다.
  • 엣지 케이스 때문에 밤새 디버깅하는 스트레스가 사라진다.
  • "완벽하진 않은데 내 일의 90%를 줄여줘서 너무 편해"라는 피드백을 듣는다.

The Ultimate Insight

전설적인 프로그래머 Tom Cargill의 "90-90 법칙": "코드의 첫 90%는 개발 시간의 90%를 차지한다. 나머지 10%의 코드는 남은 개발 시간의 90%를 차지한다."

마지막 5%는 악마가 사는 곳입니다. 그곳에 들어가지 마십시오. 대신 그 5%를 위한 아름다운 수동 인터페이스를 열어두십시오. 그것이 기계와 인간이 조화롭게 협업하는 방법입니다.


CategoryPatternLanguage CategoryProgramming CategoryAutomation CategoryProductivity

The95PercentRule (last edited 2025-12-30 10:00:27 by 정수)