왜 멀티 에이전트 AI 시스템은 프로덕션 규모에서 실패하는가?
요약
멀티 에이전트 시스템이 프로덕션 환경에서 실패하는 주요 원인인 '에이전트 간 규칙 충돌' 문제를 다룹니다. 각 에이전트가 서로 다른 제약 조건과 안전 필터를 가진 상태에서 협업할 때 발생하는 예기치 못한 성능 저하와 관리의 어려움을 분석합니다.
핵심 포인트
- 에이전트 간 서로 다른 제약 조건과 규칙이 충돌하여 의도치 않은 결과 발생
- 오케스트레이터와 하위 에이전트 간의 맥락 및 규칙 불일치 문제
- Gartner는 2027년까지 에이전트형 AI 프로젝트의 40%가 취소될 것으로 전망
- 에이전트 간 규칙 충돌을 관리할 프레임워크의 필요성 증대
원문은 robatdasorvi.com에 게시되었습니다.
지난달 저는 고객 지원 에이전트가 불과 세 메시지 전에 이미 답변했던 질문에 대해 답변을 거부하는 것을 목격했습니다. 동일한 파이프라인(pipeline)에 있는 두 번째 에이전트가 해당 주제를 민감한 것으로 분류했기 때문입니다. 첫 번째 에이전트는 해당 플래그(flag)를 읽고, 이를 따르며 사과했습니다. 두 에이전트 모두 각자의 규칙에 따라 틀린 행동을 하지 않았습니다. 하지만 함께 작용하여 아무도 의도하지 않은 결과를 만들어냈습니다.
저는 계속해서 그 사건을 생각하게 됩니다. 누구의 시스템도 실패하지 않았습니다. 바로 그것이 문제였습니다.
멀티 에이전트 파이프라인에서 에이전트 규칙이 충돌하는 이유
에이전트 규칙이 충돌하는 이유는 각 에이전트가 서로 다른 출처로부터 제약 조건(constraints)을 부여받으며, 그 제약 조건들이 서로를 인지하지 못한 상태에서 작성되었기 때문입니다.
배포된 모든 AI 에이전트는 일련의 제약 조건 안에서 작동합니다. 일부는 모델 자체에서 기인하며, 이는 훈련(training) 과정에서 내재된 가치와 행동 양식입니다. 일부는 운영자(operator)로부터 오며, 특정 사용 사례에 맞춰 에이전트를 형성하는 시스템 프롬프트(system prompt)입니다. 일부는 실시간으로 사용자로부터 옵니다. 이러한 계층들은 방 안에 에이전트가 단 하나만 있을 때는 대부분 조화롭게 작동합니다.
멀티 에이전트 시스템은 이를 깨뜨립니다. 오케스트레이션 에이전트(orchestrating agent)가 하위 에이전트(subagent)에게 작업을 전달할 때, 이는 단순히 데이터를 전달하는 것이 아닙니다. 그것은 자신이 작성하지 않은 고유한 규칙을 가진 환경으로 작업을 넘기는 것입니다. 하위 에이전트는 자신의 운영자의 지침, 자체적인 안전 필터(safety filters), 그리고 무엇이 허용되는지에 대한 자체적인 판단을 적용합니다. 만약 이러한 정의들이 오케스트레이터(orchestrator)가 가정했던 것과 충돌한다면, 시스템은 정말로 파악하기 어려운 방식으로 성능이 저하됩니다.
Gartner는 2024년 1% 미만이었던 기업용 소프트웨어 애플리케이션 중 에이전트형 AI (agentic AI)를 포함하는 비중이 2028년까지 33%에 달할 것이라고 전망합니다. 동일한 연구는 또한 비용 상승, 불분명한 비즈니스 가치, 부적절한 리스크 제어를 이유로 2027년 말까지 에이전트형 AI 프로젝트의 40% 이상이 취소될 것이라고 예측합니다. 프로덕션(production) 단계에 도달하는 대부분의 배포 사례는 어느 쪽도 설계되지 않았던 파이프라인을 공유하는 다중 에이전트(multiple agents)를 포함하게 될 것입니다. 프로덕션 환경에서 발생하는 에이전트 간 규칙 충돌(cross-agent rule collisions)의 수는 이를 관리하기 위한 프레임워크(frameworks)가 발전하는 속도보다 더 빠르게 증가하고 있습니다.
침묵해 버린 고객 지원 에이전트는 자신에게 주어진 규칙, 즉 '민감도 플래그(sensitivity flags)에 따를 것'이라는 규칙을 따르고 있었습니다. 해당 플래그는 에이전트가 활발한 법적 주제에 관여하지 못하도록 시도하는 컴플라이언스(compliance) 팀에 의해 작성되었습니다. 하지만 질문은 법적 사건과는 아무런 관련이 없었습니다. 플래그의 작성자는 다른 에이전트들이 인간이 가질 수 있는 맥락(context) 없이, 프로그래밍 방식으로 대량의 플래그를 생성해내는 세상을 상상하지 못했습니다.
멀티 에이전트의 실패가 일반적인 소프트웨어 버그와 다른 점
그 차이는 구조적인 것이 아니라 의미론적(semantic)입니다. 전통적인 소프트웨어의 불일치는 명시적으로(loudly) 실패합니다. 에이전트의 불일치는 침묵 속에서(silently) 실패하며, 옳게 보이는 틀린 답을 내놓습니다.
소프트웨어 시스템에는 항상 인터페이스 불일치(interface mismatches)가 존재해 왔습니다. API는 예상치 못한 형식을 반환합니다. 서비스는 호출 순서에 대해 잘못된 가정을 합니다. 한 구성 요소는 업데이트되었는데 다른 구성 요소는 업데이트되지 않았을 때 의존성(dependencies)이 깨집니다. 우리는 이에 대응하기 위한 수십 년간의 툴링(tooling)을 보유하고 있습니다.
에이전트의 경우, 불일치는 의미에 관한 것입니다. 즉, 요청이 무엇을 수반하는지, 언제 거절이 적용되는지, 침묵이 무엇을 신호하는지에 관한 것입니다. 에이전트들은 자연어(natural language)로 이를 해결하려 하지만, 자연어는 그러한 종류의 정밀함을 위해 설계되지 않았습니다.
전통적인 API 호출이 실패할 때는 명확하게 실패를 알립니다. 예외(Exception)가 발생하거나, 200이 아닌 상태 코드가 반환되거나, 타임아웃(Timeout)이 발생합니다. 하지만 에이전트가 다른 에이전트의 컨텍스트(Context)를 오해할 때는 아무런 실패도 일어나지 않습니다. 파이프라인은 완료되고, 응답은 전송되며, 오류는 마치 맞은 것처럼 보이는 잘못된 답변이 됩니다.
멀티 에이전트 파이프라인은 개별 단계마다 모두 정확하더라도, 전체적으로는 틀릴 수 있습니다.
제가 작년에 대화했던 한 물류 회사가 정확히 이런 문제를 겪었습니다. 그들의 가격 책정 에이전트(Pricing agent)와 재고 에이전트(Inventory agent)는 모두 주문 이행 에이전트(Fulfilment agent)를 호출하고 있었습니다. 가격 책정 에이전트의 시스템 프롬프트(System prompt)는 주문 이행 에이전트에게 모든 요청이 재무팀에 의해 사전 승인되었다고 가정하라고 지시했습니다. 반면 재고 에이전트의 프롬프트에는 승인 상태에 대한 언급이 없었습니다. 재고 에이전트가 요청을 보냈을 때, 주문 이행 에이전트는 승인 플래그(Approval flag)를 발견하지 못했고, 이를 처리하는 대신 사람이 검토하도록 조용히 대기열(Queue)에 쌓아두었습니다. 주문들은 누군가 알아차리기 전까지 4일 동안 방치되었습니다. 시스템은 명세(Specification)대로 정확하게 작동했던 것입니다.
이것이 멀티 에이전트의 실패를 찾아내는 데 막대한 비용이 드는 이유입니다. 스택 트레이스(Stack trace)가 없습니다. 실패가 스스로를 알리지 않습니다. 누군가 왜 대기열이 가득 찼느냐고 물어볼 때, 4일이 지나서야 비로소 발견하게 됩니다.
에이전트들이 누가 책임자인지에 대해 의견이 다를 때 발생하는 일
아직 에이전트 간의 신뢰 계층 구조(Trust hierarchy)를 공식적으로 정의한 사람은 없습니다. 현재 모든 멀티 에이전트 시스템은 이를 임의로 정하고 있습니다.
이론적으로는 계층 구조가 존재합니다. 모델 제작자(Model maker)는 무시할 수 없는 엄격한 제한 사항을 설정합니다. 운영자(Operator)는 그 제한 범위 내에서 동작을 구성합니다. 사용자는 운영자가 허용하는 범위 내에서 조정합니다. 단일 에이전트 시스템에서는 이것이 깔끔하게 작동합니다.
멀티 에이전트 시스템에서는 이 계층 구조가 배가됩니다. 에이전트 A가 에이전트 B를 호출할 때, 에이전트 A는 운영자로 행동하는 것입니까, 사용자로 행동하는 것입니까, 아니면 완전히 다른 무언가입니까? 만약 에이전트 B가 자동화된 호출자를 신뢰할 수 없는 사용자로 취급하고, 에이전트 A의 파이프라인이 운영자 수준의 신뢰에 의존한다면, 시스템은 깔끔하게 깨지지 않습니다. 그저 더 느려지고, 더 조심스러워지며, 원인을 파악하기 더 어려워질 뿐입니다.
Anthropic의 멀티 에이전트 오케스트레이션 (multi-agent orchestration) 가이드는 이 점을 직접적으로 인정합니다: 하위 에이전트 (subagents)는 지시 출처와 관계없이 안전하게 행동해야 하며, 자신의 원칙을 위반하는 오케스트레이터 (orchestrator)의 요청은 거부해야 합니다. 이는 올바른 직관입니다. 문제는 "안전함"의 의미가 규칙을 작성한 이가 누구냐에 따라 달라진다는 점입니다. 한 운영자의 안전한 기본 설정이 다른 운영자에게는 파이프라인 차단 요소가 될 수 있습니다.
현재 제안되고 있는 해결책들, 즉 에이전트 신원에 대한 암호화 인증 (cryptographic attestation), 자동 호출자에 대한 명시적 신뢰 수준 (explicit trust levels), 파이프라인 경계를 가로지르는 감사 추적 (audit trails) 등은 기술적으로 가능합니다. 하지만 이를 위해서는 조직들이 아직 표준으로 존재하지 않는 관례(conventions)에 합의해야 합니다. 합의가 이루어지기 전까지 에이전트는 추정된 동의 (assumed consent) 하에 작동합니다. 에이전트 A는 이해받을 것을 기대하며 에이전트 B를 호출합니다. 에이전트 B는 에이전트 A가 전혀 보지 못한 규칙을 적용한 채 응답합니다. 두 에이전트 모두 성공을 기록합니다.
프롬프트 인젝션 (Prompt injection)이 멀티 에이전트 파이프라인을 악용하는 방식
프롬프트 인젝션 (Prompt injection)이 작동하는 이유는 에이전트가 컨텍스트 (context)를 읽고 그에 따라 행동하도록 설계되었기 때문입니다. 공격 표면 (attack surface) 자체가 바로 그 기능 그 자체입니다.
악의적인 공격자는 에이전트가 읽게 될 콘텐츠, 즉 웹페이지, 이메일, 문서 등에 지시 사항을 삽입합니다. 이러한 지시 사항은 에이전트의 실제 지시를 무효화하려고 시도합니다. 에이전트에게 다른 모드에 있다고 말하거나, 이전 규칙이 중단되었다고 말하거나, 사용자가 이미 동의하지 않은 사항에 대해 이미 동의했다고 말하는 식입니다.
버퍼 오버플로 (buffer overflow)도, 인증 우회 (authentication bypass)도 필요 없습니다. 이 공격은 에이전트를 유용하게 만드는 바로 그 메커니즘을 악용합니다.
멀티 에이전트 시스템에서 주입된 지시 사항은 반드시 외부에서 올 필요는 없습니다. 침해된 다른 에이전트, 다른 당사자에 의해 설계된 에이전트, 또는 단순히 충돌하는 규칙을 실행 중인 에이전트로부터 올 수도 있습니다.
이는 이론적인 이야기가 아닙니다. Kai Greshake와 동료들은 2023년에 실제로 배포된 시스템에서 정확히 이러한 종류의 공격을 기록한 논문을 발표하며, 이를 간접 프롬프트 주입 공격 (indirect prompt injection attacks)이라고 명명했습니다. 그들은 Bing Chat과 GPT-4 기반의 코드 완성 (code-completion) 도구에 대해 작동하는 익스플로잇 (exploit)을 시연함으로써, 에이전트가 검색하는 웹 페이지나 읽는 이메일과 같은 외부 콘텐츠에 포함된 지침이 하부 인프라에 대한 직접적인 접근 없이도 프로덕션 시스템 전반에서 에이전트의 동작을 확실하게 하이재킹 (hijack)할 수 있음을 증명했습니다.
2025년에 업데이트된 OWASP의 LLM Top 10 v1.1에서도 프롬프트 주입 (prompt injection)은 여전히 LLM 애플리케이션의 위험 요소 중 1위로 기록되어 있습니다.
멀티 에이전트 파이프라인 (multi-agent pipeline)에서는 공격이 복합적으로 작용합니다. 침해된 하위 에이전트 (subagent)가 수정된 컨텍스트 (context)를 오케스트레이터 (orchestrator)에게 전달하면, 오케스트레이터는 이를 바탕으로 동작하고 오염된 내용을 계속해서 전달합니다. 악의적인 지침이 중대한 결과로 이어지는 동작에 도달할 때쯤이면, 이미 각 단계에서 받은 정보를 선의로 처리한 여러 에이전트를 거친 상태가 됩니다. 모든 단계에서 이 오염은 정상적인 컨텍스트처럼 보입니다.
"파이프라인을 방해하는 방식으로 지침을 따르는 에이전트"와 "에이전트 자체가 무기화되어 공격하는 것" 사이의 경계는 정말로 모호합니다. 에이전트 컨텍스트로 외부 콘텐츠를 검색하는 기능을 구축하고 있다면 Greshake의 논문을 읽어볼 가치가 있습니다. 읽기에 편안한 내용은 아닙니다.
멀티 에이전트 시스템에서 규칙 충돌을 누가 제어하는가
현재로서는 시스템 내에서 가장 보수적인 규칙 세트 (ruleset)가 기본적으로 승리합니다. 아무도 이를 명시적으로 선택하지 않았습니다.
두 직원이 매니저로부터 상충하는 지시를 받았을 때, 지휘 계통(chains of command), 문서화된 정책, 혹은 판결을 담당하는 직무를 가진 사람과 같은 에스컬레이션 경로(escalation paths)가 존재합니다. 하지만 두 에이전트가 상충하는 규칙을 가질 때는 에스컬레이션 경로가 없습니다. 마지막에 처리하는 에이전트가 결과를 결정합니다. 가장 먼저 거부하는 에이전트가 한계치(ceiling)를 설정합니다. 가장 보수적인 규칙 세트(ruleset)가 결국 다른 모든 것을 제약하게 되는데, 이는 누군가 그것이 옳다고 결정했기 때문이 아니라, 거부는 전파되지만 승인은 전파되지 않기 때문입니다.
자신의 에이전트가 멀티 에이전트 파이프라인(multi-agent pipelines) 내부에서 작동하기를 원하는 운영자(Operators)는 허용적인 규칙을 작성할 이유가 있습니다. 자신의 에이전트가 신뢰할 수 있게 행동하기를 원하는 운영자는 제한적인 규칙을 작성할 이유가 있습니다. 에이전트가 더 많은 다른 에이전트와 상호작용함에 따라, 두 가지 압박은 모두 커집니다. 그리고 이들은 해결되지 않습니다.
책임 소재(Accountability)는 그 간극 속으로 사라집니다. 멀티 에이전트 시스템에서 무언가 잘못되었을 때, 누가 책임을 져야 합니까? 상충하는 규칙을 작성한 운영자입니까? 기본 설정(defaults)이 예상치 못한 동작을 유발한 모델 제공자(model provider)입니까? 두 시스템의 규칙이 호환되는지 확인하지 않고 두 시스템을 연결한 엔지니어입니까? 현재의 프레임워크(frameworks)는 이에 대한 명확한 답을 가지고 있지 않습니다. 문제는 사건이 표면화되었을 때 그 사건에 가장 가까이 있는 누군가에 의해 사후적으로 해결되는 경향이 있습니다. 그것은 거버넌스(governance)가 아닙니다. 그것은 책임 전가(blame allocation)입니다.
저는 이것이 명확하게 해결될 수 있는 문제라고 생각하지 않습니다. 이것은 기술적인 문제가 아니라 거버넌스의 문제입니다. 거버넌스 문제는 더 나은 코드로 해결되지 않습니다. 거버넌스 문제는 조직이 표준에 합의함으로써 해결되며, 여기에는 시간과 갈등, 그리고 컨퍼런스 발표 주제로 삼기에는 다소 극적이지 않은 종류의 제도적 작업(institutional work)이 필요합니다.
EU AI Act (2024)와 NIST AI Risk Management Framework (AI RMF)는 모두 조직의 경계를 넘어선 AI 시스템 동작의 문서화(documentation)를 추진하고 있지만, 운영자 간의 멀티 에이전트 규칙 충돌(multi-agent rule conflicts)을 어떻게 해결해야 하는지에 대해서는 명시하지 않습니다. NIST AI RMF는 비록 직접적인 해결책을 제시하지는 않더라도, 이 문제를 어떻게 생각할지에 대한 구조를 잡는 데 진정으로 유용합니다.
프로덕션 환경에서 멀티 에이전트 실패를 방지하는 방법
모든 경계(boundary)를 문서화하세요. 하위 에이전트(downstream agent)가 요청을 거부할 때 어떤 일이 발생하는지 테스트하세요. 파이프라인(pipeline)이 당신이 생각하는 대로 동작할 것이라고 가정하지 마세요.
모든 에이전트 경계를 언젠가 예상치 못한 방식으로 동작할 인터페이스(interface)로 취급하세요. 각 에이전트에게 어떤 규칙을 부여하는지 문서화하세요. 다른 에이전트의 규칙이 무엇이라고 가정하는지 문서화한 다음, 그 가정이 실제로 맞는지 확인하세요. 무언가 잘못되었을 때, 코드 버그(code bug)인지 묻기 전에 규칙 충돌(rule conflict)이었는지 먼저 물으세요. 많은 경우 파이프라인은 정상적으로 완료되었지만, 문제는 전적으로 의미론적(semantics)인 부분에 존재합니다.
이러한 시스템을 구축하는 팀들에게 제가 말하는 몇 가지 사항입니다:
파이프라인의 모든 에이전트를 매핑하고, 각 에이전트가 명시적으로 무엇을 거부하거나 유보(defer)하도록 지시받았는지 기록하세요. 그런 다음 에이전트 경계 전반에 걸쳐 해당 목록들을 비교하세요. 배포 전에 발견할 수 있는 충돌은 비용 없이 수정할 수 있습니다.
만약 에이전트 중 하나라도 외부 콘텐츠를 읽는다면, 간접 프롬프트 주입(indirect prompt injection)을 실제 위협으로 취급하세요. 에이전트가 검색하는 콘텐츠가 무엇인지 검토하고, 동작하기 전에 이를 검증하며, 에이전트의 컨텍스트(context)가 변조된 상황을 고려하여 설계하세요.
하위 에이전트가 당신의 요청을 거부하는 상황을 대비하여 구축하세요. 이것이 끊임없이 발생하기 때문이 아니라, 거절을 우아하게 처리하는 시스템을 만드는 것이, 조용히 처리를 중단해버린 큐(queue)를 사흘 동안 디버깅(debugging)하는 것보다 배포 전에 설계하기 훨씬 쉽기 때문입니다.
팀이나 조직 간에 에이전트(agents)를 연결할 때는 신뢰 수준(trust levels)에 대한 공유된 정의를 만드십시오. "운영자 수준의 신뢰 (Operator-level trust)"는 인터페이스의 양측 모두에게 동일한 의미를 가져야 합니다.
단순히 작업 완료뿐만 아니라, 거절(refusals)과 보류(deferrals)를 명시적으로 기록할 수 있도록 파이프라인(pipelines)을 구축하십시오. 조용한 보류(Silent deferrals)는 찾아내기 가장 어려운 실패 유형입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기