절대 언러닝하면 안 되는 것
문제 정의·보안 사고력·시스템 사고·도메인 이해·코드 리터러시·엔지니어링 윤리 등 AI가 대체할 수 없는 여섯 가지 판단력을 정리하는 장
핵심 요약
- 버려야 할 것은 방법론적 습관이고, 지켜야 할 것은 사고력과 판단력이다.
- AI는 주어진 문제를 풀지만 풀어야 할 문제를 정의하지는 못한다. 구현 비용이 0에 가까워질수록 "무엇을 만들지" 정하는 일이 더 중요해진다.
- AI는 보안을 기능이 아니라 제약으로 본다. 그래서 명시하지 않으면 인증·인가·입력 검증을 생략하거나 약하게 구현한다.
- 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