LLM 기반 애플리케이션과 Agent의 차이: 무엇이 다를까?
최근 생성형 AI 시스템을 이야기할 때 가장 자주 등장하는 두 개념이 있다. 하나는 LLM 기반 애플리케이션이고, 다른 하나는 LLM 기반 Agent다. 둘 다 대형언어모델을 활용한다는 점에서는 같지만, 시스템이 문제를 해결하는 방식은 꽤 다르다. 이 차이를 이해하면 단순한 챗봇, 문서 요약기, 질의응답 시스템부터 도구를 활용해 스스로 행동하는 에이전트 시스템까지 어떻게 설계해야 하는지 훨씬 명확해진다.
이 글에서는 LLM 애플리케이션과 Agent의 개념 차이, 모델의 역할, 메모리 구성 방식, 그리고 LangGraph와 LangSmith가 각각 어떤 문제를 해결하는지까지 한 번에 정리해보겠다. (LangChain 문서)
1. LLM 기반 애플리케이션이란?
LLM 기반 애플리케이션은 특정 목적을 위해 미리 설계된 고정형 파이프라인이라고 볼 수 있다. 입력이 들어오면 개발자가 사전에 정해 둔 흐름에 따라 처리되고, 그 과정 중 일부 단계에서 LLM이 호출된다. 즉, 시스템의 전체 동작 구조는 개발자가 설계하고, 모델은 그 안에서 정해진 역할을 수행한다. 이런 구조는 비교적 예측 가능하고 안정적이기 때문에 텍스트 요약기, 문서 질의응답 시스템, 고객응대 챗봇 UI 같은 서비스에 자주 사용된다. (LangChain 문서)
예를 들어 사용자가 “오늘 서울 날씨 어때?”라고 물었을 때, 단순한 LLM 애플리케이션은 보통 다음처럼 동작한다.
입력 → 의도 분류 또는 라우팅 → 외부 날씨 API 호출 → 결과를 LLM이 자연어로 정리 → 출력
여기서 중요한 점은, 시스템이 어떤 도구를 쓸지, 어떤 순서로 처리할지는 이미 개발자가 정해 두었다는 것이다. 즉, LLM이 흐름 전체를 자율적으로 결정하는 것이 아니라 정해진 파이프라인 안에서 일부 생성 작업을 담당하는 구조다. (LangChain 문서)
정리하면 LLM 기반 애플리케이션의 핵심은 다음과 같다.
- 흐름이 고정되어 있다.
- 어떤 도구를 쓸지 개발자가 미리 정한다.
- LLM은 요약, 분류, 답변 생성 같은 특정 역할을 맡는다.
- 예측 가능성과 운영 안정성이 높다. (LangChain 문서)
2. LLM 기반 Agent란?
반면 LLM 기반 Agent는 LLM이 스스로 무엇을 해야 할지 판단하고, 필요한 행동을 선택하며, 그 결과를 바탕으로 다음 행동을 이어가는 동적 시스템이다. 공식 문서에서도 에이전트는 모델 호출과 도구 실행이 반복되는 루프 구조로 설명된다. 즉, 사용자의 입력을 받으면 모델이 단순히 답만 생성하는 것이 아니라, 현재 상황에서 검색이 필요한지, 계산이 필요한지, 외부 API를 호출해야 하는지 등을 판단하고 실행한다. 이 과정은 한 번으로 끝날 수도 있고, 여러 번 반복될 수도 있다. (LangChain 문서)
에이전트의 전형적인 흐름은 아래와 같다.
입력 → 추론(무엇을 해야 하는가?) → 도구 선택 및 호출 → 결과 해석 → 필요 시 반복 → 최종 출력
예를 들어 같은 질문인 “오늘 서울 날씨 어때?”에 대해 Agent는 다음처럼 동작할 수 있다.
- 사용자의 질문을 보고 현재 시점의 실시간 정보가 필요하다고 판단한다.
- 날씨 조회 도구가 필요하다고 결정한다.
- 입력에서 오늘, 서울, 날씨를 핵심 인자로 해석한다.
- 외부 날씨 API를 호출한다.
- 받은 결과를 바탕으로 다시 판단한 뒤 최종 답변을 생성한다.
즉, Agent의 핵심은 단순 생성이 아니라 판단과 행동의 반복에 있다. 검색 에이전트, 리서치 에이전트, 이메일·캘린더를 조작하는 비서형 서비스가 여기에 해당한다. (LangChain 문서)
3. 그렇다면 Agent는 무엇인가?
Agent를 한 문장으로 정의하면 다음과 같다.
사용자의 질문이나 지시에 대해, 적절한 행동을 취하기 위해 추론하고 실행하는 주체
여기서 핵심 구성 요소는 크게 두 가지다.
1) LLM
사용자 요청을 이해하고, 현재 무엇이 필요한지 판단한다.
2) Tools
검색, 계산, 데이터베이스 조회, 이메일 발송, 일정 등록 같은 외부 행동을 수행한다.
공식 문서에서도 tools는 잘 정의된 입력과 출력을 가진 호출 가능한 함수이며, 모델은 대화 맥락을 바탕으로 언제 어떤 도구를 호출할지 결정한다고 설명한다. 결국 Agent는 LLM + Tools의 결합체라고 이해하면 가장 직관적이다. (LangChain 문서)
4. Model은 시스템에서 어떤 역할을 할까?
LLM 시스템에서 모델은 단순히 문장을 생성하는 기계가 아니다. 현재 LangChain 문서 기준으로 모델은 standalone으로 직접 호출할 수도 있고, agent 안에서 의사결정 엔진처럼 사용할 수도 있다. 모델은 텍스트 생성, 구조화된 출력, 추론, 도구 호출 등 여러 역할을 맡는다. (LangChain 문서)
4-1. 텍스트 생성
가장 기본적인 역할은 자연어 생성이다. 사용자의 질문에 답하거나, 요약문을 만들거나, 설명문을 작성하는 작업이 여기에 해당한다. LangChain에서는 init_chat_model()로 모델을 초기화한 뒤 invoke()로 단일 요청을 보내고, stream()으로 실시간 출력 스트리밍을 받거나, batch()로 여러 요청을 한 번에 처리할 수 있다. 문서에서도 invoke, stream, batch를 핵심 호출 방식으로 설명한다. (LangChain 문서)
from langchain.chat_models import init_chat_model
model = init_chat_model("gpt-5.2", temperature=0)
response = model.invoke("안녕하세요. 당신은 누구입니까?")
print(response.content)
temperature는 응답의 무작위성을 조절하고, 일반적으로 낮을수록 일관적이고 결정적인 응답에, 높을수록 더 다양한 응답에 유리하다. 운영 환경에서는 여기에 timeout, max_tokens, max_retries 같은 파라미터를 더해 안정성과 비용을 함께 관리한다. (LangChain 문서)
4-2. 구조화된 출력 생성
실무에서는 모델이 단순 문장만 잘 쓰는 것으로는 충분하지 않다. 다음 단계의 프로그램이 그 결과를 바로 사용할 수 있도록 JSON, Pydantic 모델, Dataclass 같은 구조화된 형식으로 출력해야 하는 경우가 많다. LangChain은 이런 structured output을 공식 기능으로 지원하며, 에이전트에서는 response_format을 통해, 개별 모델 호출에서는 provider별 with_structured_output() 같은 인터페이스를 통해 사용할 수 있다. (LangChain 문서)
대표적인 방법은 두 가지다.
방법 1. Pydantic 스키마 사용
from pydantic import BaseModel, Field
from langchain_openai import ChatOpenAI
class Movie(BaseModel):
"""상세한 영화 정보"""
title: str = Field(description="영화 제목")
year: int = Field(description="개봉 연도")
director: str = Field(description="감독")
rating: float = Field(description="10점 만점 평점")
llm = ChatOpenAI(model="gpt-5.4")
structured_llm = llm.with_structured_output(Movie, method="json_schema")
response = structured_llm.invoke("영화 인터스텔라를 소개해줘")
print(response)
Pydantic을 사용하면 필드 타입 검증과 직렬화가 쉬워지고, 모델이 반환한 결과를 애플리케이션 로직에 바로 연결하기 편해진다. (LangChain 문서)
방법 2. JSON Schema 사용
from langchain_openai import ChatOpenAI
json_schema = {
"title": "Movie",
"description": "A movie with details",
"type": "object",
"properties": {
"title": {"type": "string", "description": "The title of the movie"},
"year": {"type": "integer", "description": "The year the movie was released"},
"director": {"type": "string", "description": "The director of the movie"},
"rating": {"type": "number", "description": "The movie's rating out of 10"}
},
"required": ["title", "director", "rating"]
}
llm = ChatOpenAI(model="gpt-5.4")
structured_llm = llm.with_structured_output(json_schema, method="json_schema")
response = structured_llm.invoke("영화 인터스텔라에 대해 소개해줘")
print(response)
공식 문서 기준으로 structured output은 JSON 객체, Pydantic 모델, Dataclass 등 예측 가능한 형식으로 결과를 반환하도록 설계되어 있으며, 일부 제공자는 provider-native structured output도 지원한다. (LangChain 문서)
4-3. 멀티모달 처리
최근 모델은 텍스트뿐 아니라 이미지, 오디오, 비디오 등 다양한 입력과 출력을 다루는 방향으로 확장되고 있다. 다만 어떤 멀티모달 기능을 지원하는지는 모델 제공자와 통합 패키지마다 다르므로, 실제 구현 시에는 해당 integration의 기능 표를 확인하는 것이 좋다. (LangChain 문서)
4-4. 추론
Agent 맥락에서 모델은 단순 생성기가 아니라 의사결정 엔진에 가깝다. 모델은 지금 답을 바로 해야 하는지, 검색을 먼저 해야 하는지, 도구 결과가 충분한지, 한 번 더 호출해야 하는지 등을 판단한다. 공식 문서에서도 모델은 agent의 reasoning engine이며, 도구 호출 여부와 최종 응답 시점을 결정하는 핵심 구성 요소로 설명된다. (LangChain 문서)
4-5. Tool Calling
Tool calling은 모델이 외부 기능을 활용할 수 있게 해주는 핵심 메커니즘이다. 모델은 필요한 순간에 데이터베이스 조회, 웹 검색, 코드 실행, 캘린더 등록 같은 도구를 선택하고 인자를 생성해 호출할 수 있다. LangChain 문서에서는 이를 function calling과 거의 같은 의미로 다루며, schema와 실행 함수의 조합으로 설명한다. (LangChain 문서)
5. 메모리는 어떻게 구현될까?
LLM 애플리케이션과 Agent에서 메모리는 보통 메시지의 누적으로 시작된다. 현재 대화형 모델은 단일 문자열만 받는 것이 아니라, 여러 개의 메시지 목록을 입력으로 받는다. LangChain 문서에서도 기본 메시지 타입으로 SystemMessage, HumanMessage, AIMessage, ToolMessage를 설명한다. (LangChain 문서)
메시지의 기본 구성
- System Message: 모델의 역할, 말투, 규칙, 지침을 지정
- Human/User Message: 사용자의 입력
- AI/Assistant Message: 모델의 답변
- Tool Message: 도구 호출 결과
이 메시지들이 쌓이면서 대화의 문맥이 형성되고, 이를 기반으로 모델이 이전 대화를 참조하며 응답하게 된다. 다만 컨텍스트 윈도우는 제한되어 있기 때문에, 실제 서비스에서는 오래된 메시지를 요약하거나 제거하는 short-term memory 전략이 함께 사용된다. (LangChain 문서)
방법 1. 메시지 객체 사용
from langchain.messages import HumanMessage, SystemMessage
from langchain.chat_models import init_chat_model
model = init_chat_model("gpt-5.2")
messages = [
SystemMessage("당신은 유능한 로켓 전문가입니다."),
HumanMessage("안녕하세요. 궁금한 게 있어요!")
]
response = model.invoke(messages)
print(response.content)
LangChain은 메시지 객체 기반 입력을 공식적으로 지원하며, 이 방식은 역할이 분명해서 시스템 설계 시 가장 직관적이다. (LangChain 문서)
방법 2. 딕셔너리 형식 사용
messages = [
{"role": "system", "content": "당신은 유능한 로켓 전문가입니다."},
{"role": "user", "content": "안녕하세요. 궁금한 게 있어요!"},
{"role": "assistant", "content": "로켓 관련 무엇이든 물어보세요."},
{"role": "user", "content": "추진 방식 차이를 설명해 주세요"}
]
response = model.invoke(messages)
print(response.content)
문서에서는 OpenAI chat completions 형식과 유사한 dictionary format도 지원한다고 설명한다. 보통 빠르게 프로토타입을 만들 때는 이 방식도 많이 사용된다. (LangChain 문서)
6. LangGraph는 왜 필요한가?
간단한 애플리케이션은 체인 몇 개로도 만들 수 있지만, Agent가 복잡해지면 이야기가 달라진다. 여러 단계의 판단, 반복 루프, 조건 분기, 사람의 개입, 장기 실행, 상태 저장이 필요해진다. LangGraph는 바로 이런 복잡한 agent orchestration을 위해 등장한 저수준 프레임워크다. 공식 문서도 LangGraph를 long-running, stateful agent를 위한 orchestration framework로 설명하며, durable execution, streaming, human-in-the-loop, memory 같은 기능을 핵심 장점으로 제시한다. (LangChain 문서)
쉽게 말하면 LangGraph는 “LLM을 한 번 호출하는 것”이 아니라, 여러 노드와 상태를 가진 실행 그래프를 설계하게 해주는 도구다. 그래서 다음과 같은 경우에 특히 유용하다.
- 여러 단계를 거치는 복합 워크플로우
- 조건에 따라 분기되는 처리
- 도구 호출 결과에 따라 다시 추론해야 하는 루프
- 사람의 승인이나 수정이 필요한 흐름
- 세션 상태를 오래 유지해야 하는 시스템 (LangChain 문서)
즉, LangGraph는 단순 체인보다 더 복잡한 의사결정과 상태 관리를 다뤄야 할 때 적합하다. “에이전트를 운영 가능한 구조로 만든다”는 관점에서 보면 가장 중요한 레이어 중 하나다. (LangChain 문서)
7. LangSmith는 무엇을 해주는가?
Agent나 LLM 애플리케이션을 만들다 보면 결국 이런 문제가 생긴다.
- 어느 프롬프트에서 실패했는가?
- 어떤 순서로 모델과 도구가 호출되었는가?
- 토큰 사용량과 레이턴시는 어떤가?
- 특정 데이터셋에서 성능이 안정적인가?
- 운영 중 품질 저하가 발생했는가?
LangSmith는 이런 문제를 해결하기 위한 관측성(observability)과 평가(evaluation) 플랫폼이다. 공식 문서에서도 tracing, monitoring, observability 기능과 함께 dataset 기반 evaluation, evaluator, experiment 결과 분석 기능을 제공한다고 설명한다. (LangChain 문서)
정리하면 LangSmith의 역할은 다음과 같다.
- 추적(Tracing): 모델 호출과 도구 호출의 실행 경로를 시각적으로 추적
- 모니터링(Monitoring): 운영 중 토큰, 지연시간, 에러, 실행 패턴 확인
- 평가(Evaluation): 테스트 데이터셋을 바탕으로 애플리케이션 품질을 정량적으로 검증
즉, LangGraph가 “어떻게 Agent를 설계할 것인가”를 다룬다면, LangSmith는 “그 Agent가 실제로 잘 동작하는지 어떻게 관찰하고 평가할 것인가”를 다룬다고 볼 수 있다. (LangChain 문서)
8. 한 번에 정리하면
지금까지 내용을 가장 간단히 요약하면 다음과 같다.
LLM 기반 애플리케이션은
개발자가 설계한 고정된 흐름 안에서 LLM을 활용하는 시스템이다.
LLM 기반 Agent는
LLM이 상황을 해석하고, 필요한 도구를 선택하고, 결과를 바탕으로 행동을 반복하는 동적 시스템이다.
Model은
텍스트 생성기이자, 구조화된 출력을 만드는 도구이며, Agent 안에서는 의사결정 엔진 역할도 수행한다.
Memory는
메시지의 누적과 관리로 구성되며, 대화 문맥 유지의 핵심이다.
LangGraph는
복잡한 Agent의 상태, 분기, 루프, 사람 개입까지 다루는 orchestration 프레임워크다.
LangSmith는
이 시스템이 실제로 어떻게 동작하는지 추적하고, 평가하고, 운영 품질을 관리하게 해주는 플랫폼이다. (LangChain 문서)
마무리
생성형 AI 시스템을 설계할 때 가장 먼저 해야 할 질문은 “LLM을 쓸 것인가?”가 아니라, “이 문제는 고정형 애플리케이션으로 풀 수 있는가, 아니면 Agent처럼 동적으로 판단하고 행동해야 하는가?”이다.
간단한 요약기나 FAQ 챗봇이라면 LLM 애플리케이션 구조가 더 적합할 수 있다. 반면 여러 도구를 조합하고, 상황에 따라 다른 행동을 하며, 반복적으로 문제를 해결해야 한다면 Agent 구조가 필요하다. 그리고 그 Agent가 복잡해질수록 LangGraph와 LangSmith 같은 도구의 중요성도 커진다.
결국 실무에서 중요한 것은 “LLM을 붙였다”가 아니라, 문제에 맞는 시스템 구조를 선택하고, 그 구조를 안정적으로 운영 가능하게 만드는 것이다. (LangChain 문서)