본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 17. 23:07

시스템 사이의 이음새로서의 소스 코드

요약

에이전트 중심의 환경에서 소스 코드가 시스템 간의 이음새(seam)로 변화하는 과정을 분석합니다. 자연어 기반의 기계 간 인터페이스가 가진 보안 및 모호성 문제를 지적하며, 형식 언어로서의 프로그래밍 언어의 중요성을 강조합니다.

핵심 포인트

  • 에이전트 시대에 소스 코드는 시스템 간의 이음새 역할을 수행함
  • 자연어 기반 기계 인터페이스는 보안 취약점과 모호성 문제를 가짐
  • 시스템 경계 확립을 위해 제한된 표현력과 명확한 의미론이 필요함
  • 프로그래밍 언어는 기계 간 통신을 위한 최적의 형식 언어임

이전 블로그 포스트인 Speccing Is the New Coding에서, 저는 에이전트 중심의 세상(agentic world)에서도 소스 코드가 완전히 사라지지는 않겠지만, 애플리케이션의 실체에서 시스템 사이의 이음새(seam)로 그 역할이 바뀔 것이라고 주장했습니다. 그 약속대로 다시 돌아와 이 문제에 대해 더 깊이 파고들어 보겠습니다.

한번 살펴봅시다.

과거의 방식

전통적인 소프트웨어 개발에서는 두 시스템이 서로 통신해야 할 때, 개발자가 한 시스템의 API 문서를 읽은 다음, 적절하게 구조화된 데이터로 해당 API들을 올바른 순서로 호출하는 다른 시스템을 위한 통합 코드(integration code)를 작성합니다. 이 방식은 잘 작동하며, 우리는 수십 년간 이를 연습해 왔습니다. 하지만 호출하는 시스템은 자신이 호출하는 API를 실제로 이해하지 못합니다. 오직 개발자만이 이해할 뿐입니다. 시스템은 단지 설계 시간(design time) 동안 인간이 작성한 지침을 충실히 수행할 뿐입니다.

이러한 방식은 이미 다소 구식처럼 보이기 시작했습니다. 적어도 호출하는 시스템이 에이전트적(agentic)이어서, 실행 시간(runtime)에 다른 시스템으로부터 무엇이 필요한지 스스로 결정하게 된다면, 중간에 있는 인간은 사라져야 합니다.

하향식 접근 방식: 수학적 사색

우리 인간은 서로에게 "프롬프트(prompt)"를 줄 수 있는 내장된 능력을 가지고 있습니다. 우리는 이것을 대화라고 부릅니다.

이 기술은 수 세기 동안 매우 성공적임이 증명되었으며, 우리는 심지어 최신 인간-기계 인터페이스(human-machine interface)를 이 방식에 따라 모델링하기도 했습니다. 그렇다면 여기서 멈출 이유가 있을까요? 이토록 성공적이라면, 이 개념을 기계-기계 인터페이스(machine-machine interfaces)에 적용하는 것도 타당하지 않을까요? 한 시스템이 다른 시스템에게 자신이 원하는 것을 평이한 영어로 말하게 하고, 두 시스템이 공동의 목표를 달성하기 위해 서로의 능력을 의도적으로 활용하게 하는 것입니다.

이것은 작동할 것입니다. 그리고 IT 역사상 가장 범용적이고 가장 유연한 인터페이스 기술로 기록될 것입니다.
동시에, 지금까지 출시된 것 중 가장 기억에 남는 보안 취약점(security vulnerability)으로도 기록되겠지요.

이러한 순진한 접근 방식은 실패할 운명입니다. 평이한 자연어는 설계상 경계가 없습니다. 말할 수 있는 내용에 제한이 없으며, 단어가 무엇을 의미하는지에 대한 공식적인 보장(formal guarantees)도 없습니다.

하지만 경계(boundaries)가 필요합니다. 시스템 경계(System boundaries) 말입니다.

따라서 한 시스템이 다른 시스템에 무엇을 할지 지시하기를 원한다면, 다음 두 가지가 충족되어야 합니다.

  1. 말할 수 있는 내용에 제한이 있어야 하며,
  2. 말해진 내용이 **모호하지 않은 의미(unambiguous meaning)**를 가져야 합니다.

이러한 요구 사항은 수학적 의미에서의 형식 언어(formal languages)를 명확하게 가리킵니다. 그리고 프로그래밍 언어는 유한한 구문(syntax), 정밀한 의미론(semantics), 그리고 제한된 표현력(bounded expressiveness)을 가진, 말 그대로 형식 언어입니다. 우리는 기계와 대화하기 위해 프로그래밍 언어를 발명했으며, 이것이 기계가 다른 기계와 대화하기에도 적합한 형태가 되었습니다.

상향식 접근 방식 (The bottom-up approach): 도구 사용 단계

에이전트 시스템(agentic systems) 개발 초기에는, 이들이 외부 세계와 상호작용할 방법이 필요하다는 점이 분명해졌습니다. 그래서 일련의 기술들이 발명되었으며, 우리는 이를 현재 _도구 호출(tool calling)_이라고 부릅니다. 본질적으로, 이는 에이전트가 먼저 API 명세(API spec)를 흡수한 다음 API 호출을 실행하는 방식입니다.

단순해 보이지만, 그렇지 않았습니다.

2025년 11월, MCP 표준의 제작자들은 도구 호출에 대해 배운 두 가지 중요한 교훈을 강조하는 기사를 발표했습니다.

첫째, 에이전트가 도구를 호출하려면 해당 도구가 존재한다는 것을 알아야 합니다. 따라서 모든 도구 정의는 사전에 에이전트의 컨텍스트(context)에 로드됩니다. 몇 개의 도구만 있을 때는 문제가 되지 않았지만, 결과적으로 고객들은 실제로 에이전트에게 수백 개, 심지어 수천 개의 도구를 노출해야 했습니다. 이는 컨텍스트의 혼잡, 응답 시간 증가, 그리고 비용 상승으로 이어졌습니다.

둘째, 에이전트가 도구 호출의 오케스트레이터(orchestrator) 역할을 하기 때문에, 모든 중간 도구 호출 결과가 컨텍스트에 추가됩니다. 이는 앞서 언급한 문제들과 더불어 신뢰성 및 데이터 보호 문제까지 야기했습니다.

제안된 해결책을 요약하자면, 에이전트가 API를 대상으로 코드를 작성하게 하고, 그 최종 결과만을 컨텍스트에 추가하도록 만드는 것입니다.

흥미로운 점은 우리가 매우 서로 다른 두 지점에서 시작했음에도 불구하고, 우리의 하향식 (top-down) 접근 방식과 정확히 동일한 결론에 도달했다는 것입니다.

두 시스템 사이의 이음새 (seam)는 더 이상 구조화된 데이터를 운반하는 전선이 아닙니다. 그것은 하나의 언어이며, 호출하는 시스템이 프로그램을 전송함으로써 사용하는 노출된 실행 환경 (execution environment)입니다.

앞서 언급한 기사가 제가 제안하려는 내용에 대한 초기 영감이 되었다는 점을 주목할 가치가 있습니다. 비록 이에 대한 저의 견해가 원래의 제안을 그대로 따르는 것은 아니지만 말입니다.

에이전트 우선 프로그래밍 언어 (An agent-first programming language)

이러한 결론에 도달했으므로, 다음 단계는 명백해 보입니다. 여러분이 좋아하는 언어를 선택하고, 원하는 API를 해당 언어에서 사용할 수 있도록 만든 다음, 에이전트에게 프로그램을 보내기 시작하라고 명령하는 것입니다.

전적으로 가능합니다. 실용적입니다. 하지만 과연 그것이 정말 좋은 선택일까요?

사실상 우리의 기존 주류 프로그래밍 언어들은 모두 범용 언어 (general-purpose languages)입니다. 설계상, 그것들로 말 그대로 무엇이든 할 수 있습니다. 물론, 요구 사항이 무엇이든 간에 그 조건들을 충족할 것입니다. 그리고 우리는 샌드박싱 (sandboxing)과 같은 정교한 기술을 사용하여 우리가 필요하지 않은 불필요하거나 위험한 기능들을 언제든지 억제할 수 있습니다.

하지만 앙투안 드 생텍쥐페리 (Antoine de Saint-Exupéry)의 유명한 격언처럼, "완벽함이란 더 이상 더할 것이 없을 때가 아니라, 더 이상 뺄 것이 없을 때 달성된다"라고 했습니다.

그러니, 제대로 된 순서로 처음부터 다시 시작해 봅시다. 이 특정 유스케이스 (use case)를 위해 실제로 우리에게 필요한 것은 무엇일까요?

  1. 단순성 (Simplicity): API 오케스트레이션 (orchestration)을 목표로 하는 에이전트 중심의 언어 설계. 한 번의 호출, 결과에 대한 루프 (loop), 약간의 조건부 로직, 그리고 또 다른 호출. 그게 전부입니다. 화려한 기능도, 구문 설탕 (syntactic sugar)도 필요 없습니다.
  2. 예측 가능성 (Predictability): 모든 프로그램은 설계상 종료가 보장됩니다. 파일 입출력 (file I/O), 소켓 (sockets), 시스템 접근이 없습니다. 언어 자체가 곧 샌드박스 (sandbox)입니다.
  3. 발견 가능성 (Discoverability): 프로그램이 실행 시간 (runtime)에 사용 가능한 API와 언어 자체에 대해 알아낼 수 있습니다. 사전 문서화도, 별도의 통합 단계도 필요하지 않습니다.

중간에 개입하던 인간이 사라졌습니다. 이음새(seam)는 더 이상 번역가가 배치해야 했던 두 시스템 사이의 경계에 머물지 않고, 호출되는 시스템(called system) 내부로 이동했습니다. 이음새는 언어를 노출하고, 규칙을 설정하며, 어휘(vocabulary)를 정의합니다. 호출하는 시스템(calling system)은 발견되는 것이 무엇이든 말할 준비가 된 상태로 도착합니다. 그리고 앞서 언급한 세 가지 설계 원칙은 이러한 통합을 매끄럽게(seamless) 만드는 것을 목표로 합니다. 즉, 호출하는 시스템이 사용하기에 충분히 단순하고(simple), 호출되는 시스템이 두려워할 필요가 없을 정도로 예측 가능하며(predictable), 어떤 인간도 사전에 설명할 필요가 없을 정도로 발견 가능해야(discoverable) 합니다.

이 모든 점을 염두에 두고, 저는 정확히 이러한 사용 사례를 위해 처음부터 새로운 프로그래밍 언어와 그 런타임 참조 구현체(runtime reference implementation)를 만들어냈습니다.

이에 대한 자세한 내용은 다음 시간에 다루겠습니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0