Agent가 같은 자리를 맴돌 때, 언제 멈춰야 하는지 어떻게 아는가

← 전체 목차 · 이전: 실행 중 계획이 통째로 무너지면, Agent는 어떻게 스스로 경로를 바꾸는가 · 다음: Agent는 어떤 도구를 호출해야 할지 어떻게 아는가

"같은 도구를 N번 이상 부르면 중단한다"는 판정은 가장 먼저 뚫린다. 도구를 바꿔 가며 제자리를 맴돌면 카운터에 안 잡히고, 매번 파라미터를 살짝 바꾸면 카운터가 영원히 임계값을 넘지 않는다. 순환의 진짜 정의는 **"같은 작업 아래 계획 동작이 종료 상태로 수렴하지 못한 채 자원만 계속 소모하는 것"**이며, 판정 단위를 "호출 횟수"에서 "의미"로 옮겨야 이 정의를 잡아낼 수 있다.

호출 횟수 카운팅이 못 잡는 세 가지

회피 방식왜 카운터가 못 잡는가
도구를 교대로 호출하며 제자리를 맴돎카운팅 차원(도구별)이 애초에 잘못 잡혔다
매 계획마다 파라미터를 미세 조정행위가 매번 달라지니 카운터 기준으로는 "다른 시도"다
모델이 "다음 번엔 될 것"이라는 환각에 빠짐종료권을 환각을 일으키는 당사자에게 맡긴 셈이 된다

계수는 행위를 세지만, 순환은 의도의 반복이다. 행위가 바뀌어도 의도가 그대로면 여전히 순환이다.

의미 지문 + 상태 머신 — 데이터베이스 원자 설비에 판정을 얹는다

agent_plan_trace 테이블에 계획 스텝마다 의미 지문을 남긴다.

표: agent_plan_trace
필드: task_id / plan_semantic_hash / step_status / tool_called / result_similarity
(task_id, plan_semantic_hash)에 유일 제약을 건다
매 계획 스텝 생성 → 의미 지문 계산 → 삽입 시도
  삽입 성공      → 계속 실행
  같은 지문 적중  → 즉시 실패 아니라 "검증" 트리거

상태 머신이 작업 단계를 흐르게 한다.

계획중 → 실행중 → 이미수렴
              └→ 이미차단

핵심 제약 세 가지: 매 단계 전환은 현재 상태를 기준으로 검증해야 하고, 데이터베이스 행 잠금으로 상태 전환의 유일성을 보장하며, 같은 의미의 계획이 재생성될 때 영향 행 수가 0이면 이를 순환 후보로 판정한다. 순환 판정이 별도의 if 분기가 아니라 유일 제약과 행 잠금이라는 원자 설비가 자연스럽게 함께 잡아내는 부산물이 되는 셈이다.

5층 방어선 — 원인이 다원적이니 방어도 계층으로

무한 루프의 원인은 하나가 아니다: 도구 결과를 모델이 못 알아듣거나, 작업 자체가 답이 없거나, 목표가 표류하거나, 시스템에 애초에 정지 조건이 없거나. 그래서 해법도 카운터 하나가 아니라 층마다 다른 방어가 필요하다.

방어 대상구체 수단
1. Prompt 계약층근원에서 순환 확률을 낮춤finish 도구를 명시적 계약으로 등록: "완료 또는 충분한 정보 확보 시 반드시 finish 호출, 다른 도구 계속 호출 금지" / "같은 도구·같은 파라미터 연속 2회 실패 시 방법·파라미터를 반드시 바꿀 것"
2. 편성 통제층모델에게서 종료 결정권을 회수총 라운드 상한(10~15) / 동일 도구+동일 파라미터 연속 2회 초과 시 즉시 차단 / 연속 오류 3회 시 강제 강등 — 개입은 점진적으로: 1회 실패→방법 바꾸라고 제시, 2회 실패→중복 중이라고 시스템 메시지 주입, 3회 실패→종료 후 "부분 결과 + 사유"를 출력
3. 도구 실행층단일 도구 장애가 전체를 끌고 가지 못하게 격리도구별 타임아웃 + 유한 재시도(지수 백오프) + 서킷 브레이커(연속 5회 실패 시 냉각기 진입, 냉각 후 반개방 탐침 1회)
4. 의미 감지층행위는 변하는데 진전은 없는 경우 식별무진전 감지(연속 N스텝 새 사실/데이터/결론 없음 → 강제 중단) + 목표 표류 감지(매 라운드 현재 하위 목표와 원 질문의 의미 유사도 계산, 낮으면 재계획 트리거)
5. 비용 안전망층앞의 모든 층이 실패해도 지켜지는 최후선단일 작업 토큰 예산 상한 초과 시 강제 종료 / 전역 타임아웃 도달 시 프로세스 강제 종료, 뭉툭한 결과라도 반환

가로축: 전 층에서 순환 횟수, 실패 원인, 토큰 소모, 실행 시간을 로그·모니터링에 남긴다. 온라인 장애는 모델을 추측하기 전에 먼저 모니터링으로 위치를 특정한다.

핵심 통찰

  1. 순환은 의미층에서 정의해야지 호출 횟수층에서 정의하면 안 된다 — 판정을 "같은 도구를 몇 번 불렀는가"로 잡는 순간, 도구를 교대로 부르거나 매번 파라미터를 미세 조정하는 가장 흔한 두 회피 방식이 자연 면제된다. "계획 동작이 종료 상태로 수렴하지 못한다"는 정의라야 검출 가능하다.
  2. 계수는 뒷단 안전망일 뿐이다. 계량 단위가 행위이지 의도가 아니기 때문이다 — Agent가 파라미터나 도구를 바꾸면 행위는 바뀌지만 의도는 그대로다. 의미 지문은 "의도가 반복되는가"를 낙인·유일 제약이 걸리는 스칼라값으로 바꿔 준다.
  3. 판정을 응용층의 if문이 아니라 데이터베이스의 원자 설비에 얹을 것 — 유일 제약의 "삽입 실패"와 행 잠금의 "영향 행 수 0"은 그 자체로 강한 일관성의 판정 신호다. 다시 조회해서 비교할 필요가 없고, 동시성과 재시도에 자연히 강하다.
  4. 종료권을 환각을 일으킬 수 있는 바로 그 당사자에게 맡기면 안 된다 — 대형 모델이 "다음 번엔 될 것"이라고 확신할 때, 모델의 자기 판단에 의존하는 어떤 종료 조건도 실패한다. 강제 중단은 반드시 모델 바깥의 상태 머신에서 나와야 한다.
  5. 자연어 당부는 대형 모델에 대한 강제력이 없고, 강제 호출 인터페이스로 바꿔야 준수율이 올라간다finish 도구 계약 한 줄로 저급 순환의 상당수를 막을 수 있다는 것은, "모델이 반드시 하길 바라는 일"은 전부 반드시 호출해야 하는 출구를 줘야지 당부만 해서는 안 된다는 일반 원칙을 보여준다.
  6. 통제권을 통제 대상에게 맡길 수 없다 — 편성층의 하드 카운터가 "중점 중의 중점"인 이유는, 정지 결정을 모델 손에서 코드로 되찾아오기 때문이다. 확률적 컴포넌트는 결정론적 행위를 보증할 수 없다.
  7. "없다는 것"이 "반복"보다 더 찾기 어렵고 더 비싸다 — 파라미터는 다른데 결론이 늘지 않는 호출은 문자열 비교형 차단을 전부 피해 간다. 판정은 정보 증분(새 사실/새 데이터/새 결론)에 걸어야지 행위가 같은지에 걸면 안 된다.
  8. 매 자동화 방어선마다 강등 경로가 짝을 이뤄야 한다 — 의미 검증 서비스 자체도 장애가 난다. 그럴 때는 호출 횟수 기반 임시 차단 + 사후 인력 샘플링으로 물러서는 것이, "검증이 안 되니 검증을 아예 안 한다"보다 훨씬 안전하다.

엔지니어링 실전 Tips

  • 판정과 차단을 분리할 것: "유사 지문 적중"은 차단이 아니라 검증을 트리거한다. "의심"과 "확정"을 두 단계로 나눠야 정당한 반복 시도를 포용할 수 있다.
  • 유일 제약이 가장 저렴한 중복 제거기다: 먼저 조회하고 삽입하지 말 것. 삽입 실패 자체가 신호이며, 조회 한 번을 아끼고 동시성 상황의 경쟁 조건도 같이 해결한다.
  • 행 잠금 판정은 "영향 행 수"를 볼 것, 반환값을 볼 것이 아니다: 영향 행 수가 0이면 "이 스텝은 진전이 없었다"는 뜻이며, 이는 업무 반환 코드보다 우회하기 어려운 사실이다.
  • 재시도 횟수·서킷 브레이커 임계값·냉각 시간을 별도로 설정할 것: 재시도 2회(초 단위), 서킷 브레이커 5회(분 단위 윈도우), 냉각 60초는 서로 다른 시간 단위다. 하나의 "최대 재시도" 파라미터로 뭉뚱그리면 서킷 브레이커가 무의미해진다.
  • 반개방 탐침은 서킷 브레이커에 필수다: 차단만 하고 탐침을 안 하면 해당 도구는 영구 오프라인이 된다. 냉각 후 한 번 시험 요청을 던져 성공하면 복구, 실패하면 계속 차단한다.
  • 비용 안전망은 "돈"과 "시계 시간"으로 표현할 것: 라운드는 이미 편성층에서 관리한다. 5층은 정교한 축(금액, 시간)으로 "라운드는 적은데 매 라운드가 몹시 비싼" 누락 케이스를 막는다.
  • 모니터링 필드는 첫날부터 심을 것: 순환 횟수, 실패 원인, 토큰 소모, 실행 시간 네 필드가 사후 위치 특정의 최소 집합이다. 나중에 심는 비용이 처음부터 써 넣는 것보다 훨씬 크다.