개요
많은 LLM 애플리케이션은 LLM 호출 전후에 특정 제어 흐름의 단계를 구현합니다. 예를 들어, RAG는 사용자 질문과 관련된 문서를 검색하고, 이를 LLM에 전달하여 제공된 문서 컨텍스트에 기반한 응답을 생성합니다.
하드코딩된 고정 제어 흐름 대신, 때로는 LLM 시스템이 더 복잡한 문제를 해결하기 위해 자체 제어 흐름을 선택할 수 있기를 원합니다. 이것이 에이전트의 한 정의입니다: 에이전트는 LLM을 사용하여 애플리케이션의 제어 흐름을 결정하는 시스템입니다.
LLM이 애플리케이션을 제어할 수 있는 방법은 다양합니다:
- LLM이 두 가지 잠재적 경로 중에서 라우팅할 수 있습니다
- LLM이 여러 도구 중 어떤 것을 호출할지 결정할 수 있습니다
- LLM이 생성된 답변이 충분한지 또는 더 많은 작업이 필요한지 결정할 수 있습니다
결과적으로, LLM에 다양한 수준의 제어권을 부여하는 많은 다른 유형의 에이전트 아키텍처가 있습니다.
라우터 (Router)
라우터는 LLM이 지정된 옵션 집합에서 단일 단계를 선택할 수 있게 합니다. 이는 LLM이 일반적으로 단일 결정을 내리고 제한된 사전 정의된 옵션 집합에서 특정 출력을 생성하기 때문에 상대적으로 제한된 수준의 제어를 나타내는 에이전트 아키텍처입니다.
라우터는 일반적으로 이를 달성하기 위해 몇 가지 다른 개념을 사용합니다.
구조화된 출력 (Structured Output)
LLM을 사용한 구조화된 출력은 LLM이 응답에서 따라야 할 특정 형식이나 스키마를 제공하여 작동합니다. 이는 도구 호출과 유사하지만 더 일반적입니다. 도구 호출은 일반적으로 미리 정의된 함수를 선택하고 사용하는 것을 포함하지만, 구조화된 출력은 모든 유형의 형식화된 응답에 사용할 수 있습니다.
구조화된 출력을 달성하는 일반적인 방법:
- 프롬프트 엔지니어링: 시스템 프롬프트를 통해 특정 형식으로 응답하도록 LLM에 지시
- 출력 파서: 사후 처리를 사용하여 LLM 응답에서 구조화된 데이터 추출
- 도구 호출: 일부 LLM의 내장 도구 호출 기능을 활용하여 구조화된 출력 생성
구조화된 출력은 LLM의 결정을 시스템이 안정적으로 해석하고 실행할 수 있도록 보장하기 때문에 라우팅에 중요합니다.
참고: 구조화된 출력 가이드
도구 호출 에이전트 (Tool-Calling Agent)
라우터가 LLM이 단일 결정을 내릴 수 있게 하는 반면, 더 복잡한 에이전트 아키텍처는 두 가지 주요 방식으로 LLM의 제어를 확장합니다:
- 다단계 의사결정: LLM이 하나가 아닌 일련의 결정을 차례로 내릴 수 있습니다
- 도구 액세스: LLM이 작업을 수행하기 위해 다양한 도구를 선택하고 사용할 수 있습니다
ReAct는 이러한 확장을 결합한 인기 있는 범용 에이전트 아키텍처로, 세 가지 핵심 개념을 통합합니다:
- 도구 호출: LLM이 필요에 따라 다양한 도구를 선택하고 사용할 수 있게 합니다
- 메모리: 에이전트가 이전 단계의 정보를 유지하고 사용할 수 있게 합니다
- 계획: LLM이 목표를 달성하기 위한 다단계 계획을 생성하고 따를 수 있게 합니다
이 아키텍처는 더 복잡하고 유연한 에이전트 동작을 가능하게 하며, 단순한 라우팅을 넘어 여러 단계로 동적 문제 해결을 가능하게 합니다. 원래 논문과 달리, 오늘날의 에이전트는 LLM의 도구 호출 기능에 의존하고 메시지 목록에서 작동합니다.
LangGraph에서는 사전 구축된 에이전트를 사용하여 도구 호출 에이전트를 시작할 수 있습니다.
도구 호출 (Tool Calling)
도구는 에이전트가 외부 시스템과 상호 작용하려고 할 때마다 유용합니다. 외부 시스템(예: API)은 종종 자연어가 아닌 특정 입력 스키마나 페이로드를 필요로 합니다. 예를 들어 API를 도구로 바인딩할 때, 모델에 필요한 입력 스키마를 인식시킵니다. 모델은 사용자의 자연어 입력을 기반으로 도구를 호출하도록 선택하고 도구의 필수 스키마를 준수하는 출력을 반환합니다.
많은 LLM 제공업체가 도구 호출을 지원하며 LangChain의 도구 호출 인터페이스는 간단합니다: Python function을 ChatModel.bind_tools(function)에 전달하기만 하면 됩니다.
메모리 (Memory)
메모리는 에이전트가 여러 문제 해결 단계에 걸쳐 정보를 유지하고 활용할 수 있게 하므로 에이전트에 중요합니다. 메모리는 다양한 규모에서 작동합니다:
- 단기 메모리: 에이전트가 시퀀스의 초기 단계에서 획득한 정보에 액세스할 수 있게 합니다
- 장기 메모리: 에이전트가 과거 대화의 메시지와 같은 이전 상호 작용의 정보를 회상할 수 있게 합니다
LangGraph는 메모리 구현에 대한 완전한 제어를 제공합니다:
- State: 유지할 메모리의 정확한 구조를 지정하는 사용자 정의 스키마
- Checkpointer: 세션 내의 다양한 상호 작용에 걸쳐 모든 단계에서 상태를 저장하는 메커니즘
- Store: 세션 간에 사용자별 또는 애플리케이션 수준 데이터를 저장하는 메커니즘
이러한 유연한 접근 방식을 통해 특정 에이전트 아키텍처 요구 사항에 맞게 메모리 시스템을 조정할 수 있습니다. 효과적인 메모리 관리는 컨텍스트를 유지하고, 과거 경험에서 학습하며, 시간이 지남에 따라 더 많은 정보를 바탕으로 결정을 내리는 에이전트의 능력을 향상시킵니다.
참고: 메모리 추가 및 관리에 대한 실용 가이드는 Memory를 참조하세요.
계획 (Planning)
도구 호출 에이전트에서 LLM은 while 루프에서 반복적으로 호출됩니다. 각 단계에서 에이전트는 호출할 도구와 해당 도구에 대한 입력을 결정합니다. 그런 다음 이러한 도구가 실행되고 출력이 관찰로서 LLM에 다시 피드백됩니다. while 루프는 에이전트가 사용자 요청을 해결하기에 충분한 정보를 수집했다고 결정하고 더 이상 도구를 호출할 가치가 없을 때 종료됩니다.
커스텀 에이전트 아키텍처
라우터와 도구 호출 에이전트(ReAct 같은)가 일반적이지만, 특정 작업에 맞게 에이전트 아키텍처를 커스터마이징하면 더 나은 성능을 얻을 수 있는 경우가 많습니다. LangGraph는 맞춤형 에이전트 시스템을 구축하기 위한 몇 가지 강력한 기능을 제공합니다:
휴먼-인-더-루프 (Human-in-the-Loop)
인간의 개입은 특히 민감한 작업에서 에이전트 신뢰성을 크게 향상시킬 수 있습니다. 여기에는 다음이 포함될 수 있습니다:
- 특정 작업 승인
- 에이전트 상태를 업데이트하기 위한 피드백 제공
- 복잡한 의사 결정 프로세스에서 지침 제공
휴먼-인-더-루프 패턴은 완전 자동화가 실행 가능하지 않거나 바람직하지 않을 때 중요합니다.
참고: 휴먼-인-더-루프 가이드
병렬화 (Parallelization)
병렬 처리는 효율적인 멀티 에이전트 시스템과 복잡한 작업에 필수적입니다. LangGraph는 Send API를 통해 병렬화를 지원하며, 다음을 가능하게 합니다:
- 여러 상태의 동시 처리
- 맵-리듀스와 유사한 작업 구현
- 독립적인 하위 작업의 효율적인 처리
참고: 실제 구현은 맵-리듀스 튜토리얼을 참조하세요.
서브그래프 (Subgraphs)
서브그래프는 복잡한 에이전트 아키텍처, 특히 멀티 에이전트 시스템을 관리하는 데 필수적입니다. 서브그래프를 통해 다음이 가능합니다:
- 개별 에이전트에 대한 격리된 상태 관리
- 에이전트 팀의 계층적 구성
- 에이전트와 메인 시스템 간의 제어된 통신
서브그래프는 상태 스키마의 겹치는 키를 통해 부모 그래프와 통신합니다. 이를 통해 유연하고 모듈식 에이전트 설계가 가능합니다.
참고: 서브그래프 가이드
반성 (Reflection)
반성 메커니즘은 다음을 통해 에이전트 신뢰성을 크게 향상시킬 수 있습니다:
- 작업 완료 및 정확성 평가
- 반복적인 개선을 위한 피드백 제공
- 자기 수정 및 학습 가능
반성은 종종 LLM 기반이지만 결정론적 방법을 사용할 수도 있습니다. 예를 들어, 코딩 작업에서 컴파일 오류가 피드백 역할을 할 수 있습니다. 이 접근 방식은 자기 수정 코드 생성 비디오에서 LangGraph를 사용하여 시연되었습니다.
이러한 기능을 활용함으로써 LangGraph는 복잡한 워크플로우를 처리하고, 효과적으로 협력하며, 지속적으로 성능을 개선할 수 있는 정교하고 작업별 에이전트 아키텍처를 만들 수 있게 합니다.
에이전트 아키텍처 비교
다양한 에이전트 아키텍처를 이해하고 적절한 패턴을 선택하는 것이 중요합니다:
| 아키텍처 | 제어 수준 | 적용 사례 | 특징 |
|---|---|---|---|
| Router | 제한적 | 사전 정의된 옵션 중 선택 | 단일 결정, 구조화된 출력 |
| Tool-Calling Agent | 중간 | 다단계 문제 해결 | 도구 호출, 메모리, 계획 |
| Custom Architecture | 높음 | 복잡하고 특화된 작업 | 휴먼-인-더-루프, 병렬화, 서브그래프 |