코드는 AI가 작성했는데, 왜 그렇게 만들었는지 나는 설명할 수 있을까?

Addy Osmani, Critical thinking when agents do the work, 2026.11.03.

이 글은 위 글에서 다룬 문제의식을 바탕으로, AI 코딩 에이전트를 활용하는 개발자의 관점에서 재구성한 개인적인 생각이다.

AI 코딩 에이전트가 발전하면서 개발 방식이 빠르게 바뀌고 있다.

과거에는 하나의 기능을 구현하기 위해 직접 코드를 작성하고, 오류를 수정하고, 관련 문서를 찾아보는 데 상당한 시간을 사용했다. 이제는 요구사항을 전달하면 AI가 코드를 작성하고 테스트를 실행하며, 발견한 오류까지 수정한다.

개발자가 직접 코드를 작성하는 시간은 줄어들고 있다. 생산성 측면에서는 분명 긍정적인 변화다.

그런데 여기서 한 가지 의문이 생긴다.

우리는 AI가 작성한 코드를 얼마나 이해하고 있을까?

최근 Addy Osmani의 Critical thinking when agents do the work를 읽으며 이 질문을 다시 생각하게 되었다.

이 글은 AI 사용을 줄여야 한다고 주장하지 않는다. 오히려 AI 에이전트를 적극적으로 활용하면서도 개발자가 어떻게 자신의 판단 능력을 유지할 수 있는지를 이야기한다.

AI가 정확해질수록 검토는 어려워진다

AI가 작성한 코드의 품질이 낮다면 문제를 발견하기는 비교적 쉽다.

잘못된 문법, 존재하지 않는 API, 어색한 로직은 눈에 띈다. 하지만 AI의 성능이 향상되면서 이러한 오류는 점차 줄어들고 있다.

문제는 그다음부터다.

코드 구조가 자연스럽고, 변수명도 적절하며, 테스트까지 통과했다면 우리는 얼마나 깊게 검토할까?

수백 줄의 변경 사항을 확인하면서 전체적인 구조만 살펴보고 넘어갈 수도 있다. 특히 이전 작업에서 AI가 좋은 결과를 반복적으로 보여줬다면 다음 결과도 신뢰하기 쉬워진다.

이런 행동이 반드시 잘못된 것은 아니다. 모든 코드의 모든 줄을 같은 깊이로 검토하는 것은 현실적이지 않다.

다만 여기에는 위험이 있다.

코드가 정상적으로 동작한다는 사실과 개발자가 그 코드를 이해하고 있다는 사실은 서로 다르다.

예를 들어 사용자 인증 기능에서 비밀번호 입력 실패 횟수를 제한하는 작업을 AI에게 맡겼다고 가정해 보자.

AI가 코드를 구현하고 테스트도 통과시켰다. 그러나 실패 횟수를 사용자별로 관리하는지, IP별로 관리하는지, 여러 요청이 동시에 들어올 때도 제한이 유지되는지는 별개의 문제다.

테스트가 통과했다고 해서 이러한 정책적 판단까지 올바르게 이루어졌다고 보장할 수는 없다.

개발자가 확인해야 하는 것은 코드의 문법과 정상 동작뿐만이 아니다. 그 안에 어떤 가정과 결정이 들어 있는지도 살펴봐야 한다.

인지적 위임과 인지적 항복의 차이

Addy Osmani는 AI를 활용하는 방식을 세 가지 상태로 설명한다.

  • Cognitive Offloading(인지적 위임): 작업은 AI에게 맡기지만 결과에 대한 판단과 책임은 유지한다.
  • Deferral(판단 유예): AI의 결과를 충분히 검토하지 않은 채 다음 작업의 전제로 사용한다.
  • Cognitive Surrender(인지적 항복): AI의 결론을 자신의 판단처럼 받아들이고 더 이상 검증할 필요를 느끼지 않는다.

이 중에서 가장 경계해야 할 상태는 인지적 항복이다.

처음에는 AI가 작성한 코드를 꼼꼼하게 읽는다. 이후에는 핵심 부분만 확인하고, 익숙해지면 변경된 파일 목록과 테스트 결과 정도만 살펴보게 될 수도 있다.

그러다 어느 순간 자신이 승인한 코드의 설계 이유를 설명하지 못하는 상황에 도달할 수 있다.

이때 발생하는 문제가 이해 부채(Comprehension Debt)다.

기술 부채는 코드에 남지만, 이해 부채는 개발자와 팀이 시스템을 이해하는 능력에 영향을 준다.

코드베이스는 깔끔하고 테스트도 정상적으로 통과한다. 하지만 새로운 요구사항이 들어왔을 때 왜 이런 구조가 만들어졌는지, 어디를 변경해야 안전한지 판단하기 어려워질 수 있다.

물론 개발자가 거대한 코드베이스의 모든 내용을 기억할 필요는 없다.

중요한 것은 필요한 시점에 해당 영역의 동작과 설계 의도를 다시 파악할 수 있느냐다. 코드를 기억하는 능력보다 문제를 이해하고 필요한 지식을 복원하는 능력이 중요하다고 생각한다.

코드 작성의 병목은 검증으로 이동하고 있다

AI 이전에는 코드를 구현하는 과정 자체가 많은 시간을 차지했다.

하지만 AI가 구현 속도를 높여주면서 개발자는 상대적으로 더 많은 시간을 검토와 검증에 사용하게 될 수 있다.

여기서 주의할 점이 있다.

테스트가 통과했다는 사실은 테스트가 확인한 조건이 만족되었다는 의미일 뿐이다.

AI가 잘못 해석한 요구사항을 기반으로 구현하고 동일한 가정으로 테스트를 작성했다면, 모든 테스트가 통과하더라도 실제 요구사항과 다른 결과가 나올 수 있다.

따라서 AI에게 단순히 테스트를 작성하고 실행하도록 지시하는 것만으로는 충분하지 않다.

작업을 시작하기 전에 무엇을 검증해야 하는지 정의하는 과정이 필요하다.

예를 들어 다음과 같이 구분할 수 있다.

  • 기능이 정상적으로 동작하는가?
  • 경계 조건과 실패 상황을 처리하는가?
  • 기존 기능에 영향을 주지 않는가?
  • 요구사항에 명시되지 않은 동작을 AI가 임의로 결정하지 않았는가?
  • 테스트가 확인하지 못한 부분은 무엇인가?

모든 작업에 동일한 수준의 검증을 적용할 필요는 없다.

단순한 UI 문구 수정과 인증 정책 변경은 영향 범위가 다르다. 변경의 위험이 클수록 검증에도 더 많은 시간을 투자하는 것이 합리적이다.

앞으로 개발자의 생산성을 평가할 때도 단순히 얼마나 많은 코드를 생성했는지보다, 얼마나 신뢰할 수 있는 변경을 만들어냈는지를 중요하게 봐야 하지 않을까.

좋은 프롬프트보다 중요한 것은 문제에 대한 이해다

AI를 잘 활용하려면 프롬프트를 잘 작성해야 한다는 이야기를 자주 듣는다.

하지만 좋은 프롬프트가 단순히 문장을 구체적으로 작성하는 것을 의미하지는 않는다고 생각한다.

핵심은 자신이 해결하려는 문제를 충분히 이해하고 있는가에 있다.

요구사항이 불명확한 상태에서 AI에게 구현을 맡기면 AI는 부족한 정보를 추론해 채운다. 그리고 그럴듯한 결과물을 만들어낸다.

겉보기에는 기능이 완성되었지만, 처음부터 해결하려던 문제가 정확히 정의되지 않았을 수도 있다.

Addy Osmani는 이러한 문제를 의도 부채(Intent Debt)라는 개념으로 설명한다.

개발자가 명시하지 않은 목적과 제약조건을 AI가 임의로 해석하고, 그 결과가 구현물에 남게 되는 것이다.

이를 줄이기 위해서는 구현에 앞서 최소한 네 가지를 생각해야 한다.

  1. 목적: 이 기능을 왜 만드는가?
  2. 범위: 무엇을 변경하고 무엇은 변경하지 않는가?
  3. 제약: 반드시 지켜야 하는 정책이나 기술적 조건은 무엇인가?
  4. 완료 기준: 어떤 상태가 되어야 작업이 끝났다고 판단할 수 있는가?

이러한 내용을 정리하는 과정 자체가 문제를 이해하는 과정이다.

AI를 활용하면 답을 더 빠르게 얻을 수 있다. 하지만 빠르게 얻은 답이 항상 올바른 질문에서 출발한 것은 아니다.

그래서 AI에게 구현을 요청하기 전에 자신의 가설을 먼저 세우는 습관이 중요하다고 생각한다.

처음부터 정확한 답을 알 필요는 없다. 예상한 해결 방식이 틀렸다면 AI의 분석과 근거를 통해 수정하면 된다.

중요한 것은 AI의 결과를 무조건 받아들이는 것이 아니라, 자신의 생각과 비교할 기준을 가지고 있는가다.

AI에게 무엇을 맡기고, 무엇을 직접 판단할 것인가

그렇다면 AI가 작성한 모든 코드를 자세히 분석하고 모든 설계를 직접 결정해야 할까?

그것 역시 비효율적이다.

AI를 사용하는 목적 중 하나는 반복적인 작업에서 벗어나 더 중요한 문제에 집중하기 위해서다.

따라서 모든 작업을 직접 수행하려 하기보다는 작업의 실행과 판단을 구분하는 것이 필요하다고 본다.

코드 작성, 반복적인 리팩터링, 테스트 생성, 문서 정리 등은 AI에게 맡길 수 있다.

반면 어떤 문제를 해결할 것인지, 어떤 설계가 현재 시스템에 적절한지, 어느 정도의 위험을 수용할 수 있는지는 개발자가 충분히 관여해야 한다.

물론 설계 판단에도 AI의 도움을 받을 수 있다. 대안을 비교하고 놓친 조건을 찾는 과정에서 AI는 유용한 협업 상대가 된다.

핵심은 AI의 제안을 검토할 수 있는 근거를 확보하고, 최종 선택의 이유를 설명할 수 있어야 한다는 점이다.

이를 실무에 적용한다면 다음과 같은 흐름을 생각해 볼 수 있다.

작업 전에는 해결하려는 문제와 가설, 제약조건, 완료 기준을 정리한다.

작업 중에는 AI가 구현과 자동 검증을 수행하되, 중요한 설계 변경이나 요구사항 해석은 확인한다.

작업 후에는 단순히 작업 완료 보고를 읽는 데 그치지 않고, 실제 변경 내용과 검증 결과를 살펴본다. 특히 AI가 스스로 결정한 사항과 아직 확인하지 못한 조건을 확인한다.

이 과정이 모든 문제를 해결해 주지는 않는다. 그러나 AI가 만들어낸 결과를 수동적으로 받아들이는 것보다는 판단의 주도권을 유지하는 데 도움이 될 것이다.

AI 시대에도 개발자의 사고력은 필요하다

AI가 발전하면 지금 개발자가 수행하는 많은 작업을 더 정확하고 빠르게 처리할 수 있을 것이다.

그렇다면 개발자가 직접 코드를 작성하고 디버깅하는 능력을 계속 유지해야 할까?

모든 역량을 이전과 같은 수준으로 유지할 필요는 없을지도 모른다.

하지만 AI가 작성한 코드의 문제를 판단하려면 결국 해당 기술에 대한 이해가 필요하다. 자신이 전혀 이해하지 못하는 영역에서는 AI의 설명이 타당한지조차 판단하기 어렵기 때문이다.

그래서 모든 구현을 직접 수행할 필요는 없더라도, 중요한 기술적 역량은 의도적으로 유지해야 한다고 생각한다.

때로는 AI 없이 문제를 해결해 보고, 익숙하지 않은 개념을 직접 학습하고, AI가 내놓은 해결책의 반대 근거를 찾아보는 과정도 필요하다.

그것이 AI보다 더 잘 코딩하기 위해서라기보다는, AI가 제안한 결과를 올바르게 판단하기 위한 준비에 가깝다.

마치며

AI 코딩 에이전트가 발전하면서 개발자의 역할도 달라지고 있다.

과거에는 직접 구현하는 능력이 큰 비중을 차지했다면, 앞으로는 문제를 정의하고 적절한 해결책을 선택하며 결과를 검증하는 능력의 중요성이 더욱 커질 것으로 생각한다.

이 변화가 모든 개발자에게 같은 방식으로 나타나지는 않을 것이다. 그러나 AI가 코드 작성에 투입되는 시간을 줄여준다면, 그만큼 개발자는 어디에 자신의 사고력을 사용할지 고민할 필요가 있다.

나 역시 AI를 얼마나 능숙하게 사용하는지만큼, AI를 사용하는 과정에서 어떤 판단을 직접 하고 있는지 돌아봐야겠다는 생각이 들었다.

결국 중요한 질문은 AI가 얼마나 많은 코드를 작성했느냐가 아니다.

AI가 작성한 결과에 대해 나는 무엇을 이해하고 있고, 어떤 근거로 그것이 옳다고 판단했는가?

AI에게 작업을 위임할 수는 있다. 하지만 그 결과를 책임 있게 받아들이는 일까지 무심코 넘기지는 말아야 한다.