Home / Strands 멀티에이전트 운영 / Strands 멀티에이전트 운영
Module

Strands 멀티에이전트 운영

운영 3축 · 통신 메커니즘 · 에러 처리와 복원력 · Safety 4계층과 Guardrail

⏱ 50분 114 / 189

Strands 멀티에이전트 운영

통신 · 에러 · 안전장치

멀티에이전트를 프로덕션에서 운영한다

에이전트 간 통신·에러 복원·안전 보장 — 운영의 3축

운영 개요

통신 · 에러 · 안전 — 프로덕션 3축

PART 1 · 운영 개요

멀티에이전트 운영 3축

프로덕션에서 멀티에이전트를 지탱하는 세 가지 핵심 축

  1. 1
    통신 (Communication)

    에이전트 간 메시지 전달·공유 상태·프로토콜 표준화. Shared Context부터 A2A Protocol까지 계층별 통신 전략이 필요합니다.

  2. 2
    에러 복원 (Resilience)

    타임아웃·환각·핸드오프 유실 등 분산 환경 고유의 실패 모드에 대응. Circuit Breaker와 Supervisor Escalation으로 장애를 격리합니다.

  3. 3
    안전 보장 (Safety)

    에이전트별 권한 제어·입출력 검증·행동 제한. Cedar 정책과 Bedrock Guardrails로 자율 행동의 범위를 선언적으로 제한합니다.

takeaway

축마다 전용 패턴과 AWS 서비스가 매핑됩니다 — 하나라도 비면 프로덕션에서 드러납니다.

PART 1 · 운영 개요

축별 핵심 과제

메시지 유실·장애 전파·권한 초과 — 축마다 다른 실패 양상과 대응 패턴

핵심 과제실패 시 결과대응 패턴
통신메시지 유실·순서 역전·스키마 불일치에이전트 간 상태 불일치 → 잘못된 의사결정A2A Protocol · Dead Letter Queue
에러타임아웃 연쇄·핸드오프 유실·무한 루프단일 에이전트 장애가 전체 시스템으로 전파Circuit Breaker · Supervisor Escalation
안전권한 초과·프롬프트 인젝션·출력 오염비인가 행동 실행 → 데이터 유출·규정 위반Cedar Policy · Bedrock Guardrails
takeaway

실패 시 결과의 공통 패턴은 전파입니다 — 상태 불일치·장애·비인가 행동이 시스템 전체로 번지기 전에 축별 대응 패턴으로 격리합니다.

PART 1 · 운영 개요

프로토타입 vs 프로덕션

단일 에이전트 PoC에서는 보이지 않던 문제의 프로덕션 폭발 지점

프로토타입

단일 에이전트 PoC

  • 단일 호출 — 1회 호출로 끝
  • 단일 장애 — 실패해도 그 호출뿐
  • 단일 권한 — 도구·데이터 접근 범위 하나
  • 로컬 테스트 — print 디버깅으로 충분

PoC 단계에서는 문제가 드러나지 않습니다 — 호출이 짧고, 장애가 고립되고, 권한이 하나뿐이기 때문입니다.

프로덕션

분산 멀티에이전트 운영

  • 장기 실행 — 수십 분 실행, 헬스체크·하트비트 필요
  • 장애 전파 — Circuit Breaker로 failure domain 격리
  • 권한 충돌 — Cedar 정책으로 에이전트별 최소 권한
  • 분산 관측 — OpenTelemetry + X-Ray, correlation ID로 추적

네트워크 단절·모델 스로틀링·연쇄 장애·비인가 도구 호출이 복합적으로 발생 — end-to-end 가시성까지 요구됩니다.

takeaway

네 폭발 지점의 공통 원인은 분산입니다 — 단일이던 호출·장애·권한·관측이 여러 에이전트로 쪼개지는 순간 운영 문제가 시작됩니다.

에이전트 간 통신

3계층 모델 · A2A Protocol · 메커니즘 비교

PART 2 · 에이전트 간 통신

통신 3계층 모델

결합도와 확장성에 따라 계층을 선택하는 통신 아키텍처

L3: A2A Protocol

이기종 에이전트 프레임워크 간 표준 통신. HTTP + JSON-RPC 기반으로 Agent Card 교환 후 Task 단위로 비동기 협업합니다. Linux Foundation 오픈 표준 (Google 개발·기증).

L2: Message Passing

에이전트 간 비동기 메시지 큐. SQS·SNS·EventBridge를 통해 느슨하게 결합된 이벤트 기반 통신. 순서 보장이 필요하면 FIFO 큐 사용.

L1: Shared Context

동일 프로세스 내 메모리 공유. Strands의 agent.state(AgentState)나 Swarm의 shared_context를 통해 에이전트 간 상태를 직접 공유. 가장 빠르지만 단일 프로세스 한정.

PART 2 · 에이전트 간 통신

A2A Protocol 통합

A2AServer가 Strands 에이전트를 JSON-RPC over HTTP로 노출 — Agent Card 자동 게시와 Task 단위 협업 수신

핵심 포인트

A2AServer
Strands 에이전트를 JSON-RPC over HTTP의 A2A 서버로 노출
agent_factory=
요청 컨텍스트별로 에이전트를 새로 생성하는 팩토리 장착
name / description
Agent Card 자동 생성의 원천 — /.well-known/agent-card.json 경로로 게시
serve()
host·port로 서버 시작 — Task 단위 비동기 협업 수신

코드

python
from strands import Agent
from strands.multiagent.a2a import A2AServer

# 요청 컨텍스트별로 에이전트를 생성하는 팩토리
def create_research_agent(context_id):
    return Agent(
        name="research-agent",
        description="기술 문서를 검색하고 요약합니다",
        model="us.anthropic.claude-sonnet-4-6",
        system_prompt="기술 리서치 전문 에이전트",
        tools=[web_search, summarize],
    )

# Agent Card는 name/description에서 자동 생성·게시된다
server = A2AServer(agent_factory=create_research_agent,
                   host="0.0.0.0", port=8080)
server.serve()
PART 2 · 에이전트 간 통신

통신 메커니즘 비교

지연 허용도·결합도·확장성 기준으로 메커니즘 선택

메커니즘지연결합도확장성적합한 경우
Shared Context매우 낮음 (같은 프로세스)강결합단일 프로세스부모-자식 에이전트, 동일 Lambda 내
Message Passing (SQS)수십 ms느슨무제한 스케일비동기 작업 분배, 이벤트 기반
A2A Protocol수백 ms표준 인터페이스크로스 프레임워크이기종 에이전트, 조직 간 협업
Direct Invocation수십 ms중간Lambda 동시성 한도동기 핸드오프, 즉시 응답 필요
takeaway

빠를수록 강결합, 느슨할수록 느립니다 — 같은 프로세스면 Shared Context, 비동기 분배면 SQS, 이기종 협업이면 A2A를 사용합니다.

에러 처리와 복원력

5가지 실패 모드 · 내장 안전장치 · 복구 전략 · 노드 훅

PART 3 · 에러 처리와 복원력

에러 처리와 복원력

분산 에이전트 고유의 실패 모드와 단계적 복구 — 장애 격리의 원칙

에러 처리와 복원력

단일 에이전트 장애가 전체 시스템으로 전파되기 전에 — 감지하고, 차단하고, 대체하고, 에스컬레이션합니다

  • 5가지 실패 모드 — 타임아웃·환각·도구 실패·핸드오프 유실·무한 루프
  • SDK 내장 안전장치 — 타임아웃·핸드오프 상한·핑퐁 감지
  • 복구 4단계 — Retry · Circuit Breaker · Fallback · Supervisor Escalation
  • Strands Hooks — 도구 훅(BeforeToolCallEvent) + 노드 훅(BeforeNodeCallEvent)
  • 알림 연동 — EventBridge → SNS
takeaway

실패를 없앨 수는 없습니다 — 실패가 전파되지 않게 격리하고 자동 복구하는 구조가 복원력입니다.

PART 3 · 에러 처리와 복원력

멀티에이전트 5가지 실패 모드

타임아웃 연쇄·환각 전파·도구 실패·핸드오프 유실·무한 루프 — 격리가 필요한 이유

타임아웃 연쇄

에이전트 A가 B를 기다리고, B가 C를 기다리는 체인
하나의 지연이 전체 파이프라인을 블로킹

환각 전파

에이전트 A의 환각 출력을 B가 사실로 받아들여 증폭
멀티에이전트에서 환각이 기하급수적으로 확대

도구 실패

외부 API 장애·스로틀링으로 도구 호출 실패
에이전트가 대체 전략 없이 무한 재시도

핸드오프 유실

에이전트 간 작업 인계 시 컨텍스트 손실
수신 에이전트가 불완전한 정보로 잘못된 판단

무한 루프

에이전트가 동일 도구를 반복 호출하거나 A↔B 핑퐁
max_iterations 없으면 비용 폭발

takeaway

다섯 모드의 공통점은 번진다는 것입니다 — 타임아웃은 체인으로, 환각은 증폭으로, 루프는 비용으로. 그래서 대응의 핵심은 격리입니다.

PART 3 · 에러 처리와 복원력

SDK 내장 안전장치 파라미터

Swarm 생성자·Graph 빌더에 이미 들어 있는 실행 상한 — 직접 구현 전의 1차 방어선

대상파라미터기본값막는 실패 모드
Swarmexecution_timeout900.0초전체 실행 폭주 — 타임아웃 연쇄를 상위에서 차단
Swarmnode_timeout300.0초단일 노드 응답 지연 — 노드만 실패 처리하고 격리
Swarmmax_handoffs · max_iterations각 20무한 루프 — 핸드오프·반복 횟수 상한
Swarmrepetitive_handoff_detection_window · repetitive_handoff_min_unique_agents0 (비활성)A↔B 핑퐁 — 최근 N회 핸드오프 창의 고유 에이전트 수 검사
GraphBuilderset_execution_timeout() · set_node_timeout()미설정Graph 전체·노드별 시간 상한
GraphBuilderset_max_node_executions()미설정Graph 노드 실행 횟수 폭주
takeaway

직접 구현 전에 내장부터 — Circuit Breaker를 짜기 전에 생성자 파라미터 한 줄로 막히는 실패인지 먼저 확인합니다.

PART 3 · 에러 처리와 복원력

복구 전략 4단계

실패 감지부터 Supervisor Escalation까지 단계적 복구 흐름

  1. 1
    Retry (재시도)

    Exponential backoff로 일시적 장애 극복. 모델 호출 스로틀링 재시도는 SDK 기본 내장 — Agent(retry_strategy=ModelRetryStrategy(...)), 기본 max_attempts=6·초기 지연 4초·최대 지연 128초(Python 기준)이며 None을 주면 꺼집니다. is_retryable() 오버라이드로 재시도 대상 예외를 확장할 수 있습니다. 도구 재시도는 AfterToolCallEvent 훅의 retry 플래그로 트리거합니다.

  2. 2
    Circuit Breaker (차단)

    연속 N회 실패 시 회로 차단 → 빠른 실패 반환. half-open 상태에서 주기적으로 복구 확인. 장애가 다른 에이전트로 전파되는 것을 방지합니다.

  3. 3
    Fallback (대체)

    주 경로 실패 시 대체 에이전트 또는 간소화된 응답 반환. 예: GPT 실패 → Claude로 전환, 검색 실패 → 캐시된 결과 사용.

  4. 4
    Supervisor Escalation

    모든 자동 복구 실패 시 Supervisor 에이전트가 개입. 작업을 재분배하거나 사람에게 에스컬레이션. EventBridge → SNS 알림 연동.

takeaway

순서가 곧 전략입니다 — 재시도·차단·대체까지는 자동으로 버티고, 전부 실패했을 때만 사람에게 에스컬레이션합니다.

PART 3 · 에러 처리와 복원력

Retry + Circuit Breaker 구현

Strands Hooks 기반의 자동 복구 패턴 코드

핵심 포인트

HookProvider
훅 클래스의 베이스 — register_hooks(registry)로 이벤트별 콜백 등록 (필수)
BeforeToolCallEvent
도구 호출 직전 — 회로가 열려 있으면 event.cancel_tool 설정으로 도구만 취소 (예외 전파 없이 루프 지속)
AfterToolCallEvent
도구 호출 직후 — event.exception으로 실패 판별, failures에 횟수·시각 집계 (코드에선 등록만 표시)
hooks=[...]
Agent에 훅 주입 — 이 한 줄로 자동 차단 활성화

코드

python
import time
from strands import Agent
from strands.hooks import BeforeToolCallEvent, AfterToolCallEvent, HookProvider

class CircuitBreakerHook(HookProvider):
    def __init__(self, threshold=3, reset_timeout=60):
        self.failures, self.th, self.reset = {}, threshold, reset_timeout

    def register_hooks(self, registry, **kwargs):
        registry.add_callback(BeforeToolCallEvent, self.on_before)
        registry.add_callback(AfterToolCallEvent, self.on_after)  # 실패 집계

    def on_before(self, event):  # 임계 초과면 차단 (reset 경과 후 half-open)
        s = self.failures.get(event.tool_use["name"], {})
        if s.get("count", 0) >= self.th and time.time() - s["last"] < self.reset:
            event.cancel_tool = "circuit open"  # 도구만 취소 — 루프는 지속

agent = Agent(hooks=[CircuitBreakerHook()])
PART 3 · 에러 처리와 복원력

노드 레벨 훅 — 멀티에이전트 이벤트 5종

단일 에이전트 훅 8종에 더해 노드 실행을 가로채는 전용 이벤트 — 노드 단위 승인·차단·계측

핵심 포인트

MultiAgentInitializedEvent
Swarm·Graph 초기화 완료 시 1회 — 오케스트레이션 시작점 계측
NodeCallEvent 쌍
Before/AfterNodeCallEvent — 노드(에이전트) 실행 전후, event.node_id로 어느 노드인지 식별하는 위임 추적의 정본 지점
MultiAgentInvocationEvent
Before/After 쌍 — 멀티에이전트 호출 전체의 전후, 실행 단위 비용·시간 집계
cancel_node
BeforeNodeCallEvent에서 설정 — 해당 노드만 취소. event.interrupt()로 실행 전 사람 승인 대기도 가능
hooks=[...]
Swarm·Graph 생성자에 그대로 주입 — 단일 에이전트 훅과 같은 등록 방식

코드

python
from strands import Agent
from strands.multiagent import Swarm
from strands.hooks import HookProvider, BeforeNodeCallEvent

class NodeApprovalHook(HookProvider):
    def register_hooks(self, registry, **kwargs):
        registry.add_callback(BeforeNodeCallEvent, self.on_node)

    def on_node(self, event):
        # 배포 노드만 실행 전 검사 — 거부되면 그 노드만 취소
        if event.node_id == "deploy" and not approved(event.node_id):
            event.cancel_node = "승인 거부 — deploy 노드 차단"

# 단일 에이전트와 같은 hooks= — Swarm/Graph 생성자 지원
swarm = Swarm(nodes=[research, write, deploy],
              hooks=[NodeApprovalHook()])
PART 3 · 에러 처리와 복원력

운영 장면 — 장애에서 복구까지

리서치 Swarm의 요약 노드 타임아웃부터 session_manager 재개까지 — 안전장치가 개입하는 순서








research-swarm — 실행 로그 (예시 장면)
execution_timeout 900s · node_timeout 300s



14:02:11
WARN
summarizer 노드 응답 지연
대형 문서 요약에서 반복 무응답 — Swarm 전체가 이 노드를 기다리며 블로킹


14:07:11
AUTO
node_timeout=300.0 발동
SDK가 노드 실행을 강제 종료하고 실패로 기록 — 직접 짠 감시 코드 없이 개입


14:07:38
STOP
핑퐁 감지 — 안전 종료
researcher ↔ summarizer 왕복이 감지 창(detection_window) 안에서 고유 에이전트 2개뿐 — 재시도 루프 차단


14:09:40
RESUME
session_manager로 중단 지점 재개
serialize_state가 영속화한 상태·실행 이력을 deserialize_state로 복원 — 완료된 리서치 결과는 다시 돌리지 않음, shared context도 직렬화/역직렬화 시 보존




상한은 생성자 파라미터가 지키고, 재개는 session_manager가 맡습니다 — 장애 대응 코드보다 상태 영속화가 먼저입니다


takeaway

복구의 핵심은 처음부터 다시가 아니라 중단 지점부터입니다 — 상태가 영속화되어 있어야 상한 파라미터가 안심하고 실행을 끊을 수 있습니다.

Safety와 Guardrails

4계층 Safety · Cedar 정책 · Guardrail 적용 위치

PART 4 · Safety와 Guardrails

Safety 4계층 적용

입력부터 출력까지 실행 경로 전체에 가드 배치 — 한 계층을 통과한 위협은 다음 계층이 포착

Input Guard

사용자 입력에서 프롬프트 인젝션·탈옥 시도를 탐지합니다. Bedrock Guardrails의 content filter가 악의적 입력을 차단하고, 민감 정보(PII)를 마스킹합니다.

Reasoning Guard

에이전트의 추론 과정에서 허용되지 않은 계획을 감지합니다. Cedar 정책으로 특정 도구 조합이나 위험한 행동 시퀀스를 사전 차단합니다.

Action Guard

도구 호출 직전에 권한을 검증합니다. 에이전트별 허용 액션 목록과 대상 리소스를 Cedar forbid/permit 규칙으로 제어합니다.

Output Guard

최종 응답에서 민감 정보 노출·유해 콘텐츠·할루시네이션을 검증합니다. Grounding check로 출처 없는 주장을 필터링합니다.

PART 4 · Safety와 Guardrails

Cedar 정책으로 에이전트 권한 제어

선언적 정책 언어로 에이전트의 허용·금지 도구를 코드로 정의

핵심 포인트

Action::"..."
action이 곧 도구 이름 — pip install "strands-agents[cedar]"로 설치
permit
허용 규칙 — action 목록에 있는 도구만 호출 가능
when { context.session.role }
조건부 허용 — context_enricher가 invocation_state의 role을 주입 (호출 측: invocation_state={"role": "coordinator"})
forbid
명시적 금지 — principal은 principal_resolver가 해석 (기본 User::"anonymous", 해석 실패 시 fail-closed)

코드

cedar
// 검색·요약 도구는 모두에게 허용
permit (
    principal,
    action in [Action::"web_search", Action::"summarize"],
    resource
);

// 쓰기 도구는 coordinator 역할에만 허용
permit (
    principal,
    action in [Action::"create_ticket", Action::"send_email"],
    resource
) when { context.session.role == "coordinator" };

// 삭제 도구는 명시적 금지
forbid (principal, action == Action::"delete_resource", resource);
PART 4 · Safety와 Guardrails

Guardrail 적용 위치

에이전트 실행 경로의 어디에 어떤 Guardrail을 배치하는지 매핑

적용 위치Guardrail 종류구현 방법차단 시 동작
사용자 입력 수신Content Filter + PII 마스킹BedrockModel(guardrail_id=, guardrail_version=) 모델 부착 — 입력 redact 기본(guardrail_redact_input=True)요청 거부 + 안내 메시지
에이전트 간 핸드오프Schema 검증 + 권한 확인Cedar Policy + InvokeGuardrailChecks(루프 중간 임의 지점 검사)핸드오프 거부 + Supervisor 알림
도구 호출 직전액션 권한 + 파라미터 범위Strands Hook (BeforeToolCallEvent) + Cedar도구 호출 차단 + 대체 도구 시도
최종 출력 반환Grounding + 유해 콘텐츠Bedrock Guardrails + Custom Validator응답 필터링 + 재생성 요청
takeaway

네 위치 모두 패턴은 같습니다 — 차단하고 끝내지 않고 다음 동작으로 잇습니다: 안내·알림·대체 도구·재생성. Guardrails 정책 구성 상세는 bedrock-guardrails 덱에서 다룹니다.

멀티에이전트는 만드는 것보다 운영이 어렵습니다.

통신 · 에러 · 안전장치 — 세 축을 잡아야 프로덕션에서 살아남습니다