본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 06. 18:12

에이전트 데모와 프로덕션 에이전트를 구분 짓는 세 가지 체크리스트

요약

데모 수준을 넘어 실제 프로덕션 환경에서 작동하는 에이전트를 구축하기 위한 보안 아키텍처 설계 원칙을 다룹니다. 단순한 입출력 필터링이 아닌, 데이터 접근·콘텐츠 노출·외부 통신이라는 '치명적 삼중주'를 구조적으로 차단하는 방법을 제시합니다.

핵심 포인트

  • 보안은 필터링이 아닌 아키텍처 설계 단계에서 해결해야 함
  • 데이터 접근, 신뢰할 수 없는 콘텐츠, 외부 통신이 결합되면 데이터 유출 위험 급증
  • Agentic Product Standard v2.0을 통한 실행 가능한 코드 기반의 보안 검증
  • MCP 공급망 보안 및 구조적 제어의 중요성 강조

에이전트 데모를 출시하는 데는 오후 한나절이면 충분합니다. 하지만 프로덕션(Production) 환경에서 한 분기 동안 살아남는 에이전트를 출시하는 것은 전혀 다른 차원의 일입니다. 그리고 그 격차는 거의 항상 모델 때문이 아닙니다. 대개 완전히 누락되어 있는 세 가지 지루한 요소들 때문입니다.

저는 오픈 소스이며 MIT 라이선스를 따르는 Agentic Product Standard를 유지 관리하고 있으며, v2.0의 주요 목적은 이 세 가지 요소를 단순한 조언에서 실제로 실행 가능한 코드로 전환하는 것이었습니다. 실제 코드와 함께 그 내용들을 소개합니다.

  1. 보안은 필터가 아니라 구조적이어야 합니다. 가장 흔한 실수는 안전(Safety)을 가드레일(Guardrail), 즉 가장자리(Edge) 근처의 입출력 필터로 취급하는 것입니다. 문제는 필터에는 한계가 있다는 점입니다. 최고의 콘텐츠 분류기(Content Classifier)도 약 97%의 정확도를 보이며, 이는 설계상 약 3%의 프롬프트 인젝션 (Prompt-injection) 시도가 통과된다는 것을 의미합니다. 이것은 튜닝으로 해결할 수 있는 버그가 아니라, 필터링의 본질적인 특성입니다.

진정한 안전은 아키텍처 (Architecture)에서 나옵니다. 제가 가장 먼저 확인하는 것은 Simon Willison이 말한 치명적인 삼중주(Lethal Trifecta)입니다. 에이전트가 다음 세 가지를 모두 갖추는 순간 데이터 유출(Exfiltration) 도구가 됩니다.

  • 개인 데이터에 대한 접근 권한 (Access to private data)
  • 신뢰할 수 없는 콘텐츠에 대한 노출 (Exposure to untrusted content)
  • 외부와의 통신 능력 (Ability to communicate externally)

이 중 하나만 있다면 괜찮습니다. 하지만 세 가지가 모두 결합되면, 검색된 문서에 숨겨진 페이로드 (Payload)를 기다리는 데이터 유출 채널이 됩니다. 해결책은 결코 "더 나은 필터"가 아닙니다. 다리를 부러뜨리는 것(Break a leg)입니다. 즉, 송신(Egress)을 차단하거나, 신뢰할 수 없는 입력을 격리하거나, 데이터의 범위를 제한해야 합니다.

다음은 CI 단계에서 사용하는 게이트(Gate) 예시입니다. 에이전트가 무엇을 건드릴 수 있는지 선언하며, 만약 이 삼중주가 완화(Mitigation)되지 않았다면 빌드는 실패합니다.

agent-capabilities.json

{ "name": "support-agent",

"private_data": true, "untrusted_content": true, "external_comms": true,

"mitigations": [{"leg": "external_comms", "control": "egress allow-list + approval"}] }

LEGS = ("private_data", "untrusted_content", "external_comms")

def evaluate(spec):
present = [l for l in LEGS if spec.get(l) is True]
if len(present) < 3:
return 0, f"OK: only {len(present)}/3 legs present"
broken = {m["leg"] for m in spec.get("mitigations", []) if m.get("control")}
if broken & set(LEGS):
return 0, f"OK: trifecta present but broken at {', '.join(broken)}"
return 1, "FAIL: lethal trifecta, no leg broken"

두 번째 구조적 제어(structural control)는 MCP 공급망(supply chain)입니다. 커뮤니티 MCP 서버는 신뢰할 수 없는 코드이며, 서버는 승인 시점에는 무해한 도구 설명을 제공했다가 나중에 이를 변조할 수 있습니다(이를 "러그 풀(rug pull)" 또는 도구 정의 포이즈닝(tool-definition poisoning)이라고 합니다). 따라서 도구 정의를 해시(hash)로 고정(pin)하고 변경 시 경고를 발생시켜야 합니다. CI(지속적 통합) 환경에서 몇 줄의 bash 명령어로 이를 잡아낼 수 있습니다:

도구별 정규 해시(canonical hash), 순서 변경에는 반응하지 않되 내용 변경에는 반응하도록 정렬

jq -cS '(.tools)|sort_by(.name)[]|{name,description,inputSchema}' tools.json \
| while read -r t; do printf '%s %s\n' "$(printf '%s' "$t"|sha256sum|cut -d' ' -f1)" \
"$(printf '%s' "$t"|jq -r .name)"; done > current.lock
diff -u tools.lock current.lock || { echo "::error::MCP tool def changed — possible rug pull"; exit 1; }

  1. 비용은 대시보드가 아니라 회로 차단기(circuit breaker)여야 합니다. 에이전트는 채팅과는 비교할 수 없는 속도로 토큰을 소모합니다. Anthropic의 조사에 따르면 멀티 에이전트 시스템(multi-agent systems)은 채팅 상호작용보다 약 15배 더 많은 비용을 발생시킵니다. 대부분의 공개된 멀티 에이전트 아키텍처(multi-agent architectures)는 비용 상한선을 완전히 열어두고 있습니다. 즉, 폭주하는 루프(runaway loop)를 막을 차단기가 없습니다.

v2.0은 비용을 강력한 제어 요소(hard control)로 만듭니다:

코드에 의해 강제되는 실행당 토큰/비용 상한선(각 모델 호출 전에 확인되는 차단기), 나중에 읽게 될 청구서가 아닌 방식;
안정적인 접두사(system prompt, tool schemas)에 대한 프롬프트/KV 캐싱 (prompt/KV caching);
모델 라우팅 (model routing) — 분류에는 작은 모델을, 추론에는 플래그십 모델을 사용;
그리고 사람들이 비싼 대가를 치르고 나서야 배우게 되는 경제 원칙: 멀티 에이전트 (multi-agent) 구성으로 인해 15배의 비용을 지불하는 것은 오직 그 작업의 가치가 이를 정당화할 때뿐이어야 합니다. 만약 단 하나의 에이전트만으로도 기준을 통과할 수 있다면, 오케스트라(여러 에이전트의 협업)는 낭비입니다.
핵심은 "비용"이 코드가 강제하고 작업당 트레이스(traces)에 기록되는 숫자가 되는 순간, 더 이상 놀라운 요소가 되지 않는다는 점입니다.

  1. 자체적인 스캐폴딩 (scaffolding)을 삭제하십시오. 이것이 제가 가장 많이 생각하는 부분입니다. 모델의 약점을 보완하기 위해 작성한 모든 규칙은 그 약점이 사라지는 날 사장된 무게(dead weight)가 됩니다. 더 나쁜 것은, 그 규칙들이 모델의 주의력(attention)을 분산시켜 여전히 중요한 규칙들의 성능을 저하시킨다는 점입니다.

따라서 표준에는 유지보수 교리(maintenance doctrine)가 추가됩니다 (Daniel Miessler의 PAI를 참고하여 수정함): 정기적으로 모든 지침을 감사하되, 단 하나의 질문을 던지십시오 —

"더 똑똑한 모델이라면 이 규칙을 불필요하게 만들 것인가?"

만약 그렇다면, 그것은 아키텍처 (architecture)가 아니라 스캐폴딩 (scaffolding)입니다. 즉시 제거하십시오. 규칙을 안티프래질 (anti-fragile, 평가 세트, 검증 하네스, 도구 계약, 실제 실패 사례 등 → 유지) 대 프래질 (fragile, 사고의 사슬(chain-of-thought) 오케스트레이터, 출력 파서, 재시도 연쇄 등 → 제거하거나 다음 모델 업그레이드 시 재테스트)로 태그를 지정하십시오. 계속해서 커지기만 하는 표준은 부패하기 마련입니다.

검증 가능하게 만들기
원칙은 동의하기 쉽지만 감사하기는 불가능합니다. 그래서 v2.0은 자가 평가 스코어카드(self-assessment scorecard)를 제공합니다. 이는 자율성 사다리 (autonomy ladder)에 매핑된 이진 Yes/No 성숙도 체크 (M0 프로토타입 → M1 출시 가능 → M2 프로덕션 → M3 자율 준비 완료)입니다. 당신의 레벨은 모든 게이트를 통과하는 가장 높은 단계이며, 첫 번째 "No"가 당신의 다음 과제가 됩니다. "프로덕션 준비가 되었는가?"라는 질문은 느낌(vibe)이 아닌 체크리스트가 됩니다.

그와 함께: 위에서 언급한 레드팀 키트(red-team kit)와 더불어, 평가 통과율(eval pass-rate)이 떨어질 경우 머지(merge)를 차단하는 CI 워크플로우 템플릿, 그리고 2026년 업데이트 사항(MCP + OAuth 2.1, Linux Foundation의 A2A, OpenTelemetry GenAI 트레이싱, trajectory + pass^k 평가 지표)이 포함됩니다.

이 모든 것을 관통하는 단 하나의 규칙
모델은 변수(variable)입니다. 하네스(harness)는 상수(constant)입니다. 이에 비례하여 투자하십시오.

…v2.0의 반전이 더해진다면: 하네스는 영원히 축적하는 것이 아닙니다. 그것을 큐레이션(curate)하는 것입니다. 복리 효과를 내는 부분은 키우고, 더 약한 모델을 겨우 지탱해주기만 했던 부분은 삭제하십시오.

이 프로젝트는 MIT 라이선스이며 특정 벤더에 종속되지 않습니다(의도적으로 프레임워크가 아닌 형태로 설계되었습니다). 선택 사항으로 Claude Code 기술 세트가 포함됩니다. 저는 스타(star)를 모으기보다는 무엇이 잘못되었는지 지적받기를 더 원합니다. 보류된 목록(deferred list)이 제가 가장 확신하지 못하는 부분입니다.

리포지토리(Repo): https://github.com/Moai-Team-LLC/agentic-product-standard

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0