
코드로 구현된 EA: 판단(Judgment) 대 증명(Proof)
요약
AI가 아키텍처의 일관성을 검토할 때 발생하는 추측성 답변의 한계를 지적하며, 이를 해결하기 위한 '코드로 구현된 엔터프라이즈 아키텍처(EAaC)' 개념을 제안합니다. 결정론적인 부분은 코드로 증명하고, AI는 판단 영역에만 집중하도록 분리하는 설계 원칙을 다룹니다.
핵심 포인트
- AI의 아키텍처 검토는 검증 불가능한 산문 형태의 추측에 불과함
- EAaC: 결정론적 부분은 증명하고 AI는 판단만 하는 구조
- 아키텍처를 문서가 아닌 시스템이 읽는 데이터로 취급해야 함
- 검증 불가능성, 벤더 종속성, 근거 없는 AI 보조 문제 해결
코드로 구현된 EA: 판단(Judgment) 대 증명(Proof)
당신의 AI는 당신의 아키텍처가 일관적이라고 기쁘게 말해줄 것입니다. 하지만 그것은 추측입니다.
능력 있는 모델에게 시스템 설계를 검토해 달라고 요청하면, 모델은 유창하고 자신감 넘치는 산문으로 답변합니다. 경계가 깔끔해 보이고, 의존성이 합리적이며, 모든 것이 잘 맞물려 있다는 식입니다. 마치 판결문처럼 읽힙니다. 하지만 그것은 텍스트에서 패턴을 매칭하여 얻은 인상일 뿐이며, 모델이 설명하는 대상이 실제로 결합되어 있는지 확인하는 근거는 밑바탕에 전혀 없습니다. 모델이 당신의 아키텍처가 견고하다고 말할 때, 그 문장의 단 한 단어도 검증된 것이 아닙니다.
저는 오랫동안 일반적인 방식으로 엔터프라이즈 아키텍처 (Enterprise Architecture) 업무를 수행해 왔으며, 모델이 등장하기 훨씬 전부터 동일한 격차가 존재했습니다. 아키텍처는 슬라이드 덱과 위키 페이지에 존재했습니다. "아키텍처가 일관적이다"라는 문장은 누군가가 작성한 문장일 뿐, 누구도 확인할 수 있는 사실이 아니었습니다. AI가 이 문제를 만든 것은 아닙니다. AI는 단지 그 문제를 더 빠르게 생성하게 만들었고, 추측에 더 설득력 있는 목소리를 부여했을 뿐입니다.
그래서 저는 나머지 절반을 구축했습니다. 이를 EAaC — 코드로 구현된 엔터프라이즈 아키텍처 (Enterprise Architecture as Code) — 라고 부르며, 전체 아이디어는 한 줄로 요약됩니다: 결정론적인 (Deterministic) 부분은 증명하고, AI 부분은 판단하며, 결코 그 반대는 일어나지 않는다.
산문 형태의 아키텍처가 실패하는 세 가지 방식
대부분의 아키텍처가 어디에 존재하는지 생각해 보십시오. 그것을 이해하는 시스템 안이 아니라, 그것을 설명하는 문서 안에 존재합니다. 이는 세 가지 실패를 야기하며, 이들은 서로 복합적으로 작용합니다.
- 검증 불가능한 산문 (Unvalidatable prose). "아키텍처가 일관적이다"라는 말은 아무도 확인할 수 없는 주장입니다. 누를 수 있는 버튼도, 종료 코드(exit code)도, 실패를 알리는 테스트도 없습니다. 누군가 그렇지 않다는 것을 알아차릴 때까지는 참인 상태로 남습니다.
- 단일적이고 종속(lock-in)되기 쉬운 도구 (Monolithic, lock-in-prone tooling). 엄격함을 추구하려는 순간, 특정 벤더의 모델러가 당신의 모델을 소유하게 됩니다. 그리고 그 모델은 해당 벤더의 내보내기(export) 버튼이 허용하는 범위 내에서만 이식(portable) 가능하고, 차이점 비교(diffable) 및 검토(reviewable)가 가능해집니다. 개방적이고 확인 가능해야 할 것들이 그 버튼 뒤에 갇혀 있게 됩니다.
- 근거 없는 AI 보조 (Ungrounded AI assistance). 여기에 모델을 추가해 봅시다. 모델은 화려한 문장가이자 자신감 넘치는 검토자이지만, 방금 자신이 승인한 내용이 일관성이 있는지 알 방법이 없습니다. 모델은 산문(prose)으로 추측하며, 그 산문이 충분히 훌륭하기 때문에 당신은 그것을 믿게 됩니다.
이들이 공유하는 형태를 주목하십시오. 확인 가능해야(checkable) 할 무언가가 _서사(narrative)_로 남겨져 있습니다. 이 한 가지를 해결하면 세 가지 문제 모두가 동시에 완화됩니다.
분리 (The split)
EAaC는 한 가지 움직임을 취합니다. 아키텍처의 구성 요소 중 _증명 가능한 정확성(provably correct)_이 필요한 부분과 _판단(judgment)_이 필요한 부분을 분리합니다. 정확성이 필요한 부분에는 어떤 호스트나 벤더도 소유하지 않는 하나의 안식처를 제공합니다. 그리고 아키텍처 지식의 본체 — 방법론, 타입, 규칙 — 를 하드코딩된 로직이 아닌, **시스템이 읽는 데이터(data the system reads)**로 취급합니다.
구체적으로, 이는 명확한 경계선을 가진 두 가지 요소로 나뉩니다:
- 단일한 정답을 가진 모든 작업(검증, 스캐폴딩, 그래프 생성, 보고, 승격, 마이그레이션)을 소유하는 작은 결정론적 코어 (deterministic core) (
ea, 순수하게 테스트된 Python): 동일한 입력에 대해 바이트 단위로 일치하는 출력을 내놓습니다. 실행 시간(wall-clock), 무작위성(randomness), 네트워크, 모델이 개입하지 않습니다. - AI가 상주하는 어댑터 표면 (Adapter surfaces) — 현재는 Claude Code 플러그인과 Google Antigravity 플러그인 — : 이들은 당신의 조직에 맞게 방법론을 조정하고, 산출물(artifacts) 작성을 도우며, 조언을 제공합니다. 이들은 _제안(propose)_합니다. 코어는 _결정하고 작성(decides and writes)_합니다.
그들 사이의 유일한 통합 경계는 CLI 계약(contract)입니다: 표준 출력(stdout)으로 나오는 JSON과 종료 코드(exit codes)입니다. 그 선 위의 모든 것은 판단(judgment)입니다. 그 선 아래의 모든 것은 결정론(determinism)입니다. 에이전트(agent)는 코어(core)를 통과하여 추측을 몰래 전달할 수 없습니다. 왜냐하면 당신의 저장소(repository)를 변경할 수 있는 유일한 방법은 코어에 제안(proposal)을 전달하고, 코어가 이를 검사하고 적용하도록 하는 것이기 때문입니다.
증명(Proof)은 종료 코드입니다
이 부분은 실제로 실행해 보기 전까지는 마케팅처럼 들릴 수 있으니, 직접 실행해 보십시오.
여기 실제 아키텍처인 결제 시스템(payments system)이 있습니다. 하나의 명령어가 코어에 일관성(consistent)이 있는지 묻습니다:
$ ea validate --all
{ "status": "ok", "diagnostics": [] }
exit: 0
종료 코드 0입니다. "괜찮아 보임"이 아니라, _검증됨(checks out)_입니다. 모든 참조(reference)가 해결되었고, 해당 메서드가 가진 모든 규칙이 충족되었습니다. 이제 실제 변경 사항이 시스템을 망가뜨리는 방식으로 망가뜨려 보겠습니다: 어떤 기능(capability)을 구현하는 서비스가 더 이상 존재하지 않는 기능 ID(capability id)를 가리키도록 만드는 것입니다.
$ sed -i 's/payment-processing/payment-processing-GONE/' …/card-authorization.md
$ ea validate --all
{
...
종료 코드 3입니다. 어떤 인간도 괜찮다고 선언하지 않았고, 어떤 모델(model)도 통과시켜 주지 않았습니다. 코어는 끊어진 참조(dangling reference)를 찾아내어 정확하게 말해주었으며, 이를 **종료 코드(exit code)**로 수행했습니다. 종료 코드 3은 "도구는 정상적으로 실행되었으나, 아키텍처가 유효하지 않음"을 의미하며, 이는 도구 및 사용 오류인 종료 코드 1/2, 그리고 쓰기 보호(write-guard)인 종료 코드 4와 의도적으로 구분됩니다. 그러면 CI 파이프라인(CI pipeline)은 오직 실제 아키텍처 결함에 대해서만 빌드를 실패시킬 수 있습니다:
- run: ea validate --all # 종료 코드 3은 표준 출력(stdout)에 JSON 진단 결과와 함께 빌드를 실패시킴
이제 당신의 아키텍처 일관성은 문서상의 의견이 아니라 하나의 종료 코드이며, 빌드가 실패할 수 있는 파이프라인의 게이트(gate)가 됩니다. 논제 전체가 하나의 숫자에 담겨 있습니다.
AI가 도움을 주는 부분
이것이 모델(model)의 유용성을 떨어뜨리는 것은 아닙니다. 모델이 잘할 수 있는 영역에서 유용하게 쓰이도록 만드는 것입니다.
특정 조직에 맞춰 방법론을 조정하는 것은 판단(judgment)의 영역입니다. 이는 이끌어내기(elicitation), 취향(taste), 트레이드오프(tradeoffs)와 같이 단 하나의 정답이 없는 작업들입니다. 난잡한 대화로부터 첫 번째 산출물(artifact)을 초안하는 것도 판단입니다. 무엇이 누락되었는지 조언하는 것도 판단입니다. 그러한 작업은 표면 에이전트(surface agent)의 몫이며, 코어(core)는 이 과정에서 완전히 제외됩니다. 즉, 저작 지능(authoring intelligence), "AI 리뷰어(AI reviewer)", 취향을 요구하는 그 어떤 것도 코어의 경계선 아래에 머물며 포함되지 않습니다.
이 정직함을 유지하게 만드는 규율은 이끌어내기 우선(elicit-first) 방식입니다. 에이전트는 당신의 전체 아키텍처를 미리 초안으로 작성한 뒤 한꺼번에 승인을 받는 방식이 아닙니다. 대신, 한 단계씩 당신으로부터 실질적인 내용을 이끌어내며, 모든 쓰기(write) 작업은 여전히 게이트(gate)를 거칩니다. 모든 변이 명령(mutating command)은 기본적으로 드라이 런(dry-run)으로 실행됩니다. 즉, 콘텐츠에서 유도된 토큰(content-derived token)에 결합된 계획을 반환하며, 해당 토큰을 사용하여 다시 실행할 때만 변경 사항이 적용됩니다.
$ ea init
{ "status": "ok",
"writes": ["ea.manifest.yaml"],
...
에이전트가 변경 사항을 제안하면, 당신(또는 당신의 승인에 따른 코어)이 정확한 바이트(bytes)를 확인합니다. 그 사이에 저장소(repository)가 변경되어 드리프트(drift)가 발생하면, 토큰이 더 이상 일치하지 않게 되어 코어가 실행을 거부합니다. 모델은 당신의 신뢰할 수 있는 단일 출처(source of truth)를 조용히 재작성하는 주체가 될 수 없습니다.
방법론은 코드가 아니라 데이터입니다
마지막 요소는 이것을 단순한 한 팀의 아키텍처에 대한 의견 이상으로 만들어 주는 것입니다. 방법론 그 자체 — 모델링할 수 있는 타입(types), 그들 사이의 관계, 반드시 준수해야 하는 규칙들 — 는 버전 관리되는 메서드 팩(Method Packs) 형태로 배포됩니다. 이는 코어가 런타임(runtime)에 읽어들이는 일반적인 YAML 파일입니다. 방법론을 채택하는 것은 코드 변경이 아니라 설정(configuration)의 문제입니다.
첫 번째 빌드 명령은 팩 라이브러리(pack library)를 가져옵니다. 그 이후의 모든 것은 오프라인에서 결정론적(deterministically)으로 해결됩니다.
$ ea pack fetch https://github.com/adworzynski/ea-as-code.git
$ ea init --confirm <token>
$ ea preset list # enterprise-architecture · lean-ux · open-agile-architecture
...
ea scaffold는 단순히 빈 파일을 만드는 것이 아닙니다. 대신 타입이 지정된 스텁 (stub)과 함께 pack이 정의하는 작성 가이드(authoring guidance)를 제공합니다. 즉, 어떤 필드를 채워야 하는지, 어떤 관계가 허용되는지, 따라야 할 단계가 무엇인지 등을 알려줍니다. 동일한 분업 구조가 여기에서도 축소판으로 나타납니다. pack은 구조와 표준을 제공하고, 사용자는 이를 채울 판단(judgment)을 제공하며, core는 결과물이 올바른 형식(well-formed)인지 증명(prove)합니다.
현재 세 가지 아키타입 (archetypes)이 제공됩니다. TOGAF의 ADM에 기반한 엄격한 4개 도메인 Enterprise Architecture (EA), 결과 중심의 경량화된 Lean UX, 그리고 완전한 외부 주도형(outside-in) **Open Agile Architecture (OAA)**입니다. 동일한 엔진이 세 가지 모두를 실행하는데, 이는 엔진이 이들을 미리 알고 있는 것이 아니라 읽어내기 때문입니다.
직접 시도해보기
이 주장은 반증 가능하며, 그것이 핵심입니다. 저장소(repo)를 클론(clone)하여 core가 기존 아키텍처가 일관성이 있는지 귀하의 로컬 환경에서 직접 증명하게 해보세요. 제공된 예제는 별도의 설정이 필요하지 않습니다:
$ git clone https://github.com/adworzynski/ea-as-code.git
$ cd ea-as-code/examples/payments-oaa/repo
$ ea validate --all # exit 0 — 직접 확인해보세요
모델(model)은 모델이 잘하는 일, 즉 판단(judgment), 초안 작성(drafting), 대화(conversation)에 집중하게 두십시오. 모델이 귀하의 아키텍처가 건전한지 알려주는 역할을 하게 만들지 마십시오. 실제로 검증할 수 있는 무언가가 종료 코드(exit code)를 통해 그 질문에 답하게 하십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기