1. LLM이란?
LLM은 대량의 텍스트를 학습해 다음에 올 말을 확률적으로 예측하는 언어 모델이다.
- 질문에 대한 그럴듯한 응답 생성에는 강하다.
- 하지만 스스로 외부 시스템을 조작하거나 업무를 끝까지 수행하지는 못한다.
- 기본 구조는 상태·기억·목표가 없는 stateless 단발성 응답에 가깝다.
2. AI Agent가 등장한 배경
AI Agent는 단순히 더 좋은 답변을 만들기 위해 나온 개념이 아니다. 핵심은 답변 생성 이후의 실행 문제를 해결하는 것이다.
- 대화 맥락과 정보를 지속적으로 기억하지 못함
- DB, API, 알림 같은 외부 시스템을 직접 제어하지 못함
- 목표 달성 여부나 결과 검증에 대한 책임 구조가 없음
- 답변 생성을 넘어 실제 업무를 처리하는 AI가 필요해짐
- LLM에 상태, 도구 사용, 실행 로직을 결합함
- 반복 작업, 워크플로우, 자동화를 제어 가능한 구조로 만들 수 있음
3. AI Agent란?
AI Agent는 생각만 하는 AI가 아니라, 상황을 이해하고 필요한 일을 나눠 실제 행동까지 수행하도록 만든 프로그램 구조다.
단순 챗봇이 답변 생성에 집중한다면, 에이전트는 보통 아래 요소를 함께 가진다.
| 구성 요소 | 역할 |
|---|---|
| Tool Calling | DB 조회, API 호출, 파일 읽기/쓰기, Slack 전송 등 외부 행동을 수행한다. |
| State | 대화·작업 컨텍스트, 세션 메모리, 장기 메모리를 관리한다. |
| Orchestration | 어떤 순서로 어떤 작업을 시킬지 결정하고, 실패 시 재시도·대체 경로를 적용한다. |
| Guardrail | 정책, 보안, PII 마스킹, 입력 검증, 비용·시간 제한을 관리한다. |
4. Single Agent에서 Multi-Agent로
처음에는 하나의 Agent가 모든 역할을 맡아도 된다. 하지만 검색, 요약, 분류, 검증, 실행이 한 곳에 몰리면 복잡도와 실패 리스크가 커진다.
빠르게 시작하기 좋은 구조
- 사용자 입력
- LLM이 생각과 툴 호출을 결정
- 툴 결과를 반영해 최종 답변
한계: 역할이 한 곳에 모여 실패·지연·비용이 커지고 테스트와 디버깅이 어렵다.
운영 가능한 구조로 분리
- Router: 의도 분류
- Retriever: 근거 수집
- Planner: 계획 수립
- Executor: 툴 실행
- Verifier: 검증
- Summarizer: 결과 정리
- Memory Manager: STM/LTM 관리
Single → Multi 구조화 단계
- 역할 분리 + 계약
각 서브 에이전트의 입력/출력 스키마(JSON)를 고정한다. 예를 들어 Retriever는 근거 목록, 출처, 신뢰도만 반환하게 만든다. - 오케스트레이터 도입
중앙 Orchestrator가 어떤 에이전트를 언제 호출할지, 타임아웃·재시도·폴백을 어떻게 처리할지 결정한다. - 비동기화 + Pub/Sub / Queue 확장
요청량이 늘어나면 동기 체인이 길어져 느려지고 불안정해진다. 이때 이벤트와 작업 큐를 분리한다. - 상태/메모리 분리
에이전트가 각자 메모리를 갖지 않도록 하고, Memory Service를 통해 STM과 LTM을 중앙 관리한다.
5. 멀티 에이전트 아키텍처 패턴 3가지
Manager-Worker
Manager가 계획을 세우고 Worker들이 검색, 실행, 검증을 담당한다.
장점: 통제가 쉽고 운영·디버깅이 편하다.
예시: 사내 업무 자동화, 고객응대, 워크플로우
Event-Driven
이벤트가 발생하면 여러 에이전트가 구독해 각자 필요한 처리를 한다.
장점: 확장성과 느슨한 결합이 좋다.
주의: 관측성이 없으면 추적과 디버깅이 어려워진다.
Pipeline / DAG
정해진 단계대로 A → B → C 순서로 처리한다.
장점: 결과 재현과 테스트가 쉽다.
예시: 문서 처리, 분류, 추출, 요약, 검증
6. Pub/Sub vs Queue
둘 다 비동기 구조에서 자주 등장하지만 역할은 다르다. 헷갈리면 이렇게 기억하면 된다.
사용자 메시지 들어옴
→ 콘텐츠인지 판단
→ 웹검색/사내검색
→ 요약
→ 검증
→ Slack 전송/저장
| 구분 | 예시 | 의미 |
|---|---|---|
| Pub/Sub 이벤트 | MessageReceived, ContentDetected, EvidenceCollected, DraftReady, Verified | 어떤 일이 발생했음을 여러 소비자에게 알린다. |
| Queue 작업 | RunDetectionJob, RunRetrievalJob, RunSummarizeJob, RunVerificationJob, RunPublishJob | 처리해야 할 일을 안정적으로 순서·부하 조절하며 수행한다. |
7. Sample Architecture
7-1. 동기 버전: Orchestrator 중심
초기에는 API가 Orchestrator를 호출하고, Orchestrator가 각 Agent와 Memory Service를 동기적으로 호출하는 구조가 가장 단순하다.
Mermaid 코드 보기
flowchart LR
U[User/App] --> API[Fastify API]
API --> ORCH[Orchestrator/Manager]
ORCH --> R[Router Agent]
ORCH --> P[Planner Agent]
ORCH --> RET[Retriever Agent]
ORCH --> EXE[Executor Agent]
ORCH --> V[Verifier Agent]
ORCH --> S[Summarizer Agent]
ORCH <--> MEM[Memory Service]
MEM <--> STM[(Redis: STM)]
MEM <--> LTM[(DB/Vector: LTM)]
EXE --> TOOLS[Tools: DB/API/Slack]
ORCH --> API --> U
7-2. 비동기 버전: Pub/Sub + Queue
요청량이 늘거나 특정 단계가 오래 걸리면 Pub/Sub와 Queue를 통해 처리 단계를 분리한다. 실패한 작업은 DLQ로 보내고 운영 알람을 붙인다.
Mermaid 코드 보기
flowchart TB
U[User/App] --> API[Fastify API]
API --> EV[Event: MessageReceived]
EV --> EG[(Pub/Sub: Event Bus)]
EG --> ORCH[Orchestrator]
ORCH --> Q1[(Queue: Detect/Route Jobs)]
ORCH --> Q2[(Queue: Retrieval Jobs)]
ORCH --> Q3[(Queue: Summarize/Verify Jobs)]
ORCH --> Q4[(Queue: Publish/Store Jobs)]
Q1 --> R[Router Agent]
Q2 --> RET[Retriever Agent]
Q3 --> S[Summarizer Agent]
Q3 --> V[Verifier Agent]
Q4 --> PUB[Publisher Agent]
ORCH <--> MEM[Memory Service]
MEM <--> STM[(Redis STM)]
MEM <--> LTM[(Cosmos/PG + Vector LTM)]
PUB --> Slack[Slack Webhook]
PUB --> DB[(DB/Blob)]
PUB --> EG2[Event: Done/Failed] --> EG
Azure 리소스 위치
| 리소스 | Azure Portal 경로 |
|---|---|
| Event Grid | Azure Portal → Event Grid → Topics / Subscriptions |
| Service Bus | Azure Portal → Service Bus → Queues / Topics |
| Azure Functions | Azure Portal → Function App |
| Redis | Azure Portal → Azure Cache for Redis |
| Cosmos DB | Azure Portal → Azure Cosmos DB |
| Monitor / Logs | Azure Portal → Monitor → Log Analytics / Application Insights |
8. 서브 에이전트 입력/출력 계약
멀티 에이전트에서 가장 중요한 것은 역할 분리보다 계약을 고정하는 것이다. 입력과 출력 형태가 고정되어야 테스트, 교체, 장애 분석이 가능하다.
공통 Envelope
{
"traceId": "uuid",
"sessionId": "string",
"timestamp": "ISO-8601",
"input": {},
"context": {
"userLocale": "ko-KR",
"tenant": "dev|stg|prd",
"budget": { "maxTokens": 2000, "maxToolCalls": 5 },
"security": { "piiAllowed": false }
}
}
Router Agent
// input
{
"message": "사용자 원문",
"hints": { "channel": "web|slack|app", "knownIntents": ["news", "weather", "content"] }
}
// output
{
"route": "content_search|qa|action|handoff",
"confidence": 0.0,
"signals": ["hasContentTitleLikePhrase", "needsWebSearch"],
"normalizedQuery": "검색 키워드",
"language": "ko"
}
Planner Agent
// input
{
"goal": "무엇을 달성할지",
"routeResult": { "route": "content_search", "normalizedQuery": "..." },
"constraints": { "timeLimitMs": 8000, "noWeb": false }
}
// output
{
"plan": [
{ "step": 1, "agent": "Retriever", "task": "관련 근거 수집", "inputs": { "query": "..." } },
{ "step": 2, "agent": "Summarizer", "task": "요약 초안", "inputs": { "style": "short" } },
{ "step": 3, "agent": "Verifier", "task": "팩트/정책 검증", "inputs": {} }
],
"stopConditions": { "maxSteps": 6, "failFast": true }
}
Retriever / Executor / Verifier / Memory Manager 핵심 출력
// Retriever output
{
"evidence": [
{
"title": "문서/기사 제목",
"snippet": "핵심 발췌",
"source": "web|internal",
"url": "가능하면",
"publishedAt": "ISO-8601",
"confidence": 0.0
}
],
"coverage": { "isEnough": true, "missingAngles": ["공식 발표", "가격"] }
}
// Verifier output
{
"verdict": "pass|revise|fail",
"issues": [
{ "type": "missing_citation", "detail": "2번째 문장 출처 필요" },
{ "type": "overclaim", "detail": "단정 표현 완화 필요" }
],
"revisedDraft": "수정본"
}
9. 샘플 워크플로우
콘텐츠명 추정 → 검색 → 요약 → 검증 → 공유/저장
- API가 사용자 발화를 수신하고
MessageReceived이벤트를 발행한다. - Router Job이 콘텐츠명, 뉴스, 일반 Q&A 등으로 분기한다.
- Retriever Job이 웹/내부 검색을 통해 근거를 수집한다.
- Summarize Job이 짧은 요약과 핵심 포인트를 생성한다.
- Verify Job이 출처, 과장 표현, 정책 위반 여부를 검증한다.
- Publish Job이 Slack, DB, 블로그 등으로 전송하거나 저장한다.
- 실패 시 DLQ로 보내고
Failed이벤트를 발행해 알람을 보낸다.
Router 분기 예시
// 입력
"냉부해 보고 싶어"
// Router Output
{
"route": "content_search",
"confidence": 0.82,
"signals": ["hasContentTitleLikePhrase", "needsWebSearch"],
"normalizedQuery": "냉부해 프로그램"
}
Node/Azure 구현 팁
운영 안정성
- 모든 이벤트/큐 메시지에
traceId넣기 - 같은 Job이 두 번 실행돼도 깨지지 않도록 Idempotency Key 사용
- Retrieval은 재시도 2~3회, Publish는 멱등성과 짧은 timeout 우선
비용과 품질
- step별
maxTokens,maxToolCalls하드 제한 - Memory Service 중앙화
- latency, 에러율, 토큰, 툴콜 수를 Application Insights에 로깅
예시: 오늘 날씨 무드에 맞는 노래와 영화 추천
| Agent | 하는 일 |
|---|---|
| Router | 날씨 기반 감성 추천으로 분기하고 요청을 날씨 조회, 무드 추출, 음악, 영화로 쪼갠다. |
| Planner | 날씨 → 무드 → 후보 수집 → 정렬 → 검증 → 응답 플랜을 만든다. |
| Weather Agent | 사용자 위치 기준 오늘 날씨를 가져온다. |
| Mood Mapper | 비/흐림은 차분·멜랑콜리, 맑음은 산뜻·활기처럼 날씨를 무드로 변환한다. |
| Retriever | 음악/영화 후보 리스트를 내부 DB, 추천 API, 캐시 등에서 가져온다. |
| Ranker | 무드 일치도, 대중성, 다양성, 사용자 선호를 반영해 정렬한다. |
| Verifier | 과장, 금칙, 부적절 콘텐츠 여부를 점검한다. |
| Composer | 보기 좋은 포맷으로 추천과 한 줄 코멘트, 대체안을 구성한다. |
10. Next AI Agent
현재 Agent는 유용하지만 만능은 아니다. 이해가 아니라 패턴 추정에 가깝고, 장기 목표의 일관성이나 자기 평가, 현실 세계와의 직접 경험에는 한계가 있다.
세계 모델을 가진 Agent
내부에 세상 시뮬레이터를 두고, 행동 전에 여러 미래를 가상으로 돌려본다.
집단 지능 시스템
Agent, 사람, 규칙, 피드백 루프가 함께 판단을 개선한다.
스스로 변하는 시스템
실패와 성공을 구조적으로 학습해 프롬프트, 룰, 워크플로우를 조정한다.
인간 참여형 AI
Agent가 단독으로 결정하지 않고 근거를 만들어 사람이 최종 판단하도록 돕는다.
결론
Agent 설계의 목표는 “사람 대신 결정하는 AI”가 아니라, 사람이 더 나은 판단을 하도록 돕는 시스템을 만드는 것이다.