AI Architecture · Agent Design · Azure

AI Agent 개념부터
멀티 에이전트 아키텍처까지

LLM의 한계에서 출발해 Single Agent, Multi-Agent, Pub/Sub, Queue, Azure 기반 운영 구조까지 한 번에 연결해서 이해하는 실전 설계 가이드

LLM 한계 Agent 구조 Multi-Agent Pub/Sub vs Queue Azure Architecture

1. LLM이란?

LLM은 대량의 텍스트를 학습해 다음에 올 말을 확률적으로 예측하는 언어 모델이다.

  • 질문에 대한 그럴듯한 응답 생성에는 강하다.
  • 하지만 스스로 외부 시스템을 조작하거나 업무를 끝까지 수행하지는 못한다.
  • 기본 구조는 상태·기억·목표가 없는 stateless 단발성 응답에 가깝다.
LLM은 말을 생성하지만, Agent는 목표를 가지고 일을 수행한다.

2. AI Agent가 등장한 배경

AI Agent는 단순히 더 좋은 답변을 만들기 위해 나온 개념이 아니다. 핵심은 답변 생성 이후의 실행 문제를 해결하는 것이다.

LLM의 한계
  • 대화 맥락과 정보를 지속적으로 기억하지 못함
  • DB, API, 알림 같은 외부 시스템을 직접 제어하지 못함
  • 목표 달성 여부나 결과 검증에 대한 책임 구조가 없음
Agent의 필요성
  • 답변 생성을 넘어 실제 업무를 처리하는 AI가 필요해짐
  • LLM에 상태, 도구 사용, 실행 로직을 결합함
  • 반복 작업, 워크플로우, 자동화를 제어 가능한 구조로 만들 수 있음

3. AI Agent란?

AI Agent는 생각만 하는 AI가 아니라, 상황을 이해하고 필요한 일을 나눠 실제 행동까지 수행하도록 만든 프로그램 구조다.

핵심 루프: Plan → Act → Observe → Iterate

단순 챗봇이 답변 생성에 집중한다면, 에이전트는 보통 아래 요소를 함께 가진다.

구성 요소역할
Tool CallingDB 조회, API 호출, 파일 읽기/쓰기, Slack 전송 등 외부 행동을 수행한다.
State대화·작업 컨텍스트, 세션 메모리, 장기 메모리를 관리한다.
Orchestration어떤 순서로 어떤 작업을 시킬지 결정하고, 실패 시 재시도·대체 경로를 적용한다.
Guardrail정책, 보안, PII 마스킹, 입력 검증, 비용·시간 제한을 관리한다.

4. Single Agent에서 Multi-Agent로

처음에는 하나의 Agent가 모든 역할을 맡아도 된다. 하지만 검색, 요약, 분류, 검증, 실행이 한 곳에 몰리면 복잡도와 실패 리스크가 커진다.

Single Agent

빠르게 시작하기 좋은 구조

  1. 사용자 입력
  2. LLM이 생각과 툴 호출을 결정
  3. 툴 결과를 반영해 최종 답변

한계: 역할이 한 곳에 모여 실패·지연·비용이 커지고 테스트와 디버깅이 어렵다.

Multi-Agent

운영 가능한 구조로 분리

  • Router: 의도 분류
  • Retriever: 근거 수집
  • Planner: 계획 수립
  • Executor: 툴 실행
  • Verifier: 검증
  • Summarizer: 결과 정리
  • Memory Manager: STM/LTM 관리
Single Agent는 빠르지만 취약하고, Multi Agent는 느릴 수 있지만 운영 가능하다.

Single → Multi 구조화 단계

  1. 역할 분리 + 계약
    각 서브 에이전트의 입력/출력 스키마(JSON)를 고정한다. 예를 들어 Retriever는 근거 목록, 출처, 신뢰도만 반환하게 만든다.
  2. 오케스트레이터 도입
    중앙 Orchestrator가 어떤 에이전트를 언제 호출할지, 타임아웃·재시도·폴백을 어떻게 처리할지 결정한다.
  3. 비동기화 + Pub/Sub / Queue 확장
    요청량이 늘어나면 동기 체인이 길어져 느려지고 불안정해진다. 이때 이벤트와 작업 큐를 분리한다.
  4. 상태/메모리 분리
    에이전트가 각자 메모리를 갖지 않도록 하고, Memory Service를 통해 STM과 LTM을 중앙 관리한다.

5. 멀티 에이전트 아키텍처 패턴 3가지

Pattern 1

Manager-Worker

Manager가 계획을 세우고 Worker들이 검색, 실행, 검증을 담당한다.

장점: 통제가 쉽고 운영·디버깅이 편하다.

예시: 사내 업무 자동화, 고객응대, 워크플로우

Pattern 2

Event-Driven

이벤트가 발생하면 여러 에이전트가 구독해 각자 필요한 처리를 한다.

장점: 확장성과 느슨한 결합이 좋다.

주의: 관측성이 없으면 추적과 디버깅이 어려워진다.

Pattern 3

Pipeline / DAG

정해진 단계대로 A → B → C 순서로 처리한다.

장점: 결과 재현과 테스트가 쉽다.

예시: 문서 처리, 분류, 추출, 요약, 검증

6. Pub/Sub vs Queue

둘 다 비동기 구조에서 자주 등장하지만 역할은 다르다. 헷갈리면 이렇게 기억하면 된다.

Pub/Sub = 알림(Event), Queue = 작업(Job)
사용자 메시지 들어옴
→ 콘텐츠인지 판단
→ 웹검색/사내검색
→ 요약
→ 검증
→ 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를 동기적으로 호출하는 구조가 가장 단순하다.

동기 Orchestrator 중심 멀티 에이전트 아키텍처
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로 보내고 운영 알람을 붙인다.

비동기 Pub/Sub Queue 기반 멀티 에이전트 아키텍처
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 GridAzure Portal → Event Grid → Topics / Subscriptions
Service BusAzure Portal → Service Bus → Queues / Topics
Azure FunctionsAzure Portal → Function App
RedisAzure Portal → Azure Cache for Redis
Cosmos DBAzure Portal → Azure Cosmos DB
Monitor / LogsAzure 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. 샘플 워크플로우

콘텐츠명 추정 → 검색 → 요약 → 검증 → 공유/저장

  1. API가 사용자 발화를 수신하고 MessageReceived 이벤트를 발행한다.
  2. Router Job이 콘텐츠명, 뉴스, 일반 Q&A 등으로 분기한다.
  3. Retriever Job이 웹/내부 검색을 통해 근거를 수집한다.
  4. Summarize Job이 짧은 요약과 핵심 포인트를 생성한다.
  5. Verify Job이 출처, 과장 표현, 정책 위반 여부를 검증한다.
  6. Publish Job이 Slack, DB, 블로그 등으로 전송하거나 저장한다.
  7. 실패 시 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에 로깅

예시: 오늘 날씨 무드에 맞는 노래와 영화 추천

날씨 무드 추천 동기 처리 흐름도
날씨 무드 추천 비동기 Pub/Sub Queue 처리 흐름도
Agent하는 일
Router날씨 기반 감성 추천으로 분기하고 요청을 날씨 조회, 무드 추출, 음악, 영화로 쪼갠다.
Planner날씨 → 무드 → 후보 수집 → 정렬 → 검증 → 응답 플랜을 만든다.
Weather Agent사용자 위치 기준 오늘 날씨를 가져온다.
Mood Mapper비/흐림은 차분·멜랑콜리, 맑음은 산뜻·활기처럼 날씨를 무드로 변환한다.
Retriever음악/영화 후보 리스트를 내부 DB, 추천 API, 캐시 등에서 가져온다.
Ranker무드 일치도, 대중성, 다양성, 사용자 선호를 반영해 정렬한다.
Verifier과장, 금칙, 부적절 콘텐츠 여부를 점검한다.
Composer보기 좋은 포맷으로 추천과 한 줄 코멘트, 대체안을 구성한다.

10. Next AI Agent

현재 Agent는 유용하지만 만능은 아니다. 이해가 아니라 패턴 추정에 가깝고, 장기 목표의 일관성이나 자기 평가, 현실 세계와의 직접 경험에는 한계가 있다.

Model-based Agent

세계 모델을 가진 Agent

내부에 세상 시뮬레이터를 두고, 행동 전에 여러 미래를 가상으로 돌려본다.

Collective Intelligence

집단 지능 시스템

Agent, 사람, 규칙, 피드백 루프가 함께 판단을 개선한다.

Learning System

스스로 변하는 시스템

실패와 성공을 구조적으로 학습해 프롬프트, 룰, 워크플로우를 조정한다.

Human-in-the-loop

인간 참여형 AI

Agent가 단독으로 결정하지 않고 근거를 만들어 사람이 최종 판단하도록 돕는다.

결론

Agent 설계의 목표는 “사람 대신 결정하는 AI”가 아니라, 사람이 더 나은 판단을 하도록 돕는 시스템을 만드는 것이다.