본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 10. 20:48

우리는 이미 이를 경험했습니다: 에이전트 시대의 API에 대해 SOA가 우리에게 가르쳐 주는 것

요약

AI 에이전트 시대의 API 설계가 과거 SOA(서비스 지향 아키텍처)의 실패를 반복하지 않기 위해 가져야 할 교훈을 다룹니다. 단순한 구조적 인터페이스를 넘어 비즈니스 의도와 컨텍스트를 포함하는 풍부한 설계의 중요성을 강조합니다.

핵심 포인트

  • 에이전트는 API를 대체하는 것이 아니라 기존 API의 품질을 드러내는 도구임
  • SOA의 실패 원인은 기술적 복잡성이 아닌 컨텍스트가 결여된 인터페이스 설계에 있음
  • 단순한 데이터 타입 정의를 넘어 비즈니스 의도와 상태 변화를 설명해야 함
  • 에이전트 중심 아키텍처에서도 상호 운용성을 위한 풍부한 계약(Contract)이 필수적임

시리즈의 첫 번째 글에서 저는 에이전트(Agents)가 API를 대체하는 것이 아니라, 그 아래에 있는 API의 품질을 드러낼 뿐이라고 주장했습니다.

이 내용은 익숙하게 느껴질 것입니다. 왜냐하면 우리는 이미 이런 상황을 겪어본 적이 있기 때문입니다.

현재의 AI 에이전트, MCP, 그리고 도구 중심 아키텍처(tool-driven architectures)의 물결은 인식 가능한 패턴을 따르고 있습니다. 시스템이 더 조합 가능(composable)해지고, 더 상호 운용(interoperable) 가능해지며, 더 재사용(reusable) 가능해질 것이라는 이야기를 듣고 있습니다. 소프트웨어가 다른 소프트웨어를 동적으로 호출할 것입니다. 기능(Capabilities)은 런타임(runtime)에 발견되고 호출될 것입니다. 호출자가 진행 과정에서 무엇을 사용할지 결정할 수 있기 때문에 통합(Integration)은 덜 경직될 것입니다.

도구(tooling)가 새롭기 때문에 이것이 새롭게 들릴 뿐입니다. 아키텍처 이야기는 새롭지 않습니다.

우리는 서비스 지향 아키텍처(Service-Oriented Architecture, SOA)에 대해서도 거의 똑같은 말을 했습니다.

최소한 기업용 형태의 SOA는 그 약속을 이행하지 못했습니다. 쉬운 설명은 기술을 탓하는 것입니다. SOAP, XML, WS-* 그리고 그 주변의 모든 복잡한 절차(ceremony)들 말입니다. 그것은 편리한 설명이지만, 더 유용한 교훈을 놓치고 있습니다. 문제는 단순히 서비스가 어떻게 통신하느냐가 아니었습니다. 문제는 서비스가 어떻게 설계되었는지, 그리고 우리가 계약(contract)이 실제로 무엇을 의미한다고 생각했는지에 있었습니다.

이것은 지금 매우 중요합니다. 왜냐하면 에이전트가 우리를 동일한 영역으로, 다만 더 빠르게 밀어 넣고 있기 때문입니다.

SOA는 인터페이스(Interfaces)에서 실패하지 않았습니다

SOA는 우리에게 강력한 인터페이스 정의를 제공했습니다. WSDL은 작업(operations), 입력(inputs), 출력(outputs), 스키마(schemas), 그리고 타입(types)을 설명할 수 있었습니다. 당시 그것은 기업용 시스템들이 더 공식적인 방식으로 서로 대화할 수 있도록 만들기 위한 진지한 시도였습니다.

서류상으로는 상호 운용성(interoperability)처럼 보였습니다.

실제로는 그렇지 않은 경우가 많았습니다.

계약(contract)은 메시지의 형태(shape)는 알려줄 수 있었지만, 메시지의 의미(meaning)에 대해서는 충분히 알려주지 못했습니다. 특정 작업이 존재한다는 것은 알려줄 수 있었지만, 그 뒤에 어떤 비즈니스 의도(business intention)가 담겨 있는지는 항상 알려주지 못했습니다. 필드와 타입을 설명할 수는 있었지만, 서비스가 전제하고 있는 가정(assumptions), 기대하는 상태(states), 또는 정상 경로(happy path)를 벗어났을 때 어떻게 동작하는지에 대해서는 설명할 수 없었습니다.

두 시스템이 구조적 수준에서는 완벽하게 통합될 수 있어도, 서로를 완전히 오해할 수 있었습니다.

그것이 더 깊은 실패의 원인이었습니다. SOA (Service-Oriented Architecture)가 실패한 이유는 인터페이스가 쓸모없었기 때문이 아닙니다. 인터페이스가 그것이 생성된 컨텍스트 (context) 외부에서 생존할 만큼 충분히 풍부하지 않았기 때문에 실패한 것입니다.

알려진 소비자 문제 (The Known Consumer Problem)

많은 SOA 서비스들은 실제로 범용적인 기능이 아니었습니다. 그것들은 특정 애플리케이션, 프로세스, 또는 통합을 위해 추출되었거나 설계된 서비스였습니다.

이는 공식적인 인터페이스가 계약 (contract)의 일부일 뿐이라는 것을 의미했습니다. 나머지 부분은 공유된 컨텍스트 (shared context) 안에 존재했습니다. 소비하는 시스템은 예상되는 시퀀스 (sequence)를 알고 있었습니다. 팀들은 어떤 필드를 사용하는 것이 안전한지 알고 있었습니다. 관련 인원들은 어떤 상태 값 (status values)이 의미가 있는지, 어떤 예외 케이스 (edge cases)가 중요한지, 그리고 어떤 호출이 기술적으로는 가능하지만 운영상으로는 어리석은 일인지 이해하고 있었습니다.

인터페이스가 공개되었기 때문에 서비스가 재사용 가능한 것처럼 보였습니다. 하지만 원래의 컨텍스트 외부에서의 재사용은 여전히 인간의 협상을 필요로 했습니다.

이것은 오늘날 많은 API에서 우리가 목격하는 것과 동일한 문제입니다. 인터페이스는 기술적으로 사용 가능하지만, 그 올바른 사용은 명시적으로 드러나지 않은 가정 (assumptions)에 의존합니다. 소비자가 더 이상 당신이 설계했던 대상이 아니게 되는 순간, 그 취약점이 드러나게 됩니다.

SOA 시대의 한 구체적인 사례가 제 기억에 남아 있습니다. 아키텍트들은 공용 CRM 기능이 되어야 했을 것을 설계했습니다. 즉, 하나 이상의 소비자에게 안정적인 엔터프라이즈 접점 역할을 할 수 있는 고객 API였습니다. 하지만 실제로는 첫 번째 통합 사례를 중심으로 형태가 잡혔습니다. 요청 모델 (request model), 시퀀싱 (sequencing), 선택적 필드 (optional fields), 그리고 에러 핸들링 (error handling)은 광범위한 비즈니스 기능보다는 연결되는 두 시스템의 요구사항을 반영했습니다.

그것은 재사용 가능한 서비스의 언어를 가지고 있었지만, 설계는 포인트 투 포인트 (point-to-point) 커넥터와 같았습니다.

에이전트 (Agents)는 정의상 원래의 알려진 소비자가 아니기 때문에, 이러한 취약성을 더욱 심각하게 만듭니다.

이것의 한 가지 구체적인 사례는 엔드 투 엔드 (end-to-end) 고객 여정입니다. 저는 이전에 리드 투 캐시 (lead-to-cash)가 다이어그램 상으로는 깔끔해 보이지만 마케팅, 풀필먼트 (fulfilment), 빌링 (billing), 결제, 운영, 그리고 여러 시스템 소유자를 가로지르는 프로세스에 대해 쓴 적이 있습니다. SOA 및 ESB (Enterprise Service Bus) 환경에서 프로세스 모델은 해당 여정이 단일 계약 (contract)을 가진 것 같은 인상을 줄 수 있었습니다. 하지만 실제로 계약은 라우팅 규칙 (routing rules), 서비스 가정 (service assumptions), 소유권 경계 (ownership boundaries), 그리고 서비스 주변의 예외 처리 (exception handling) 속에 존재하는 경우가 많았습니다.

인터페이스는 그 모든 것을 담고 있지 않았습니다. 프로세스가 담고 있었습니다.

구조는 의미가 아니다

가장 중요한 차이점은 구조적 정밀함 (structural precision)과 의미론적 명확성 (semantic clarity) 사이의 구분입니다.

SOA는 종종 구조적으로 정밀했습니다. 스키마 (schema)는 엄격할 수 있었고, 서비스는 유효하지 않은 메시지를 거부할 수 있었으며, 타입 (types)을 확인할 수 있었습니다. 시스템은 좁은 기술적 의미에서 정확할 수 있었습니다.

하지만 status라고 불리는 필드는 여전히 모호할 수 있었습니다. 이것이 현재의 비즈니스 상태를 설명하는 것인가요, 마지막으로 완료된 프로세스 단계를 설명하는 것인가요, 유효성 검사 (validation check) 결과인가요, 아니면 특정 사용자 역할에 보이는 상태인가요? 어떤 전환 (transitions)이 유효한가요? 상태가 변경될 때 어떤 부작용 (side effects)이 발생하나요? 어떤 시스템이 신뢰할 수 있는 단일 원천 (source of truth)인가요?

그러한 답변들은 계약 안에 들어 있는 경우가 거의 없었습니다. 그것들은 문서, 프로젝트의 기억, 지원 팀, 또는 상황을 충분히 알고 있을 만큼 오래 머물렀던 사람들의 머릿속에 있었습니다.

이것은 작은 격차가 아닙니다. 서비스를 호출할 수 있는 것과 서비스를 올바르게 사용할 수 있는 것 사이의 차이입니다.

거버넌스와 운영 현실의 분리

SOA는 두 번째 교훈도 가르쳐 줍니다. 바로 거버넌스 (governance)가 약한 계약 위에 단순히 프로세스를 얹는 방식이 되어서는 안 된다는 것입니다.

조직들은 서비스 재사용과 변경 관리 (change management)가 어렵다는 것을 인식했고, 이에 따라 버전 관리 규칙 (versioning rules), 승인 위원회 (approval boards), 중앙 레지스트리 (central registries), 그리고 서비스 거버넌스 프로세스를 도입했습니다. 의도는 합리적이었습니다. 성장하는 서비스 자산에 질서를 부여하는 것이었습니다.

더 깊은 문제는 거버넌스 (governance)와 운영 현실 (operational reality)이 서로 갈라졌다는 점이었습니다.

SOA 레지스트리 (registry)는 신뢰할 수 있는 단일 정보원 (source of truth) 역할을 해야 했지만, 계약 (contract)의 내용을 충분히 표현할 수 없었습니다. 서비스, 엔드포인트 (endpoint), 스키마 (schema), 그리고 아마도 일부 소유권 메타데이터 (ownership metadata) 정도는 설명할 수 있었습니다. 하지만 비즈니스적 의미 (business meaning), 가정 (assumptions), 부작용 (side effects), 운영 제약 사항 (operational constraints), 또는 안전한 사용 패턴 (safe usage patterns)을 신뢰성 있게 표현할 수는 없었습니다.

그래서 아키텍트 (architects)와 팀들은 어쩔 수 없이 해야 할 일을 했습니다. 바로 레지스트리를 중심으로 별도의 문서를 작성하는 것이었습니다.

그것은 한동안 도움이 되었지만, 새로운 문제를 야기했습니다. API, 레지스트리, 그리고 문서가 이제 동일한 계약에 대한 세 가지 별개의 표현 방식이 되어버린 것입니다. 이들은 서로 다른 속도로 변경되었고, 서로 다른 사람들이 관리했으며, 예상대로 서로 어긋나기 (drift) 시작했습니다.

일단 그런 일이 발생하면, 거버넌스는 더 이상 현실에 대한 신뢰할 수 있는 설명이 아니게 됩니다. 그것은 조정해야 할 또 다른 유물 (artefact)이 되어버렸습니다.

저는 감사 (audit) 및 컴플라이언스 (compliance) 작업에서 이러한 운영상의 버전을 목격했습니다. 제가 함께 일했던 전문가들은 서비스 다이어그램 (service diagram)을 최종적인 진실로 간주하는 데 관심이 없었습니다. 그들은 가공되지 않은 데이터 (raw data)를 원했는데, 왜냐하면 데이터베이스에 기록된 데이터만이 실제로 무슨 일이 일어났는지에 대한 유일하고 지속적인 증거였기 때문입니다. 큐 상태 (queue state), 프로세스 상태 (process state), 그리고 통합 로그 (integration logs)도 중요했지만, 그것들이 관리되는 기록 원천 (governed source of record)을 대체할 수는 없었습니다.

교훈은 거버넌스가 나쁘다는 것이 아닙니다. 교훈은 거버넌스가 계약 설계 자체에 녹아들어야 한다는 것입니다. 의미, 권한, 동작, 그리고 변경에 대한 기대치가 인터페이스 (interface)의 일부가 아니라면, 프로세스 문서가 이를 구원할 수는 없습니다.

재사용의 환상

SOA는 재사용 가능한 서비스 (reusable services)를 약속했습니다. 하지만 많은 조직이 실제로 얻은 것은 기술적으로는 재사용 가능하지만, 실제로는 첫 번째 사용 사례 (use case)에 종속된 서비스들이었습니다.

이 차이는 매우 중요합니다.

기술적 재사용성 (Technical reusability)은 다른 시스템이 해당 서비스를 호출할 수 있음을 의미합니다. 실질적 재사용성 (Practical reusability)은 다른 시스템이 서비스를 안전하게 호출하고, 그 의미를 이해하며, 동작에 의존할 수 있고, 시간이 흐름에 따라 함께 진화할 수 있음을 의미합니다. SOA는 종종 첫 번째를 제공하고 두 번째가 뒤따를 것이라고 가정했습니다.

하지만 뒤따르지 않았습니다.

재사용은 여전히 인간이 의미론 (semantics)을 이해하고, 숨겨진 가정을 찾아내며, 변경 사항을 협의하는 것에 의존했습니다. 계약 (contract)이 충분한 작업량을 감당하지 못했던 것입니다.

에이전트가 오래된 문제를 다시 새롭게 만드는 이유

에이전트 (Agents)는 소비 모델을 변화시킵니다.

알려진 프론트엔드 (front end)나 통제된 통합 (integration) 대신, 이제 우리는 도구를 동적으로 발견하고, 런타임 (runtime)에 작업을 구성하며, API를 구축한 팀의 공유된 배경 지식 없이도 행동할 수 있는 소비자들을 마주하게 되었습니다. 에이전트는 당신이 무엇을 의도했는지 알지 못합니다. 에이전트는 당신이 무엇을 노출했는지만을 압니다.

이는 과거의 약점들을 더 즉각적인 위험으로 바꿉니다. 모호한 필드는 잘못된 결정이 됩니다. 숨겨진 가정은 실패한 워크플로 (workflows)가 됩니다. 불분명한 동작은 예측 불가능한 행동이 됩니다. 인간 개발자에게 그저 불편했을 뿐이었던 계약이, 자율적인 호출자가 다른 기능들과 이를 조합하기 시작할 때는 위험해질 수 있습니다.

이것이 바로 SOAP에서 REST로, XML에서 JSON으로, 또는 WSDL에서 OpenAPI로의 전환이 그 자체만으로는 문제를 해결하지 못하는 이유입니다. 현대적인 스택은 더 깔끔하고 작업하기 즐겁지만, 대부분의 API 계약은 여전히 의미 (meaning)보다는 구조 (structure)를 더 잘 설명합니다. 계약은 엔드포인트 (endpoints), 페이로드 (payloads), 응답 코드 (response codes), 그리고 스키마 (schemas)에 대해 알려줍니다. 하지만 의도 (intent), 도메인 컨텍스트 (domain context), 동작 보장 (behavioural guarantees), 권한 경계 (authority boundaries), 그리고 부수 효과 (side effects)에 대해서는 훨씬 적게 말해줍니다.

이것이 바로 우리가 반복할 위험이 있는 패턴입니다.

진짜 교훈

SOA는 서비스들이 대화하는 방식을 표준화했습니다. 서비스들이 무엇을 의미하는지를 표준화한 것은 아니었습니다.

그것이 바로 우리가 앞으로 가져가야 할 가치 있는 교훈입니다.

에이전트 (Agents)가 우리를 완전히 새로운 아키텍처 문제로 몰아넣고 있는 것은 아닙니다. 그들은 기존의 문제를 무시하기 더 어렵게 만들고 있을 뿐입니다. 만약 계약 (Contract)이 원래의 컨텍스트 (Context) 밖에서도 생존할 수 있을 만큼 충분한 의미를 담고 있지 않다면, 동적 구성 (Dynamic composition)은 시스템을 더 신뢰할 수 있게 만드는 것이 아니라, 오해를 더 빠르게 확산시킬 뿐입니다.

따라서 다음 질문은 우리가 API가 필요한가 하는 것이 아닙니다. 우리는 필요합니다.

질문은 호출자 (Caller)가 더 이상 알려진 애플리케이션이나 알려진 팀, 혹은 알려진 워크플로 (Workflow)가 아닐 때, API 계약 (API contract)이 무엇을 포함해야 하는가 하는 것입니다.

그리고 그 이면에는 더 깊은 문제가 있습니다. 우리의 API는 데이터 구조 (Data structures)를 노출할 뿐, 의미 (Meaning)를 노출하지 않는다는 점입니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0