마크다운을 넘어선 스킬 자가 진화, SkillScriptBench가 재는 것

문서와 스크립트가 한 묶음으로 움직이는 실행형 에이전트 스킬을 어떻게 고치고 유지할지, 350개 작업으로 따로 재는 벤치마크를 읽어봅니다.

원문 논문 보기
'마크다운을 넘어선 스킬 자가 진화, SkillScriptBench가 재는 것' 기사 커버 이미지

오늘 다룰 논문은 SkillScriptBench: Benchmarking Self-Evolution of Executable Agent Skill Packages Beyond Markdown입니다. 이 연구는 arXiv에 공개되었고 식별자는 2610.04008입니다. 원문 링크는 제목 아래에 걸어두었습니다.

이 연구가 내세우는 주장은 한 문장으로 정리됩니다. 실행형 에이전트 스킬을 제대로 고친다는 것은 문서와 스크립트를 함께 되살리는 자가 진화 능력을 갖추는 것이고, 그래서 350개 작업으로 문서 수리, 스크립트 수리, 유지 능력을 따로 재야 한다는 것입니다.

안녕하세요, 패트릭입니다.

저는 평소에 조수에게 일을 맡길 때 설명서와 도구가 따로 놀면 얼마나 답답해지는지 자주 느낍니다. 설명서에는 이렇게 하라고 적혀 있는데 막상 도구는 다르게 움직이면, 그 간극을 메우는 일은 결국 제 몫이 되니까요. 그렇다면 AI 에이전트에게 건네는 스킬 묶음도 같은 문제를 안고 있지 않을까요. 제가 이 논문에서 가장 흥미롭게 본 부분은 바로 그 지점이었습니다. 문서를 예쁘게 다듬는 일을 넘어, 문서와 코드가 함께 고장 나고 함께 나아야 하는 상황을 벤치마크로 옮겨왔다는 점이죠.

매번 처음부터 헤매는 조수를 본 적 있으신가요

현장에서 에이전트를 써보면 비슷한 장면이 반복됩니다. 어제는 잘하던 작업이 오늘은 어긋나고, 설명을 조금만 바꾸면 스크립트가 엉뚱한 곳에서 멈춥니다. 그래서 운영자는 매번 처음부터 헤매는 조수를 들여다보는 기분이 되는데, 이 답답함은 생각보다 구조적인 이유에서 옵니다.

에이전트용 스킬이라는 말은 요즘 꽤 넓게 쓰입니다. 그런데 여기서 말하는 실행형 스킬은 범위가 분명합니다. 자연어로 적힌 사용 설명과 실제로 돌아가는 스크립트가 한 패키지로 묶여 있고, 에이전트는 그 묶음을 통째로 불러다 쓰는데요. 설명이 바뀌면 동작이 바뀌어야 하고, 동작이 바뀌면 설명도 따라 바뀌어야 합니다. 한쪽만 고치면 다른 쪽이 거짓말이 되기 때문입니다.

그렇다면 자가 진화라는 말은 무엇을 뜻할까요. 모델 가중치를 다시 학습한다는 뜻이 아닙니다. 이미 배포된 스킬 묶음에 수리 요청이 들어왔을 때, 에이전트 스스로 문서와 코드를 손봐서 고장 난 부분은 고치고 멀쩡한 부분은 그대로 두는 능력을 말합니다. 생각해보면 사람도 비슷하게 배웁니다. 실수한 대목을 노트에 적어두고 다음에는 같은 실수를 피하는데, 이때 멀쩡하던 습관까지 뒤집을 필요는 없죠. 이 논문은 그 당연해 보이는 일을 측정 가능한 형태로 바꿨습니다.

문서 카드와 스크립트 파일이 한 묶음으로 연결된 에이전트용 스킬 패키지 개념도
문서 카드와 스크립트 파일이 한 묶음으로 연결된 에이전트용 스킬 패키지 개념도

35,000개 중에서 100개를 고르면 무엇이 남을까

벤치마크를 읽을 때 저는 숫자보다 그 뒤의 선별 과정을 먼저 봅니다. 이 연구는 GitHub에 올라온 스킬 저장소 35,000여 개를 훑는 일부터 시작했는데, 이 규모는 그 자체로 메시지를 담고 있습니다. 실행형 스킬이 이미 현장에서 빠르게 번지고 있다는 뜻이니까요.

연구진은 그 많은 저장소 가운데 100개 패키지를 골라 150개 수리 작업을 만들었습니다. 비율로만 보면 0.3%도 안 되는 셈인데, 이렇게 좁히는 과정에는 분명한 의도가 있습니다. 너무 작거나 의존성이 꼬인 묶음, 실행으로 확인할 수 없는 묶음은 빼고, 수리 요청과 실행 검사를 붙일 수 있는 묶음만 남긴 것이죠. 저는 이 대목에서 멈칫했습니다. 벤치마크가 쉬워서가 아니라, 측정이 가능하도록 깎아내는 작업이 연구의 절반이라는 생각이 들었기 때문입니다.

남은 100개는 그래서 평균적인 스킬이 아닙니다. 현실에서 자주 쓰이는 형태이면서도, 고장을 넣고 다시 돌려볼 수 있는 형태입니다. 마치 공구함 35,000개를 열어본 뒤에, 수리 실습에 쓸 만한 100개를 골라 작업대에 올려둔 셈인데요. 이 선별이 잘 되었는지는 뒤에 나오는 통제 실험을 보면 좀 더 분명해집니다.

수많은 공개 저장소에서 선별된 스킬 패키지로 좁혀지는 선별 과정을 담은 도식
수많은 공개 저장소에서 선별된 스킬 패키지로 좁혀지는 선별 과정을 담은 도식

수리 요청서 한 장과 고장 난 공구함이 함께 도착합니다

150개 작업의 구성은 단순하면서도 까다롭습니다. 각 작업은 고장이 주입된 스크립트를 담은 패키지, 유지보수 요청서, 그리고 요구된 동작을 실행으로 확인하는 검사로 이루어져 있는데, 이 세 가지가 한 세트로 움직입니다.

요청서는 이런 식으로 읽힙니다. 어제까지 되던 기능이 오늘은 특정 조건에서 깨지니 고쳐달라는 주문이죠. 이때 에이전트는 문서만 만질 수도 있고 스크립트만 만질 수도 있으며, 둘 다 만질 수도 있습니다. 평가는 말의 매끈함으로 갈리지 않고, 검사를 통과했는지로 갈립니다. 실행이 말을 검증하는 구조입니다.

여기서 재미있는 질문이 생깁니다. 고장을 인위적으로 넣었다면 현실과 멀어지는 것 아닐까요. 저는 그렇게만 보지 않습니다. 현장의 고장은 원인이 뒤섞여 있어서 무엇을 재는지가 흐려지기 쉬운데, 주입된 고장은 어디가 아픈지를 정확히 알고 시작할 수 있기 때문입니다. 병원에서 증상이 분명한 모의 환자로 술기를 시험하는 일과 비슷하죠. 물론 모의 환자가 실제 환자를 대신할 수는 없습니다. 그래서 이 논문은 주입된 고장만으로 끝내지 않고, 뒤에서 상태를 나눈 통제 실험을 덧붙입니다.

수리 요청과 실행 검사가 맞물려 돌아가는 복구 작업 흐름을 정리한 도식
수리 요청과 실행 검사가 맞물려 돌아가는 복구 작업 흐름을 정리한 도식

같은 요청을 네 가지 상태로 돌려보면 무엇이 보일까

이 논문에서 제가 앞으로 보고 싶은 것 못지않게 눈여겨본 대목은 200개 작업으로 이루어진 통제 트랙입니다. 50개 패키지를 가져와 같은 유지보수 요청을 네 가지 상태에서 시험하는데, 멀쩡한 상태, 문서에만 고장이 있는 상태, 스크립트에만 고장이 있는 상태, 둘 다 고장 난 상태가 그것입니다.

같은 요청을 조건만 바꿔가며 돌리면, 에이전트의 행동을 훨씬 또렷하게 읽을 수 있습니다. 문서 고장은 잘 고치는데 스크립트 고장 앞에서 멈추는지, 스크립트는 고치면서 멀쩡하던 설명을 망가뜨리는지, 멀쩡한 패키지에 손을 대서 오히려 일을 만드는지가 드러나니까요. 저는 이 설계를 보고 무릎을 쳤습니다. 현실에서는 고장의 위치를 알 수 없어서 해석이 흐려지는데, 여기서는 고장의 위치를 실험자가 쥐고 있으니 변별력이 생기기 때문입니다.

문제는 그다음입니다. 이렇게 조건을 나누면 점수도 나눠서 읽어야 합니다. 문서 수리, 스크립트 수리, 유지라는 세 가지 능력이 서로 다른 방향을 가리킬 수 있기 때문입니다. 잘 고치는 것과 건드리지 않아야 할 것을 건드리지 않는 것은 다른 재능인데, 그동안 많은 평가는 둘을 한 점수에 섞어왔습니다. 이 벤치마크는 그 섞음을 풀어놓자고 제안합니다.

같은 요청을 네 가지 고장 상태로 나눠 시험하는 통제 실험 구성을 보여주는 그림
같은 요청을 네 가지 고장 상태로 나눠 시험하는 통제 실험 구성을 보여주는 그림

문서 점수와 스크립트 점수를 따로 재야 하는 이유

저희가 새로운 AI 아키텍처를 볼 때도 벤치마크 숫자만 보지는 않습니다. 실제로 무엇이 바뀌었고, 그 변화가 시스템에서 어떤 비용 구조를 만드는지를 함께 봅니다. 이 논문의 세 갈래 평가도 같은 자세에서 읽힙니다.

문서 수리는 설명이 요구 사항과 어긋난 부분을 바로잡는 일입니다. 스크립트 수리는 깨진 동작을 실행 검사 기준으로 되살리는 일입니다. 그리고 유지는 고치지 않아도 되는 부분을 그대로 두는 일인데, 이 마지막 항목이 생각보다 중요합니다. 수리를 핑계로 멀쩡한 동작을 깨뜨리면 현장에서는 그게 더 큰 사고가 되기 때문입니다.

표면적으로 보면 단순합니다. 실제로는 그렇지 않습니다. 문서와 스크립트는 서로를 참조하면서 얽혀 있어서, 한쪽을 고치면 다른 쪽의 정합성이 흔들리기 쉽습니다. 설명에는 새 인자를 적어두고 코드에는 옛 인자를 남겨두면, 그 어긋남은 다음 호출에서 바로 터집니다. 그래서 따로 재는 일은 점수를 쪼개는 잔기술이 아니라, 얽힌 묶음을 다루는 능력을 정직하게 보려는 시도에 가깝습니다. 그렇다면 기존 방법들은 이 세 갈래에서 어떤 모습을 보였을까요.

마크다운만 고치는 방법이 쉽게 무너지지 않는 지점

여기서는 조금 조심해서 읽을 필요가 있습니다. 네 가지 LLM에 걸쳐 시험한 결과, 문서와 스크립트를 함께 고치는 방법들은 스크립트 고장을 다루는 데에는 분명히 도움이 되었습니다. 코드까지 손을 댈 수 있으니 당연한 면도 있죠.

그런데 문서 수리와 유지에서는 이야기가 달라졌습니다. 함께 고치는 방법이 마크다운만 다듬는 수정을 일관되게 앞지르지 못했다는 것입니다. 이 결과는 마음에 들지만, 여기까지 일반화하기에는 데이터가 부족합니다. 다만 방향은 분명합니다. 손댈 곳이 넓어졌다고 해서 모든 방향으로 잘하는 것은 아니라는 뜻이니까요.

이 차이는 생각보다 중요합니다. 스크립트를 고치다가 문서의 정합성을 깨뜨리거나, 멀쩡하던 동작을 건드리면 종합 점수는 오히려 내려갑니다. 도구를 꺼낼수록 고칠 수 있는 것도 늘지만, 망가뜨릴 수 있는 것도 함께 늘기 때문입니다. (참고로 함께 고치는 쪽에는 날것의 패키지를 직접 고치는 방식과 CoEvoSkills라는 공진화 방식이 포함되는데, 둘의 결은 뒤에 나오는 새로운 방법이 잘 보여줍니다.) 그래서 다음 질문은 자연스럽게 이렇게 이어집니다. 넓어진 손을 조심스럽게 쓰는 방법은 없을까.

요구 사항을 코드 위치와 연결해 수리 범위를 좁히는 AST 기반 접근을 그린 도식
요구 사항을 코드 위치와 연결해 수리 범위를 좁히는 AST 기반 접근을 그린 도식

AST를 따라가며 고치는 방법은 어디가 달랐을까

연구진이 함께 내놓은 방법은 이름 그대로 AST에 기대고 있습니다. AST-Guided Skill Revision은 유지보수 요청이 오면 추상 구문 트리와 호출 관계를 따라가며 요구와 관련된 코드 위치를 먼저 찾습니다. 그리고 스크립트 수정은 그 위치로 제한하고, 문서도 그 변경에 맞춰 함께 고칩니다.

순서를 풀어보면 이렇습니다. 요청 문장에서 손봐야 할 동작을 뽑아내고, 트리 위에서 그 동작과 연결된 함수와 호출 가지를 따라갑니다. 관련 없는 파일은 처음부터 손댈 후보에서 빼고, 고친 뒤에는 바뀐 동작대로 설명을 고쳐서 어긋남을 남기지 않습니다. 공구함 전체를 뒤집는 대신, 고장 난 서랍만 열어보는 셈이죠.

저는 이 숫자보다 그 뒤의 구조가 더 중요하다고 봅니다. 수정 범위를 좁히면 두 가지가 좋아집니다. 관련 없는 코드를 건드릴 확률이 줄어서 유지가 쉬워지고, 문서도 바꿔야 할 대목이 분명해져서 정합성을 맞추기 쉬워지기 때문입니다. 물론 트리를 따라간다고 모든 연결이 잡히는 것은 아닙니다. 동적으로 엮인 호출이나 외부 도구에 걸친 흐름은 트리만으로 다 보이지 않으니까요. 그럼에도 방향은 분명합니다. 넓게 고치는 힘보다 좁게 고르는 힘이 먼저라는 것이죠. 그렇다면 이 좁히기는 점수로 어떻게 증명되었을까요.

21.9%와 27.7%라는 숫자를 어떻게 읽어야 할까

수치는 크고 분명합니다. 모델 평균으로 보면, 수리 단계가 고장 난 패키지에서 복구 성공률을 날것의 패키지 방식 기준으로 21.9%포인트, CoEvoSkills 기준으로 27.7%포인트 끌어올렸다는 것입니다. 절대 수치로 읽히는 이 폭은 작은 조정을 넘어 체감되는 변화에 가깝습니다.

이 숫자는 그대로 믿기 전에 조건을 봐야 합니다. 분모가 고장 난 패키지라는 점, 평균이 네 가지 모델에 걸쳐 계산되었다는 점, 그리고 실행 검사를 통과해야 성공으로 쳤다는 점이 함께 붙어 있기 때문입니다. 조건을 붙이면 숫자가 작아 보이기보다 해석이 단단해집니다. 언제, 어디서, 무엇을 기준으로 올랐는지가 분명해지니까요.

같은 맥락에서 저는 비교 대상이 둘이라는 점을 좋게 봤습니다. 날것의 패키지를 직접 고치는 단순한 출발선과, 문서와 코드를 함께 진화시키려는 CoEvoSkills라는 적극적인 출발선을 둘 다 두고 올랐으니, 한쪽에만 유리한 설정이라는 의심을 덜 수 있습니다. 숫자가 크다고 박수를 치기보다, 어디에서 올랐는지를 묻는 편이 이 논문을 제대로 읽는 태도에 가깝습니다. 그리고 그 물음에 답하는 숫자가 하나 더 있습니다.

수리 성공과 유지 성능이 함께 오르는 모습을 개념적으로 그린 차트
수리 성공과 유지 성능이 함께 오르는 모습을 개념적으로 그린 차트

세 번 모두 풀었다는 말이 가진 무게

연구는 한 번 풀고 마는 성공과 세 번 모두 푸는 성공을 구분합니다. 세 번의 실행에서 모두 풀린 작업 비율이 날것의 패키지 방식에서는 20.8%포인트, CoEvoSkills에서는 31.5%포인트 올랐습니다. 한 번의 요행과 반복되는 실력을 가르는 기준이죠.

에이전트 수리는 원래 흔들리기 쉽습니다. 같은 요청에도 고치는 경로가 매번 달라지고, 운 좋게 검사를 통과하는 경우도 생깁니다. 그래서 세 번 모두 통과했다는 말은 단순한 가산점이 아닙니다. 고치는 방법이 어느 정도 안정 궤도에 올랐다는 신호에 가깝습니다. 밤사이 공지가 늦게 도착하거나 아침에 특정 작업이 몰려도 라인이 멈추면 안 되는 운영 측면에서 보면, 이 안정성은 성공률 자체만큼 반갑습니다.

반면 과장해서 읽을 여지도 있습니다. 세 번의 성공이 현장의 모든 흔들림을 보증하지는 않기 때문입니다. 모델이 바뀌거나 의존 패키지가 바뀌면 궤도가 다시 흔들릴 수 있습니다. 그럼에도 세 번이라는 기준은 정직합니다. 한 번의 성공을 실력이라 부르지 않겠다는 선언이니까요. 그렇다면 이제 마지막으로 남는 질문이 있습니다. 잘 고치는 일만큼 소중한, 고치지 않는 일은 어떻게 잴까요.

고치지 않고 두는 능력도 실력입니다

벤치마크의 통제 트랙으로 돌아오면, 멀쩡한 상태에서의 행동이 눈에 들어옵니다. 멀쩡한 패키지에 수리 요청이 와도 손댈 곳이 없으면 그대로 두어야 하는데, 이게 말처럼 쉽지 않습니다. 에이전트는 요청이 오면 무언가 바꿔야 한다는 압박을 느끼기 쉽고, 그 압박은 불필요한 수정으로 이어지기 쉽기 때문입니다.

이 지점에서 유지 점수는 일종의 절제력을 잽니다. 고쳐야 할 때 고치고, 두어야 할 때 두는 리듬이죠. 일상의 비유로 옮기면, 아픈 곳만 치료하고 건강한 곳은 건드리지 않는 진료와 비슷합니다. 검사 항목이 많아질수록 손댈 유혹도 커지는데, 그 유혹을 이겨내는 쪽이 현장에서는 더 신뢰를 받습니다.

그렇다면 사람의 역할은 무엇일까요. 저는 이 논문을 읽고 나서 스킬 묶음의 유지보수를 전적으로 에이전트에게 맡기는 그림이 아직은 멀었다고 봅니다. 고치는 힘은 분명히 커졌지만, 언제 멈출지를 아는 힘까지 같은 속도로 크지는 않았기 때문입니다. 앞으로 보고 싶은 것은 더 큰 점수보다 더 정직한 멈춤입니다. 어떤 요청에는 손을 대지 않았다고 말하고, 왜 대지 않았는지를 설명과 함께 남기는 에이전트 말이죠. 그 멈춤까지 잴 수 있게 되었다는 점에서, 이 350개 작업은 다음 연구를 위한 작업대처럼 느껴집니다.

참고 자료

  1. SkillScriptBench: Benchmarking Self-Evolution of Executable Agent Skill Packages Beyond Markdown · arxiv.org

    리뷰 원문