
소프트웨어 개발은 차원 변환이다 —— 책임을 추적하여 AI 생성의 이상을 포착할 수 있는가
요약
소프트웨어 개발을 추상적인 사양(SPEC)에서 구체적인 소스 코드(SRC)로 자유도를 축약해 나가는 '차원 변환' 과정으로 정의합니다. 이 과정에서 각 단계별로 계승되고 분할되는 '책임'을 추적함으로써, AI 생성 과정에서 발생할 수 있는 논리적 이상을 포착할 수 있는 방법론을 제시합니다.
핵심 포인트
- 개발은 SPEC에서 SRC로 내려가며 자유도를 줄이는 차원 변환 과정임
- 구현 단계는 기존의 구조적 덩어리(패턴, 라이브러리 등)를 대입하며 진행됨
- 단계별로 계승되고 분할되는 '책임'은 추적 가능한 요소임
- 책임 추적을 통해 AI 생성 결과물의 논리적 오류를 포착할 수 있음
이 기사가 향하는 하나의 질문
먼저, 결론이 아니라 이 기사가 마지막에 던지고 싶은 질문을 말해두겠다.
AI는 확률적으로 생성하는 기계다. 따라서 문서에서 문서로 내려갈 때, 의미를 유지한 채로 남아있으리라는 보장이 없다.
——그렇다면, 생성할 때마다 책임을 추적(trace)한다면, 문서 간에 책임이 이상하게 변화한 지점을 포착할 수 있지 않을까?
이 질문이 성립하기 위해서는, 그전에 두 가지를 말해둘 필요가 있다.
하나는, 소프트웨어 개발이란 무엇인가.
다른 하나는, 그 변환을 통해 무엇을 쫓을 수 있는가.
이 기사에서는 전자를 차원 변환 (Dimension Transformation) 으로 파악하고, 후자를 책임 (Responsibility) 으로 파악한다. 아래는 이 질문에 도달하기 위한 준비 과정이다.
소프트웨어 개발은 차원 변환이다
소프트웨어 개발을 다음과 같이 재정의하고 싶다.
개발이란 SPEC이라는 문서를 SRC라는 문서로 변환해 나가는 작업이다.
사양서도, 설계도도, 소스 코드(Source Code)도 모두 '문서'다. 개발이란 가장 추상적인 문서(SPEC)에서 가장 구체적인 문서(SRC)로, 여러 개의 중간 문서를 경유하며 내려가는 과정이다.
이 관계를 도식화하면 다음과 같다.
여기서 중요한 점은, 아래로 내려갈수록 정보량은 늘어나는 반면, 선택 가능한 해(solution)의 공간은 좁아진다는 점이다.
나는 이 '내려가는 과정'을 차원 변환 (Dimension Transformation) 이라고 부르고 싶다. SPEC과 SRC의 차이는 상세함의 차이가 아니라, 자유도의 차이이기 때문이다.
SPEC은 무엇을 만들지는 말하지만, 어떻게 만들지는 말하지 않는다. 따라서 하나의 SPEC을 만족하는 SRC는 무수히 많다. 자유도가 높고, 해의 공간이 넓다.
반면, SRC는 적어도 그 구현으로서는 선택을 거의 고정하고 있다. SPEC이 허용했던 많은 해 후보 중, "이 구조로 동작시킨다"라고 하나를 선택해낸 상태다.
개발이란 이 넓은 해의 공간을 하나의 구현으로 축약(reduction)해 나가는 작업이다. 하강의 각 단계는 그때마다 자유도를 깎아내며 해의 공간을 좁혀간다. SRC는 SPEC보다 훨씬 많은 문자를 갖지만, 선택할 수 있는 해는 훨씬 적다.
상세함이 늘어나는 대신 자유를 잃는다. 차원 변환이란 바로 이 자유도의 축약이다.
축약은 '구조의 덩어리'를 대입하며 진행된다
그렇다면 그 축약은 어떻게 진행되는가.
설계자는 무(無)에서 코드를 짜내는 것이 아니다. 실제로 일어나고 있는 것은 기존에 알고 있는 구조의 덩어리를 대입하는 것이다.
디자인 패턴(Design Pattern)에서 가져온 구조. 라이브러리(Library)가 제공하는 구조. 과거에 작성했던, 동작하는 코드를 복사해온 구조. 그리고 출처는 스스로도 말할 수 없지만 손이 기억하고 있는 구조.
이러한 덩어리들은 모두 '어떤 구조'와 '그것이 맡아야 할 역할'을 세트로 가지고 있다. 설계자는 자신이 가진 구조의 덩어리 중에서 맞는 것을 골라 대입한다. 대입하는 순간, 그 단계의 자유도가 단번에 줄어든다. 덩어리가 해의 형태를 결정해주기 때문이다.
하강이란 이러한 이질적인 덩어리들을 차례차례 대입하여 연결해 나가는 과정이다. 추상 계층에서는 큰 덩어리를 대입하고, 내려갈수록 작은 덩어리를 대입한다. 덩어리가 덩어리를 포함하고, 연결되며, 구체적인 방향으로 조립되어 올라간다.
변환은 책임의 변화를 동반하며, 또한 추적 가능하다
덩어리를 대입하며 내려갈 때, 무엇이 단계에서 단계로 계승되는가.
계승되는 것은 책임 (Responsibility) 이다.
어느 단계에서 "이 부분은 입력을 검증하는 책임을 진다"라고 결정된다. 다음 단계로 내려가도 그 책임은 사라지지 않는다. 하지만 그대로 있지도 않다. 대개 책임은 분할 (Partitioning) 된다.
예를 들어, "입력을 검증한다"라는 책임은 "형식을 검증한다", "값의 범위를 검증한다", "중복을 검증한다"로 나뉜다. 반대로 여러 책임이 하나의 구현 요소로 묶이기도 (Bundling) 한다.
도식화하면 다음과 같은 관계가 된다.
이 도식에서 보고 싶은 것은 책임이 동일한 형태로 남는 것이 아니다. 형태를 바꾸더라도 그 유래를 추적할 수 있다는 점이다.
즉, 하강을 통해 책임은 분할되고, 묶이고, 형태를 바꾼다. 하지만——이것이 핵심이다——변하더라도 추적할 수 있다.
"형식을 검증한다"라는 자식 책임은 "입력을 검증한다"라는 부모로부터 나뉘어 태어났다. 이 부모-자식 관계는 추적 가능하다. 하류의 임의의 책임으로부터 그것이 어느 상류의 책임에서 유래했는지 거슬러 올라갈 수 있다. 반대로 상류에서 하류의 어디로 전개되었는지도 추적할 수 있다.
책임은 변환할 때마다 모습을 바꾼다. 하지만 계보는 끊기지 않는다.
왜 추적해야 할 대상을 '책임'에 두는가?
물론, 추적할 수 있는 것이 책임(Responsibility)뿐만은 아니다. 데이터, 상태, 제약 조건, 인터페이스, 품질 속성(Quality Attribute) 또한 다른 관점에서는 추적할 수 있다. 하지만 SPEC(명세)에서 SRC(소스 코드)까지를 가로질러 추적한다면, 책임은 가장 굵은 척추가 된다.
구현은 하강 과정에서 통째로 교체될 수 있다. 알고리즘이 바뀌고, 클래스가 래퍼(Wrapper)로 감싸지며, 내부 내용이 교체된다. 하지만 그 시점에도 수행해야 할 역할은 비교적 유지된다.
구현 구조가 바뀌더라도 "무엇을 수행해야 하는가"는 그렇게 쉽게 바뀌지 않는다. 그렇기에 책임이 변환을 관통하며 추적되는 가장 굵은 선이 된다.
이것은 새로운 주장이 아니다
여기까지는 나의 단순한 아이디어만이 아니다. 각각 확립된 연구의 계보 위에 놓여 있다.
"차원 변환 = 자유도의 축약"은 Niklaus Wirth의 **단계적 상세화 (Stepwise Refinement, 1971)**와 정제 계산법 (Refinement Calculus) (Back, Morgan, Dijkstra)의 흐름을 따른다. 후자는 상세화를 "구체 프로그램의 동작 집합이 추상 프로그램의 동작 집합에 포함되는 것"으로 정의한다.
동작의 집합이 좁아진다. 이것이 내가 말하는 자유도 축약의 정확한 형태다.
또한, "개발은 문서 간의 변환이다"라는 출발점은 모델 주도 공학 (MDE / MDA) 의 세계관 (CIM → PIM → PSM → 코드)과도 유사하다.
"구조의 덩어리를 맞추는 것"은 디자인 패턴 (GoF, 1994)과 그 원류인 Alexander의 패턴 랭귀지 (Pattern Language)를 따른다.
"책임의 분할·할당·추적"에는 거의 정면으로 대응하는 대상이 있다. 목표 지향 요구 공학(Goal-oriented Requirements Engineering)의 KAOS (van Lamsweerde)다. KAOS는 목표(Goal)를 AND/OR 분해로 상세화하고, 책임 할당 링크를 통해 목표를 담당자에게 할당한다. 전용 "책임 모델"을 가지며, 그 원리는 "단일 담당자에게 할당될 수 있을 때까지 목표를 상세화하는 것"에 있다.
이는 내가 말하는 "책임이 분할되며 내려가고, 최하류에서 담당자가 결정된다"는 관점과 상당히 유사하다. 추적 측면은 요구사항 추적성 (Requirements Traceability) 이라는 분야가 뒷받침한다.
내가 추가하고 있는 것은 새로운 부품이 아니다. 조합하는 방식이다.
Refinement calculus는 변환을 형식화하지만, 추적할 불변량(Invariant)으로서 책임을 중심에 두지는 않는다. KAOS는 책임 할당을 다루지만, 주 전장은 요구 공학이며, 로버스트니스 다이어그램(Robustness Diagram), 상세 설계, 클래스, SRC까지를 하나의 구현 라인으로 끝까지 추적하는 것을 주 목적으로 하지 않는다.
이 두 가지를 코드에 이르는 하강의 전 과정으로 묶는다. 그리고 추적하는 척추는 책임이라고 명명한다.
그것이 이 관점의 위치이다.
의미의 거리는 "다른가"까지만 말할 수 있다
여기서 지금까지 내가 해온 측정 방식에 대해 언급해두고 싶다.
문서 간의 의미 연결이 얼마나 유지되고 있는가. 이를 나는 ONNX에 실린 임베딩 모델을 통해 의미의 거리 (Semantic Distance) 로 수치화해 왔다.
이전 단계의 문서와 다음 단계의 문서를 각각 의미 벡터로 만들어 그 거리를 측정한다. 거리가 가까우면 의미가 잘 연결되어 있다고 보고, 멀면 어딘가에서 의미가 떨어졌다고 판단해 왔다.
이 방법은 저렴하다. 책임이라는 구조를 해석할 필요 없이 문서를 임베딩하여 거리만 측정하면 된다. 어떤 문서에도 즉시 자동으로 적용할 수 있다.
하지만 한계가 있다.
의미의 거리가 답하는 것은 "무언가 다른가"까지다.
거리가 멀다고 나와도 무엇이 다른지는 말해주지 않는다. 사람이 두 문서를 대조하며 처음부터 다시 확인해야 한다. 그리고 그 확인—어디가, 왜 다른가—이야말로 가장 시간이 많이 걸리고 가장 놓치기 쉬운 작업이다.
의미의 거리는 경보를 울린다. 하지만 경보 이후의 수색은 통째로 사람에게 떠넘긴다.
왜 거기서 멈추는가?
의미의 거리는 방향성을 갖지 않는 하나의 스칼라 (Scalar) 이기 때문이다. 이전 단계와 다음 단계 사이의 무방향적 격차. 방향이 없기에 "분할했다", "떨어졌다", "늘어났다"와 같은 변화의 서사를 가질 수 없다. "멀다"라는 정지된 한 점만을 내놓을 수 있을 뿐이다.
책임 추적은 "어떻게 되었는가"까지 말할 수 있는가
여기서 책임 추적은 의미의 거리와는 측정하는 대상이 완전히 다르다.
의미의 거리가 묻는 것은 "다른가"이다. 책임 추적이 묻는 것은 "어떻게 되었는가"이다. 이 둘은 비교할 수 없다. 답의 종류가 다르기 때문이다.
의미의 거리는 차분의 존재를 알린다. 책임 추적은 차분의 종류를 명명한다.
책무 트레이스 (Responsibility Trace)는, 이전 단계의 책무가 다음 단계의 어떤 책무로 분할되고, 묶이고, 혹은 누락되거나, 혹은 늘어났는지——그 계보를, 방향성을 가지고 추적한다.
방향성이 있기에, 변화의 서사를 그려낼 수 있다.
"무언가 다르다"가 아니다.
"이 책무가 둘로 나뉘었다".
"이 책무가 어디에도 전개되지 않고 누락되었다".
"이 책무는 그 어떤 상류 단계로도 거슬러 올라갈 수 없는, 새로 늘어난 것이다".
그렇게, 무슨 일이 일어났는지를 명명할 수 있다.
의미의 거리가 탐색을 인간의 몫으로 남겨두는 반면, 책무 트레이스는 탐색을 트레이스(Trace)의 방향성 그 자체에 포함시키고 있다.
——이 차이가 AI의 하강 (Descent) 과정에서 힘을 발휘할 것이다.
AI 생성에서는 책무의 계보가 끊어지기 쉽다
이제, 하강의 많은 부분을 AI에게 맡길 수 있게 되었다. SPEC (사양)을 주면, AI가 SRC (소스 코드)까지 내려준다.
하지만, AI는 확률적으로 생성하는 기계다. 다음 토큰을 분포에서 선택한다. 그리고 확률적인 생성기는 공백을 마주하면, 침묵하기보다 그럴듯한 무언가로 채우는 것을 선택하기 쉽다.
따라서 AI의 하강에서는, 문서에서 문서로 의미가 전달될 때 그것이 유지된다는 보장이 없다. SPEC에 없던 책무가 그럴싸하게 추가될 수도 있다. SPEC에 있던 책무가 조용히 누락될 수도 있다. 테스트는 통과하더라도 말이다.
문서 간에 의미를 유지한 채 내려가는 것은 어렵다.
이는 AI에 국한된 이야기가 아니다. 인간의 하강에서도 일어난다. 하지만 AI는 확률적으로 생성하는 만큼 더 일어나기 쉽고, 게다가 그럴듯하게 꾸며지는 만큼 알아차리기 어렵다.
그렇다면, 하고 생각한다.
책무가 변환을 관통하여 추적될 수 있다면——생성될 때마다 책무를 트레이스하면 된다.
AI가 내려놓은 SRC의 책무 그래프를 그리고, 그것을 SPEC의 책무 그래프와 대조한다. SPEC의 그 어떤 책무로도 거슬러 올라갈 수 없는 책무가 SRC에 나타나지 않았는가. 즉, 추가된 책무는 없는가. SPEC에 있던 책무가 SRC의 어디에도 전개되지 않은 것은 아닌가. 즉, 누락된 책무는 없는가.
예를 들어, SPEC에는 "사용자는 이메일 주소로 등록할 수 있다"라고만 되어 있는데, SRC 측에 "등록 시 추천 코드를 검증한다"라는 책무가 나타났다면, 그것은 상류에서 유래하지 않은, 늘어난 책무일 수 있다.
반대로, SPEC에는 "중복된 이메일 주소로는 등록할 수 없다"라고 되어 있는데, SRC 측에 중복을 확인하는 책무가 어디에도 전개되어 있지 않다면, 그것은 누락된 책무일 수 있다.
책무의 계보를 대조하면, 이러한 단절이 지점으로서 드러난다.
그렇게, 문서 간에 책무가 이상하게 변화한 지점을 포착할 수 있는 것이 아닐까.
테스트가 "동작하는가"를 본다면, 이것은 "SPEC에 충실하게 내려왔는가"를 책무 계보의 연속성으로서 본다. 만약 그것이 가능하다면——AI에게 하강을 맡길수록, 더욱 효과적일 것이다.
인간의 관여는 책무 그래프 전체를 확인하는 것이 아니라, 트레이스가 "여기서 책무의 계보가 끊겨 있다"라고 지적한 요점(Key point)에만 집중할 수 있다.
다만, 이것은 아직 질문이다
다만, 두 가지 솔직하게 말해두겠다.
첫째. 책무 트레이스가 "어떻게 되었는지"까지 말할 수 있는 것은, 책무를 동일시(Identify)할 수 있을 때뿐이다.
어디에 어떤 책무가 있는지를 읽어낸다. 이 단계가 사실 가장 어렵다. 그 자동화 자체도 아직 해결되지 않은 과제이다.
둘째. 책무의 계보는 연결되어 있지만, 표현이나 어휘가 크게 변한 것과 같은 종류의 어긋남은 책무 트레이스에 잘 보이지 않는다. 그것은 여전히 의미의 거리의 영역이다.
즉, 의미의 거리와 책무 트레이스는 우열 관계가 아니다. 보고 있는 층위가 다르다.
거리가 "다른가"를 저렴하고 넓게 알려준다. 트레이스가 "어떻게 되었는가"를, 동일시하는 수고와 맞바꾸어 깊게 파헤친다.
전자가 경보라면, 후자는 진단이다. 대체하는 것이 아니라, 겹쳐질 수 있다.
이것은 아직 질문이다. 책무가 정말로 어디까지 정확하게 추적될 수 있는가. 추적하더라도 이상과 정상를 구분할 수 있는가. 그것을 실제로 측정하는 도구를 만들 수 있는가. 만들어서 무엇을 볼 수 있는가.
모두 아직 알 수 없다.
하지만, 질문의 형태는 갖추어졌다.
소프트웨어 개발을 책무를 추적할 수 있는 차원 변환으로 본다. 그렇게 보았을 때, AI 생성의 이상은 책무 계보의 단절로서 포착될 수 있을지도 모른다.
보지 않으면 알 수 없다. 보더라도 알 수 없을지도 모른다.
그럼에도 불구하고, 볼 가치가 있는 형태가 되어가고 있다는 느낌이 든다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기