실무 Multi-Agent 오케스트레이션 9장 · 에이전트 루프 직접 구현 6 / 7 ← 이전목차다음 → TechLead Cro

9장. 에이전트 루프 직접 구현

정리와 체크리스트

9장에서 배운 것

  • 에이전트 루프(agent loop) — 조회하고, 결과를 보고, 다음 할 일을 정하는 일을 끝날 때까지 되풀이하는 구조.
  • ReAct — 한 바퀴를 생각(Thought) → 행동(Action) → 관찰(Observation)로 나눈 방식. 생각은 모델, 행동과 관찰은 우리 코드.
  • contents — 질문, 모델의 요청, 도구의 결과가 차례로 쌓이는 리스트. 루프의 기억이고, 매 바퀴 통째로 모델에게 갑니다.
  • 종료 조건 — 응답에 도구 요청이 없으면 최종 답변. 끝낼 때는 모델이 정합니다.
  • max_steps — 모델이 끝내지 않을 때를 대비한 반복 한도. 닿으면 티켓을 실제로 접수하고 그 번호를 안내합니다.
  • 병렬 함수 호출 — 모델이 한 응답에 도구 요청을 여러 개 담는 것.

한눈에 보는 핵심

contents = [질문]
for step in range(1, max_steps + 1):
    response = client.models.generate_content(model=MODEL, contents=contents, config=config)  # Thought
    if not response.function_calls:
        return response.text                                   # 도구 요청이 없다 → 종료
    contents.append(response.candidates[0].content)            # 모델의 요청을 통째로 기록
    parts = [도구를 실행한 결과 … for fc in response.function_calls]   # Action
    contents.append(types.Content(role="user", parts=parts))   # Observation
ticket = tools["create_ticket"](...)                           # 한도 도달 → 실제로 접수
return f"… 티켓({ticket['ticket_id']})으로 접수해 드렸어요."
모델이 정하는 것 우리 코드가 정하는 것
어떤 도구를, 어떤 인자로 쓸 수 있는 도구의 목록
한 번에 몇 개를 요청할지 도구의 실제 실행
몇 바퀴 만에 답할지 최대 몇 바퀴까지 허락할지
측정 이번 장의 값
바퀴 수 3
모델 호출 / 도구 실행 3번 / 4번
바퀴별 입력 토큰 694 → 1,427 → 2,003

체크리스트

  • [ ] "배송중인 주문의 송장번호를 전부 알려 달라"가 한 번의 도구 호출로 풀리지 않는 이유를 설명할 수 있다.
  • [ ] 6장부터 쓴 자동 함수 호출과 이번 장의 루프가 어떤 관계인지 말할 수 있다.
  • [ ] ReAct의 세 단계를 말하고, 각각 코드의 어느 줄인지 짚을 수 있다.
  • [ ] 루프가 정상적으로 끝나는 조건을 코드 한 줄로 가리킬 수 있다.
  • [ ] contents에 한 바퀴마다 무엇이 쌓이는지 순서대로 말할 수 있다.
  • [ ] 도구 결과를 돌려줄 때 role에 무엇을 쓰는지 안다.
  • [ ] 실행 결과에서 step 2의 주문번호가 어디서 왔는지 설명할 수 있다.
  • [ ] 바퀴가 늘수록 입력 토큰이 늘어나는 이유를 contents로 설명할 수 있다.
  • [ ] max_steps가 너무 작을 때와 너무 클 때 각각 무슨 일이 생기는지 말할 수 있다.
  • [ ] 8장의 도구가 예외를 내지 않는데도 루프에 try가 있는 이유를 설명할 수 있다.

한 줄 핵심

에이전트 루프는 "모델에게 묻고, 요청한 도구를 실행하고, 결과를 쌓아 다시 묻는" 반복문입니다. 다음에 무엇을 할지는 모델이 정하고, 어디까지 허락할지는 우리가 정합니다.

← 이전 절따라하기 — ReAct 루프 만들기다음 절 →실습문제와 해답
오명운 · macro@prag-ai.com