📚 Agentic AI - 기업용 자율 에이전트 개발 4장 · 에이전트 ② 웹검색 Agentic AI란

종료 조건 — 무한 반복과 비용 폭탄 막기

한 줄 요약

에이전트는 스스로 멈출 줄 압니다. 다만 못 멈추는 경우가 있고, 그때는 요금이 계속 나갑니다. MAX_STEPS 한 줄이 그 사고를 막습니다.


1. 종료는 두 가지

아래는 code/ch04_web_agent.py 의 일부입니다 — 위에서 이미 붙여 넣었으니 다시 넣지 마세요.

for step in range(1, MAX_STEPS + 1):
    ...
    if not resp.function_calls:
        return resp.text.strip()          # ① 정상 종료
    ...
return "(최대 단계에 도달해 중단했습니다)"    # ② 강제 종료
언제 결과
① 정상 종료 모델이 "이제 답할 수 있다"고 판단 답변 반환
② 강제 종료 MAX_STEPS 번을 다 썼는데도 안 끝남 중단 메시지

대부분은 ①입니다. 앞 절의 실행에서도 3단계 만에 스스로 끝났습니다.


2. 못 멈추는 경우

②가 필요한 이유는 이런 상황들 때문입니다.

① 도구가 계속 실패한다

[1단계] search_web("스마트워치 시장") → "검색에 실패했습니다(TimeoutError)"
[2단계] search_web("스마트워치 가격") → "검색에 실패했습니다(TimeoutError)"
[3단계] search_web("smartwatch price") → "검색에 실패했습니다(TimeoutError)"
[4단계] ...

모델은 "검색어가 나빴나?" 하고 바꿔 가며 계속 시도합니다. 나쁜 판단은 아닙니다 — 원인이 네트워크라는 걸 모르니까요. 하지만 몇 번을 해도 안 됩니다.

② 답할 수 없는 것을 계속 찾는다

질문: "승승장구몰의 2027년 매출 전망을 알려주세요"

[1단계] search_web("승승장구몰 매출 전망")  → 결과 없음
[2단계] search_web("승승장구몰 2027")       → 결과 없음
[3단계] get_product_info("승승장구몰")      → 찾을 수 없음
[4단계] ...

애초에 어디에도 없는 정보입니다. 그런데 모델은 "다른 도구로 찾아보자"를 반복합니다.

③ 두 도구를 오간다

[1단계] get_product_info("스마트워치")   → 159,000원
[2단계] search_web("스마트워치 가격")     → 시장 정보
[3단계] get_product_info("스마트워치")   → 159,000원   ← 아까 한 것
[4단계] ...

드물지만 일어납니다. 이미 얻은 정보를 다시 가져오는 것이죠.


3. 왜 이게 사고인가

LLM 호출 한 번에 요금이 나갑니다. 그리고 history 는 계속 자랍니다.

[1단계] 입력 500 토큰
[2단계] 입력 1,200 토큰    (1단계 것이 다 들어감)
[3단계] 입력 2,000 토큰
[4단계] 입력 3,100 토큰
...
[50단계] 입력 60,000 토큰

단계가 늘수록 한 단계의 비용도 커집니다. 2장에서 본 그 특성이 여기서 더 두드러집니다.

while True: 로 짜고 이 상황이 되면 — 프로그램은 안 멈추고 요금은 계속 나갑니다. 밤새 돌면 어떻게 될지 상상해 보세요.

루프의 출구는 두 개입니다모델 호출도구 실행다시① 정상 종료부를 도구가 없다모델이 스스로 멈춥니다② 강제 종료MAX_STEPS 도달이 출구가 없으면반복이 계속되면 요금도 늘어납니다단계가 진행될수록 입력 토큰 수도 늘어납니다1단계5002단계1,2003단계2,0004단계3,100· · ·50단계60,000※ 50단계 막대는 축소해서 표시했습니다막대가 길어지는 동시에 개수도 늘어납니다 — 그래서 반복 횟수 상한이 없으면 요금이 두 배로 불어납니다.
루프에서 빠져나가는 길은 두 개이고, 단계마다 입력 토큰 수도 함께 늘어난다

이걸 왜 알아야 하나 — 이걸 모르면 에이전트를 서버에 올려놓고 "왜 요금이 이렇게 나오지?" 할 때, 원인이 루프가 안 끝나는 것이라는 걸 떠올리지 못합니다. 그리고 대책(반복 횟수 상한, 로그, 반복 감지)도 생각해 내지 못합니다.


4. MAX_STEPS — 가장 단순한 안전장치

아래는 code/ch04_web_agent.py 의 일부입니다 — 위에서 이미 붙여 넣었으니 다시 넣지 마세요.

MAX_STEPS = 5          # 안전장치: 아무리 꼬여도 5번 안에 멈춘다

아래는 code/ch04_web_agent.py 의 일부입니다 — 위에서 이미 붙여 넣었으니 다시 넣지 마세요.

for step in range(1, MAX_STEPS + 1):

while 이 아니라 for + 상한을 쓴 이유입니다. 못 멈추는 상황이 와도 반드시 끝납니다.

몇으로 잡나

언제
3 도구 1~2개, 단순 조회
5 이 과정의 기본값. 도구 2~3개
10 도구가 많고 여러 번 오가야 할 때
20+ 코드 작성처럼 시행착오가 필요한 작업

너무 작으면 정상적인 작업도 중간에 잘립니다. 너무 크면 안전장치 역할을 못 합니다.

감을 잡는 법 — 정상적인 질문 몇 개를 돌려 보고 보통 몇 단계에 끝나는지 확인한 뒤, 그 두 배쯤으로 잡으면 무난합니다. 우리 예제는 3단계에 끝났으니 5는 적절합니다.


5. 중단됐을 때 무엇을 돌려주나

아래는 code/ch04_web_agent.py 의 일부입니다 — 위에서 이미 붙여 넣었으니 다시 넣지 마세요.

return "(최대 단계에 도달해 중단했습니다)"

빈 문자열이나 None 을 돌려주면 안 됩니다. 사용자에게는 아무 일도 안 일어난 것처럼 보이니까요.

실제 서비스라면 이렇게 하는 편이 낫습니다.

아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.

return ("죄송합니다. 요청하신 내용을 확인하는 데 실패했습니다. "
        "잠시 후 다시 시도하거나 상담원에게 문의해 주세요.")

그리고 로그에는 자세히 남깁니다 — 몇 단계까지 갔는지, 어떤 도구를 반복했는지. 그래야 나중에 원인을 찾습니다.


6. 더 나은 안전장치들 (참고)

이 과정에서는 MAX_STEPS 하나로 충분하지만, 실제로는 이런 것들도 씁니다.

장치 무엇을 막나
최대 단계 수 무한 반복 (우리가 쓴 것)
누적 토큰 상한 비용 폭탄
시간 제한 응답이 안 오는 상황
같은 호출 반복 감지 같은 도구를 같은 인자로 두 번 부르면 중단
도구별 호출 횟수 제한 검색만 20번 하는 상황

세 번째까지는 만들기 쉽습니다. 예를 들어 같은 호출을 감지하려면:

아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.

seen_calls = set()
...
key = (fc.name, str(dict(fc.args)))
if key in seen_calls:
    result = "이미 같은 조회를 했습니다. 다른 방법을 시도하거나 지금까지의 정보로 답하세요."
else:
    seen_calls.add(key)
    result = TOOLS[fc.name](**dict(fc.args))

결과 문자열로 모델에게 알려 주는 것을 눈여겨보세요. 3장에서 배운 원칙 그대로입니다 — 실패했을 때도 상황을 설명하는 문장을 돌려준다.


7. 5장에서는

LangChain에도 같은 개념이 있습니다. 이름과 방식이 다를 뿐입니다.

아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.

agent.invoke({...}, {"recursion_limit": 10})

이름이 달라도 하는 일은 같습니다 — 몇 번까지 돌지 정하는 것. 여기서 손으로 MAX_STEPS 를 걸어 봤기 때문에, 라이브러리에서 이 설정을 찾아 쓸 수 있습니다.


스스로 해 보기

  1. MAX_STEPS = 1 로 바꾸고 실행해 보세요. 무엇이 출력되나요?
  2. 답할 수 없는 질문을 던져 보세요.
    python answer = run_agent("승승장구몰의 2027년 매출 전망은 어떻게 되나요?")
    몇 단계까지 가나요? 어떤 도구를 반복하나요?
  3. 매 단계 history 길이를 찍어 보세요. 단계가 늘수록 얼마나 커지나요?
  4. 위의 같은 호출 반복 감지를 직접 넣어 보세요.

핵심 정리

  • 종료는 두 가지 — ① 모델이 스스로 멈춤(정상)MAX_STEPS 로 강제 중단.
  • 못 멈추는 경우가 있습니다 — 도구가 계속 실패 · 없는 정보를 계속 찾음 · 같은 조회 반복.
  • while True: 는 위험합니다. 단계가 늘수록 history 가 커져 한 단계의 비용도 커집니다.
  • for + MAX_STEPS 가 가장 단순하고 확실한 안전장치입니다. 이 과정의 기본값은 5.
  • 값을 정하는 법 — 정상적인 질문이 몇 단계에 끝나는지 보고 그 두 배쯤.
  • 중단됐을 때 사용자에게 보여 줄 문장을 돌려주고, 로그에는 자세히 남깁니다.
  • 5장 LangChain에도 같은 개념이 recursion_limit 이라는 이름으로 있습니다.
← 이전 절07. 따라하기 for 루프로 에이전트 직접 만들기다음 절 →09. 검색은 실패한다 끊겨도 멈추지 않게