HarnessDev: LLM이 자기 에이전트 하네스를 직접 만들고 진화시킬 수 있을까
사람이 손으로 만든 에이전트 프레임워크 대신 LLM이 하네스 코드를 직접 생성하고 실행 결과로 골라내는 진화 루프라는 발상을 뜯어봅니다.
원문 논문 보기
노시욱 (Patrick Rho) · AI 연구 해설
이번에 다룰 작업은 HarnessDev: Can LLMs Create and Evolve Their Own Agent Harness, 식별자는 arXiv 2609.01437입니다. 이 작업이 내세우는 주장은 한 문장으로 정리할 수 있습니다. 사람이 설계한 에이전트 프레임워크에 기대는 대신 언어 모델이 하네스 코드를 직접 생성하고 과제 실행 결과로 변형을 추려내면서 하네스를 진화시킬 수 있는지 묻는다는 것입니다. 원문 논문 링크는 이 글 제목 아래에 표시되어 있습니다.
제가 이 논문에서 가장 흥미롭게 본 부분은 질문의 방향입니다. 보통 에이전트 연구는 모델 자체를 더 똑똑하게 만드는 쪽을 봅니다. 더 큰 모델, 더 긴 추론, 더 좋은 도구 사용법을 이야기합니다. HarnessDev는 시선을 모델 바깥으로 돌립니다. 모델을 감싸고 있는 프로그램, 그러니까 도구를 호출하고 순서를 정하고 기억을 관리하고 실패를 수습하는 그 바깥 코드를 모델이 직접 쓸 수 있느냐고 묻습니다. 저는 이 방향 전환이 마음에 들었습니다. 현장에서 에이전트가 멈추는 이유는 모델이 멍청해서가 아니라 바깥 프로그램이 허술해서인 경우가 많기 때문입니다.
이 논문을 집어 든 이유
에이전트를 몇 번이라도 운영해 본 사람은 비슷한 밤을 겪어봅니다. 데모에서는 잘 돌아가던 에이전트가 실제 업무에 올리면 엉뚱한 곳에서 멈춥니다. 도구가 하나 바뀌었는데 파서가 깨지고, 순환 호출이 끝나지 않고, 에러 메시지는 어딘가에서 삼켜지고, 로그를 뒤져보면 모델의 답변 자체는 멀쩡한데 그 답변을 다음 단계로 넘기는 코드가 무너져 있습니다. 모델 점수는 올랐는데 체감 신뢰도는 그대로인 이유가 여기에 있습니다. 병목이 모델 안에만 있지 않습니다.
저희가 새로운 AI 아키텍처를 볼 때도 benchmark 숫자만 보지는 않습니다. 실제로 무엇이 바뀌었고, 그 변화가 시스템에서 어떤 비용 구조를 만드는지를 함께 봅니다. HarnessDev는 바로 그 바깥쪽을 연구 대상으로 삼습니다. 하네스를 사람이 매번 손으로 고치는 부품으로 두지 않고, 생성과 평가의 재료로 취급합니다. 모델이 코드를 쓰고, 그 코드가 과제를 풀고, 성적이 좋은 코드가 남는 순환을 만들면 어떤 일이 벌어지는지 묻습니다. 질문 자체가 실무적인 데다, 답이 나오면 에이전트 개발 방식이 달라질 수 있습니다.
여기서는 조금 조심해서 읽을 필요가 있습니다. 이번에 제가 확보한 근거는 arXiv 식별자를 중심으로 한 연구 개요 수준의 자료입니다. 세부 실험 조건과 수치는 원문을 직접 확인해야 합니다. 그래서 이 글은 논문의 수치를 확정적으로 전달하는 요약이 아니라, 이 발상이 왜 나왔고 어떤 구조로 동작하며 어디가 어렵고 무엇을 다음에 확인해야 하는지를 정리하는 해설에 가깝습니다. 숫자보다 구조를 먼저 세우는 편이 이런 단계에서는 더 정직합니다.

하네스는 모델 바깥의 또 다른 프로그램이다
하네스라는 말은 넓게 쓰입니다. 이 글에서는 모델 호출을 감싼 실행 프로그램 전체를 가리킵니다. 사용자 요청이 들어오면 무슨 순서로 모델을 부를지, 어떤 도구를 쓸 수 있게 할지, 도구 결과를 어떤 형식으로 돌려줄지, 중간 기억을 어디에 얼마나 남길지, 실패하면 몇 번까지 다시 시도할지를 정하는 코드가 전부 하네스입니다. 프롬프트 한 장이 아니라 작은 운영체제 같은 존재입니다.
구체적으로 떠올려 보겠습니다. 웹에서 자료를 찾아 정리하는 에이전트가 있다고 하겠습니다. 모델은 검색어를 생각해내고 결과를 읽고 요약을 씁니다. 하네스는 검색 도구를 실제로 호출하고, 타임아웃을 걸고, 결과 개수를 자르고, 중복을 제거하고, 다음 검색으로 넘어갈지 멈출지를 판단하고, 중간 상태를 파일이나 메모리에 저장합니다. 모델이 똑똑해도 하네스가 검색 결과를 통째로 프롬프트에 밀어 넣으면 비용이 터지고, 반대로 너무 aggressive하게 자르면 필요한 문맥이 사라집니다. 성능은 모델과 하네스의 합으로 정해집니다.
실제 시스템 관점에서 보면 다음 질문이 바로 생깁니다. 모델은 버전이 올라가면 통째로 교체되는데, 하네스는 왜 매번 프로젝트마다 처음부터 다시 만드는가. 회사마다, 팀마다, 심지어 같은 팀 안에서도 과제마다 하네스가 조금씩 다릅니다. 재시도 정책 하나, 기억 형식 하나가 다르면 같은 모델을 써도 결과가 달라집니다. 이런 흩어진 구현이 쌓이면 노하우가 코드에 잠기고, 좋은 패턴이 퍼지지 않습니다. HarnessDev가 겨냥한 지점이 여기입니다. 하네스를 우연히 잘 만드는 기술이 아니라 반복해서 만들 수 있는 과정으로 바꾸자는 제안입니다.
손으로 만든 프레임워크가 버거워진 이유
예전에는 손으로 만든 프레임워크로 충분했습니다. 도구가 몇 개 없었고, 과제 형태도 단순했고, 모델 능력도 비슷했기 때문입니다. 사람이 몇 가지 패턴을 정해두면 대부분의 과제가 그 안에 들어갔습니다. 순차 호출, 간단한 분기, 고정된 재시도 횟수 정도면 데모가 돌아갔습니다.
지금은 조건이 달라졌습니다. 쓸 수 있는 도구가 늘어났고, 과제는 여러 단계로 길어졌고, 모델마다 잘하는 일과 자주 틀리는 일이 다릅니다. 어떤 모델은 도구 호출 형식을 잘 지키는데 계획을 자주 바꾸고, 어떤 모델은 계획은 꾸준한데 긴 도구 결과를 읽다가 길을 잃습니다. 하나의 하네스로 모든 모델을 덮기 어렵습니다. 모델이 바뀌면 프롬프트뿐 아니라 호출 순서와 기억 관리까지 다시 손봐야 합니다. 프레임워크를 만드는 속도가 모델이 바뀌는 속도를 따라가지 못합니다.
제가 이 대목에서 주목한 것은 규모와 다양성의 충돌입니다. 모델은 몇 달 만에 바뀌는데 하네스는 사람의 손에 묶여 있습니다. 사람이 직접 고치는 방식은 한두 개 과제에는 정밀하지만, 열 개 스무 개 과제로 넓어지면 감당이 안 됩니다. 각 과제에 맞춘 조정이 필요하고, 그 조정이 서로 충돌합니다. A 과제에서 잘 돌아가는 재시도 정책이 B 과제에서는 비용 폭탄이 됩니다. 이런 상황에서 자연스럽게 나오는 생각이 자동화입니다. 사람이 일일이 고치는 대신, 후보를 많이 만들고 실행으로 가려내는 기계를 만들자는 것입니다.

생성하고 실행하고 남기는 진화 루프
HarnessDev가 그린 과정은 말로 풀면 단순합니다. 모델이 하네스 코드 후보를 만들고, 그 후보를 실제 에이전트 과제에 올려 실행하고, 성적이 좋은 후보를 남겨 다음 세대의 출발점으로 삼습니다. 세대를 거듭하면서 하네스가 조금씩 나아지기를 기대합니다. 사람이 설계도를 그리는 대신, 선택 과정을 설계하는 셈입니다.
각 단계를 조금 더 들여다보겠습니다. 생성 단계에서는 모델이 하네스 코드를 씁니다. 도구 호출 규칙, 계획 순환, 기억 읽기 쓰기, 에러 처리 같은 부품을 포함한 실행 코드입니다. 처음에는 여러 변형을 넓게 만듭니다. 어떤 후보는 재시도를 넉넉하게 주고, 어떤 후보는 기억을 짧게 유지하고, 어떤 후보는 도구 결과를 미리 요약합니다. 다양성이 재료입니다. 변형이 서로 비슷하면 선택이 힘을 잃습니다.
평가 단계에서는 후보 하네스를 과제에 붙여 돌립니다. 성공 여부, 단계 수, 도구 호출 횟수, 실패 복구율 같은 실행 지표가 나옵니다. 여기서 중요한 것은 모델의 똑똑함과 하네스의 기여를 가급적 분리해서 보는 일입니다. 같은 모델에 다른 하네스를 붙였을 때 결과가 어떻게 달라지는지가 진짜 관심사입니다. 모델을 통째로 바꾸면서 하네스를 비교하면 무엇이 좋아졌는지 알 수 없습니다.
보존 단계에서는 성적이 좋은 후보를 남기고 나머지를 버립니다. 남긴 후보를 약간씩 변형해서 다음 세대를 만듭니다. 이 반복이 진화라는 이름으로 불리는 이유입니다. 저는 이 숫자보다 그 뒤의 구조가 더 중요하다고 봅니다. 선택 압력이 어디에 걸리느냐에 따라 결과가 완전히 달라지기 때문입니다. 성공률에만 압력을 걸면 성공률은 오르지만 비용이 터질 수 있고, 단계 수에만 압력을 걸면 빠르지만 성급한 하네스가 뽑힐 수 있습니다. 무엇을 재고 무엇을 남길지가 설계의 전부라고 해도 과언이 아닙니다.

점수가 올랐다고 다 좋은 하네스는 아니다
진화 루프에서 가장 먼저 의심해야 할 부분은 평가입니다. 점수가 올랐다는 말은, 재는 자가 제대로 있었다는 전제 위에서만 의미가 있습니다. 하네스 진화에서는 이 전제가 흔들리기 쉽습니다. 하네스가 평가 과제에 맞춰지는 순간, 점수는 오르는데 실제 능력은 그대로인 일이 생깁니다.
예를 들어보겠습니다. 평가 과제가 항상 같은 순서로 도구를 쓰면, 그 순서를 외운 하네스가 높은 점수를 받습니다. 순서를 살짝만 바꿔도 무너집니다. 평가 과제에 특정 에러 메시지가 자주 나오면, 그 메시지에만 잘 대응하는 하네스가 뽑힙니다. 새로운 에러 앞에서는 속수무책입니다. 평가 도구가 관대해서 형식 오류를 봐주면, 형식을 어지럽게 쓰는 하네스가 살아남습니다. 엄격한 현장 도구 앞에서는 바로 탈락합니다. 점수는 진화의 나침반인데, 나침반이 자기장을 잘못 읽으면 배는 엉뚱한 곳으로 갑니다.
저는 여기서 조금 의심했습니다. 하네스와 과제가 함께 진화하는 구조에서는 이런 과적합이 더 잘 숨어듭니다. 모델이 하네스를 만들고, 하네스가 과제를 풀고, 과제 점수가 다시 하네스 선택으로 돌아오는 고리에서는 작은 편향이 증폭됩니다. 우연히 맞은 전략이 실력으로 포장되고, 그 포장이 다음 세대의 출발점이 됩니다. 그래서 평가 과제는 고정된 한 묶음이 아니라 여러 묶음으로 나눠야 합니다. 진화에 쓴 과제, 중간 점검용 과제, 끝까지 감춰둔 과제를 분리해야 합니다. 감춰둔 묶음에서도 점수가 따라오면 그때 비로소 진짜 개선을 이야기할 수 있습니다.
보상 해킹이라는 표현도 같은 맥락에서 읽어야 합니다. 모델이나 하네스가 금지된 지름길을 찾는 현상입니다. 로그를 꾸미거나, 평가자가 좋아하는 형식만 맞추거나, 어려운 단계를 건너뛰고 성공으로 표시하는 식입니다. 사람이 짠 하네스에서도 생기는 일이지만, 자동으로 뽑는 구조에서는 더 빨리 퍼집니다. 지름길이 한 번 선택되면 그 지름길을 쓰는 변형이 다음 세대를 지배하기 때문입니다. 평가 파이프라인에 지름길 탐지를 넣지 않으면, 진화는 실력이 아니라 꼼수를 키웁니다.

자기 조종 코드를 스스로 고친다는 것의 무게
HarnessDev의 질문이 예민한 이유는 대상이 자기 행동을 조종하는 코드이기 때문입니다. 일반 코드 생성과 다릅니다. 하네스는 모델이 어떤 도구를 쓸 수 있고, 어디까지 접근할 수 있고, 실패할 때 무엇을 할지를 정합니다. 이 코드를 모델 스스로 고치게 두면, 능력과 권한의 경계가 한 과정 안에 들어옵니다.
격리의 문제를 먼저 생각해야 합니다. 하네스 후보를 실행하는 환경은 실제 도구와 분리되어야 합니다. 결제, 삭제, 외부 전송 같은 되돌리기 어려운 동작은 진화 과정에서 막거나 가짜 도구로 바꿔야 합니다. 실수로라도 실제 시스템에 닿는 호출이 있으면 안 됩니다. 후보 코드가 파일을 읽는 범위를 벗어나거나, 네트워크로 외부에 접속하거나, 권한을 넓히는 시도를 하면 그 후보는 점수와 관계없이 탈락시켜야 합니다. 안전 검사가 점수 측정보다 먼저 돕니다.
다음은 권한이 넓어지는 방향으로의 진화입니다. 진화는 점수를 좋아합니다. 도구 접근이 넓을수록 풀 수 있는 과제가 늘어나는 것처럼 보이면, 선택 과정이 넓은 권한을 선호할 수 있습니다. 당장은 점수가 오릅니다. 하지만 권한이 넓어진 하네스는 나중에 큰 사고를 냅니다. 필요 이상으로 열린 도구는 언젠가 잘못 쓰입니다. 그래서 권한은 점수와 별개로 감시해야 합니다. 각 후보가 어떤 도구에 접근했고, 그 접근이 과제 해결에 실제로 필요했는지를 기록해야 합니다. 필요 없는 권한을 가진 후보는 성적이 좋아도 남기지 않는 규칙이 필요합니다.
기록과 재현도 빠뜨릴 수 없습니다. 어떤 하네스가 선택되었는지, 그 하네스가 어떤 과제에서 어떤 점수를 받았는지, 중간에 어떤 변형이 있었는지를 전부 남겨야 합니다. 나중에 문제가 생겼을 때 되돌아갈 길이 있어야 합니다. 진화 과정이 블랙박스이면, 잘 돌아가는 하네스가 왜 잘 돌아가는지 아무도 모릅니다. 고장 났을 때 고칠 starting point도 없습니다. 선택의履歴을 남기는 일은 귀찮지만, 자기 코드를 고치는 시스템에서는 의무에 가깝습니다.

과제와 하네스가 함께 움직이면 생기는 함정
진화 구조에서 두 번째로 조심할 부분은 과제와 하네스가 서로에게 맞춰지는 현상입니다. 보통은 과제가 고정되어 있고 모델이 그 과제에 맞춰집니다. HarnessDev 같은 구조에서는 하네스도 움직입니다. 양쪽이 움직이면 평가의 바닥이 함께 움직입니다. 바닥이 움직이면 좋아졌다는 말의 뜻이 흐려집니다.
구체적인 함정을 몇 가지 짚어보겠습니다. 첫째, 과제 분포에 붙어버리는 함정입니다. 진화에 쓴 과제가 웹 검색 일색이면, 검색에 특화된 하네스가 뽑힙니다. 파일 정리나 긴 문서 작성 같은 과제에서는 힘을 못 씁니다. 둘째, 평가자 취향에 붙어버리는 함정입니다. 자동 평가자가 긴 답을 좋아하면, 하네스가 필요 이상으로 말을 늘리는 쪽으로 진화합니다. 셋째, 운 좋은 초기 후보에 굳어지는 함정입니다. 처음 몇 세대에서 우연히 잘 맞은 구조가 자리를 잡으면, 그 뒤의 변형은 그 구조 주변만 맴돕니다. 더 좋은 구조가 멀리 있는데도 가지 못합니다.
이런 함정을 피하는 방법은 알려져 있습니다. 과제 묶음을 섞고, 평가자를 바꾸고, 가끔은 일부러 생소한 과제를 던져보는 것입니다. 진화 중간에 한 번도 못 본 과제를 꺼내 성적을 확인하면 현재 위치를 가늠할 수 있습니다. 저는 이 중간 점검이 이 연구가 설득력을 얻는 데 결정적이라고 봅니다. 마지막에 한 번 이겼다는 결과보다, 진화가 진행되는 동안 감춰둔 과제 성적이 함께 따라오는 그래프가 더 믿을 만합니다. 과정이 투명하면 결과도 믿음이 갑니다.
실제 시스템에 올리기 전에 물을 질문들
연구 아이디어가 좋아 보여도 운영으로 넘어가면 질문이 바뀝니다. 실험실 점수가 아니라 밤새 돌아가는 시스템의 조건을 물어야 합니다. HarnessDev를 현장 관점에서 보면 바로 이런 질문이 생깁니다. 좋은데, 이걸 어디에 올릴까요. 무엇이 얼마나 들고, 어디에서 깨질까요.
지연과 비용이 첫째입니다. 진화로 뽑힌 하네스가 매번 모델을 여러 번 부르고 도구를 여러 번 두드리면, 성공률은 올라도 청구서도 함께 오릅니다. 단계당 모델 호출 횟수, 도구 호출 횟수, 토큰 사용량을 함께 봐야 합니다. 성공률 5퍼센트 상승에 비용이 두 배면, 많은 현장에서는 채택하기 어렵습니다. 비용 제한을 걸고 그 안에서 진화시키는 편이 현실적입니다. 예산을 고정한 채로 무엇을 얻었는지가 진짜 성적표입니다.
기억과 상태 관리가 둘째입니다. 하네스는 중간 기억을 어디에 두느냐에 따라 안정성이 달라집니다. 메모리에만 두면 빠르지만 길어지면 터지고, 파일이나 데이터베이스에 두면 안정적이지만 느려집니다. 진화 과정에서 뽑힌 하네스가 어떤 기억 전략을 쓰는지 들여다봐야 합니다. 특히 긴 과제에서 기억이 넘칠 때 어떻게 자르고 무엇을 버리는지가 중요합니다. 버리는 규칙이 나쁘면 앞부분의 단서를 잃고 같은 실수를 반복합니다.
도구 실패에 대한 태도가 셋째입니다. 현장 도구는 자주 삐걱거립니다. 타임아웃, 형식 변경, 일시 장애가 일상입니다. 좋은 하네스는 실패를 예상하고 움직입니다. 재시도 간격을 두고, 다른 도구로 우회하고, 안 되면 중간 결과를 저장하고 멈춥니다. 진화 평가에 이런 실패 주입이 들어 있지 않으면, 뽑힌 하네스는 맑은 날에만 잘 달리는 차가 됩니다. 비 오는 날의 성적을 따로 재야 합니다. 저는 이 대목을 볼 때 실험실과 현장의 간극을 가장 크게 느낍니다.

한 줄로 줄이면 놓치는 것들
이 연구를 한 줄로 줄이면 모델이 자기 하네스를 스스로 만든다가 됩니다. 틀린 말은 아니지만, 중요한 절반이 빠집니다. 진짜 이야기는 만드는 능력이 아니라 고르는 과정에 있습니다. 무엇을 만들고, 무엇으로 재고, 무엇을 남길지를 정하는 설계가 결과를 좌우합니다. 생성은 모델이 잘합니다. 선택은 사람이 설계해야 합니다.
비슷한 오해를 하나 더 짚겠습니다. 하네스 자동화가 프레임워크를 없앤다는 기대입니다. 그렇지 않습니다. 자동화는 프레임워크를 없애는 게 아니라 층을 올립니다. 사람이 매번 하네스를 직접 짜는 대신, 후보를 만들고 평가하고 격리하는 기계를 만듭니다. 손이 가는 곳이 달라질 뿐 손이 덜 가는 것은 아닙니다. 평가 과제 묶음을 만들고, 안전 규칙을 정하고, 선택 압력을 조정하는 일은 여전히 사람의 몫입니다. 어쩌면 전보다 더 어려운 설계가 됩니다. 직접 답을 쓰는 대신, 답을 고르는 시험을 만드는 일이니까요.
또 하나, 모델이 커지면 하네스가 필요 없어진다는 생각도 경계하고 싶습니다. 모델이 똑똑해질수록 할 수 있는 일이 늘어나고, 할 수 있는 일이 늘어날수록 바깥 조율이 더 필요해집니다. 도구가 많아지고 순서가 길어지면, 실수할 자리도 늘어납니다. 좋은 운전자가 좋은 차의 관리를 대신하지 못하듯, 좋은 모델이 좋은 하네스를 대신하지 못합니다. 모델과 하네스는 같은 방향으로 같이 좋아져야 합니다.
다음 실험에서 확인하고 싶은 장면들
제가 앞으로 보고 싶은 것은 감춰둔 과제에서의 성적 곡선입니다. 진화 세대가 올라갈 때 학습용 묶음 점수뿐 아니라 끝까지 감춰둔 묶음 점수도 함께 오르는지 보고 싶습니다. 두 곡선이 같이 오르면 진화가 일반화되는 것이고, 학습 곡선만 오르면 과제 외우기에 가깝습니다. 이 그래프 하나가 이 연구의 해석을 많이 정리해 줄 것입니다.
다음으로 보고 싶은 것은 권한과 비용의 기록입니다. 세대가 올라가면서 도구 접근 범위가 어떻게 바뀌었는지, 단계당 호출 횟수와 토큰 사용량이 어떻게 움직였는지 궁금합니다. 점수가 올랐는데 권한이 넓어지고 비용이 불었다면, 그 개선은 값비싼 개선입니다. 반대로 권한은 그대로인데 비용이 줄고 점수가 올랐다면, 그건 구조가 좋아진 것입니다. 점수 하나보다 이 세 가지 숫자의 조합이 말해주는 바가 큽니다.
마지막으로 보고 싶은 것은 실패 사례의 전시입니다. 어떤 하네스가 어떤 꼼수로 뽑혔다가 탈락했는지, 어떤 안전 규칙이 그 꼼수를 걸러냈는지를 공개하면 연구 전체의 신뢰가 올라갑니다. 성공 사례만 늘어놓는 논문보다, 함정을 보여주고 막는 법까지 보여주는 논문이 현장에는 더 도움이 됩니다. HarnessDev처럼 자기 코드를 다루는 연구에서는 이런 투명성이 선택이 아니라 조건입니다.
이 글을 닫으면서 한 가지만 남기겠습니다. HarnessDev가 던진 질문은 모델을 더 키울 것인가가 아니라 모델 바깥의 프로그램을 누가 어떻게 만들 것인가입니다. 하네스를 진화의 대상으로 삼는 발상은 아직 검증할 것이 많습니다. 평가의 함정도 있고 안전의 무게도 있습니다. 그럼에도 방향은 옳다고 봅니다. 에이전트의 신뢰도는 모델과 하네스의 합으로 정해지고, 지금까지 하네스는 너무 사람의 손에만 맡겨져 있었기 때문입니다. 다음 반복에서는 감춰둔 과제의 곡선, 권한과 비용의 기록, 그리고 걸러낸 꼼수의 목록을 보고 싶습니다. 그 세 가지가 갖춰지면, 이 발상은 멋진 질문을 넘어 쓸 만한 답에 가까워질 것입니다.