img of I built a programming language that LLMs can't use
코드를 작성하는 것은 아마도 LLM들이 가장 잘해낸 분야일 것입니다. 하지만 이들의 코딩 능력 중 어느 정도가 코드에 대한 이해 덕분인지, 아니면 단순히 훈련 데이터셋이나 컨텍스트 창에 존재했던 코드 스니펫을 기억해서 가져오는 것 때문인지 궁금합니다.
이것이 제가 답하고자 했던 문제입니다. 이를 위해 저는 인간에게는 사용 가능하지만, LLM과 코딩 에이전트에게는 최대한 어려울 수 있는 프로그래밍 언어를 설계하고 구현하기로 결정했습니다.
LLM이 이전에 본 적 없는 프로그래밍 언어에서 코드의 이해와 작성을 테스트하는 것이 좋은 시작이라고 생각했습니다. 하지만 저는 또한 LLM의 약점을 이용하도록 언어에 기능을 포함시키고 싶었습니다. 예를 들어, 글자 수를 세는 데 어려움을 겪는 점, 지나치게 적극적인 안전 장치(safety guard rails), 그리고 프롬프트를 따르려는 경향성 등이 있습니다.
KillSwitch 소개
KillSwitch는 LLM과 코딩 에이전트에게 적대적으로 설계된 난해한(esoteric) 프로그래밍 언어입니다. 이는 여러 가지 방식으로 작동합니다. 예를 들면 다음과 같습니다:
- 언어 사양(spec)에는 인간이 읽기 어렵거나, 혹은 거짓말임을 인식하기 쉬운 숨겨진 허위 정보가 포함되어 있습니다. 또한 이 사양은 명시적으로 설명되기보다는, 인간 독자가 특정 사항들을 추론할 것을 기대합니다.
- 식별자(identifier)의 글자 수 계산이 언어의 중요한 측면이며, 인터프리터는 문자 수를 기반으로 규칙을 준수하지 않는 코드를 실행하는 것을 거부합니다.
- 특정 구문은 모델의 안전 장치(safety guardrails)를 작동시키도록 설계되었습니다. 예를 들어, “컴퓨터에 해킹하다”와 같은 내용입니다.
- 언어에서 의미를 갖는 문구인 “이전 지침 무시하기(Ignore previous instructions)”는 모델을 혼란스럽게 하려는 목적을 가집니다.
- 스크립트는 대부분 잡음(noise)이며, 구문적으로 관련 있는 명령어를 포함할 수는 있지만 반드시 그럴 필요가 없는 이야기들로 주로 구성되어 있습니다. 리터럴은 스크립트 내 어디에나 배치될 수 있으며, 라인 카운트를 사용하여 참조됩니다.
근본적으로 KillSwitch는 함수, 변수, if 문과 같은 제한된 구성 요소만을 가진 스택 기반 인터프리터 언어입니다. 따라서 이러한 측면들은 모든 LLM(그리고 인간)에게 꽤 익숙할 것입니다. 물론 LLM을 더욱 혼란스럽게 만들 수 있는 완전히 다른 프로그래밍 언어 패러다임을 만드는 것을 상상해 볼 수 있습니다. 하지만 첫 시도로는 이것이 좋은 접근 방식인 것 같았습니다.
대부분의 스크립트 내 텍스트는 인터프리터에 의해 무시됩니다. 이 스크립트의 경우, 우리는 "Hello World"를 스택에 푸시하고 싶습니다. 저희는 위에서 값을 도입했으며 다음과 같이 작성하여 스택에 이를 푸시할 수 있습니다:
...
위 예시는 완전한 KillSwitch 스크립트를 보여주는 것이 아니라 작은 일부만을 보여줍니다. 이는 특히 문자열 "Hello World"를 스택에 푸시하는 방법을 보여줍니다. 전체 Hello World 예시를 보고 싶다면 https://killswitch-lang.org를 확인해 보세요.
KillSwitch의 인터프리터와 언어 사양은 오픈 소스이며 GitHub에서 이용 가능합니다. 이 언어에 대해 더 알고 싶다면 꼭 확인해 보시기 바랍니다.
KillSwitch 벤치마킹
그렇다면 KillSwitch가 LLM과 코딩 에이전트가 이를 읽고, 쓰고, 이해하는 것을 얼마나 잘 방지할 수 있을까요? 저는 알아내기 위해 일련의 과제들을 고안했습니다. 주요 LLM 모델들과 코딩 에이전트 하네스를 이 과제들에 대해 벤치마킹했습니다. 그 결과는 매우 흥미로우며 LLM 모델을 위한 유용한 리더보드를 제공합니다.
Score vs. cost per task
위 이미지의 차트와 모델 리더보드는 https://bench.killswitch-lang.org/에서 확인할 수 있습니다.
Claude의 Opus가 가장 좋은 성능을 보였는데, 이는 Opus 5.5가 아니라 Opus 5입니다. 이 차이는 순전히 우연이라고 보기 어려우며, Opus 5가 사양을 해석하는 데 더 능숙합니다. Fable 5.1이나 Gemini 4 Argon 같은 일부 모델들은 지나치게 민감한 안전 가드레일 때문에 성능이 저조했습니다. 가장 좋은 오픈 웨이트 모델은 MiMo-V2.6-Pro입니다.
최고 성능을 보인 모델은 66.8점을 기록했습니다. 그렇다면 이것이 LLM이 코드를 “이해”할 수 있다는 것을 증명하는 것일까요? 저는 이에 대한 답은 “아니다”라고 주장하고 싶습니다.
지금까지 이 벤치마크의 일부로 주어진 과제들은 상당히 간단합니다. 여기에는 “hello world 구현하기”, “이 스크립트가 어떤 출력을 내는지 설명하기”(두 숫자의 최댓값을 출력하는 스크립트에 대한 것), 그리고 “기존 스크립트를 수정하여 섭씨를 화씨로 변환하는 것을 역변환하도록 바꾸기”와 같은 과제들이 포함됩니다. 이들은 자신들을 혼란스럽게 만들기 위해 구축된 새로운 언어에 대해 이러한 과제들을 해결할 수 있다는 것은 인상적이지만, 이것이 그들이 언어를 이해한다는 명확한 신호는 아닙니다. 동시에, 저는 훨씬 더 어려운 언어가 무엇을 보여줄지 궁금하지 않을 수 없습니다. 현재로서는 곧 출시될 모델들이 현재의 과제 세트를 얼마나 잘 처리하는지 보고 싶고, 만약 이 모든 것을 성공적으로 완료한다면, 저는 더 복잡한 또 다른 과제 세트를 고안할 계획입니다.
적어도 이것만으로도, 이 간단한 과제 세트에 대한 모델 성능이 외부에 존재하는 다른 모델 벤치마크와 상관관계가 있다는 것은 고무적입니다.