절대 언러닝하면 안 되는 것
AI 시대에도 변하지 않는 개발자 기본기
이 핸드북은 기존 습관을 버리라고 말합니다. 하지만 모든 것을 버리라는 뜻이 아닙니다. AI가 아무리 발전해도 변하지 않는 개발자의 핵심 역량이 있습니다.
버려야 할 것과 지켜야 할 것의 경계는 어디일까요? 직접 타이핑해야 진짜 개발자라는 생각은 버려야 하지만, 코드를 읽고 판단하는 능력은 지켜야 합니다. 사전 설계를 완벽히 해야 시작할 수 있다는 관성은 내려놓을 수 있지만, 문제를 정확히 정의하는 능력은 오히려 더 중요해집니다. 모든 코드를 외워야 한다는 압박은 놓을 수 있지만, 도메인과 사용자에 대한 공감은 AI가 대신할 수 없습니다.
공통적인 구분 기준이 있습니다. 버려야 할 것은 방법론적 습관이고, 지켜야 할 것은 사고력과 판단력입니다. 도구가 바뀌어도 판단력은 사람에게 남아야 합니다.
문제를 정확히 정의하는 능력
AI는 주어진 문제를 풀기 잘합니다. 하지만 풀어야 할 문제가 무엇인지 정의하는 것은 여전히 사람의 몫입니다.
Andrej Karpathy는 개발자의 자기주도 작업이 80%에서 20%로 줄어들고 있다고 관찰했고, Addy Osmani는 **문제 정의 70%, 실행 30%**로 비율을 역전시켜야 한다고 제안합니다. 두 사람이 같은 결론에 도달한 것은 우연이 아닙니다. AI가 실행을 가속시킬수록, 문제 정의 능력이 개발자의 핵심 차별화 요소가 됩니다.
이 차이를 구체적으로 보면 명확해집니다. AI는 장바구니 수량 변경 기능을 훌륭하게 구현하지만, 사용자가 수량을 변경하는 진짜 이유를 파악하지는 못합니다. 주어진 스펙대로 API를 설계하지만, 이 API가 정말 필요한지 판단하지는 않습니다. 에러 메시지를 개선할 수는 있지만, 에러가 발생하지 않는 UX를 설계하는 것은 다른 차원의 문제입니다.
문제 정의의 깊이가 결과를 결정한다
다음 사례를 살펴보면 문제 정의의 깊이에 따라 결과가 얼마나 달라지는지 알 수 있습니다.
가상 운영 예시
아래 수치는 특정 서비스의 공개 지표가 아니라, 문제 정의의 깊이를 보여주기 위한 가상 운영 예시입니다.
팀에서 받은 요구사항: "검색 결과 페이지에 필터 기능을 추가해주세요"
얕은 문제 정의 (AI에게 바로 전달):
"검색 결과에 카테고리, 가격, 날짜 필터를 추가해줘"
깊은 문제 정의 (사람이 먼저 분석):
현상: 사용자가 검색 후 원하는 결과를 찾지 못해 이탈한다.
데이터: 검색 결과 페이지 이탈률 68%, 평균 체류 시간 12초
가설: 결과가 너무 많아서 원하는 항목을 찾기 어렵다.
실험: 상위 5개 결과의 관련성을 높이는 것과
필터를 추가하는 것 중 어떤 것이 효과적인지 A/B 테스트
결론: 필터보다 검색 알고리즘 개선이 근본 해결책일 수 있다.두 번째 접근에서 AI는 도구로서 최대의 가치를 발휘합니다. 검색 알고리즘 개선 프로토타입을 빠르게 만들어볼 수 있으니까요. 하지만 "필터가 아니라 검색 알고리즘이 문제일 수 있다"는 판단은 사람이 해야 합니다.
구현 비용이 0에 가까워지면
구현 비용이 거의 0에 가까워지면, 무엇을 만들지 결정하는 것이 어떻게 만들지 결정하는 것보다 훨씬 중요해집니다. 잘못된 문제를 AI로 빠르게 풀면, 잘못된 결과를 빠르게 얻을 뿐입니다.
"왜?"를 반복해서 묻는 습관은 단순하지만 강력합니다. "관리자 대시보드에 실시간 알림 기능을 추가해주세요"라는 요구사항을 받았을 때, "왜 실시간 알림이 필요한가?"부터 시작해서 몇 단계를 파고 들어가면, 대시보드가 아닌 슬랙이나 이메일 알림이 더 효과적일 수 있다는 결론에 도달하는 경우가 적지 않습니다. 이런 판단은 AI가 대신하기 어렵습니다.
보안 사고력
AI가 만든 코드도 취약할 수 있습니다. AI는 보안을 기능이 아니라 제약으로 인식하는 경향이 있어서, 명시적으로 요청하지 않으면 보안 로직을 생략하거나 약하게 구현하는 경우가 많습니다.
AI가 자주 놓치는 보안 영역
인증에서는 토큰 만료 처리를 누락하고, 인가에서는 리소스 소유자 검증을 빠뜨리며, 입력 검증에서는 기본적인 수준만 구현하는 경향이 있습니다. 에러 처리에서 스택 트레이스를 노출하거나, 의존성에서 CVE를 확인하지 않고 최신 버전을 사용하거나, 시크릿을 코드에 하드코딩하는 경우도 흔합니다.
구체적인 사례를 보면 이 문제가 더 선명해집니다.
// AI가 생성한 코드 - 기능적으로 정상 동작
app.get('/api/users/:id/profile', async (req, res) => {
const user = await db.users.findById(req.params.id);
res.json(user);
});
// 보안 사고력이 있는 개발자가 발견한 문제:
// 1. 인증 미들웨어가 없음 - 누구나 접근 가능
// 2. 인가 검증이 없음 - 다른 사용자 정보 조회 가능
// 3. 반환 데이터 필터링 없음 - 비밀번호 해시 등 노출
// 4. Rate limiting 없음 - 전체 사용자 정보 수집 가능
// 5. 입력 검증 없음 - NoSQL 인젝션 가능
// 보안을 고려한 코드
app.get('/api/users/:id/profile',
authenticate, // 인증 확인
rateLimit({ max: 60 }), // Rate limiting
async (req, res) => {
// 인가: 본인 또는 관리자만 접근
if (req.user.id !== req.params.id
&& req.user.role !== 'admin') {
return res.status(403).json({
error: 'Forbidden'
});
}
// 입력 검증
if (!isValidObjectId(req.params.id)) {
return res.status(400).json({
error: 'Invalid ID'
});
}
const user = await db.users.findById(req.params.id);
// 민감 정보 제거
res.json(sanitizeUser(user));
}
);첫 번째 코드는 기능적으로 완벽하게 동작합니다. 테스트도 통과할 것입니다. 하지만 프로덕션에 배포되는 순간 심각한 보안 문제가 됩니다. 이런 차이를 발견하는 것이 보안 사고력이고, 이것은 AI에게 "보안을 강화해줘"라고 요청하는 것과는 다른 차원의 능력입니다.
AI 보안 코드의 함정
AI에게 보안을 강화해달라고 하면 보안처럼 보이는 코드를 생성할 수 있습니다. 하지만 실제로 안전한지는 보안 전문 지식이 있는 사람만 판단할 수 있습니다. 표면적인 검증 로직과 실제 보안은 다릅니다.
시스템 사고: 전체를 보는 눈
AI는 주어진 범위 내에서 최적의 코드를 생성합니다. 하지만 그 코드가 시스템 전체에 미치는 영향을 판단하는 것은 사람의 역할입니다.
AI의 시야는 현재 파일, 현재 함수, 그리고 그에 대한 테스트 수준에 머무르는 경향이 있습니다. 반면 사람은 전체 아키텍처에서 서비스 의존성, 배포 환경, 성능 병목, 사용자 경험까지 연결해서 사고할 수 있습니다.
이 차이가 극명하게 드러나는 사례가 캐시 추가입니다.
AI에게 요청: "이 API 응답을 Redis로 캐시해줘"
AI가 생성한 코드: 기능적으로 완벽한 Redis 캐시 코드
시스템 사고가 있는 개발자의 추가 질문:
1. 캐시 무효화 전략은? 데이터가 변경되면 어떻게 갱신?
2. Redis가 죽으면? 폴백(fallback) 로직은?
3. 캐시 용량 계산은? 메모리 비용 대비 효과는?
4. 다른 서비스도 같은 데이터를 캐시하는가? 정합성 문제는?
5. 캐시 히트율 모니터링은? 효과를 어떻게 측정?
6. 개발/스테이징 환경의 Redis 설정은?AI가 생성한 캐시 코드 자체는 완벽할 수 있습니다. 하지만 그 코드가 시스템 전체에 미치는 영향을 이해하고, 운영 환경에서 발생할 수 있는 문제를 예측하는 것은 전혀 다른 역량입니다. 새 API 엔드포인트를 추가할 때 기존 API 일관성과 버전 관리를 고려하는 것, DB 쿼리를 최적화할 때 전체 DB 부하와 커넥션 풀을 함께 보는 것, 새 라이브러리를 도입할 때 번들 사이즈와 라이선스와 유지보수 상태를 확인하는 것 -- 이런 판단들은 시스템 전체를 보는 눈에서 나옵니다.
사용자 공감과 도메인 이해
AI는 코드를 생성하지만, 그 코드를 쓰는 사용자의 감정과 맥락을 이해하지 못합니다.
// AI가 만든 코드: 기능적으로 정확
function calculateTax(income: number): number {
return income * 0.25;
}
// 도메인을 아는 개발자의 피드백:
// - 누진세율이 적용되어야 함
// - 공제 항목이 반영되어야 함
// - 연도별로 세율이 달라짐
// - 소수점 처리 기준이 세법에 규정되어 있음
// - 지방세와 국세가 별도 계산됨
// - 비과세 소득 구간이 존재함이 차이는 코딩 실력이 아니라 도메인 지식에서 비롯됩니다. AI는 학습 데이터에 없는 암묵적 규칙을 인식하지 못하고, 사용자의 불안이나 급한 감정을 무시하며, 지역별 관행 차이를 반영하기 어렵고, 최신 법규 반영이 지연되며, 기능 간 우선순위를 판단하지 못합니다.
이것은 AI의 결함이 아니라 본질적 한계입니다. 도메인 이해는 업무 경험, 사용자와의 대화, 업계 동향 파악에서 쌓이는 것이지, 학습 데이터에서 추출되는 것이 아닙니다. AI 시대에 개발자의 도메인 전문성이 오히려 더 가치 있어지는 이유가 여기에 있습니다. 구현은 AI가 빠르게 해결하니, 무엇을 구현할지 결정하는 도메인 판단력이 차별화 요소가 되는 것입니다.
코드 리터러시: 읽고 판단하는 능력
"AI가 코드를 다 짜주는데 코드를 읽을 줄 알아야 하나?"
반드시 알아야 합니다. AI가 생성한 코드를 읽고, 이해하고, 판단하는 능력은 AI 시대에 오히려 더 중요해졌습니다.
이 흐름도가 보여주는 분기점은 명확합니다. AI 코드를 이해하면 수용, 수정, 거부를 판단할 수 있고, 이해하지 못하면 맹목적으로 수용하게 되어 기술 부채가 쌓입니다.
AI가 생성하는 코드에서 반복적으로 관찰되는 문제 패턴이 있습니다. 간단한 로직에 불필요한 패턴을 적용하는 과잉 추상화, catch 블록에서 로그만 남기고 계속 진행하는 낙관적 에러 처리, 작동하지만 성능이 나쁜 비효율적 알고리즘, 환경별 설정을 코드에 직접 작성하는 하드코딩, 표준 라이브러리로 충분한 기능에 외부 패키지를 추가하는 불필요한 의존성 등이 대표적입니다.
이런 문제를 발견하려면 코드를 읽고 판단하는 능력이 필요합니다. 과잉 추상화를 발견하려면 적정 설계 수준에 대한 감각이 있어야 하고, 낙관적 에러 처리를 잡으려면 에러 전파 메커니즘을 이해해야 하며, 비효율적 알고리즘을 개선하려면 알고리즘 기본기가 뒷받침되어야 합니다.
코드를 쓰는 것에서 읽는 것으로
AI 시대에 개발자는 작가에서 편집자로 역할이 전환됩니다. 편집자가 글을 잘 쓸 줄 알아야 좋은 편집을 할 수 있듯, 개발자도 코드를 잘 읽을 줄 알아야 AI의 출력을 제대로 검증할 수 있습니다.
엔지니어링 윤리와 책임감
AI가 코드를 생성하더라도, 그 코드의 영향에 대한 책임은 사람에게 있습니다.
이 여정도를 따라가 보면 흥미로운 점이 발견됩니다. AI가 코드를 생성하는 단계에서는 AI의 만족도가 높지만, 그 전후로 모든 결정과 책임은 개발자에게 있습니다. 코드 리뷰를 생략한 것, 테스트를 충분히 하지 않은 것, 배포를 승인한 것 -- 모두 사람의 판단입니다.
운영 책임과 배포 책임
법적 책임의 최종 배분은 국가, 계약, 조직 역할에 따라 달라질 수 있습니다. 이 핸드북이 강조하는 것은 법률 해석이 아니라, 엔지니어링 관점에서 피할 수 없는 책임입니다.
핵심 원칙은 단순합니다.
핵심 원칙: "AI가 초안을 만들더라도, 배포 판단과 운영 책임은 사람에게 남는다"
1. 이해하지 못한 코드를 승인하면 그 위험도 함께 승인한 것이다
2. 테스트와 리뷰를 생략하면 도구가 아니라 프로세스가 실패한 것이다
3. "AI가 추천했다"는 말은 품질 검증을 대신하지 못한다책임 있는 AI 활용의 원칙들
이런 운영 현실에서 자연스럽게 도출되는 원칙들이 있습니다.
이해하지 못하는 코드를 배포하지 않는 것이 첫 번째입니다. AI가 생성한 코드라도 배포 전에 반드시 이해해야 합니다. "작동하니까 됐다"는 프로덕션에서는 통하지 않습니다.
AI의 한계를 인지하고 보완하는 것이 두 번째입니다. AI는 학습 데이터에 기반하므로, 최신 보안 취약점이나 도메인 특수 규정을 반영하지 못할 수 있습니다.
결과에 대한 책임을 수용하는 것이 세 번째입니다. 도구가 바뀌어도 엔지니어의 책임은 바뀌지 않습니다. 컴파일러의 버그로 인한 오류를 개발팀이 추적하듯, AI가 만든 오류도 결국 팀이 이해하고 대응해야 합니다.
투명성을 유지하는 것이 네 번째입니다. AI를 사용했다면 팀에 공유하고, 코드 리뷰에서 AI 사용 여부를 숨기지 않는 것. 이것은 윤리의 문제이기도 하지만, 실용적으로도 중요합니다. AI가 생성한 코드라는 사실을 알아야 리뷰어가 올바른 관점으로 검토할 수 있기 때문입니다.
배포 책임은 남는다
AI는 도구입니다. 망치가 못을 잘못 박았다고 망치를 탓하지 않듯, AI가 잘못된 코드를 생성했다고 검증 책임까지 사라지지는 않습니다. 코드에 이름을 걸고 배포한 순간, 그 결과를 이해하고 대응할 주체는 결국 팀입니다.
여섯 가지의 공통점
여섯 가지 역량을 나열하고 보니, 공통점이 보입니다. 모두 판단력에 해당합니다. 무엇을 만들지 판단하고(문제 정의), 안전한지 판단하고(보안), 전체에 미치는 영향을 판단하고(시스템 사고), 사용자에게 가치 있는지 판단하고(도메인 이해), 코드가 올바른지 판단하고(리터러시), 결과에 책임지는 것(윤리).
AI가 "어떻게"를 대신하더라도, "무엇을"과 "왜"는 사람의 영역으로 남습니다. 그리고 구현 비용이 낮아질수록, 이 판단력의 상대적 가치는 오히려 높아지는 경향이 있습니다. 코드를 작성하는 기술이 AI로 평준화되는 세계에서, 개발자를 차별화하는 것은 결국 무엇을 만들고 무엇을 만들지 않을지 판단하는 능력일 수 있습니다.
다음 장 미리보기
무엇을 버리지 말아야 하는지 정리했다면, 마지막 장에서는 이제 실제 전환 순서를 다룹니다. 개인과 팀이 4주 안에 무엇을 관찰하고, 무엇을 실험하고, 어떤 규칙을 남겨야 하는지 살펴봅니다.
참고 자료
참고 자료 안내
이 장의 관점과 프레임워크를 뒷받침하는 참고 자료입니다. 본문의 모든 주장이 아래 자료에서 직접 인용된 것은 아니며, 실무 경험과 커뮤니티 사례를 종합한 해석이 포함되어 있습니다.
- OWASP Foundation. "OWASP Top Ten." https://owasp.org/www-project-top-ten/
- ACM Code of Ethics (2018). https://www.acm.org/code-of-ethics
- IEEE Code of Ethics. https://www.ieee.org/about/corporate/governance/p7-8.html