Agent Executor 동작 원리 이해하기
· Agent Executor는 LLM이 "어떤 도구를 어떤 입력으로 쓸지" 스스로 정하고, 그 결과를 다시 받아 다음 행동을 이어 가도록 반복을 돌려 주는 LangChain의 실행 엔진입니다.
· 핵심은 생각 → 행동 → 관찰을 한 바퀴로 묶어, 최종 답이 나올 때까지 이 루프를 자동으로 반복한다는 점입니다.
· 도구 호출·결과 수집·종료 판단을 사람이 손으로 짜지 않아도, Executor가 LLM의 결정을 실제 실행으로 연결해 줍니다.
앞선 편들에서는 프롬프트를 만들고, 체인을 잇고, 대화를 기억하게 하는 방법을 살펴봤습니다. 그런데 "검색해서 찾아보고, 계산까지 한 다음 답해 줘" 같은 요청은 한 번의 LLM 호출로는 끝나지 않습니다. 모델이 필요한 도구를 직접 골라 쓰고, 그 결과를 보고 다음 행동을 다시 정해야 하기 때문입니다. 이 반복을 대신 돌려 주는 것이 바로 Agent Executor입니다. 오늘은 이 실행 엔진이 안에서 무엇을 하는지 차근차근 따라가 보겠습니다.
🧩 Agent와 Agent Executor는 다릅니다
먼저 헷갈리기 쉬운 두 개념을 구분해야 합니다. Agent는 "지금 상황에서 무엇을 할지 결정하는 두뇌"입니다. 질문과 지금까지의 진행 상황을 받아, 다음에 어떤 도구를 어떤 입력으로 쓸지, 아니면 이제 최종 답을 낼지를 한 번 판단해 돌려줄 뿐입니다. 즉 Agent 자체는 결정만 하고, 실제로 도구를 실행하지는 않습니다.
반면 Agent Executor는 그 결정을 받아 실제로 실행에 옮기고, 결과를 다시 Agent에게 돌려주며, 최종 답이 나올 때까지 이 과정을 반복으로 묶어 주는 실행 담당입니다. 다시 말해 Agent가 "다음 수"를 고르는 사람이라면, Executor는 그 수를 실제 판 위에 두고 다음 차례를 계속 돌려 주는 진행자인 셈입니다.
Agent는 무엇을 할지 결정하고, Agent Executor는 그 결정을 실제 실행과 반복으로 연결합니다 — 둘이 짝을 이뤄야 비로소 "스스로 도구를 쓰는 AI"가 됩니다.
🔁 생각-행동-관찰 루프
Agent Executor의 동작은 흔히 생각(Reason) → 행동(Act) → 관찰(Observe)이라는 한 바퀴로 설명됩니다. 모델이 먼저 지금 무엇을 해야 할지 생각하고, 그 생각에 따라 도구를 실행한 뒤, 돌아온 결과를 관찰해 다음 생각의 재료로 삼는 흐름입니다.
중요한 점은 이 한 바퀴가 한 번으로 끝나지 않는다는 것입니다. 관찰한 결과만으로 답하기에 부족하면 Executor는 그 결과를 다시 프롬프트에 담아 다음 바퀴를 돌립니다. 모델이 "이제 충분하다"고 판단해 최종 답을 내놓을 때까지, 이 루프가 계속 이어집니다.
🔍 한 바퀴 안에서 벌어지는 일
Executor가 루프 한 바퀴에서 내부적으로 하는 일을 단계로 나눠 보면 구조가 한눈에 들어옵니다.
정리하면 흐름은 이렇게 이어집니다. 사용자의 질문이 들어오면 Executor가 Agent에게 다음 행동을 묻고, 돌아온 결정대로 도구를 실행합니다. 결과를 진행 기록에 덧붙인 뒤 다시 Agent에게 물어, 이번에도 도구를 쓰라고 하면 반복하고 최종 답을 주면 그것을 돌려주며 끝냅니다. 이렇게 매 바퀴마다 기록이 쌓이므로, Agent는 이전에 무엇을 해 봤는지를 알고 다음 수를 고를 수 있습니다.
⚙️ 코드로 살펴보기
가장 기본적인 형태는 도구 목록과 Agent를 만들어 AgentExecutor에 넘기는 것입니다. 여기서는 간단한 계산 도구 하나를 정의해, 모델이 필요할 때 이 도구를 쓰도록 구성해 보겠습니다.
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
# 1) 도구 정의 — 모델이 필요할 때 호출한다
@tool
def add(a: int, b: int) -> int:
"""두 정수를 더한다."""
return a + b
tools = [add]
llm = ChatOpenAI(temperature=0)
prompt = ChatPromptTemplate.from_messages([
("system", "너는 도구를 활용해 답하는 assistant다."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"), # 진행 기록이 쌓이는 자리
])
# 2) 결정만 담당하는 Agent
agent = create_tool_calling_agent(llm, tools, prompt)
여기까지는 결정 두뇌만 만든 상태입니다. 이제 이 Agent를 AgentExecutor로 감싸면, 도구 실행과 반복까지 Executor가 알아서 처리해 줍니다.
# 3) 실행과 반복을 담당하는 Executor
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = executor.invoke({"input": "17 더하기 25는 얼마야?"})
print(result["output"])
# 모델이 add 도구를 호출 → 결과 42 관찰 → 최종 답 생성
위에서 agent_scratchpad가 바로 진행 기록이 쌓이는 자리입니다. Executor는 매 바퀴마다 방금의 행동과 관찰값을 이 자리에 채워 넣어, 다음 결정 때 모델이 지금까지의 흐름을 보고 판단하게 합니다. verbose=True로 두면 어떤 도구를 어떤 입력으로 썼고 무엇을 관찰했는지 중간 과정이 로그로 보이므로, 디버깅할 때 유용합니다.
🪜 루프를 멈추는 기준
스스로 반복한다는 말은 잘못하면 끝없이 돌 수도 있다는 뜻이기도 합니다. 그래서 Agent Executor에는 루프를 안전하게 끊는 멈춤 장치가 마련돼 있습니다. 대표적인 기준을 표로 정리했습니다.
| 멈춤 기준 | 언제 멈추나 |
|---|---|
| 최종 답 도달 | Agent가 도구 대신 최종 답을 내놓으면 그 즉시 루프를 끝내고 결과를 돌려줍니다. |
| max_iterations | 정해 둔 최대 반복 횟수를 넘으면, 답이 안 났더라도 더 돌지 않고 멈춥니다. |
| max_execution_time | 전체 실행이 정해 둔 시간 한도를 넘으면 중단합니다. |
예를 들어 반복 횟수를 제한하고 싶다면, 아래처럼 max_iterations를 지정하면 됩니다.
executor = AgentExecutor(
agent=agent,
tools=tools,
max_iterations=5, # 최대 5바퀴까지만 반복
# max_execution_time=30, # 필요하면 시간 한도도 함께
)
이렇게 상한을 걸어 두면 모델이 같은 도구를 계속 맴돌거나 답을 못 내는 상황에서도, 루프가 무한정 이어지지 않고 안전하게 끊깁니다. 즉 스스로 판단하는 자유와, 폭주하지 않는 안전장치를 함께 갖춘 구조입니다.
🔧 실무 팁
- 반복은 곧 비용 — 한 바퀴를 돌 때마다 LLM을 다시 호출하므로, 루프가 길어질수록 토큰 비용과 지연이 함께 늘어납니다. 꼭 필요한 도구만 쥐여 주는 것이 좋습니다.
- 도구 설명은 또 하나의 프롬프트 — 모델은 도구의 이름과 설명(docstring)을 보고 쓸지 말지 정합니다. 설명이 모호하면 엉뚱한 선택을 하므로, 무엇을 하는 도구인지 분명히 적어야 합니다.
- 상한은 되도록 설정 — 운영 환경이라면 max_iterations나 시간 한도를 걸어, 예상 밖의 무한 루프와 비용 폭주를 막는 편이 안전합니다.
- 중간 과정을 확인 — 기대와 다른 답이 나오면 verbose 로그로 어느 바퀴에서 어떤 도구를 잘못 썼는지 되짚으면 원인을 빨리 찾을 수 있습니다.
❓ 자주 묻는 질문 (FAQ)
Q. Agent만 있으면 되지, Executor가 왜 따로 필요한가요?
A. Agent는 "다음에 무엇을 할지" 결정만 하고 멈춥니다. 그 결정을 실제 도구 호출로 옮기고, 결과를 다시 넣어 반복을 돌려 주는 역할이 Executor입니다. 둘이 짝을 이뤄야 실제로 동작합니다.
Q. 모델이 도구를 안 쓰고 바로 답해 버리면요?
A. 그래도 괜찮습니다. Agent가 처음부터 최종 답을 내놓으면 Executor는 도구를 거치지 않고 그 답을 바로 돌려줍니다. 도구 사용은 필요할 때만 일어납니다.
Q. 루프가 멈추지 않으면 어떻게 되나요?
A. max_iterations나 max_execution_time 같은 상한에 걸리면 강제로 중단됩니다. 상한을 걸지 않았다면 비정상적으로 오래 돌 수 있으므로, 운영 시에는 설정해 두는 것이 안전합니다.
마무리
정리하면, Agent Executor는 "무엇을 할지 결정하는" Agent와 짝을 이뤄, 그 결정을 실제 도구 실행과 반복으로 연결해 주는 실행 엔진입니다. 핵심은 생각 → 행동 → 관찰을 한 바퀴로 묶어, 매 바퀴의 결과를 진행 기록에 쌓아 가며 최종 답이 나올 때까지 돌린다는 점이었습니다. 그리고 이 자유로운 반복이 폭주하지 않도록 최대 반복 횟수와 시간 한도 같은 멈춤 장치가 함께 준비돼 있다는 것도 살펴봤습니다. 다음 편에서는 이 Agent가 고를 수 있는 재료인 Tools를 직접 정의하고 다루는 방법으로 이야기를 이어가 보겠습니다.
댓글
댓글 쓰기