🔥 고급2026-05-056~8분
멀티 에이전트 환경에서 안전한 Tool 실행 아키텍처
에이전트가 에이전트를 호출하는 계층 구조에서 tool 실행 권한을 잘못 설계하면 권한 에스컬레이션과 무한 루프가 발생한다. 샌드박스 격리와 실행 예산 패턴으로 이를 방지한다.
multi-agenttool-usesafety
멀티 에이전트 Tool 실행의 핵심 위협
오케스트레이터가 서브에이전트에게 tool을 위임할 때 세 가지 위협이 존재한다:
- 권한 에스컬레이션: 서브에이전트가 오케스트레이터 권한을 상속받아 의도치 않은 시스템 접근
- 무한 루프: Agent A → Agent B → Agent A 순환 호출로 토큰 비용 폭증 (실사례: 2시간에 $340 소모)
- Prompt Injection: 외부 데이터(웹, DB)를 읽는 tool이 악의적 명령을 에이전트에 주입
실행 예산 패턴 구현
import anthropic
from dataclasses import dataclass, field
from typing import Any
@dataclass
class ExecutionBudget:
max_tool_calls: int = 20
max_depth: int = 3
current_calls: int = 0
current_depth: int = 0
allowed_tools: set = field(default_factory=set)
def run_subagent(
task: str,
budget: ExecutionBudget,
tools: list[dict]
) -> str:
if budget.current_depth >= budget.max_depth:
return "[BLOCKED] 최대 에이전트 깊이 초과"
client = anthropic.Anthropic()
# 서브에이전트에게 허용된 tool만 전달 (권한 축소)
filtered_tools = [
t for t in tools
if t["name"] in budget.allowed_tools
]
messages = [{"role": "user", "content": task}]
while True:
if budget.current_calls >= budget.max_tool_calls:
return "[BLOCKED] tool 호출 예산 소진"
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=4096,
tools=filtered_tools,
messages=messages,
system="당신은 제한된 권한의 서브에이전트입니다. 주어진 tool만 사용하세요."
)
if response.stop_reason == "end_turn":
return response.content[-1].text
# tool_use 블록 처리
tool_results = []
for block in response.content:
if block.type == "tool_use":
budget.current_calls += 1
# 실제 tool 실행은 샌드박스에서
result = execute_in_sandbox(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
def execute_in_sandbox(tool_name: str, inputs: dict) -> Any:
# Docker/gVisor 격리 실행 (타임아웃 30초)
# 네트워크: allowlist 기반
# 파일시스템: read-only 마운트
pass
트레이드오프와 운영 전략
깊이 제한 설정 기준:
- depth=2: 오케스트레이터 + 단일 전문가 에이전트 (안전, 느림)
- depth=3: 계층적 분해 가능 (권장 최대치)
- depth=5+: 예측 불가능한 비용, 디버깅 난이도 급증
tool 권한 축소 원칙: 서브에이전트는 상위 에이전트 권한의 부분집합만 상속. 오케스트레이터가 DB write 권한을 가져도 서브에이전트는 read-only로 제한.
Prompt Injection 방어: 외부 데이터를 읽는 tool 결과는 별도 XML 태그로 감싸 에이전트 명령과 구분한다: <external_data>...</external_data>
운영 체크리스트
- [ ] 모든 tool 호출에
agent_id,depth,parent_call_id로깅 (추적성) - [ ] 호출 트리 시각화 대시보드 구축 (Langsmith 또는 자체 구현)
- [ ] 서브에이전트별 토큰 예산 상한 설정 (
max_tokens엄격 제한) - [ ] 동일 tool+인자 조합 중복 호출 감지 및 캐시 처리
- [ ] 프로덕션 배포 전 혼돈 테스트: 의도적 루프 시나리오로 예산 차단 검증