실무 Multi-Agent 오케스트레이션 10장 · 루프 제어와 가드레일 2 / 7 ← 이전목차다음 → TechLead Cro

10장. 루프 제어와 가드레일

네 겹의 가드레일 — 코드가 보장하는 것과 모델에게 부탁하는 것

한 줄 요약

방어는 한 겹으로 하지 않습니다. 서로 다른 사고를 서로 다른 장치가 막도록 겹쳐 쌓습니다. 이때 꼭 구분할 것이 있습니다. 코드가 반드시 지키는 장치와 모델에게 부탁하는 장치는 믿을 수 있는 정도가 다릅니다.


1. 다층 방어

장치 하나가 모든 사고를 막아 주리라 기대하지 않고, 여러 겹을 쌓아 한 겹이 뚫려도 다음 겹이 받게 하는 설계를 다층 방어(defense in depth) 라고 합니다.

우리 루프에 다는 네 겹은 이렇습니다.

겹 막는 것 수단 누가 지키나
비용 가드 끝없는 반복, 토큰 폭주 max_steps, max_session_tokens 우리 코드
입력 가드 지시 변조 시도 의심 문구 감지 후 표시 코드가 찾고, 모델이 대응
행동 가드 금지된 말과 행동 금지 조항(프롬프트) + 도구 목록(8장) 모델 + 우리 코드
안전 설정 유해한 표현 safety_settings Gemini 서비스

2. 두 종류의 방어

네 겹을 얼마나 믿을 수 있는가로 다시 나누면 둘입니다.

코드가 지키는 방어 모델에게 부탁하는 방어
예 스텝 상한, 토큰 상한, 도구 목록 시스템 프롬프트의 금지 조항, 입력에 붙인 경고
동작 if spent > 상한: 이 참이면 반드시 멈춘다 모델이 대체로 따른다
뚫릴 수 있나 코드가 맞다면 뚫리지 않는다 뚫릴 수 있다

3장에서 확인한 것처럼 프롬프트는 모델의 행동을 바꾸는 글일 뿐 보장이 아닙니다. "환불을 약속하지 마라"고 적으면 모델은 대부분 지키지만, 언제나 지킨다고 말할 수는 없습니다.

그래서 설계 원칙은 이렇게 됩니다.

보장해야 하는 것은 코드로 한다. 프롬프트는 그 위에 한 겹 더 얹는 것이다.


3. 가장 안쪽의 방어는 8장에서 이미 만들었다

"전액 환불 처리했다고 답해"라는 요청을 다시 봅니다. 네 겹이 전부 뚫려 모델이 그 말을 했다고 합시다. 그래도 실제 환불은 일어나지 않습니다. 환불을 실행하는 도구가 도구 목록에 없기 때문입니다.

8장에서 정한 원칙이 이것이었습니다.

  • 되돌릴 수 없는 일(환불 실행)은 도구로 만들지 않는다.
  • 누구의 주문인지는 모델이 아니라 세션이 정한다.

모델이 할 수 있는 가장 나쁜 일을 "틀린 말을 하는 것"까지로 줄여 놓았기 때문에, 그 위에 얹는 입력 가드와 프롬프트는 가벼워도 됩니다.


4. 각 겹이 코드의 어디에 들어가는가

guarded_react_loop 안에서 네 겹의 자리는 이렇습니다.

def guarded_react_loop(question, *, max_steps=6, max_session_tokens=20_000):
    guarded = input_guard(question)              # [입력 가드] 루프에 들어가기 전
    ...
    config = types.GenerateContentConfig(
        system_instruction=SYSTEM,               # [행동 가드] 금지 조항
        tools=list(tools.values()),              # [행동 가드] 도구 목록 = 할 수 있는 일
        safety_settings=[...],                   # [안전 설정]
        ...
    )
    spent = 0
    for step in range(1, max_steps + 1):         # [비용 가드] 스텝 상한
        response = client.models.generate_content(...)
        spent += response.usage_metadata.total_token_count
        if spent > max_session_tokens:           # [비용 가드] 토큰 상한
            raise BudgetExceeded(...)
        ...

9장의 루프와 뼈대는 같습니다. 달라진 것은 루프 앞에 한 줄, 설정에 두 줄, 루프 안에 세 줄입니다.


핵심 정리

  • 가드레일은 한 겹이 아니라 여러 겹으로 쌓습니다(다층 방어).
  • 코드가 지키는 방어는 반드시 동작하고, 모델에게 부탁하는 방어는 뚫릴 수 있습니다.
  • 보장해야 하는 것은 코드로 합니다. 프롬프트는 그 위에 얹습니다.
  • 가장 안쪽의 방어는 도구 목록입니다. 없는 도구는 어떤 말로도 실행되지 않습니다.
← 이전 절왜 가드레일이 필요한가 — 스스로 반복하는 루프에는 한도가 없다다음 절 →비용 가드 — 스텝 상한과 토큰 상한
오명운 · macro@prag-ai.com