iBetter Books
수정

에이전트 루프란 무엇인가

일반적인 대화형 요청은 단발성이다. 사용자가 메시지를 보내면 모델이 텍스트로 답하고 그것으로 끝난다. 그러나 에이전트는 외부 세계와 상호작용하면서 여러 단계에 걸쳐 작업을 완수해야 한다. 파일을 읽고, 검색을 하고, 그 결과를 보고 다음 행동을 정한다. 이렇게 모델이 도구를 요청하고 애플리케이션이 그 결과를 돌려주는 과정이 작업이 끝날 때까지 반복되는 구조가 에이전트 루프다.

핵심은 모델 스스로는 코드를 실행하지 못한다는 점이다. Claude가 "search_flights라는 도구를 이런 입력으로 호출하고 싶다"고 응답에 담아 보내면, 실제로 그 함수를 실행하는 주체는 여러분의 애플리케이션이다. 이렇게 애플리케이션이 직접 실행하는 도구를 클라이언트 도구(client tool)라고 한다. 클라이언트 도구를 쓰는 한, 루프를 돌리는 책임은 모델이 아니라 애플리케이션에 있다. 모델은 "무엇을 할지"를 결정하고, 애플리케이션은 "그것을 실제로 수행"하며 결과를 다시 모델에게 전달한다. 시험은 바로 이 책임 분리를 묻는다. "도구 실행은 누가 하는가", "루프를 누가 주도하는가"라는 질문에 대한 정답은 클라이언트 도구의 경우 모두 애플리케이션이다.

한 번의 왕복은 다음과 같이 진행된다. 애플리케이션이 도구 정의(tools)를 포함해 메시지를 보낸다. 모델은 도구가 필요하면 응답 안에 tool_use 블록을 담아 보내고 stop_reasontool_use가 된다. 애플리케이션은 그 도구를 실행하고 결과를 tool_result 블록으로 만들어 다음 요청에 붙여 다시 보낸다. 모델이 더 이상 도구가 필요 없다고 판단하면 텍스트로 답하고 stop_reasonend_turn이 되며 루프가 끝난다. 이 왕복 한 번이 루프의 한 사이클이고, 작업이 끝날 때까지 이 사이클이 반복된다.

아래는 개념을 보여 주는 최소 형태의 루프다. 모델 ID는 claude-opus-4-8을 사용하고, 무한 반복을 막기 위한 반복 한계(max_iterations)를 둔다. 사고(thinking)는 별도의 budget 설정 없이 adaptive로 동작하므로 여기서는 호출 파라미터로 다루지 않는다.

# 새 파일: agent/loop.pyfrom anthropic import Anthropicclient = Anthropic()def run_agent_loop(messages, tools, max_iterations=10):    iterations = 0    while iterations < max_iterations:        iterations += 1        response = client.messages.create(            model="claude-opus-4-8",            max_tokens=4096,            messages=messages,            tools=tools,        )        messages.append({"role": "assistant", "content": response.content})        if response.stop_reason != "tool_use":            return messages  # 도구 요청이 없으면 작업 완료        tool_results = []        for block in response.content:            if block.type == "tool_use":                result = execute_tool(block.name, block.input)                tool_results.append({                    "type": "tool_result",                    "tool_use_id": block.id,                    "content": result,                })        messages.append({"role": "user", "content": tool_results})    return messages

여기서 자주 나오는 함정이 두 가지다. 첫째, "에이전트는 모델이 알아서 도구를 실행한다"는 진술은 클라이언트 도구에 대해서는 틀렸다. 모델은 요청만 하고 실행은 애플리케이션이 한다. 둘째, 루프 종료 판단을 tool_use 블록의 유무로만 보는 것은 맞지만, 더 정확한 신호는 stop_reason이다. 도구 요청이 없으면 stop_reasontool_use가 아니게 되고, 그때 루프를 끝낸다. 이 둘을 함께 이해해야 다음 절의 사이클 구조와 종료 조건이 자연스럽게 이어진다.

정리

  • 에이전트 루프는 모델의 도구 요청과 애플리케이션의 도구 실행이 작업 완료 시까지 반복되는 왕복 구조다.
  • 클라이언트 도구는 모델이 아니라 애플리케이션이 실행하며, 루프를 주도하는 책임도 애플리케이션에 있다. 시험은 이 책임 분리를 자주 묻는다.
  • 한 사이클은 요청 전송, tool_use 응답, 도구 실행, tool_result 회신으로 구성되고, 도구 요청이 없으면 stop_reasontool_use가 아니게 되어 루프가 끝난다.
  • 무한 반복과 비용 폭주를 막기 위한 반복 한계는 모델이 아니라 클라이언트 코드가 둔다.