AI 에이전트가 같은 처리를 반복하여 시간이나 토큰만 소모하는 현상이 있습니다.
이러한 '진전 없는 반복'을 Doom Loop라고 합니다. OpenRouter의 공식 자료에서도 동일한 툴 호출이나 문장을 반복하며 앞으로 나아가지 못하는 상태로 설명하고 있습니다.
에이전트를 만들 때는 성공적인 절차와 함께, 막혔을 때 멈출 조건도 설계해야 합니다.
예를 들어, 존재하지 않는 파일을 읽으려고 시도하다가 오류가 발생한 경우입니다. 파일 이름을 확인하면 되는데, 같은 경로로 계속 읽기를 반복하는 상황이 있습니다.
코드 수정에서도 이런 상태가 생각할 수 있습니다.
- 수정한다
- 테스트가 실패한다
- 수정을 되돌린다
- 또다시 같은 수정을 한다
처리는 작동하고 있지만, 문제는 해결에 가까워지지 않고 있습니다.
일시적인 통신 오류라면, 잠시 기다렸다가 재시도하는 의미가 있습니다.
반면, 권한 부족이나 입력의 실수는 같은 조건으로 반복해도 개선되기 어렵습니다.
재시도하기 전에 **'다음에는 성공할 가능성이 있는 이유'**를 확인하고 싶습니다.
상황이 변해서 기다려야 하는지. 입력을 고쳤는지. 다른 수단으로 전환했는지 등을 말입니다.
조건이 바뀌지 않은 채 횟수만 늘어난다면, 막힘(行き詰まり)을 의심합니다.
전에 소개했던 Tool-Call Fingerprinting은 툴 이름과 인자로부터 동일한 호출을 식별하는 방법입니다.
Repetition Cycle Detection은 기록으로부터 동일한 호출 순서의 반복을 찾습니다.
Doom Loop는 이들로 감지하고 싶은 '진전 없는 상태'를 말합니다.
다만, 인자가 조금씩 바뀌는 루프도 있습니다. 호출 일치뿐 아니라, 새로운 정보를 얻었는지, 미해결 문제가 줄었는지도 살펴봐야 합니다.
단순히 '같은 것을 반복하지 마라'라고 지시하는 것만으로는 정지를 보장할 수 없습니다.
구현 시에는 다음과 같은 조건을 조합합니다.
| 조건 | 목적 |
|---|
| 같은 처리가 지속되면 경고 | 방침 변경을 촉진 |
| ... | |
| LangGraph에도, 정지 조건에 도달하지 못한 채 스텝 수의 상한선에 도달하면 오류가 발생하는 메커니즘이 있습니다. 다만, 정상적인 긴 처리에서도 상한선에 도달할 수 있습니다. | |
동일한 툴 호출을 거부하더라도, 에이전트가 그 거부를 받고 재시도하는 것이 계속될 가능성이 있습니다.
OpenRouter의 자료에서도 블록만으로는 재시도가 계속될 수 있으므로, 정지 조건을 함께 설정할 필요성이 설명되어 있습니다.
정지 시점에는 시도했던 것, 실패 이유, 재개를 위해 필요한 정보를 남겨야 합니다.
그렇게 설계하면, 사람이 상황을 확인하고 다음 단계를 선택하기가 더 쉬워집니다.