에이전트 = 모델×하니스: 평가 레이어는 별도 도구가 아니라 에이전트의 일부다
출처: Dev.to
에이전트가 왜 slick demo 에이전트가 프로덕션에서 붕괴되는지 궁금해할 때, 나는 계속 되돌아오는 공식이다:
에이전트 = 모델 × 하니스
모델은 원시적인 추론 — Claude, GPT 등이다. 스와핑 가능하며, 여러분이 제어하지 않는 곡선상 개선되고 있다. 하니스는 나머지는 목표, 루프, 도구, 스케줄러, 재시도 로직 등 모든 것을 의미한다. 중요한 엔지니어링 대부분은 모델이 아닌 하니스에 있다.
팀들이 자주 틀리는 부분은 하니스를 모델을 실행하기 위한 배관(목표 + 루프 + 도구)으로 정의하고, 그 뒤에 평가를 외부 QA용으로 별도로 붙이는 것이다. 외부에서 사후에 agente를 지적하는 것들이다.
하니스 = 목표 + 루프 + 도구 + 렌즈 + 평가. 앞의 세 가지는 에이전트가 동작하게 하고, 후의 두 가지는 동작이 얼마나 좋은지 판단하게 하며, 이것이 agente가 실행되는 것으로 그 자체가 개선되는 유일한 요소이다.
구체적으로 설명드리자면, 나는 비매력적인 방식으로(실제 현장에서) 일정 스케줄링된 에이전트가 충돌하고 하니스 중 어떤 부분이 나를 구했는지 정확히 발견했다.
오픈 루프 에이전트는 동작하고 바로 진행한다. 파일을 쓰고, API를 호출하고, 커밋을 전송한다 — 그 결과가 정확한지 여부조차도 에이전트 자신도 모르는 경우가 많다. 문제가 있음을 알게 되는 순간은 인간이 무언가 깨졌다는 것을 감지할 때이다.
실제 세계의 대부분의 ‘자율’ 에이전트는 오픈 루프다. 초기에는 인상적이지만, 3일 동안 조용히 잘못 수행하는 경우가 많다.
폐쇄 루프 에이전트는 다음과 같은 피드백 경로를 가진다:
act → observe → evaluate → correct → act better
이것을 닫는 두 요소는 렌즈(관측성 — 모델 호출 및 도구 단계, 해결된 입력, 원시 출력 등 모든 것이 블랙 박스가 되지 않음)와 평가(evals) (판단 — 출력을 표준에 맞춰 점수 매김: 결정적 검증, 계약 검증, 모델-as-재지udge)이다. 렌즈는 에이전트가 무엇을 했는지 알려주고, 평가는 그것이 좋은지 여부를 말해준다.
둘 다 하니스 자체에 연결해 두어야 하며, 한 주에 한 번 인간이 기억을 되새겨서 수동으로 실행하는 것이 아니라.
나는 크론 스케줄링된 백그라운드 워커들의 풀을 운영한다. 각각 타이머에 따라 집중적인 작업을 수행하고, 메인 프로세스가 실시간으로 볼 수 없는 고립된 세션 안에서 동작한다.
그 중 하나가 실행 중간에 충돌했다.
오픈 루프 환경에서는 이는 무음 재난이다: 워커가 죽고何も 생산하지 않으며 흔적을 남기지 않는다. 결과물이 존재해야 할 때 며칠 뒤에야 그 사실이 발견된다. (배경 에이전트를 실행해 본 적이 있다면 이 정확한 고통을 알 것이다 — 1주가 지나고도 아무도 모르는 사이에 “어둠”에 빠지는 경우.)
대신에 벌어진 일은 다음과 같다, 렌즈와 평가 레이어가 하니스에 포함돼서:
-
렌즈 덕분에 실패가 기록되었다. 모든 워커는 시작하는 순간부터 실제 작업을 하기 전에 트랜스크립트 스텁을 먼저 쓴다: Outcome: IN-PROGRESS. 따라서 1초 뒤에 죽어도 발자국은 남는다. crash는 보이지 않았으나, “시작했지만 절대 끝내지 못했다”고 기록된 트랜스크립트가 있었다.
-
평가가 Failure을 크게 그리고 반복적으로 잡았다. 워커 트랜스크립트는 버전화된 계약에 맞춰 검증된다. IN-PROGRESS 상태의 스텁은 정상 모드에서는 괜찮지만(“아직 실행 중일 수 있음”), “finished” 체크에서는 에러가 된다:
# Normal: an unfinished stub is acceptable
agent-eval validate transcripts/
# Finished mode: a lingering IN-PROGRESS is a hard error
agent-eval validate transcripts/ --finished
그 결과는 단순히 기록만 남긴 것이 아니라, 무효 처리 점수를 받았고, 누군가가 해결할 때까지 게이트의 무효 목록에 계속 나타나는 상태가 되었다. 평가 레이어는 Failure이 배경에 스며들지 못하게 막았다.
전체 포인트는 이것이다. 렌즈는 실패를 관측 가능하게 했고, 평가는 이를 무시할 수 없게 만들었다 — 이것이 무음 블랙홀에서 트래킹 가능한 결함으로 전환하는 것이다. 감지는 observe + evaluate이며, 마지막 단계는 correction이다.
천진한 해결책은 “크래시 시 워커가 자체 트랜스크립트를 최종화하도록 finally 블록을 추가하는 것”이다. 그러나 이는 작동하지 않으며, instructive한 이유가 있다: 크래시된 고립된 세션은 사라진다. finally를 실행할 프로세스는 이미 죽은 것이다. 죽은 워커에게 스스로 청소를 맡길 수 없다.
수정 단계는 워커 외부에서 별도의 작은 루프로 존재해야 한다. 나는 스위퍼를 만들었다: 인 프로그레스 상태에 머무는 트랜스크립트 중 실행이 끝났다고 provably 판단되는(안전하게 정의된 임계값보다 오래 지속된) 워커들을 스캔하고 최종화해 실패로 만드는 일정 정리 작업이다.
논리는 의도적으로 평범하다:
for each transcript stub still marked IN-PROGRESS:
if age > MAX_RUN_TIME + safety_margin: # the run is provably dead
rewrite Outcome -> "fail (auto-finalized: abandoned mid-run)"
아이디멤포텐트이며, 아무것도 삭제하지 않고 타이머에 따라 실행된다.
첫 실행 시 이미 오래된 스텁들의 백로그를 최종화하고, finished 모드에서의 게이트 무효 수를 알려진 예외들만 남게 했다. 이후에는 자동으로 루프가 닫힌다: 워커가 여전히 충돌할 수 있지만, 그 사체는 1시간 이내에 정리되고 나는 개입하지 않는다.
이것은 act → observe → evaluate → correct 로 완전히 연결된 것이며, 네 단계 중 세 개는 렌즈와 평가 레이어가 수행한다.
여기서 솔직히 말해야 할 부분이 있다, 이는 과장하기 쉬운 부분이다. 내가 구축한 것은 자기 수정이 가능한 하니스다. 루프가 닫혔다: 시스템은 자체 표준에서 벗어난 점을 감지하고 인간 개입 없이 수정한다.
그것은 실제이며, 자율 에이전트 풀의 밑바닥으로 삼아야 할 것이다.
하지만 자기 수정은 자기 개선과 다르다. 자기 수정은 시스템이 라인을 유지한다는 의미이며, 표준에 머무르게 한다.
자기 개선은 시스템이 스스로 라인을 올리는 것을 의미한다: 체크가 거짓 양성률을 보인다는 것을 감지하고 자체 규격을 강화하거나, 워커가 지속적으로 후퇴한다는 것을 감지하고 그 워커의 지침을 조정하는 것이다.
내 하니스는 그렇지 않다. 나는 모든 개선을 직접 작성한다.
루프는 스스로 실행되고, 루프 자체는 인간이 설계했다.
그리고 솔직히 말해 — 지금은 그 정도가 적절하다.
자체 워커와 평가 기준을 비감독으로 재작성하는 하니스는 다른 것이며, 훨씬 위험한데, 이는 평가가 동일한 시스템이 작성한 작업을 평가한다는 점 때문이다. 평가되는 것과 심udge하는 것이 같은 폐쇄된 시스템이고 외부 앵커가 없을 때, “자신의 평가에 통과한다”는 의미가 크게 사라진다.
인간이 설정한 계약 안에서의 자기 수정은 올바른 버전이다. 자체 계약을 수정하는 것은 하드 가드레일과 인간 게이트를 확보한 후에야 작동하게 해야 한다.
따라서 정확한 공식은 다음과 같다:
Agent = Model × Harness, where Harness = goals + loops + tools + lens + evals — 그리고 렌즈와 평가가 agente를 자기 수정하게 만든다. 여기서부터 자기 개선으로 가는 것은 실제 추가 단계이며, 이를 신중히 수행하고 인간 게이트를 두는 것이 바람직하다.
에이전트를 구축하고 evals와 trace가 외부에서 가끔 실행되는 것이라면, 당신은 폐쇄 루프를 갖지 못하고 오픈 루프 에이전트에 일부 QA 스크립트가 있는 것이다.
업그레이드는 더 많은 툴이 아니라 리패일이다:
렌즈와 평가는 하니스 안에 들어가며, 요청에 응답할 때마다 동작해야 한다.
렌즈는 실패를 관측 가능하게 하고, 평가는 이를 무시할 수 없게 만든다 — 이것이 무음 블랙홀에서 트래킹 가능한 결함으로 전환하는 것이다. 수정 단계를 마무리하는 것은 종종 별도의 루프를 필요로 한다,因为 실패한 것이 스스로 청소할 수 없는 경우가 많기 때문이다.
자기 수정은 바닥이며, 자기 개선은 추가적인 신중한 단계이다