AI 에이전트가 불안정한 이유와 신뢰성을 높이는 7가지 규칙
요약
AI 에이전트의 불안정성을 해결하기 위해 프롬프트 의존도를 낮추고 결정론적 가드레일을 구축하는 방법을 제시합니다. Claude Code의 훅(hooks) 기능을 활용하여 민감한 파일 접근을 차단하고 파괴적인 명령을 방지하는 구체적인 설계 패턴을 다룹니다.
핵심 포인트
- 에이전트 불안정성은 모델 문제가 아닌 명세(specification) 문제임
- 최대 단계 수, 타임아웃, 진전 없음 감지기 등 하드 리밋 설정 필수
- 자연어 요청 대신 코드 기반의 결정론적 가드레일 사용 권장
- Claude Code의 PreToolUse 훅을 통한 보안 및 포맷팅 자동화
- 상태(state) 관리를 채팅 기록이 아닌 외부 구조화된 객체로 분리
당신은 AI 에이전트를 만들었습니다. 데모에서는 마법 같았습니다. 하지만 실제 환경에서는 루프를 돌거나, 도구 호출에 대해 환각을 일으키고, 요청한 형식을 두 번 '잊어버리며', 때로는 파일 시스템에서 약간 불안하게 만드는 행동을 합니다.
이런 에이전트를 많이 출시해 본 후 깨달은 불편한 진실은 이것입니다: 불안정한(flaky) 에이전트는 거의 모델 자체의 문제가 아닙니다. 그것은 명세(specification) 문제입니다. 모델은 당신의 프롬프트, 도구, 그리고 제어 루프가 지시한 대로 정확히 작동하고 있습니다 — 그런데 그 지시 내용이 당신이 생각했던 것보다 훨씬 적다는 것이 밝혀집니다.
아래는 에이전트를
모든 자율 에이전트(autonomous agent)는 세 가지 엄격한 제한(hard limits)이 필요합니다. 그렇지 않으면 결국 영원히 실행될 것입니다: 최대 단계 수(max step count), 실제 시간 타임아웃(wall-clock timeout), 그리고 진전 없음 감지기(no-progress detector) (마지막 두 작업이 동일하면 중단)입니다. 모델은 스스로를 안정적으로 멈추지 못할 것입니다. 이것은 프롬프트 외부의 코드상에서 당신이 처리해야 할 작업입니다.
4. 정중한 요청보다 결정론적 가드레일(deterministic guardrails)을 선호하라
프롬프트에 넣는 모든 것은 하나의 _요청(request)_입니다. 모델은 대개 이를 준수합니다. 하지만 "대개"라는 말은 보안 모델이 될 수 없습니다. 만약 어떤 동작이 위험하거나 되돌릴 수 없다면, 영어(자연어)가 아닌 코드에서 차단하십시오.
구체적으로, Claude Code에서는 훅(hooks)을 통해 이를 수행할 수 있습니다. 훅은 도구 호출(tool call) 전에 실행되어 이를 차단할 수 있는 결정론적 스크립트(deterministic scripts)입니다. 제가 거의 모든 프로젝트에 넣는 세 가지는 다음과 같습니다.
가드레일 A — 민감한 경로에 대한 편집 차단. .env, .git/, 또는 비밀 정보(secrets)에 대한 모든 쓰기 작업을 거부하는 PreToolUse 훅:
{
"hooks": {
"PreToolUse": [
...
종료 코드(Exit code) 2는 Claude Code에 해당 작업이 차단되었음을 알리고 그 이유를 모델에 다시 전달합니다. 따라서 모델은 조용히 실패하는 대신 동작을 조정합니다.
가드레일 B — "rm -rf"를 절대 통과시키지 마라. 명백히 파괴적인 명령에 대해 하드 실패(hard-fail)를 일으키는 Bash에 대한 PreToolUse 매처(matcher):
{
"matcher": "Bash",
"hooks": [{
...
가드레일 C — 매 편집 후 자동 포맷팅, 이를 통해 매번 요청하지 않아도 에이전트의 출력이 일관되게 유지됩니다:
{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\" 2>/dev/null || true" }]
...
여기서 중요한 패턴은 다음과 같습니다: 모델은 제안하고, 결정론적 코드가 결정한다(the model proposes, deterministic code disposes). 훅은 모델이 지침을 준수하고 싶어 하든 아니든 상관없이 실행됩니다.
5. 상태(state)를 명시적이고 외부적으로 만들어라
만약 에이전트의 "메모리 (memory)"가 단순히 길어지는 채팅 기록(chat transcript)뿐이라면, 에이전트는 표류하게 됩니다. 초기 지침은 희석되고, 매 턴마다 비용은 상승합니다. 지속 가능한 사실들(작업, 제약 조건, 완료된 사항 등)을 매 단계마다 다시 주입하는 작은 구조화된 객체 (structured object)에 보관하고, 채팅 기록은 소모적인 것으로 취급하세요. 매 루프마다 자신의 목표를 다시 읽는 에이전트는, 40개의 메시지로 구성된 컨텍스트 (context)에 의존하는 에이전트보다 훨씬 더 오랫동안 작업에 집중할 수 있습니다.
6. 소프트웨어처럼 테스트하라, 왜냐하면 그것은 소프트웨어이기 때문이다
테스트가 전혀 없는 함수를 배포하지 않듯이, 테스트가 전혀 없는 에이전트도 배포하지 마세요. 아주 작은 평가 세트 (eval set)를 구축하십시오. 확인 가능한 기대 속성을 가진 10~15개의 대표적인 입력값만 있어도 충분합니다 (규칙 #1이 이를 가능하게 합니다). 프롬프트가 변경될 때마다 이를 실행하세요. "무해한" 프롬프트 수정이 12개 케이스 중 3개를 조용히 망가뜨리는 것을 처음 경험하는 순간, 왜 이것이 프로젝트 전체에서 가장 영향력 있는 30분인지 이해하게 될 것입니다.
7. 사용자에게는 조용히 실패하지 말고, 인간에게는 크게 실패하라
에이전트가 불확실하거나 가드레일 (guardrail)이 작동했을 때, 최악의 결과는 틀린 답을 자신 있게 내놓는 것입니다. "확실하지 않습니다, 이유는 다음과 같습니다"라고 말하는 명시적인 경로를 설계하세요. 중요한 작업에서 5%의 확률로 틀리는 자신감 넘치는 에이전트보다, 가끔씩 _"X를 확인할 수 없어 중단합니다"_라고 말하는 신뢰할 수 있는 에이전트가 더 많은 신뢰를 얻습니다.
한 단락 요약 버전
신뢰성은 구매하는 모델이 아니라, 강제하는 규율입니다. 성공 여부를 확인할 수 있게 만들고 (#1, #6), 도구를 모호하지 않고 명확하게 만들며 (#2), 루프를 제한하고 (#3), 위험한 요소는 산문(prose)이 아닌 코드(code)로 강제하며 (#4), 상태를 외부화하고 (#5), 인간에게 크게 실패하도록 하세요 (#7). 이 규칙들을 지킨다면 평범한 모델도 믿을 수 있는 모델처럼 동작할 것입니다.
이 내용을 인쇄 가능한 체크리스트와 바로 붙여넣을 수 있는 세 가지 추가 Claude Code 가드레일로 받고 싶다면, 이메일 등록 없이 무료 필드 가이드를 작성해 두었습니다: Ship a Reliable AI Agent — the Free Field Guide. 위 내용의 모든 것을 10분 버전으로 요약한 것입니다.
에이전트를 구축하면서 당신을 가장 힘들게 했던 실패 모드(failure mode)는 무엇이었나요? 저는 이러한 사례들을 수집하고 있는데, 생각보다 패턴이 반복되는 것을 볼 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기