
AI가 작성한 코드를 인간이 읽을 수 있는 언어 — Jacquard v0.1 rc3 사용 기록
요약
AI가 생성한 코드를 인간이 효율적으로 리뷰할 수 있도록 설계된 연구용 언어 Jacquard v0.1 rc3를 소개합니다. 이 언어는 함수의 시그니처에 부작용(side effect)을 명시하고 런타임에서도 이를 강제하여 코드의 안전성을 보장합니다.
핵심 포인트
- AI 생성 코드 리뷰의 부담을 줄이기 위해 설계된 언어
- Effect row를 타입에 포함하여 부작용을 명시적으로 관리
- 컴파일 단계와 런타임 모두에서 Capability를 통한 실행 제어 제공
- 간편한 설치 프로세스와 실질적인 동작 검증 가능
지난주, Jacquard라는 연구용 언어의 v0.1 rc3가 공개되었습니다. star 수는 현재 시점에서 100여 개 정도입니다. 일본어권에서 이 언어에 대해 작성된 기사는 제가 조사한 바로는 아직 한 건도 없습니다.
먼저 결론부터 말씀드리겠습니다. **「AI에게 작성하게 한 코드를 인간이 리뷰하는 시대」**를 향해 설계된, 처음으로 실제로 동작하는 언어입니다. 착상은 Koka / Unison / Racket / Haskell의 합성으로 아주 새롭지는 않지만, effect row를 타입에 싣고, 실행 시에도 capability로서 강제한다는 조합을, install부터 10분 만에 만져볼 수 있는 완성도로 내놓았다는 점이 현재의 다른 언어들과의 차이점입니다.
이 기사에서는 실제로 install 하여 3가지 demo를 거쳐, 동작하는 화면을 캡처한 것까지 실행 명령과 출력을 그대로 남기겠습니다.
Jacquard는 무엇을 해결하려 하는가
일반적인 언어에서, 다음과 같은 Python 코드가 Pull Request로 올라왔다고 가정해 봅시다.
def normalize_name(name):
return lookup_alias(name).strip().lower()
normalize_name은 네트워크에 접속할까요? 파일을 작성할까요? 답을 하려면 lookup_alias의 내용과, 그 안에서 호출되는 함수를 전부 읽어야 합니다. 부작용 (side effect)은 함수의 시그니처 (signature)에 나타나지 않기 때문에, 리뷰어는 transitive closure를 추적해야 합니다. 사람이 작성한 코드에서도 번거로운 이 작업이, 모델이 작성한 코드를 읽는 빈도가 높아지는 순간 일상의 부담이 됩니다.
Jacquard의 동일한 함수는 다음과 같이 작성합니다.
normalize-name : (Text) ->{Net} Text
시그니처의 ->{Net}가 이 함수가 네트워크를 접한다는 계약입니다. **checker가 이 row를 call graph로부터 자동으로 추론하며, 누락되어 있다면 컴파일 에러 (compile error)**가 발생합니다. 실행 시에도 --allow net을 붙이지 않으면 거부(refuse)됩니다. 「시그니처에 쓴 대로만 동작한다」는 것을 언어 스스로가 담보합니다.
install부터 동작 확인까지
install은 명령어 한 줄이면 됩니다. OCaml도 opam도 필요 없으며, 바이너리가 내려받아질 뿐입니다.
curl -fsSL https://raw.githubusercontent.com/jbwinters/jacquard-lang/jacquard-core-0.1-rc3/scripts/install.sh | sh
~/.local/bin/jac run ~/.local/share/jacquard/demos/basics/m1-fact.jac
# → 120
120 (5의 계승/factorial)이 나오면 셋업 완료입니다.
실연 1: capability gate가 실행을 거부한다
먼저 「시그니처에 쓴 효과를 runtime도 강제한다」는 부분을 보겠습니다.
net-sample : (Text) ->{Net} Text
net-sample(url) = match fetch(MkRequest(url, "")) {
| MkResponse(_, body) -> body
...
->{Net}를 선언한 이 함수를, 우선 허가를 주지 않고 실행합니다.

--allow를 붙이지 않은 실행에서는, runtime이 실행 자체를 거부합니다.
error[E0814]: this program requires the `net` effect, which is not granted (performed via `net-sample`)
hint: grant it with --allow net, or handle the effect in the program
종료 코드 3. --allow net을 다시 붙이면 통과하며, stub 응답이 반환되어 종료 코드 0이 됩니다. **「타입에 쓴 효과 = 실행 시에 허가된 효과」**의 대응이, 커맨드라인 인자 하나로 물리적으로 강제됩니다.
이는 JavaScript의 --allow-net (Deno)이나, Rust의 unsafe
블록(Block)과는 다릅니다. Deno는 "프로세스에 대한 권한"이며, 모듈 내부에서 어떤 일이 일어나는지는 추적할 수 없습니다. Rust의 unsafe는 "메모리 안전성(memory safety)을 포기하는 영역"의 선언이며, 부작용(side effect) 그 자체를 표현하지는 않습니다. Jacquard는 함수의 타입에 효과(effect)를 싣고, 호출 그래프(call graph) 전체로 전파시키며, 실행 시점에 방출(discharge)하는 설계입니다. 동적으로 로드된 코드에도 동일한 규칙이 적용됩니다.
실연 2: 동일한 정책(policy)을 3가지 세계에서 실행하기
demo tree에 포함된 case-studies/release-risk/run.sh를 실행하면, inventory와 payments의 건전성(health)을 바탕으로 Ship / Canary / Hold를 결정하는 policy를 3가지 핸들러(handler)로 나누어 사용하는 모습을 볼 수 있습니다.
sh ~/.local/share/jacquard/demos/case-studies/release-risk/run.sh

위에서부터 차례대로 읽어보겠습니다.
inferred authority의 4행은 checker가 추론한 함수의 효과(effect) 행(row)입니다.
release-assessment : () ->{Telemetry} Assessment
with-snapshot : forall a | e. (Health, Health, Bool, () ->{Telemetry | e} a) ->{| e} a
with-risk-model : forall a | e. (() ->{Dist, Telemetry | e} a) ->{Dist | e} a
...
release-assessment는 Telemetry를 요구합니다. with-risk-model은 그 Telemetry를 받아서 Dist로 변환하여 외부로 내보냅니다. conditioned-release-risk는 Dist만을 외부에 남깁니다. "어떤 효과를 요구하고, 어떤 핸들러(handler)에서 방출(discharge)할 것인가"를 시그니처(signature) 상에서 추적할 수 있다는 점이 이 언어의 리뷰 경험의 핵심입니다.
그 다음에 3가지 실행 결과가 나열됩니다.
-
결정론적 핸들러(deterministic handler):
with-snapshot(Healthy, Degraded, False, ...)로Telemetry를 고정값으로 고정(pin)하여 실행 →assessment(healthy, degraded, false, canary(5)) -
확률적 핸들러(probabilistic handler):
with-risk-model이Telemetry를 확률 분포로 사상(mapping)하고, "checkout 실패를 관측했다"는 조건하에서의 사후 분포(posterior distribution)를 열거(enumerate)합니다:0.305077 canary(5) 0.295394 hold("inventory-down") 0.184621 canary(10) 0.155903 hold("payments-down") 0.059005 ship
0.059005 ship은 "ship 할 확률 5.9%"가 아니라, "checkout 실패를 관측한 조건하에서 이 policy가 ship을 선택할 사후 확률(posterior probability)"입니다. 베이지안 증거(Bayesian evidence)가 observe라는 효과 연산(effect op)으로 작성되며, 핸들러(handler)가 추론(inference) 알고리즘 측을 담당하는 분리된 설계입니다.
- 철저한 핸들러(exhaustive handler): Warp(동봉된 테스트 프레임워크)가 18가지의 telemetry world를 **전체 열거(enumerate)**하여, "down 의존성이 있으면 ship을 선택하지 않는다"는 성질을 증명합니다. 샘플링(sampling)이 아닌 열거(enumerate)입니다.
동일한 policy 코드를 단 한 번만 작성하고, 핸들러(handler)를 교체하여 3가지 세계에 연결합니다. mock, 속성 테스트(property test), 확률 모델(probabilistic model)이 별개의 라이브러리가 아니라, 핸들러의 변수로서 언어에 내장되어 있습니다.
AI 시대의 설계 원칙을 선점하고 있는 부분은 어디인가
저는 AI 안전성 연구자가 아니라, 코드 리뷰에 시간을 뺏기는 평범한 엔지니어입니다. 저에게 Jacquard의 가치는 다음 두 가지로 요약됩니다.
- 프롬프트 인젝션 (prompt injection) 계열의 공격이 숨을 곳이 없어진다. LLM이 악의적인 부작용 (side effect)을 헬퍼 (helper) 함수 안에 심어두더라도, 콜 그래프 (call graph)를 통해 이펙트 로우 (effect row)의 호출부에서 반드시 드러납니다.
--allow net옵션을 전달하지 않고 실행하면, 페이로드 (payload)가 발화하기 전에 프로세스가 중단됩니다. 즉, '리뷰에서 놓칠 위험'을 '실행 시 옵션 설계'의 문제로 대체할 수 있습니다. - 같은 코드를 다른 환경에서도 실행할 수 있다. Mock을 다시 작성할 필요도, Pyro의 다른 구현체나 프로퍼티 테스트 (property test)를 위한 별도의 파일도 필요하지 않습니다. Mock과 프로덕션 (production) 환경의 불일치로 발생하는 버그를 설계 단계에서부터 원천적으로 제거할 가능성이 있습니다.
이는 단순히 'AI가 작성한 코드'이기 때문이 아니라, '타인이 작성한 코드'를 안전하게 리뷰하고 싶은 사람에게도 동일하게 유효합니다. 사람이 작성한 오래된 코드라 할지라도 시그니처 (signature)가 이펙트 로우 (effect row)를 가지고 있다면 독해 부하는 똑같이 줄어듭니다. 다만, AI 생성 코드의 양이 기하급수적으로 늘어나고 있는 현 상황에서 그 필요성이 가시화되었다고 생각합니다.
제약 사항
솔직하게 말씀드리겠습니다.
- v0.1 rc3는 연구용 프로토타입 (prototype)입니다. 리포지토리 (repo)에
docs/release/0.1/LIMITS.md가 동봉되어 있으며, 프로덕션 (production) 용도로 사용하는 것은 명확히 부정됩니다. - 에코시스템 (ecosystem)은 이 리포지토리 하나뿐입니다. 서드파티 패키지 (third-party package)는 아직 존재하지 않습니다.
- 문법이 아직 거칠 수 있습니다. 제가 작성한 Warp 테스트 초안은
throw이펙트 (effect)를 로우 (row)에 포함하지 않아 컴파일이 되지 않았고,throw.catch로 흡수하여 수정했습니다. 에러 메시지가 정확하여 수정에는 3분이 걸렸지만, 학습 과정이 전혀 필요 없는 수준은 아닙니다. - 설치 스크립트 (install script)는 외부 DNS 통신이 가능해야 합니다. 샌드박스 (sandbox) 환경에서는 미리 가져온 타볼 (tarball)을 사용해야 합니다.
이것들은 '언어 철학의 한계'가 아니라 'rc3 단계의 완성도 문제'이므로, v1.0을 향해 가면서 해결될 것입니다.
직접 실행해 보는 데 10분이면 충분합니다
자신의 머신 (machine)에서 동일한 화면을 보고 싶다면, 다음 명령어를 순서대로 입력하기만 하면 됩니다.
# install
curl -fsSL https://raw.githubusercontent.com/jbwinters/jacquard-lang/jacquard-core-0.1-rc3/scripts/install.sh | sh
# 실행 확인
...
마지막 명령어의 출력이 이 기사의 두 번째 스크린샷과 일치합니다. 작성된 내용 그대로 재현할 수 있음을 직접 눈으로 한 번 확인한 뒤에, 이 언어를 '만져볼 가치가 있는지' 판단하는 것이 좋을 것 같습니다.
참조
- Repo: github.com/jbwinters/jacquard-lang
- 설계자에 의한 해설: research.friendmachine.co/jacquard
- 실행 환경: macOS 15.5 (Darwin 25.5.0), jacquard-core 0.1 rc3
Discussion

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