ai | coding-agent | decision-making | cognitive-debt | software-engineering

AI에게 어떤 의사결정을 맡길 수 있는가, Evaluability와 Controllability 두 기준

코딩 에이전트에게 일을 맡길수록 팀의 공유 멘탈 모델이 침식되는 인지 부채가 쌓입니다. 주문 취소 예제로 기능 하나에 숨은 의사결정 구조를 드러내고, Evaluability와 Controllability라는 두 기준으로 사람이 쥘 결정과 AI에게 넘길 결정을 가르는 방법을 설명합니다.

Mimul
MimulAugust 10, 2026 · 39 min read · Last Updated:

코딩 에이전트에게 기능 하나를 통째로 맡겼을 때, 돌아온 코드가 테스트를 통과했는데도 어딘가 찜찜했던 경험이 한 번쯤 있을 것이다. 결과를 눈으로 바로 판정할 수 있는 일은 마음 편히 맡기지만, 업무 규칙이 얽힌 코드를 맡길 때는 매번 “어디까지 넘겨도 되는가”를 두고 망설인다. 이 글은 그 망설임을 두 개의 기준으로 정리한다. 하나는 성과물의 내부를 이해하지 않아도 올바르다고 판정할 수 있는가(Evaluability)이고, 다른 하나는 틀렸을 때 피해를 제어할 수 있는가(Controllability)이다.

AI 시대에 인지 부채가 다시 불거지는 이유

개발팀에는 코드에 쌓이는 기술 부채와는 다른 종류의 부채가 있다. 시스템이 바뀌는 속도를 팀의 공유 이해가 따라가지 못해, 시스템을 안전하고 확신 있게 바꾸는 데 필요한 공유 멘탈 모델이 서서히 침식되는 현상이다. 이것을 인지 부채 (cognitive debt)라고 부른다. 기술 부채가 코드 안에 있다면 인지 부채는 사람 안에 있다. 변경할 때 자신이 없어지고, 리뷰 부담이 늘고, 디버깅이 느려지고, 새 팀원이 적응하는 데 오래 걸리는 형태로 드러난다.

성과물의 내부를 끝까지 이해하지 못한 채 쓰는 일은 AI 이전부터 있었다. 외부 라이브러리의 구현을 모두 읽고 쓰는 사람은 없고, 동료가 짠 모듈도 인터페이스만 보고 호출한다. 그렇다면 왜 지금 이 문제가 다시 부각되는가. 예전에는 시간을 들이면 측정할 수 있었던 것, 적어도 측정하고 있다는 체면은 차릴 수 있었던 것이 AI의 출력 속도와 양을 따라가지 못해 측정 불가능한 영역으로 밀려났기 때문이다. 하루에 사람이 읽을 수 있는 코드 양은 그대로인데 생성되는 코드 양은 몇 배로 늘었으니, 읽어서 이해하는 방식의 품질 확인은 산술적으로 무너진다.

왼쪽 언덕에는 컴파일·테스트·린트·CI처럼 기계가 판정하는 항목이, 오른쪽 언덕에는 아키텍처·유지보수성·도메인 의미·진화 가능성처럼 사람이 이해해야 판정할 수 있는 항목이 놓이고, 그 사이에 측정 가능성의 골짜기가 벌어진 모습을 그린 그림
왼쪽 언덕에는 컴파일·테스트·린트·CI처럼 기계가 판정하는 항목이, 오른쪽 언덕에는 아키텍처·유지보수성·도메인 의미·진화 가능성처럼 사람이 이해해야 판정할 수 있는 항목이 놓이고, 그 사이에 측정 가능성의 골짜기가 벌어진 모습을 그린 그림

위 그림처럼 품질 확인 항목은 두 언덕으로 나뉜다. 왼쪽 언덕의 컴파일, 테스트, 린트, CI는 기계가 몇 초 만에 판정하므로 AI가 아무리 빨리 출력해도 따라간다. 오른쪽 언덕의 아키텍처, 유지보수성, 도메인 의미, 앞으로의 진화 가능성은 사람이 내용을 이해해야 판정할 수 있다. 두 언덕 사이의 골짜기가 측정 가능성의 골짜기 이다. 큰 단위의 일을 AI에게 맡기면 그 안에서 수많은 의사결정이 이루어지는데, 그 결정들의 효과와 영향은 대부분 오른쪽 언덕에 속하므로 측정되지 않은 채 코드베이스에 스며든다. 그 결정들은 누구의 머릿속도 거치지 않았으므로, 팀이 공유하는 모델과 실제 시스템은 아무도 모르는 사이에 어긋나기 시작한다. 인지 부채는 바로 이 골짜기에서 쌓인다.

주문 취소 하나에 숨은 의사결정

골짜기의 깊이를 실감하려면 평범한 요청 하나를 들여다보는 편이 빠르다. 기존 EC 시스템에 “사용자가 주문을 취소할 수 있게 해 달라”는 요구가 들어왔다고 하자. 개발자는 코딩 에이전트에게 이렇게 요청한다.

주문 취소를 구현해 줘. 결제가 끝난 주문이면 환불하고, 재고도 되돌려 줘.

에이전트는 다음과 비슷한 코드를 돌려줄 가능성이 높다.

@Transactional
public void cancel(OrderId id) {
    Order order = repository.find(id);

    payment.refund(order.paymentId());
    inventory.restore(order.items());

    order.cancel();
    repository.save(order);
}

열 줄 남짓한 코드이고, 요청한 세 가지(취소, 환불, 재고 복원)가 모두 들어 있다. 테스트도 통과한다. 그런데 이 코드에는 요청에 없던 결정이 여럿 암묵적으로 내려져 있다.

  • 환불을 먼저 하고 재고를 되돌리는 순서로 한다.
  • 외부 결제 시스템의 환불 호출을 DB 트랜잭션과 같은 의미로 다룬다. 즉 롤백할 수 있는 것처럼 취급한다.
  • 이미 출하된 주문도 취소할 수 있다.
  • 환불이 성공한 뒤 DB가 롤백되는 상황은 허용한다.
  • 재고 복원은 반드시 한 번만 일어난다고 가정한다.

다섯 가지는 성질이 서로 다르다. 첫 번째는 구현 순서의 문제이고, 두 번째와 네 번째는 외부 시스템과 트랜잭션 경계에 관한 기술 결정이며, 세 번째는 업무 규칙이고, 다섯 번째는 멱등성에 관한 운영 가정이다. 요청자는 이 중 어느 것도 명시하지 않았고, 에이전트는 어느 것도 물어보지 않았다. 코드 리뷰어가 이 다섯 가지를 모두 짚어 내려면 결제 시스템의 특성과 출하 업무의 규칙을 이미 알고 있어야 한다. 그 지식이 바로 공유 멘탈 모델이고, 그것 없이 코드만 읽어서는 판정할 수 없다.

의사결정은 DAG를 이룬다

그렇다면 이 결정들은 서로 어떤 관계인가. 독립적으로 흩어져 있지 않고 방향이 있는 의존 구조를 이룬다. “취소란 무엇인가”라는 결정이 “어떤 조건에서 취소할 수 있는가”와 “취소 전후로 지켜야 할 업무 불변 조건은 무엇인가”를 정하고, 그 둘이 “장애가 났을 때 취소는 어떤 상태로 남아야 하는가”를 정한다. 장애 시의 의미가 정해져야 트랜잭션 방식과 멱등성 방식을 고를 수 있고, 그것이 정해져야 구현 구조와 구체 코드가 결정된다. 순환이 없는 이 의존 그래프를 DAG(Directed Acyclic Graph, 방향 비순환 그래프)라고 부른다.

D0 취소의 의미에서 시작해 D1 취소 가능 조건과 D2 업무 불변 조건, D3 장애 시의 의미, D4 트랜잭션 방식과 D5 멱등성 방식, D6 구현 구조, D7 구체 코드로 내려오는 의사결정 DAG 위에, D4·D5와 D6 사이를 가로지르는 인간/AI 책임 분리선을 점선으로 그린 그림
D0 취소의 의미에서 시작해 D1 취소 가능 조건과 D2 업무 불변 조건, D3 장애 시의 의미, D4 트랜잭션 방식과 D5 멱등성 방식, D6 구현 구조, D7 구체 코드로 내려오는 의사결정 DAG 위에, D4·D5와 D6 사이를 가로지르는 인간/AI 책임 분리선을 점선으로 그린 그림

이 구조에서 중요한 결정은 많은 결정이 기대고 있는 상위 노드다. 취소의 의미가 바뀌면 그 아래 모든 결정이 다시 내려져야 하지만, 구체 코드가 바뀌어도 위쪽은 흔들리지 않는다. 문제는 이 구조가 코드에는 드러나지 않는다는 데 있다. 앞의 열 줄짜리 코드만 봐서는 D3 장애 시의 의미가 “환불 성공 후 DB 롤백 허용”으로 결정되었다는 사실을 읽어 낼 수 없다.

현재 많은 팀이 긋고 있는 인간과 AI의 책임 분리선은 그림의 점선 근처에 있다. 리프(가장 아래 노드)에서 위로 거슬러 올라가며 “이 결정까지 넘기면 품질 특성을 평가할 수 없게 된다”는 지점이 그 팀이 AI에게 맡길 수 있는 영역의 경계가 된다. 구체 코드와 구현 구조는 테스트가 판정해 주므로 넘기고, 트랜잭션 방식부터는 사람이 쥔다. 다만 이 선의 위치는 고정되어 있지 않다. 테스트 자산이 두텁고 결제 시스템의 특성을 검증 코드로 적어 둔 팀이라면 선을 한 칸 위로 올릴 수 있고, 그렇지 않은 팀은 한 칸 아래로 내려야 한다. 그리고 이 선에는 빠진 질문이 하나 있다. 넘긴 결정이 틀렸을 때 어떻게 되는가다.

위임의 두 조건, Evaluability와 Controllability

어떤 결정을 넘겨도 되는가를 한 문장으로 줄이면 “이해하지 않아도 올바르다고 판정할 수 있는가”이다. 이 문장을 뜯어 보면 두 가지 조건이 나온다.

첫 번째는 성과물의 내부를 이해하지 않아도 외부 기준으로 올바르다고 판정할 수 있는가이다. 컴파일러, 테스트, 타입 검사, 스키마 검증, 확인용 SQL처럼 사람의 이해를 대신해 주는 외부 기준이 있으면 이 조건이 충족된다. 이 성질을 Evaluability (평가 가능성)라고 부른다. 앞 절의 분리선을 결정하던 기준이 바로 이것이다.

두 번째는 판정이 틀렸거나 판정 자체를 건너뛰었을 때, 그 피해를 제어할 수 있는가이다. 되돌릴 수 있는가, 영향 범위를 좁힐 수 있는가, 일부 사용자에게만 먼저 노출할 수 있는가가 여기에 해당한다. 이 성질을 Controllability (제어 가능성)라고 부른다. Evaluability가 사전 판정에 관한 조건이라면 Controllability는 사후 수습에 관한 조건이다.

가로축을 Controllability, 세로축을 Evaluability로 두고 네 칸으로 나눈 그림. 둘 다 높으면 맡길 수 있다, Evaluability만 높으면 맡기기 어렵다, Controllability만 높으면 틀리면 고친다, 둘 다 낮으면 맡길 수 없다로 분류하고 각 칸에 예를 적었다
가로축을 Controllability, 세로축을 Evaluability로 두고 네 칸으로 나눈 그림. 둘 다 높으면 맡길 수 있다, Evaluability만 높으면 맡기기 어렵다, Controllability만 높으면 틀리면 고친다, 둘 다 낮으면 맡길 수 없다로 분류하고 각 칸에 예를 적었다

두 조건을 축으로 놓으면 위 그림처럼 네 칸이 나온다. 오른쪽 위, 둘 다 높은 칸이 마음 놓고 맡길 수 있는 영역이다. 테스트가 판정하고 틀려도 되돌릴 수 있는 리프 결정이 여기에 들어간다. 왼쪽 아래, 둘 다 낮은 칸은 맡길 수 없는 영역이다. 취소의 의미나 업무 불변 조건처럼 “무엇을 올바르다고 할 것인가”를 정하는 상위 결정이 여기에 놓인다. 왜 이 칸인지는 Evaluability의 한계를 다루는 절에서 다시 본다.

흥미로운 쪽은 나머지 두 칸이다. Evaluability가 높아도 Controllability가 낮으면 위임하기 어렵다. 운영 환경의 데이터 마이그레이션 SQL을 작성해서 실행하는 일을 생각해 보자. 실행 결과가 올바른지는 확인용 SQL 한 번이면 쉽게 알 수 있으니 Evaluability는 높다. 그러나 잘못된 DDL이나 데이터 갱신이 실행되는 순간 이미 큰 사고이고, 확인용 SQL은 사고가 난 뒤에야 그 사실을 알려 준다. 판정이 쉽다는 것과 틀려도 괜찮다는 것은 전혀 다른 문제이고, 위임 여부를 가르는 것은 후자다. 반대로 Evaluability가 낮아도 Controllability가 높으면 “틀리면 고친다”는 전략이 성립한다. 올바른지 미리 판정하기 어려운 UI 변경이라도 카나리 뒤에 두고 소수 사용자에게만 노출하면, 실패를 관측한 뒤 수정하는 비용이 사전 판정 비용보다 싸진다.

Controllability를 높이는 장치는 이미 손에 있다

두 축 가운데 Controllability 쪽은 다행히 새로 발명할 것이 없다. 틀린 변경의 피해를 사용자에게 닿지 않게 하는 장치는 소프트웨어 공학이 오랫동안 쌓아 온 자산 그대로다.

목적장치
배포와 릴리스를 분리한다Feature Toggle, Expand and Contract
조금씩 노출한다 (Progressive Exposure)Canary Release, Blue/Green Deployment
잘못을 국소에 가둔다Bulkhead, Circuit Breaker
실행된 뒤에도 되돌린다Recovery, Compensation
잘못된 변경을 중심에 두고 되돌린다, 가둔다, 조금씩 노출한다, 배포와 릴리스를 분리한다는 네 겹의 동심원이 감싸며, 겹이 많을수록 피해가 사용자에게 닿지 않음을 나타낸 그림
잘못된 변경을 중심에 두고 되돌린다, 가둔다, 조금씩 노출한다, 배포와 릴리스를 분리한다는 네 겹의 동심원이 감싸며, 겹이 많을수록 피해가 사용자에게 닿지 않음을 나타낸 그림

네 장치는 그림처럼 겹을 이룬다. 배포는 했지만 토글이 꺼져 있으면 잘못된 코드는 실행조차 되지 않는다. 토글을 켜더라도 카나리 단계면 일부 사용자에게만 닿는다. 그 사용자에게서 장애가 나도 Bulkhead와 Circuit Breaker가 다른 기능으로 번지는 것을 막는다. 거기까지 뚫려 실제로 잘못된 처리가 실행되었더라도 보상 트랜잭션으로 되돌릴 수 있다. 겹이 하나 늘 때마다 “틀려도 되는” 결정의 범위가 한 칸씩 넓어지고, 그만큼 AI에게 넘길 수 있는 영역도 넓어진다.

개인적으로 이 대목이 가장 반가웠다. AI 시대의 위임 문제를 풀려면 뭔가 새로운 AI 전용 도구가 필요할 것 같은 분위기가 있는데, 적어도 Controllability 축은 Feature Toggle과 카나리 릴리스를 제대로 갖추는 평범한 일로 환원된다. 앞의 운영 DB 마이그레이션 예로 돌아가면, 스키마 변경에 한해서는 Expand and Contract로 되돌릴 수 있는 단계로 쪼개고 새 컬럼을 토글 뒤에 두는 것만으로 같은 작업이 왼쪽 위 칸에서 오른쪽 위 칸으로 옮겨 간다. 데이터 갱신까지 넘기려면 갱신 전 스냅숏이나 보상 절차처럼 되돌릴 겹을 하나 더 마련해야 한다. 어느 쪽이든 작업의 성격이 바뀐 것이 아니라 피해를 가두는 겹을 늘렸을 뿐이다.

Evaluability에 비용을 얼마나 쓸 것인가

Evaluability 쪽은 다르다. 외부 기준을 만드는 데는 비용이 들고, 그 비용이 지나치면 AI에게 맡겨서 얻는 속도를 도로 잃는다. 모든 기능에 대해 사람이 이해할 수 있을 만큼 촘촘한 사양과 테스트를 먼저 쓰라고 하면, 그것은 결국 사람이 다 설계하고 AI는 타이핑만 하는 구도로 돌아간다.

비용 문제에 대한 대응은 두 갈래로 나타난다. 하나는 Controllability에 기대는 쪽이다. 틀림은 기본적으로 받아들이고, 실패를 알아차리면 고치면 된다는 Resilience(회복 탄력성)의 태도다. 다른 하나는 Evaluability 자체를 싸게 만드는 쪽이다. 무거운 E2E 평가를 매번 돌리는 대신, 중간 단계를 검증하는 가벼운 행동 평가로 쪼개 로컬에서 몇 초 안에 돌린다. 당분간은 두 갈래 가운데 앞쪽, 즉 완벽한 사전 판정보다 사후 수습에 기대는 흐름이 주류가 될 것으로 보인다. 평가는 싸고 빠른 것부터 갖추고 나머지는 Controllability로 메우는 선택이다.

외부 기준이 사람의 판정을 대신한다는 이 관점은 인지 부채를 다루는 방식도 바꾼다. 인지 부채를 “AI가 만든 코드를 사람이 다 이해하지 못하는 상태”로 정의하면 출력량이 늘수록 부채는 필연적으로 쌓인다. 하지만 Evaluability가 충분히 유지되는 영역이라면 AI가 만든 성과물의 내용을 사람이 이해하지 않아도 된다. 이것이 하네스 엔지니어링 (harness engineering, 에이전트의 출력을 자동으로 판정하고 제약하는 장치를 설계하는 일)의 기초 개념이다. 사람이 쥐어야 할 것은 코드의 내용이 아니라 판정 기준이고, 공유 멘탈 모델이 담아야 할 것도 구현의 세부가 아니라 “무엇이 올바른가”가 된다.

Evaluability에 대한 과신

문제는 Evaluability의 정의 자체에 있다. “성과물의 내부를 이해하지 않아도 외부 기준으로 올바르다고 판정할 수 있다”는 조건은, 그 외부 기준을 누가 어떻게 만드는가라는 관점에서 물음표를 던져 준다. 현장에서 흔히 듣는 세 가지 처방과 그 현실을 나란히 놓으면 이렇다.

처방현실
AI가 틀리지 않도록 사양을 정확히 쓴다처음부터 그렇게 쓸 수 있었다면 애초에 고생하지 않았다
도메인 전문가와 함께 올바른 사양을 쓴다그런 사람이 있다면 데려와 주기 바란다
개발 루프를 돌리며 틀린 것을 고쳐 나가면 올바른 결과에 가까워진다기준이 없는 상태에서 루프를 몇 번 돌려야 성공인지 알 수 없다

세 처방 모두 “무엇이 올바른가”가 어딘가에 이미 존재한다고 가정한다. 그러나 DAG의 상위 노드로 올라갈수록 사정은 반대다. 취소의 의미, 취소 가능 조건, 업무 불변 조건 같은 상위 의사결정은 무엇을 올바르다고 할지를 정하는 일 자체가 산출물이다. 판정 기준이 산출물이므로 그것을 판정할 외부 기준은 정의상 존재하지 않고, 틀렸을 때는 그 아래 모든 결정이 함께 틀어져 피해도 제어되지 않는다. 매트릭스의 왼쪽 아래 칸에 이 결정들을 둔 이유가 이것이고, 따라서 위임할 수 없다. 두 기준으로 위임 범위를 넓혀 가더라도 결국 이 벽에 부딪힌다.

인지 부채의 해법, 공유 멘탈 모델을 평가자로 만든다

이 벽을 넘을 실마리는 인지 부채의 정의로 돌아가면 보인다. 침식되는 것은 공유 멘탈 모델이었다. 그렇다면 상위 의사결정을 사람 머릿속에 두지 말고 적어 두고, 그 적어 둔 것을 하위 의사결정의 평가자(Evaluator)로 쓰자는 방향이 나온다. 공유 멘탈 모델을 이렇게 적어 둔 것을 이 글에서는 모델이라 부른다. 쉽게 말해, 상위 결정을 모델로 적어 두면 그 모델이 하위 결정이 맞는지 틀리는지를 사람 대신 판정해 준다. 위임할 수 없는 상위 결정을 억지로 위임하자는 제안이 아니라, 상위 결정을 그 아래 결정들의 Evaluability를 만들어 내는 재료로 쓰자는 제안이다. 미리 말해 두면 이 방향은 아직 검증된 방법이라기보다 가설에 가깝다.

왼쪽의 사람은 무엇이 올바른지와 모델 바깥의 오해를, AI는 빠른 초안과 검증을 실행 가능한 공유 멘탈 모델에 보태고, 업무 데이터와 행위, 컴파일 시점에 검증되는 입출력 예시로 이루어진 그 모델이 오른쪽의 트랜잭션 방식·멱등성 방식·구체 코드 같은 하위 결정을 평가하며, 판정이 어긋나거나 빈칸이 남으면 모델의 해상도를 올리는 되먹임을 점선으로 그린 그림
왼쪽의 사람은 무엇이 올바른지와 모델 바깥의 오해를, AI는 빠른 초안과 검증을 실행 가능한 공유 멘탈 모델에 보태고, 업무 데이터와 행위, 컴파일 시점에 검증되는 입출력 예시로 이루어진 그 모델이 오른쪽의 트랜잭션 방식·멱등성 방식·구체 코드 같은 하위 결정을 평가하며, 판정이 어긋나거나 빈칸이 남으면 모델의 해상도를 올리는 되먹임을 점선으로 그린 그림

그렇다면 모델은 무엇으로 이루어지는가. 두 부분이다. 하나는 업무에서 다루는 데이터와 행위를 적은 부분이고, 다른 하나는 그 행위를 실제로 실행했을 때 기대하는 구체적인 입출력 예시다. 주문 취소라면 “주문에는 다섯 가지 상태가 있고 취소라는 행위가 있다”가 앞부분이고, “결제 완료 주문을 취소하면 취소 완료 주문이 된다”가 뒷부분이다. 여기에 조건이 하나 붙는다. 모델은 문서가 아니라 실행되는 것이어야 한다. 문서로 적힌 모델은 코드가 그것을 어기는지 아무것도 알려 주지 않으므로, 컴파일되고 예시가 기계적으로 검증되는 모델만이 평가자 노릇을 할 수 있다.

올바르다고 말할 수 있는 사양을 처음부터 쓸 수 있는 사람은 없으므로, 모델과 예시는 번갈아 고쳐 가며 만든다. 이 과정을 돕는 도구가 있다고 가정하자. 모델을 컴파일하고, 예시를 컴파일 시점에 실행해 어긋나면 빌드를 멈추며, 모델이 표현한 경우 가운데 예시가 없는 칸을 찾아 빈 뼈대를 만들어 주는 도구다. 주문 취소 예제로 그 흐름을 따라가면 이렇다.

  1. 주문 상태를 미결제, 결제 완료, 출하 준비 중, 출하 완료, 취소 완료의 다섯 가지로 두고, 취소 행위는 환불과 재고 복원에 의존한다고 대충 적는다. 예시는 결제 완료 주문을 취소하는 한 줄뿐이다.
  2. 도구가 다섯 상태 가운데 예시가 없는 네 상태를 찾아 예시의 뼈대를 만들어 준다. 기대 결과 칸은 비어 있다.
  3. 빈칸을 채우려다 보면 “출하 완료된 주문은 취소할 수 없다”, “이미 취소된 주문을 다시 취소하면 어떻게 되는가” 같은 질문에 답해야 한다. 앞의 코드가 암묵적으로 내렸던 세 번째 결정(출하된 주문도 취소할 수 있다)이 여기서 명시적인 질문으로 바뀐다.
  4. 질문에 답하다 보면 취소 행위의 결과가 단순한 주문 하나가 아니라 취소된 주문, 출하 준비에 들어감, 이미 출하됨, 이미 취소됨 같은 여러 경우로 나뉜다는 것을 알게 된다. 사양의 해상도가 올라갔으니 모델을 고친다.
  5. 모델을 고치면 기존 예시가 컴파일되지 않으므로 예시를 다시 손본다. 이 과정을 반복한다.

이 흐름에서 누가 무엇을 하는지 정리하면 역할이 셋으로 나뉜다. 도구는 빠뜨린 칸을 찾는다. 사람은 빠뜨린 상태를 찾는다. 도구가 찾아 주는 빈칸은 모델이 이미 표현한 다섯 상태 가운데 예시가 없는 칸일 뿐이고, 모델이 아예 모르는 상태(예를 들어 부분 출하)나 잘못 이해한 업무 규칙은 빈칸으로 드러나지 않으므로 여전히 사람이 도메인 전문가와 이야기해서 찾아야 한다. AI의 몫은 초안이다. 기존 코드와 문서에서 상태와 행위의 후보를 뽑아 모델의 첫 판을 쓰고 예시의 입력 쪽을 채우는 일은 AI가 빠르다. 그러나 예시의 기대 결과만은 사람이 확정해야 한다. AI가 기대 결과까지 채우면 AI가 AI를 판정하는 꼴이 되어 모델은 외부 기준이기를 멈춘다.

그래서 앞 절에서 던진 “기준 없이 몇 번 돌려야 성공인가”라는 질문에 이 방식이 주는 답은 절반이다. 모델이 표현한 범위 안에서는 “모든 칸이 채워지고 모두 통과하는 순간”이라는 기계적인 종료 조건이 생긴다. 모델 바깥의 오해는 종료 조건이 없고, 그 부분은 끝까지 사람의 책임으로 남는다. 다만 그 절반이 작지 않다. 모델이 표현한 범위 안에서 모든 예시를 다 쓴 순간, 그 범위에 한해 사양을 만족하는 동작하는 모델이 손에 있고, 그 모델은 그 자체가 외부 기준이 된다. 남은 바깥쪽(컨트롤러, DB 접근, 외부 결제 연동)은 “이 모델을 만족하도록 만들어 달라”고 코딩 에이전트에게 넘길 수 있다. 정형화된 연결 코드는 에이전트가 잘 다루는 영역이기도 하다. 도구가 무엇이든 핵심은 같다. 사람이 쥐는 산출물을 코드가 아니라 모델과 예시로 옮긴다.

발상 자체는 새롭지 않다. 요구 사항을 구체적인 예시로 적고 그 예시를 자동화된 검증으로 돌리는 Specification by Example(예시에 의한 명세)이 있고, 프로그래밍의 본질은 코드가 아니라 개발자 머릿속의 이론을 세우는 일이라는 Naur의 Programming as Theory Building이 있다. 인지 부채라는 용어 자체가 이 Naur의 논의 위에 서 있다.

도메인 주도 설계(DDD)와는 더 직접 겹친다. 이해 격차가 사람과 사람 사이에서 사람과 에이전트 사이로 옮겨 왔을 뿐, 처방은 같다. DDD는 애초에 도메인 전문가와 개발자 사이의 이해 격차를 유비쿼터스 언어와 도메인 모델로 메우려는 방법론이었고, 업무 규칙을 담은 도메인 계층을 컨트롤러나 DB 접근 같은 인프라에서 격리하라고 가르쳤다. 이 글에서 사람이 쥐는 영역과 AI에게 넘기는 영역의 경계는 그 도메인 계층의 경계와 겹친다. 다른 점은 하나다. DDD의 도메인 모델은 보통 테스트와 별개로 존재하지만, 여기서 말하는 모델은 예시가 모델과 함께 컴파일되어 모델과 테스트가 하나다. 그 차이가 Evaluability를 만든다. 도메인 모델과 표현의 관계는 소프트웨어 설계에서 도메인 모델과 표현에서, 상태를 값으로 다루는 방식은 값으로 다루는 객체, Value Object에서 따로 다루었다.

인지 부채의 관점에서 이 전환이 갖는 뜻은 조건부다. 공유 멘탈 모델이 사람 머릿속에만 있을 때는 코드가 늘어나는 속도에 비례해 침식된다. 그것을 실행 가능한 모델과 예시로 외부화하면, 코드가 모델을 어기는 순간을 컴파일러가 잡아 주므로 사람이 이해해야 할 범위가 코드 전체에서 모델로 좁아진다. 그만큼 인지 부채가 쌓이는 속도도 느려질 수 있다. 다만 두 가지 조건이 붙는다. 팀이 실제로 모델을 읽고 고치는 장소로 써야 하고, 모델이 현실의 업무와 어긋난 채 방치되지 않아야 한다. 아무도 읽지 않는 모델은 또 하나의 낡은 문서이고, 현실과 어긋난 모델은 틀린 기준으로 코드를 통과시키는 더 나쁜 부채가 된다.

요약

  • AI 시대의 인지 부채는 성과물을 이해하지 못해서가 아니라, AI의 출력 속도가 사람의 측정 속도를 넘어서면서 측정 가능성의 골짜기에 결정들이 쌓이기 때문에 커진다.
  • 기능 요청 하나에는 성질이 다른 여러 의사결정이 숨어 있고, 그 결정들은 DAG를 이룬다. 많은 결정이 기대는 상위 노드일수록 중요하지만 코드에는 드러나지 않는다.
  • 위임할 수 있는 결정은 Evaluability(내부를 몰라도 외부 기준으로 판정할 수 있는가)와 Controllability(틀렸을 때 피해를 제어할 수 있는가)가 모두 높은 결정이다. 판정이 쉽다고 위임해도 되지는 않으며, 운영 DB 마이그레이션이 그 반례다.
  • Controllability는 Feature Toggle, 카나리, Bulkhead, 보상 트랜잭션 같은 기존 자산으로 높일 수 있다. Evaluability는 비용이 들어, 평가를 싸게 만들거나 Controllability로 보완하는 두 대응이 나오며 당분간은 후자가 주류가 될 것으로 보인다.
  • 무엇이 올바른지를 정하는 상위 의사결정은 위임할 수 없다. 대신 그것을 실행 가능한 모델과 예시로 외부화해 하위 결정의 평가자로 쓰면, 모델이 표현한 범위 안에서는 기계적인 판정 기준이 생기고 공유 멘탈 모델의 침식도 늦출 수 있다. 모델 바깥의 오해를 찾는 일은 여전히 사람의 몫이다.

솔직히 말하면 나는 아직 매트릭스의 오른쪽 아래 칸, 즉 “틀리면 고친다”는 전략에 완전히 마음을 놓지 못한다. 카나리 뒤에 두면 안전하다는 말은 관측 체계가 실패를 제때 잡아낸다는 전제 위에서만 성립하고, 업무 규칙의 오류는 장애처럼 요란하게 드러나지 않는 경우가 많기 때문이다. 그래서 내 경우 코딩 에이전트에게 일을 맡기기 전에 두 질문을 먼저 적어 본다. 이 결과를 내가 읽지 않고도 판정할 외부 기준이 있는가. 그 기준이 틀렸을 때 되돌릴 겹이 몇 개나 있는가. 두 질문에 모두 답할 수 있는 결정만 넘기고, 답할 수 없는 결정은 모델로 적는 데 시간을 쓴다. 느려 보이지만, 측정 가능성의 골짜기에 떨어진 결정을 나중에 건져 올리는 비용에 비하면 싸다.

참조 사이트


Mimul

Written byMimul
Mimul is a programmer, technologist, exercise enthusiast and more.
Connect

Related ArticlesView All

Related StoriesView All