본문으로 건너뛰기

© 2026 Molayo

HN요약2026. 05. 14. 07:23

Show HN: Mog 프로그래밍 언어

요약

Mog는 AI 에이전트가 스스로를 빠르고 안전하게 수정하고 확장할 수 있도록 설계된 정적 타입, 컴파일형 임베디드 프로그래밍 언어입니다. 이 언어는 LLM이 작성하기 용이하며, 네이티브 코드로 컴파일되어 저지연 플러그인 실행에 최적화되었습니다. Mog는 역량 기반 권한(capability-based permissions)을 통해 에이전트가 자신의 코드로 확장할 때도 보안성을 유지합니다.

핵심 포인트

  • Mog는 LLM 작성을 염두에 두고 설계된 정적 타입, 컴파일형 임베디드 언어입니다.
  • 네이티브 코드로 컴파일되어 인터프리터 오버헤드가 없는 저지연 플러그인 실행을 지원합니다.
  • 역량 기반 권한(capability-based permissions) 모델을 통해 에이전트의 코드 확장 과정에서도 보안성을 유지합니다.
  • 스크립팅 및 훅 구현에 적합하며, 특히 bash 사용 시 발생할 수 있는 보안 허점을 차단하는 데 강점이 있습니다.

Mog: AI 에이전트를 위한 프로그래밍 언어

AI 에이전트가 스스로를 빠르고, 쉽고, 안전하게 수정할 수 있다면 어떨까요? Mog는 바로 이를 위해 설계된 프로그래밍 언어입니다.

개요 (Overview)

Mog는 LLM(Large Language Models)이 작성하도록 설계된 정적 타입 (statically typed), 컴파일형 (compiled), 임베디드 언어 (embedded language)입니다 (정적 타입의 Lua를 생각하면 됩니다). 전체 사양(spec)이 3200 토큰 안에 들어갑니다.

  • AI 에이전트가 Mog 프로그램을 작성하고, 이를 컴파일한 뒤 플러그인, 스크립트 또는 훅(hook)으로 동적 로드합니다.
  • 호스트(host)는 Mog 프로그램이 호출할 수 있는 함수를 정확히 제어하며 (역량 기반 권한 (capability-based permissions)), 따라서 권한은 에이전트에서 에이전트가 작성한 코드로 전파됩니다.
  • 저지연 (low-latency) 플러그인 실행을 위해 네이티브 코드 (native code)로 컴파일됩니다. 인터프리터 오버헤드(interpreter overhead), JIT, 프로세스 시작 비용이 없습니다.
  • 컴파일러는 안전한 Rust로 작성되어 전체 툴체인 (toolchain)에 대한 보안 감사가 가능합니다.
  • 완전한 보안 감사 없이도, Mog는 에이전트가 자신의 코드로 스스로를 확장하는 데 이미 유용합니다.
  • MIT 라이선스이며, 기여를 환영합니다. https://github.com/voltropy/mog

예시 (Examples)

에이전트 훅 (Agent hook)

컨텍스트 압축 (context compaction) 후에 실행되는 에이전트 훅입니다. 모든 I/O 함수는 호스트에 의해 제공됩니다: import는 호스트가 정의한 타입을 가져오며, optional 역량 (capabilities)은 제공되지 않을 경우 우아하게 성능을 저하시킵니다 (degrade gracefully).

import agent; // Agent, Message, Role 타입
optional log; // 제공되지 않으면 조용히 무시됨
// 압축 후 훅: 손실되었을 수 있는 핵심 컨텍스트를 재주입
...

재시도가 포함된 비동기 HTTP (Async HTTP with retry)

재시도 로직이 포함된 비동기 (async) HTTP 페처 (fetcher)입니다. Mog는 호스트의 에이전트 루프를 차단하지 않고 중단되는 async / await를 지원하며, Result 값을 구조 분해 (destructuring)하기 위한 match, 그리고 표현식 보간 (expression interpolation)을 위한 f-string을 지원합니다.

async fn fetch_with_retry(url: string, max_retries: int) -> Result<string> {
attempts := 0;
for attempts < max_retries {
...

텐서 상의 FFT (FFT on tensors)

Mog는 다차원 배열 (tensors)에 대한 네이티브 지원과 함께 머신 코드 (machine code)로 컴파일됩니다. 다음은 tensor<f32>에 대한 radix-2 FFT입니다.

data. 실수(foot-guns)를 최소화하기 위해, Mog는 연산자 우선순위(operator precedence)가 없으므로 결합법칙이 성립하지 않는 연산이 포함된 산술 연산에는 명시적인 괄호가 필요합니다. size as float와 같은 타입 변환(Type conversion)은 항상 명시적이며, 암시적 형변환(implicit coercion)은 허용되지 않습니다.

// Fast Fourier Transform (Cooley-Tukey, radix-2, in-place)
// 2×n 텐서를 반환합니다: row 0 = 실수부, row 1 = 허수부.
fn fft(re: tensor<f32>, im: tensor<f32>) -> tensor<f32> {
...

왜 Mog인가?

범용 AI 에이전트(general-purpose AI agent)는 스스로를 지속적으로 확장하고 수정할 수 있어야 합니다. 시간이 흐름에 따라 에이전트는 온갖 방식으로 작업을 관리하는 개인용 서버로 성장해야 합니다. 이를 위해 에이전트는 자신의 코드를 직접 작성해야 하며, 그 코드는 안전해야 합니다.

에이전트가 작성하는 가장 단순한 형태의 프로그램은 특정 작업을 달성하기 위한 일회성 스크립트입니다. 예시는 다음과 같습니다:

  • 마크다운(markdown) 파일을 PDF로 변환.
  • 데이터베이스 결과가 포함된 CSV 분석.
  • 애플리케이션의 HTTP 엔드포인트(endpoint)로 테스트 요청 전송.
  • 폴더 내의 모든 파일 이름 변경.
  • 의존성(dependencies) 설치.

코딩 에이전트들은 보통 이를 위해 bash를 사용하며, 때로는 인라인(inline) Python이나 TypeScript 스크립트를 사용하기도 합니다. Mog는 이러한 용도에 매우 적합합니다. 작성하기 쉽고 컴파일이 빠르기 때문입니다. 특히, 스크립팅은 에이전트가 자신의 샌드박스(sandbox)를 벗어나는 주요 방법 중 하나인데, Mog는 이 허점을 차단합니다. 설령 호스트 에이전트가 Mog에게 bash 명령어를 호출할 수 있는 권한(capability)을 부여하더라도, 호스트는 모델이 직접 bash 도구를 호출했을 때와 마찬가지로 자신의 권한에 따라 해당 명령어들을 필터링할 수 있는 능력을 여전히 유지합니다.

프로그램 에이전트가 흔히 작성하는 두 번째 종류는 훅 (hook)입니다. 이는 에이전트 루프 (agentic loop) 내의 특정 시점에서 반복적으로 실행되는 코드 조각입니다. 도구 사용 전후 (pre- and post-tool-use) 훅뿐만 아니라, 압축 전 (pre-compaction) 훅도 흔히 사용됩니다. 훅의 경우, 컴파일 속도가 빠른 것은 중요하지 않지만, 시작 속도와 실행 속도는 빨라야 합니다. 왜냐하면 구현이 느릴 경우 사용자 경험을 유의미하게 저하시킬 정도로 빈번하게 호출될 수 있기 때문입니다. Mog는 네이티브 코드 (native code)로 컴파일되며, 이후 해당 머신 코드 (machine code)를 에이전트의 실행 중인 바이너리 (running binary)에 로드할 수 있습니다. 이를 안전하게 만드는 핵심 속성은 다음과 같습니다. Mog 컴파일러에 의해 컴파일된 네이티브 코드는 호스트가 명시적으로 허용한 것 외에는 아무것도 할 수 없으며, 메모리나 시간 제한조차 초과할 수 없습니다. 에이전트는 런타임 (runtime)에 Mog 프로그램을 자신에게 통합할 수 있으며, 프로세스 간 통신 (inter-process communication, IPC) 오버헤드나 프로세스 시작 지연 시간 (process startup latency) 없이 이를 호출할 수 있습니다.

세 번째 카테고리는 에이전트 자체의 일부를 작성하거나 재작성하는 것입니다. 이는 에이전트가 LLM에 노출하는 새로운 도구를 추가하는 것, 사용자 인터페이스를 위한 상태 표시줄, 에이전트 기술 또는 세션 관리에 관한 설정 등을 의미할 수 있습니다. 즉, 확장이나 특성화를 통해 이득을 얻을 수 있는 잠재적으로 긴 에이전트 내부 기능 목록을 포함합니다.

거의 모든 기능을 수행하기 위해 Mog 코드를 호출하는 작은 Rust 코드 백본 (backbone)으로 작성된 마이크로커널 (microkernel) 에이전트를 상상해 볼 수 있습니다. 커널은 이벤트 루프 (event loops), 멀티스레딩 (multi-threading), 루트 권한 (root permissions), Mog 프로그램의 컴파일 및 로드, 그리고 아마도 업그레이드 기능의 일부를 관리하겠지만, 시스템의 나머지 부분은 Mog로 작성될 수 있습니다. 이는 최소한의 세밀한 권한 (granular permissions)으로 실행되며, 에이전트에게 스스로를 수정하도록 프롬프트 (prompt)를 주는 것만으로 재시작 없이 즉석에서 업그레이드할 수 있습니다.

대안 (Alternatives)

Mog와 같은 것이 없다면, AI가 생성한 에이전트 코드에 대한 모든 옵션에는 단점이 있습니다. 그중 주요한 하나는 권한을 강제하는 것입니다. Jeffrey Emanuel의 dcg와 같은 도구는 rm -rf를 차단할 수 있습니다.

그리고 이와 유사하게 파괴적인 셸 명령어도 마찬가지입니다. 하지만 에이전트가 폴더 내의 파일들을 순회하며 각 파일에 대해 os.remove()를 호출하는 Python 코드를 생성하는 것까지 막을 수는 없습니다.

다음 단계는 일반적으로 Docker 컨테이너와 같은 샌드박스 (sandbox) 내에서 에이전트를 실행하는 것입니다. 하지만 이 경우 권한이 샌드박스 전체에 적용되는 경향이 있습니다. 따라서 에이전트가 호스트 컴퓨터를 유의미한 방식으로 사용하게 하려면 (예: 환경 변수 가져오기, CLI 도구 접근, 브라우저 제어, HTTP 요청 생성 등), 샌드박스의 경계를 개방해야 합니다. 그 시점에서 에이전트는 본질적으로 해당 기능에 대해 제한 없는 접근 권한을 다시 얻게 됩니다.

지금 부족한 것은 에이전트에게 부여된 권한을 그 에이전트가 작성한 프로그램으로 전파할 수 있는 방법입니다. Mog는 이 문제를 직접적으로 해결합니다.

외부 스크립트의 또 다른 문제는 공유 문제입니다. 신뢰할 수 없는 소스로부터 스크립트를 받는 것은 보안 위험이 따릅니다. Mog를 사용하면, 수신 측 에이전트가 기기를 장악할 수 있는 사전 컴파일된 바이너리 (pre-compiled binary)를 실행하는 대신 Mog 소스 자체를 컴파일합니다.

LLM 기반 확장 시스템에는 다른 접근 방식들도 존재합니다. Jeffrey Emanuel는 권한이 부여된 JavaScript 컨테이너를 사용하여 유사한 것을 구축하고 있는데, 이는 정신적으로 Mog와 매우 유사하며 그 이면에 인상적인 수준의 인프라를 갖추고 있습니다. Mog는 이러한 시스템을 보완할 수 있으며, 특히 고성능 플러그인에 유용할 수 있습니다. Mog의 인프라는 Rust로 작성되어 있어 통합이 용이합니다. Emanuel의 Rust 버전 Pi 에이전트는 Mog 기반의 마이크로커널 (microkernel) 에이전트를 위한 자연스러운 시작점이 될 것입니다.

WASM은 더 표준적인 샌드박싱 (sandboxing) 기술이기에 또 다른 자연스러운 선택지입니다. Mog는 다른 접근 방식을 취합니다. 배열에 대한 핫 루프 (hot loop)가 JIT 컴파일의 예측 불가능성, WASM 해석의 오버헤드, 또는 외부 바이너리의 프로세스 시작 시간 없이 네이티브 속도로 실행됩니다.

언어 (The Language)

Mog는 LLM (Large Language Models)에 의해 작성되도록 설계된 최소한의 언어입니다. 예시를 포함한 전체 명세(Specification)는 단일 3200-토큰 마크다운 파일에 들어갈 정도로 작으며, LLM은 Mog 프로그램을 작성할 때 이를 컨텍스트(Context)에 고정(Pin)할 수 있습니다. 언어의 모든 요소는 특정 작업을 위한 프로그램을 작성하도록 LLM에 요청하는 시점과, 해당 작업을 수행하는 성능 좋은 프로그램이 준비되는 시점 사이의 지연 시간(Latency)을 최적화하도록 설계되었습니다.

Mog 구문(Syntax)의 주요 목표는 LLM에게 친숙하게 만드는 것입니다. 이는 TypeScript, Rust, Go가 혼합된 형태이며, 약간의 Python 스타일(Pythonisms)이 가미되어 있습니다. 모듈 시스템은 Go 모듈을 모델로 합니다. Mog는 작지만 사용 가능한 언어이며, 실수할 여지(Foot-guns)가 없습니다. 암시적 타입 변환(Implicit type coercion), 연산자 우선순위(Operator precedence), 초기화되지 않은 데이터(Uninitialized data)가 존재하지 않습니다.

왜 정적 타입(Statically typed)이며 컴파일(Compiled) 방식인가요? 이 영역에서는 지연 시간(Latency)이 중요하기 때문입니다. 모든 도구 호출(Tool call) 전에 실행되는 에이전트 플러그인(Agent plugin)을 생각해 보십시오. 플러그인은 빨라야 하며, 그렇지 않으면 사용할 가치가 없습니다. Jeffrey Emanuel는 시작 시간(Startup time)을 줄이고 Python의 오버헤드(Overhead)를 낮추기 위해 자신의 모든 에이전트 플러그인을 Rust로 다시 작성했습니다. 현대의 컴퓨터는 빠르지만, Python은 빠르지 않습니다. 대폭 최적화된 Bun의 시작 시간조차 Rust 프로그램의 시작 시간에는 훨씬 못 미치며, 그조차도 프로세스 내 라이브러리(In-process library)를 호출하는 것에 비하면 느립니다.

예시 (Example)

다음은 에이전트가 자신의 도구 호출 오류를 모니터링하기 위해 작성할 수 있는 Mog 훅(Hook)입니다:

requires fs; // 호스트(Host)에 의해 제공되어야 함
optional log; // log가 없어도 실행됨
pub fn on_tool_result(tool_name: string, stderr: string) {
...

처음 두 줄은 보안(Security)에 관한 이야기를 해줍니다. 이 훅은 파일에 내용을 추가하고 선택적으로 로그를 남길 수는 있지만, HTTP 요청을 보내거나, 셸 명령(Shell commands)을 실행하거나, 환경 변수(Environment variables)를 읽을 수는 없습니다. 호스트는 이 프로그램이 무엇을 할 수 있는지 결정합니다. 만약 이 프로그램에 권한이 없다면 fs.append_file() 호출을 차단(Interdict)할 수도 있습니다.

에이전트가 더 복잡해지고 맞춤형(Bespoke) 코드가 많아질수록, 결합된 시스템의 성능, 정확성(Correctness), 그리고 보안을 유지하는 것이 더 어려워집니다. Mog는 이러한 문제들을 해결하기 위해 설계되었습니다.

권한 시스템 (The Capability System)

Mog는 임베디드 언어 (embedded language)입니다. Lua와 매우 유사하게 호스트 프로그램 내부에서 실행됩니다. Mog 호스트가 게스트 (guest) Mog 프로그램에 함수를 제공하는 방식은 Lua의 우아하고 검증된 설계를 직접적으로 따릅니다. Mog 프로그램 자체는 어떠한 I/O도 수행할 수 없으며, 시스템 콜 (syscalls)을 실행하거나 로우 메모리 (raw memory)에 접근할 수 없습니다. 오직 함수를 실행하고 값을 반환할 수 있을 뿐입니다. 이것이 Mog 샌드박스 (sandbox)의 범위입니다.

모든 I/O, FFI, 시스템 콜 (syscalls) 또는 다른 시스템과의 상호작용은 호스트 함수 (host function)를 호출함으로써만 수행될 수 있습니다. 호스트 함수란 호스트가 Mog 프로그램이 사용할 수 있도록 제공하는 함수를 의미합니다. 이것이 Mog 권한 시스템 (capability system)의 핵심입니다. 즉, 호스트는 게스트가 호출할 수 있는 함수를 정확히 결정합니다. 또한 호스트는 해당 함수의 입력값을 필터링하거나 Mog 프로그램으로 전달되는 응답을 필터링할 수도 있습니다.

이러한 격리 (isolation)의 일부는 Mog 프로그램이 더 미묘한 방식으로 호스트 프로세스를 장악하는 것을 방지하는 것을 포함합니다. 호스트는 Mog 프로그램이 더 큰 메모리 아레나 (memory arena)를 요청할 수 있는지 여부를 제어할 수 있어, 게스트가 사용 가능한 모든 RAM을 소비하는 것을 방지할 수 있습니다. 협력적 인터럽트 폴링 (Cooperative interrupt polling)은 Mog 루프의 모든 백 엣지 (back-edges)에 인터럽트 체크가 추가됨을 의미하며, 이를 통해 호스트는 프로세스를 종료하지 않고도 게스트 프로그램을 중단시킬 수 있습니다. 이는 타임아웃 강제 (timeout enforcement)를 가능하게 합니다. 게스트 프로그램이 메모리를 오염시키거나 프로세스를 종료할 방법은 없습니다 (컴파일러와 호스트가 올바르게 구현되었다는 가정하에).

전형적인 에이전트 (agent)는 이벤트 루프 (event loop)를 실행하므로, Mog 프로그램은 JavaScript나 TypeScript를 작성해 본 사람이라면 익숙할 이벤트 루프 내부에서 실행되도록 설계되었습니다. Mog의 이러한 지원은 주로 async/await 구문으로 구성됩니다. Mog 프로그램은 비동기 함수 (async functions)를 정의할 수 있으며, 중요한 점은 호스트 또한 게스트가 호출할 수 있는 비동기 함수를 제공할 수 있다는 것입니다. 이를 통해 게스트 프로그램은 HTTP 요청과 타이머를 동시에 실행하고, 어느 것이 먼저 완료되는지에 따라 서로 다른 작업을 수행할 수 있습니다. 내부적으로 컴파일러는 LLVM의 동일한 설계를 기반으로 코루틴 로워링 (coroutine lowering)을 사용하여 이를 구현합니다.

컴파일러 (The Compiler)

컴파일러 (The Compiler)

컴파일러는 안전한 Rust로 재작성된 QBE를 코드 생성 백엔드 (code generation backend)로 사용합니다. Mog 프로그램을 컴파일, 로드 및 실행하기 위한 전체 툴체인 (toolchain)은 Rust로 작성되었습니다. 목표는 이 모든 것을 안전한 Rust로 구현하여, 툴체인 내에서 익스플로잇 (exploit)을 찾는 것을 훨씬 더 어렵게 만드는 것입니다.

Mog의 첫 번째 구현체는 백엔드로 LLVM을 사용했습니다. LLVM은 광범위한 최적화 덕분에 다소 더 빠른 코드를 생성할 수 있지만, 두 가지 주요한 문제가 있었습니다. 첫째, 컴파일 시간이 충분히 빠르지 않았습니다. 새로운 컴파일러의 컴파일 시간은 Go만큼 좋지는 않지만, 1,000줄 미만의 프로그램의 경우 그 차이가 한 자릿수(order of magnitude) 이내입니다. 즉, 일회성 스크립트의 시작 시간이 고통스럽지 않을 만큼 충분히 빠릅니다. Mog는 제로 코스트 추상화 (zero-cost abstractions)나 임의의 저수준 최적화 기회를 제공한다고 주장하지 않습니다. 네이티브 코드 (native code)로 컴파일되지만, 전문가는 여전히 더 빠른 C 또는 C++를 작성할 수 있습니다.

LLVM의 두 번째 문제는 Mog의 경우 컴파일러 자체가 신뢰 컴퓨팅 기반 (trusted computing base)의 일부라는 점입니다. 만약 컴파일러에 보안 결함이 있다면, 에이전트 (agent)에도 보안 결함이 있는 것입니다. 이로 인해 LLVM과 같이 거대한 코드베이스는 제외됩니다. 컴파일러는 제어하고 감사 (audit)할 수 있을 만큼 충분히 작아야 합니다.

현재 상태 (Current Status)

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0