레슨 1: 하네스란 무엇인가: 모델을 감싸는 제어 코드
학습 목표:
- 하네스와 모델의 경계선을 긋고, '액션을 제안하기'가 어느 쪽에 속하고 '실행하고 제어하기'가 어느 쪽에 속하는지 말하기
- 에이전트와 워크플로의 차이를 사용해, 어떤 시스템이 무엇을 근거로 '에이전트'라는 이름을 얻는지 설명하기
- '우리 에이전트가 충분히 신뢰할 만하지 않다'는 문제를 모델 계층에서 고칠지 하네스 계층에서 고칠지 판단하기
전제: 이 시리즈의 앞선 여섯 개 과정을 마쳤고, 한 번의 도구 호출 왕복(stop_reason: "tool_use" / tool_result)을 이해하고 있어야 합니다 | 다음: 레슨 2 >>
그 한 번의 왕복에서 이미 하네스를 보았습니다
'에이전트 도구 호출: 에이전트가 실제로 일하게 만들기'에서 완전한 도구 호출 왕복을 분해했습니다. 모델은 여러분의 질문과 도구 목록을 보고, stop_reason: "tool_use" 와 함께 "이 도구를, 이 파라미터로 호출하라"고 말하는 tool_use 블록을 돌려줍니다. 그다음에 무슨 일이 일어나는지 문서는 솔직하게 말합니다. "The model never executes anything on its own. It emits a structured request, your code (or Anthropic's servers) runs the operation, and the result flows back into the conversation."(모델은 스스로 아무것도 실행하지 않는다. 구조화된 요청을 발행할 뿐이고, 여러분의 코드(또는 Anthropic의 서버)가 그 작업을 실행하며, 결과가 대화로 다시 흘러들어온다)1 파일을 여는 것, 명령을 실행하는 것, 네트워크 호출을 하는 것 — 그 모든 것은 에이전트를 돌리고 있는 호스트 코드의 일입니다. 호스트는 작업을 마치면 출력을 tool_result 로 감싸 대화에 덧붙이고, 다음 요청을 쏘아 보냅니다.
그 호스트 코드 덩어리 — 도구를 실행하고 다음에 무엇을 할지 결정하는 부분 — 가 이 레슨의 주제입니다. 여기에는 이름이 있습니다. 하네스(harness), 모델을 감싸고 있는 제어 코드의 층입니다.
다만 그 앞선 과정은 한 번의 왕복에서 멈췄습니다. 실제 에이전트가 왕복 한 번으로 끝나는 일은 드뭅니다. 도구 호출이 결과를 돌려주고, 모델이 그 결과를 보고, 대개는 또 다른 도구를 호출하고 싶어 하고, 또 하나를 호출하며, 빙글빙글 돌아갑니다. 그 돌아가는 움직임을 누가 돌립니까? 언제 멈춰야 할지를 누가 결정합니까? 표류할 때 누가 끌어당겨 되돌립니까? 그 모든 것이 하네스의 일입니다. 이 레슨에서는 하네스와 모델의 경계선을 긋습니다. 그 뒤의 레슨들에서는 하네스를 하나씩 부품으로 분해합니다.
에이전트란 무엇인가: 루프 안에서 도구를 사용하는 LLM
Anthropic의 엔지니어링 팀은 에이전트에 대해 평이한 정의를 내놓습니다. "They are typically just LLMs using tools based on environmental feedback in a loop."(그것들은 전형적으로, 루프 안에서 환경 피드백에 기반해 도구를 사용하는 LLM에 불과하다)2 이 한 문장에서 무게를 지는 것은 세 단어입니다 — 도구, 환경 피드백, 그리고 루프. 모델이 도구를 호출하고(도구), 호스트가 그것을 실행해 결과를 돌려주고(환경 피드백), 모델이 결과를 읽고 다음에 무엇을 할지 결정하며, 경우에 따라 또 다른 도구를 호출하고, 그렇게 다시 돕니다(루프). 앞서 배운 왕복은 바로 이 루프의 첫 한 바퀴였습니다.
같은 글은 사람들이 끊임없이 혼동하는 두 종류의 시스템을 갈라놓습니다. 첫 번째는 워크플로입니다. "Workflows are systems where LLMs and tools are orchestrated through predefined code paths."(워크플로란, LLM과 도구가 사전 정의된 코드 경로를 통해 오케스트레이션되는 시스템이다)2 이것을 하고, 다음에 저것을 하고, 이 분기에서는 왼쪽으로 간다 — 모두 사람이 미리 정해 둔 것입니다. 두 번째는 에이전트입니다. "Agents, on the other hand, are systems where LLMs dynamically direct their own processes and tool usage"(반면 에이전트란, LLM이 자신의 프로세스와 도구 사용을 동적으로 지휘하는 시스템이다)2.
이 두 정의를 나란히 놓으면, 차이는 모델의 강함에 관한 이야기가 아님을 알 수 있습니다. 누가 제어 흐름의 결정을 내리는가에 관한 이야기입니다. 워크플로에서는 다음 단계가 하드코딩되어 있습니다. 에이전트에서는 다음 단계가 루프 안에서 모델이 그 자리에서 결정한 것입니다. 로드맵의 표현을 빌리면, 그것이야말로 에이전트라는 이름에 값하는 조건입니다. "An agent makes its own control-flow decisions inside a loop."(에이전트는 루프 안에서 스스로 제어 흐름의 결정을 내린다)3 그리고 그 루프를 떠받치고, 모델의 결정을 실제 효과로 바꾸는 것이 하네스입니다.
여기서 표현 하나에 주의가 필요합니다. "모델이 다음 단계를 결정한다"는 말은, 모델이 매 턴 액션을 제안한다는 뜻입니다. 루프가 애초에 도는지 아닌지, 모델에게 다시 물을지 아닐지는 여전히 하네스의 코드에 달려 있습니다. 모델은 제안하고, 하네스가 재정한다. 이 선이 이후의 모든 것의 토대가 됩니다.
같은 모델, 다른 하네스, 완전히 다른 결과
자, 이 레슨이 가장 기억해 주기를 바라는 한 문장입니다. 어느 커뮤니티 로드맵은 이를 단호하게 적습니다. "Same model, different harness, completely different result."(같은 모델, 다른 하네스, 완전히 다른 결과)3
처음에는 거꾸로 들릴지 모릅니다. 우리는 에이전트의 신뢰성을 모델의 계좌에 다는 데 익숙합니다 — 이건 강하고, 저건 약하다고 말이죠. 하지만 그 왕복에서 모델이 실제로 무엇을 했는지 떠올려 보십시오. 현재 대화를 보고, 다음 액션을 제안했을 뿐입니다. 그 액션이 정말 실행되는지, 그 뒤로도 루프가 계속되는지, 스무 턴을 헛돌고 난 뒤 중단할지, 제안된 액션이 데이터베이스 테이블을 통째로 떨어뜨리는 것일 때 먼저 사람에게 확인할지 — 그중 어느 하나도 모델의 재량이 아닙니다. 그 모두가 하네스에 속합니다.
구체적인 비교를 하나 들겠습니다. 같은 모델, 같은 도구 세트, 같은 작업: 프로젝트 안의 사용하지 않는 의존성을 정리하기.
- 하네스 A는 모델이 제안한 액션을 무조건 전부 실행합니다. 턴 수 상한도 없고, 에이전트가 같은 자리에서 헛돌고 있지 않은지 확인하는 검사도 없습니다. 어느 턴에서 모델이 판단을 그르쳐 잘못된 삭제를 제안합니다. 하네스는 삭제합니다. 그 뒤 모델은 이미 스스로 망가뜨린 상태에서 앞으로 추론을 진행하고, 하나의 잘못된 단계가 열 개로 부풀어 오릅니다. 이런 종류의 시스템이 골치 아픈 것은 에이전트의 자율성에서 곧장 옵니다. "The autonomous nature of agents means higher costs, and the potential for compounding errors."(에이전트의 자율적인 성질은 더 높은 비용과, 에러가 누적될 가능성을 의미한다)2
- 하네스 B는 같은 모델을 돌리고 같은 제안을 받지만, 이 제어 층은 턴 수에 상한을 두고, 실질적인 진전이 없는 턴이 여러 번 이어지지 않는지 감시하며, 삭제처럼 영향이 큰 액션을 실행하기 전에는 손을 멈추고 사람에게 묻습니다. 같은 나쁜 제안이 여기서는 디스크가 아니라 승인 밸브에 부딪힙니다.
모델은 동일합니다. 제안도 양쪽에서 동일했을지 모릅니다. 한쪽의 실행은 프로젝트를 망가뜨리고, 다른 쪽은 궤도에 머뭅니다. 차이는 전부 바깥쪽 제어 코드에서 옵니다. 그러니 에이전트가 신뢰할 만하지 않을 때, 먼저 더 강한 모델에 손을 뻗지 마십시오 — 많은 경우 문제는 모델 계층이 아니라 하네스 계층에 있습니다.
하네스는 하나의 물건이 아니라 부품의 집합입니다
이 지점에서 하네스를 '그 루프'라고 그려 볼지도 모르지만 — 딱 맞지는 않습니다. 루프는 그 중심 조각이지만, 하네스는 함께 일하는 부품들의 집합입니다. 로드맵은 이를 합집합으로 묘사합니다. "the harness is the union of:"(하네스는 다음의 합집합이다) 루프 제어, 도구 디스패치, 컨텍스트 관리, 그리고 그 외의 것들입니다.3 지금 각 부품의 얼굴을 익혀 두십시오. 뒤의 레슨들이 하나씩 분해합니다.
- 루프 제어, 로드맵에서 이렇게 묘사됩니다. "loop control. The while-loop driving model→tools→model."(루프 제어. 모델→도구→모델을 돌리는 while 루프) 3 모델이 돌려주는
stop_reason 을 읽고, 이 턴 다음에 또 한 턴이 이어질지 아니면 정지가 이어질지 결정합니다. 이것이 하네스의 심장이며, 레슨 2가 여기에 바쳐집니다.
- 도구 디스패치: 모델이 "이 도구를 이 파라미터로 호출하라"고 제안하면, 그 요청을 실제 함수로 라우팅하고, 그것을 실행하고, 출력을 다시
tool_result 로 담는 코드입니다. 이것의 단일 단계 버전은 앞서 만났습니다. 하네스가 하는 일은 그것을 루프 안에 엮어 넣어 몇 번이고 되풀이해 쓰는 것입니다.
- 컨텍스트 관리: 루프가 한 바퀴 돌 때마다 더 많은 데이터가 대화에 쌓입니다. "An agent running in a loop generates more and more data that could be relevant for the next turn of inference"(루프 안에서 돌아가는 에이전트는, 다음 추론 턴에 관련될 수 있는 데이터를 점점 더 많이 생성한다)이기 때문입니다4. 그리고 모델의 어텐션은 공짜가 아닙니다. "LLMs have an "attention budget" that they draw on when parsing large volumes of context"(LLM에는, 대량의 컨텍스트를 파싱할 때 끌어다 쓰는 '어텐션 예산'이 있다)4, "Every new token introduced depletes this budget by some amount"(새로 도입된 토큰은 저마다 그 예산을 어느 정도 소모한다)4. 그래서 하네스는 그 히스토리을 어디에 두고 얼마만큼을 남길지 결정해야 하며, 그것이 부풀어 오르도록 내버려 두어서는 안 됩니다.
두 부품이 더 이 과정 뒤쪽에서 온전히 다뤄집니다. 이들도 하네스에 속한다는 것을 알 수 있도록 여기서 이름을 밝혀 둡니다.
- 정지 조건:
stop_reason 을 따르는 것 외에도, "it's also common to include stopping conditions (such as a maximum number of iterations) to maintain control."(제어를 유지하기 위해 정지 조건(최대 반복 횟수 등)을 포함하는 것도 흔하다)2 언제 손을 뗄지가 레슨 3의 주제입니다.
- 폭주 방지책과 사람의 개입: 루프는 긴 구간 동안 돌 수 있고, "The LLM will potentially operate for many turns, and you must have some level of trust in its decision-making."(LLM은 다수의 턴에 걸쳐 동작할 가능성이 있으며, 그 의사결정에 어느 정도의 신뢰를 두어야 한다)2 다만 신뢰가 백지 위임과 같지는 않습니다 — "Agents can then pause for human feedback at checkpoints or when encountering blockers."(그러고 나서 에이전트는 체크포인트에서, 혹은 장애물에 부딪혔을 때 사람의 피드백을 기다리며 일시 정지할 수 있다)2 무한 루프, 헛돎, 예산 소진을 어떻게 잡는지(레슨 4), 그리고 사람이 실행 도중에 끼어들어 방향을 바꾸는 방법(레슨 5)이 모두 이 계층에 있습니다.
각 부품의 세부를 지금 외울 필요는 없습니다. 전체 윤곽만 붙들어 두십시오. 하네스는 모델을 감싸는 제어 코드의 총칭이며, 이 에이전트가 얼마나 안정적으로 돌아가는지를 함께 결정하는 여러 부품으로 조립되어 있습니다. 그것이 또한, 하네스를 교체하면 결과가 왜 그토록 크게 달라지는지도 설명합니다 — 여러분이 교체한 것은 코드 한 줄이 아니라, 루프를 제어하는 전략 전체입니다.
이 제어 층이 실제로 필요할 때
하네스가 관리할 수 있는 것이 이토록 많음을 보고 나면, 반대 극단으로 미끄러지기 쉽습니다. 모델을 쓸 때마다 루프 제어, 승인 밸브, 헛돎 검출을 갖춘 완전한 구성이 필요할까요? 아닙니다.
에이전트 대 워크플로의 선으로 돌아가 봅시다. 여러분의 작업이 고정된 경로를 따른다면 — 티켓이 들어오고, 분류되고, 종류별로 라우팅된다 — 그리고 모든 분기를 미리 정할 수 있다면, 그것은 워크플로이고, 그것을 "through predefined code paths"(사전 정의된 코드 경로를 통해)2 오케스트레이션하는 것으로 충분합니다. 모델이 루프 안에서 제어 흐름을 결정하게 할 이유가 없습니다. 거기에 자율적인 루프를 붙여 봤자, 그것이 궤도를 벗어날 기회만 늘어납니다.
진정으로 완전한 하네스가 필요한 것은 단계의 수와 경로를 미리 말할 수 없는 작업입니다. 몇 개의 파일을 고쳐야 하는지, 어느 것을 먼저 읽을지, 한 단계의 결과가 앞선 단계를 다시 하도록 되돌리는지. 그것들은 현재 상태를 보는 모델만이 정할 수 있습니다. 그럴 때 모델이 루프 안에서 스스로 결정하게 하면서도 단단히 제어 아래에 두는 하네스를 원하게 됩니다. 일반적인 절제 하나는 붙들어 둘 가치가 있습니다. "you should consider adding complexity only when it demonstrably improves outcomes."(복잡성은 그것이 결과를 입증 가능하게 개선할 때에만 더하는 것을 고려해야 한다)2 여러분의 하네스에 있는 모든 제어 로직은, 남들이 다 그렇게 만들기 때문이 아니라, 실제로 제어 상실 문제에 부딪혔기 때문에 거기 있어야 합니다.
이 과정의 나머지는 그 두 번째 종류의 작업에서 가장 중요하고, 가장 자주 부서지는 부분 — 루프 그 자체 — 에 초점을 맞춥니다. 하네스가 에이전트의 신뢰성을 좌우하고, 루프 제어가 하네스의 심장이므로, 다음 레슨은 그 루프가 한 번의 왕복에서 어떻게 계속 돌아가는 무언가로 자라나는지에서 시작합니다.
Recap
- 하네스는 모델을 감싸는 제어 코드의 총칭이다 — 도구를 실행하고, 루프를 몰고, 언제 멈추고 언제 사람을 기다릴지 결정한다. 모델은 다음 액션을 제안할 뿐이고, 그 액션이 실행되는지 그리고 루프가 계속되는지는 하네스가 재정한다.1
- 에이전트는 환경 피드백에 기반해 루프 안에서 도구를 사용하는 LLM이다.2 워크플로와 그것을 가르는 것은 모델의 강함이 아니라 누가 제어 흐름의 결정을 내리는가이다. 워크플로는 사전 정의된 코드 경로를 따르지만, 에이전트의 다음 단계는 루프 안에서 모델이 정하며,2 그 루프를 떠받치는 것이 하네스이다 — 에이전트는 루프 안에서 스스로 제어 흐름의 결정을 내린다.3
- 같은 모델, 다른 하네스, 완전히 다른 결과.3 그러니 에이전트가 신뢰할 만하지 않을 때는 하네스 계층을 먼저 확인한다. 턴 상한, 진전 없음 검출, 영향이 큰 액션의 승인은 대개 더 강한 모델보다 더 많은 것을 고친다.
- 하네스는 하나의 물건이 아니라 부품의 집합이다: 루프 제어, 도구 디스패치, 컨텍스트 관리가 저마다의 일을 가진다.3 특히 컨텍스트는 관리가 필요한데, 루프가 한 바퀴 돌 때마다 더 많은 데이터가 대화에 쌓이고 유한한 어텐션 예산을 끌어다 쓰기 때문이다.4
- 모든 상황이 완전한 하네스를 필요로 하지는 않는다. 경로가 고정된 작업은 워크플로로 충분하고,2 단계와 경로를 미리 말할 수 없어 모델이 정말로 스스로 결정해야 할 때에만 하네스에 손을 뻗으며, 복잡성은 그것이 결과를 입증 가능하게 개선할 때에만 더한다.2
>> 레슨 2: 코어 루프: 한 번의 왕복에서 지속적인 운전으로