에이전트와 하네스, 실제로 어떻게 움직이나
안녕하세요! 재니미입니다.
지난 글에서 하네스는 실체가 있는 소프트웨어이고, 에이전트는 그 위에서 모델이 스스로 판단하는 동작 방식이라고 정리했습니다. 이번엔 실제로 하네스가 모델을 어떤 순서로 부르는지, 같은 하네스가 워크플로우와 에이전트 중 뭘로 쓰이는지 예시로 따라가 보겠습니다.
하네스 루프, 한 단계씩 따라가보면
코딩 작업을 맡기는 하네스에 “이 버그 좀 고쳐줘”라고 요청하는 상황을 가정해봅시다. 실제로는 대략 이런 순서로 돌아갑니다.
- 하네스가 사용자 메시지, 시스템 프롬프트, 지금 쓸 수 있는 도구 목록(파일 읽기, 파일 쓰기, 명령 실행 등)을 묶어서 모델에 보냅니다.
- 모델은 아직 버그가 어디 있는지 모르니, “관련 파일부터 찾아야겠다”고 판단하고 파일 검색 도구를 호출하겠다는 응답을 내놓습니다.
- 하네스가 그 도구 호출을 받아서 실제로 파일 시스템을 뒤지고, 검색 결과를 다시 모델에 넣어줍니다.
- 모델은 검색 결과를 보고 이번엔 “이 파일을 고치고 테스트를 돌려야겠다”고 판단해서 파일 쓰기 도구, 명령 실행 도구를 순서대로 호출합니다.
- 하네스는 매번 그 호출을 실행하고 결과를 모델에 되먹입니다. 이 주고받기를 몇 차례 반복하다가 모델이 “이제 끝났다”고 판단하면 하네스가 루프를 멈추고 최종 응답을 사용자에게 보여줍니다.
이 사이클 전체, 즉 프롬프트를 조립하고 모델을 부르고 응답에서 도구 호출을 뽑아 실행하고 결과를 다시 넣어주는 반복을 실제로 돌리는 쪽이 하네스입니다. 그리고 그 반복 안에서 “다음에 뭘 할지”를 매번 모델이 스스로 고른다는 점이 에이전트적으로 동작하고 있다는 뜻입니다.
에이전트 관점에서 보면
방금 본 루프에서 하네스는 도구를 실제로 실행하고 결과를 넘겨주는 배관 역할만 합니다. 그 배관 안에서 모델이 실제로 하는 일은 네 가지로 나뉘는데, 전부 “모델이 정한다”로 끝나긴 해도 성격이 조금씩 다릅니다.
- 정보가 없는 상태에서 첫 행동을 만들어냅니다. “버그를 고쳐라”는 목표만 있을 뿐 어디부터 봐야 하는지는 안 주어졌습니다. 에러 메시지나 최근 변경 이력 같은 단서를 종합해서 “일단 여기부터 보자”는 첫 가설을 모델이 세워줘야 합니다.
- 애매한 결과 중에서 고릅니다. 검색 결과가 여러 개 나왔을 때 어느 게 진짜 원인인지는 정답표가 없습니다. 이름이 비슷한 함수가 세 파일에 있다면, 그중 최근에 고친 파일이나 에러 줄 번호에 가까운 쪽으로 모델이 후보를 좁혀줘야 합니다.
- 실패를 보고 계획을 바꿉니다. 고친 코드로 테스트가 실패했다면 하네스는 “실패했다”는 사실만 돌려줄 뿐, 왜 실패했는지는 알려주지 않습니다. 원인을 다시 추론해서 다른 파일을 볼지 같은 파일을 다르게 고칠지 모델이 정해줘야 합니다.
- 끝났다는 기준 자체를 정합니다. “완료”라는 상태는 하네스에 정의돼 있지 않습니다. 테스트가 몇 번 통과해야 끝인지 기준을 모델이 세워줘야 루프가 멈춥니다.
없는 정보로 첫 행동 만들기, 여럿 중 고르기, 실패를 되짚기, 끝을 스스로 정의하기. 이렇게 성격이 다른 판단들을 그때그때 채워 넣는 게 에이전트로 동작한다는 것의 실체입니다.
같은 하네스, 워크플로우로 쓸 수도 에이전트로 쓸 수도
여기서 워크플로우는 정해진 순서를 코드로 못박아둔 것을, 에이전트는 그 순서를 모델이 상황 봐가며 스스로 정하는 것을 말합니다(지난 글에서 다룬 구분입니다). 이번엔 PR(Pull Request, 코드 변경 사항을 저장소에 반영하기 전에 검토받는 단위)을 검토하는 하네스를 가정해봅시다. 쓸 수 있는 도구는 린트 실행, 테스트 실행, 커버리지 확인, 코멘트 작성, 이렇게 넷입니다.
워크플로우로 짜면 이렇게 됩니다. PR이 열리면 코드가 “린트 실행 → 테스트 실행 → 커버리지 확인 → 결과를 코멘트로 남기기” 순서를 그대로 못박아둡니다. 모델은 각 단계 결과를 요약하는 역할만 하고, 다음에 뭘 실행할지는 모델이 아니라 코드가 정합니다. 문서만 고친 PR이든 핵심 로직을 고친 PR이든 똑같은 네 단계를 다 거칩니다.
에이전트로 열어두면 다릅니다. 하네스는 “이 PR을 검토해줘”라는 요청과 같은 도구 넷만 모델에 쥐여줍니다. 모델이 PR 내용을 보고 “이건 문서만 고쳤으니 테스트는 건너뛰고 린트만 돌리면 되겠다”거나 “핵심 로직이 바뀌었으니 넷 다 순서대로 돌려야겠다”처럼 상황에 따라 다음 행동과 순서를 스스로 정합니다.
도구 넷과 코드베이스는 완전히 같습니다. 그 위에서 순서를 코드가 정하면 워크플로우, 모델이 정하면 에이전트라는 차이만 있습니다.
왜 이 구분이 쓸모 있나
뭔가 잘못됐을 때 어디를 들여다봐야 하는지가 이 구분에 따라 갈립니다. 하네스가 도구를 실행하다 에러를 던졌다면 코드나 로그를 보면 됩니다. 원인이 뻔히 코드 안에 있으니까요. 반면 모델이 매번 다른 도구를 고르다가 이상한 순서로 실행했다면, 그건 코드의 버그가 아니라 그 앞뒤에 있던 프롬프트나 도구 설명이 모델의 판단을 어떻게 이끌었는지를 봐야 하는 문제입니다. 하네스와 에이전트를 구분해두면 “코드를 고칠 문제”와 “프롬프트·도구 설계를 고칠 문제”를 헷갈리지 않게 됩니다.
감사합니다.