AI 에이전트 · LLM · 도구 호출

LLM과 AI 에이전트의 차이 이해하기

한 번 답하는 LLM 호출이 상태·도구·반복을 갖춘 AI 에이전트로 확장되는 구조를 살펴봅니다.

무료 공개 · 최근 수정

답변 생성과 작업 수행 구분하기

대규모 언어 모델(Large Language Model; LLM)은 입력을 받아 다음에 올 토큰을 생성합니다. 질문에 답하거나 문장을 요약하는 일은 이 한 번의 호출만으로도 충분할 수 있습니다. 그러나 “오늘 서울의 날씨를 확인해 일정표를 고쳐 줘”처럼 최신 정보를 조회하고 외부 시스템을 바꿔야 하는 요청은 텍스트 생성만으로 끝나지 않습니다. 무엇을 이미 확인했는지 기억하고, 다음 행동을 고르고, 실행 결과에 따라 계획을 수정해야 합니다.

AI 에이전트(AI Agent)는 모델 호출을 상태, 도구, 실행 정책과 연결해 목표를 향해 여러 단계를 진행하는 프로그램입니다. 모델은 다음 행동을 제안하지만 파일이나 API를 직접 다루지는 않습니다. 모델을 둘러싼 실행 환경인 하네스가 허용된 도구를 실제로 호출하고 결과를 기록합니다. 따라서 모델은 판단을 돕는 구성 요소이고, 하네스는 권한·반복·실패를 통제하며, 둘이 결합된 전체 프로그램을 에이전트라고 이해하는 편이 정확합니다.

가장 작은 에이전트 루프는 다음 네 단계로 설명할 수 있습니다.

  1. 현재 상태와 사용자 요청을 모델에 전달합니다.
  2. 모델이 최종 답변 또는 도구 호출을 제안합니다.
  3. 에이전트 실행 환경(하네스; Harness)이 권한과 인자를 확인한 뒤 허용된 도구를 실행합니다.
  4. 실행 결과를 상태에 추가하고, 끝낼 조건을 충족할 때까지 다시 판단합니다.

여기서 상태는 원래 요청, 지금까지의 메시지, 도구 결과와 남은 작업을 담습니다. 행동은 모델이 제안한 도구 호출이나 최종 답변이고, 관찰은 도구의 성공·오류·반환값입니다. 도구가 필요 없는 질문이라면 한 번의 모델 호출로 끝나지만 파일 읽기나 API 조회가 필요하면 관찰을 바탕으로 다음 행동을 정합니다. 이 차이 때문에 에이전트에는 모델 품질뿐 아니라 종료 조건, 권한 검사, 실패 처리와 실행 기록이 필요합니다.

에이전트를 쓰기 전에 작업의 불확실성도 살펴야 합니다. 실행 순서와 규칙이 모두 정해진 데이터 변환은 일반 함수나 워크플로가 더 단순하고 재현하기 쉽습니다. 반대로 어떤 정보를 찾아야 할지 입력마다 달라지고, 관찰 결과에 따라 다음 단계가 달라질 때 에이전트 루프가 유용합니다. “LLM을 사용한다”와 “에이전트가 필요하다”는 같은 판단이 아닙니다.

작은 루프로 확인하기

다음 코드는 모델 대신 미리 정한 판단 함수를 사용해 구조만 보여 줍니다.

def decide(state):
    if "weather" not in state:
        return {"tool": "weather", "city": "Seoul"}
    return {"answer": f"현재 관찰값은 {state['weather']}입니다."}
 
def call_weather_tool(city):
    return "맑음, 21°C"  # 예제용 고정 관찰값
 
 
state = {"question": "서울 날씨는?"}
for _ in range(3):
    action = decide(state)
    if action.get("tool") == "weather":
        state["weather"] = call_weather_tool(action["city"])
    else:
        state["answer"] = action["answer"]
        break
else:
    raise RuntimeError("최대 단계 수 안에 작업을 끝내지 못했습니다.")
 
print(state["answer"])

첫 번째 반복에서는 날씨 도구 호출이 선택되고, 그 결과가 상태에 저장됩니다. 두 번째 반복에서는 이미 관찰값이 있으므로 최종 답을 만들고 종료합니다. 이처럼 상태가 다음 판단을 바꾸는 것이 단순한 재시도와 에이전트 루프의 차이입니다. 실제 에이전트에서는 고정값 대신 도구가 반환한 결과를 저장하며, 같은 도구를 끝없이 호출하지 않도록 최대 단계 수, 시간 제한과 비용 한도를 함께 둡니다.

어디까지 맡길지 정하기

에이전트가 도구 호출을 제안했다고 해서 실행 권한까지 얻는 것은 아닙니다. 삭제, 결제, 외부 메시지 전송처럼 영향이 큰 작업은 애플리케이션이 별도로 승인해야 합니다. 입력 검증과 권한 검사는 프롬프트가 아니라 결정적인 코드로 구현합니다.

처음 설계할 때는 다음 질문으로 범위를 좁힐 수 있습니다.

  • 외부 세계의 최신 정보나 실행 결과를 관찰해야 하는가?
  • 관찰에 따라 다음 단계가 실제로 달라지는가?
  • 읽기와 쓰기 도구의 권한을 따로 제한했는가?
  • 성공, 실패와 중단을 코드로 판정할 수 있는가?
  • 실행 과정을 나중에 재현할 기록이 남는가?

앞의 두 항목이 아니라면 한 번의 모델 호출이나 고정된 파이프라인으로도 충분할 가능성이 큽니다. 에이전트가 필요하다면 작은 읽기 전용 도구 하나로 시작해 상태와 종료 조건을 확인한 뒤 쓰기 기능을 추가하는 것이 안전합니다.

다음 글에서는 이 반복을 구체화하는 ReAct와 도구 호출, 상태 기반 흐름을 만드는 LangGraph, 로컬 모델을 실행하는 Ollama를 살펴봅니다.

참고 문서

설명이 어렵거나 잘못된 부분을 발견하셨나요?

문서 수정 의견 보내기