Neander와 Grotto: 코드 모드(Code Mode)를 넘어서
요약
에이전트 중심 프로그래밍 언어인 Neander와 그 런타임 Grotto를 소개합니다. 기존의 샌드박스 격리 방식 대신, 언어 설계 단계부터 튜링 완전성을 배제하여 구조적 안전성을 확보하는 '감산을 통한 안전성' 접근법을 제시합니다.
핵심 포인트
- 에이전트가 도구 호출 대신 코드를 직접 작성하여 작업을 조율하는 '코드 모드' 개념 설명
- 기존의 격리 방식(샌드박스)과 차별화된 '구조적 안전성(Safe by construction)' 지향
- Neander는 튜링 완전하지 않으며 재귀가 없고 모든 루프가 정적으로 경계됨
- 실행 전 종료 여부가 결정되며 파일, 소켓, 시스템 콜 접근이 원천 차단됨
Field Notes from the Grotto가 여기서 시작됩니다 — Neander 언어와 그 런타임(runtime)인 **Grotto**의 기능별 투어입니다. 그리고 저는 가장 큰 특징인 Neander 자체로 시작하려 합니다. 이미 우리가 사용할 수 있는 풍부하고 잘 확립된 프로그래밍 언어들이 있는데, 왜 완전히 새로운 언어를 만들어야 할까요?
이전 포스트에서 저는 시스템 사이의 이음새(seam)가 하나의 언어로 변하고 있다는 논거를 제시했습니다 — 즉, 도구(tool)를 하나씩 호출하는 대신, 에이전트(agent)가 당신에게 작은 프로그램을 보내 당신 쪽에서 작업을 조율(orchestrate)하게 해야 한다는 것입니다. 그 아이디어에는 이름이 있습니다 — 바로 코드 모드 (code mode) — 그리고 이것은 제 아이디어가 아닙니다. 이제 이것은 논쟁의 여지도 없습니다. 다른 이들도 각자의 방향에서 이 결론에 도달했으며, 이미 이를 구현하여 출시 중인 실제 솔루션들이 존재합니다. 또한, 모델이 도구 호출(tool calls)을 생성하는 것보다 코드를 작성하는 것을 더 잘한다는 근본적인 주장은 단순히 주장된 것이 아니라 측정되었습니다. 따라서 *무엇(what)*에 대해서는 결정되었습니다. 이 포스트는 *어떻게(how)*에 대한 더 좁은 논쟁에 관한 것입니다.
제가 접한 모든 기존 솔루션은 솔직히 말해서 당연한 답변을 공유하고 있습니다. 모델이 이미 유창하게 작성하는 잘 알려진 언어를 선택하고, 당신의 도구로부터 API를 생성한 다음, 에이전트의 코드를 샌드박스(sandbox)에서 실행하는 것입니다. 실용적입니다. 오늘날 바로 사용 가능합니다. 그리고 이를 안전하게 만들기 위한 진지한 노력이 뒷받침되고 있습니다 — 신뢰할 수 없는 코드를 실행하는 방법론에 대한 전체 산업이 존재합니다: 경량 가상 머신(lightweight virtual machines), 격리된 컨테이너(isolated containers), 시스템 호출 방화벽(syscall firewalls), 그리고 오직 '안 돼'라고 말하는 것이 유일한 임무인 네트워크 프록시(network proxies)까지 말이죠. 실제 엔지니어링이며, 이는 성과를 내고 있습니다.
그렇다면 왜 저는 그중 어떤 것도 선택하지 않았을까요? 왜 대신 빈 문법(empty grammar)에서 시작했을까요?
그 모든 것들이 하나의 형태, 즉 '감산을 통한 안전성 (safety by subtraction)'을 공유하고 있기 때문이며, 저는 다른 형태를 원했기 때문입니다.
구조적 안전성 (Safe by construction)
그러한 접근 방식들은 모두 무엇이든 할 수 있는 언어에서 시작하여, 파일 시스템을 격리하고, 네트워크를 차단하며, 제한 시간이 다 되면 프로세스를 종료하는 식으로 무언가를 뺏어가는 데 노력을 기울입니다. 언어 자체가 위협이며, 안전성은 이 범죄자 주변에 세워진 감옥으로부터 옵니다.
Neander는 그런 위협이 아닙니다. Neander는 영원히 실행될 수 없습니다. 이는 튜링 완전(Turing-complete)하지 않으며, 재귀(recursion)가 없고, 모든 루프는 정적으로 경계(statically bounded)가 정해져 있으며, 종료 여부는 프로그램이 실행되기 _전(before)_에 결정됩니다. Neander는 외부로 손을 뻗을 수 없습니다. 문법 어디에도 파일, 소켓, 시스템 콜(system call)이 존재하지 않습니다. Neander는 비용을 폭증시킬 수 없습니다. 모든 프로그램은 연산, 메모리, 시간에 대한 엄격한 상한선(hard ceilings) 하에서 실행됩니다. 샌드박스 탈출(sandbox escapes), 권한 상승(privilege escalation), 데이터 유출(data exfiltration)과 같은 공격 카테고리 전체가 아예 적용되지 않는데, 이는 그들이 악용할 수 있는 권한(capability) 자체가 애초에 존재하지 않기 때문입니다.
죄수가 없기에 감옥도 없습니다. 샌드박스 방식은 당신에게 케이지(cage)를 믿으라고 요구합니다. Neander의 안전성은 케이지가 필요할 만한 요소 자체가 부재함에서 옵니다. 언어가 할 수 있는 일이 적을수록 잘못될 일도 적어지며, 당신이 믿음(faith)에 의존해야 하는 부분도 줄어듭니다. 전체 샌드박스 산업은 범용 코드(general-purpose code)를 가두기 위해 존재하지만, Neander는 그것이 필요하지 않은 길을 택했습니다.
구조적 균일성 (Uniform by construction)
에이전트가 어떤 프로그램을 제출하든, 결과는 동일한 형태, 즉 언어 자체에 의해 정의된 단일 응답 봉투(response envelope)로 돌아옵니다. 이 봉투는 프로그램이 생성한 값 또는 값을 생성하지 못한 정확한 이유를 담고 있습니다. 이러한 균일성이 유지되는 이유는 실패가 혼란 속으로 탈출하도록 내버려 두지 않기 때문입니다. 실행 도중 발생한 오류나 소진된 예산은 제멋대로 표출되도록 두는 대신 포착되어 분류되며, 실행조차 되지 않는 잘못된 프로그램조차 응답을 생성합니다. 봉투에는 메타데이터도 포함됩니다. 여기에는 프로그램이 사용한 리소스나 런타임(runtime)이 강제하는 사용 제한 등이 포함됩니다. 에이전트는 수신한 응답을 통해 자신이 작동하는 바로 그 상한선(ceilings)을 학습하게 됩니다.
균일한 응답 엔벨로프 (envelope)는 단순히 편의를 위한 것이 아닙니다. 도구 호출 (tool calls)의 스트림 대신 코드를 보내는 핵심 목적은 에이전트의 컨텍스트 (context)를 깨끗하게 유지하는 것이었습니다. 즉, 모든 중간 단계가 쌓이는 대신 하나의 압축된 결과만을 입력받는 것입니다. 균일한 엔벨로프는 이러한 이점을 실제로 구현하는 요소입니다. 에이전트는 자신이 항상 읽는 법을 알고 있는 단일한 기계 판독 가능 (machine-readable) 판결을 돌려받으며, 오직 그 판결만이 컨텍스트 비용을 발생시킵니다. 에이전트는 산문 (prose)을 파싱하거나, 스택 트레이스 (stack trace)를 유심히 들여다보거나, 서로 다른 오류 형식을 조정할 필요가 없습니다. 엔벨로프를 읽는 것만으로 자신의 상태가 정확히 어디인지 알 수 있습니다.
구조에 의한 개방 (Open by construction)
Grotto의 다음 단계
개요는 이와 같습니다. 이 시리즈의 나머지 부분은 상세한 내용을 다룹니다. 각 항목은 하나의 기능을 다루며, 그 각각은 위의 논증을 구체화한 조각들입니다. 가장 먼저, 전체적인 역전 (inversion)을 가능하게 하는 기능부터 시작합니다. 즉, 에이전트가 API 카탈로그를 들고 다니지 않고도 런타임 (runtime)에 당신의 API가 무엇인지 어떻게 찾아내는지에 대한 내용입니다.
그동안 Neander 명세 (spec)를 읽어보시고, 당신의 앱에 Grotto를 임베드 (embed) 해본 뒤, 어떤 점이 부족한지 알려주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기