4

ReAct 최적화: 제조 현장 실전 팁

Day 3: ReAct 에이전트

학습 목표
  • ReAct Agent의 성능을 최적화하는 방법을 안다
  • 제조 현장에서 흔한 ReAct 문제와 해결책을 이해한다
  • Token 비용을 절감하면서 정확도를 유지하는 전략을 안다
최종 검수: 2026-07

ReAct Agent 최적화 5가지

1. 프롬프트 최적화

# 나쁜 프롬프트
system_prompt = "설비 관리를 도와주세요."

# 좋은 프롬프트
system_prompt = """당신은 제조 현장 설비 관리 AI입니다.

## 행동 순서
1. 설비 상태 조회 -> 문제 설비 식별
2. 문제 설비의 알람 코드 확인
3. 매뉴얼에서 원인/조치 검색
4. 필요 부품 재고 확인
5. 종합 보고서 작성

## 금지 행동
- 정상 설비에 대한 추가 조회 금지
- 이미 조회한 정보 재조회 금지
- 존재하지 않는 설비/부품 코드 추측 금지

## 응답 형식
- 표 형식으로 현황 정리
- 긴급도별 분류 (긴급/주의/정상)
- 구체적 조치 방안 + 예상 비용
"""

규칙: 프롬프트가 구체적일수록 불필요한 Tool 호출이 줄어든다.


2. Tool 결과 압축

# 나쁜 Tool 결과 (너무 길다)
def get_equipment_status(equipment_id: str) -> str:
    # 전체 이력, 센서 데이터 100줄, 유지보수 기록...
    return massive_json_string  # 3000 토큰

# 좋은 Tool 결과 (핵심만)
def get_equipment_status(equipment_id: str) -> str:
    # 현재 상태 요약만 반환
    return f"상태:{status}|가동률:{util}%|알람:{alarms}"  # 50 토큰
접근 방식토큰비용정확도
전체 데이터3000/회높음높음 (정보 과다로 혼란 가능)
요약 데이터50/회낮음높음 (핵심만 전달)
단계적 상세화50-500/회중간최상 (필요시 추가 조회)

3. 캐싱으로 비용 절감

from functools import lru_cache
import time

class CachedTools:
    def __init__(self, cache_ttl=300):
        self._cache = {}
        self._ttl = cache_ttl

    def get_equipment_status(self, equipment_id: str) -> str:
        cache_key = f"eq_{equipment_id}"
        if cache_key in self._cache:
            data, timestamp = self._cache[cache_key]
            if time.time() - timestamp < self._ttl:
                return data + " (캐시된 데이터)"

        result = self._fetch_from_mes(equipment_id)
        self._cache[cache_key] = (result, time.time())
        return result

4. 조기 종료 조건

# 같은 (Tool, 인자) 조합이 되풀이될 때만 멈춘다
class SmartAgentExecutor:
    def __init__(self, max_repeat=2):
        self.call_counts = {}          # (도구, 인자) -> 지금까지 부른 횟수
        self.max_repeat = max_repeat

    def should_stop(self, tool_name, args) -> bool:
        key = f"{tool_name}:{json.dumps(args, sort_keys=True, ensure_ascii=False)}"
        self.call_counts[key] = self.call_counts.get(key, 0) + 1
        return self.call_counts[key] > self.max_repeat

중복 판정은 도구 이름이 아니라 (이름, 인자) 쌍으로 세야 한다. 이름만 보고 막으면 get_equipment_status("CNC-001") 다음의 get_equipment_status("CNC-002")가 중복으로 잡혀, 이 주차의 간판 시나리오인 "A라인 설비 전체 점검"이 두 번째 설비에서 끊긴다. check_inventory(BRG-002) -> check_inventory(BRG-003) 연쇄도 마찬가지다.

라인 4대 순차 조회:
  get_equipment_status(CNC-001) -> 1회  -> 계속
  get_equipment_status(CNC-002) -> 1회  -> 계속   (인자가 다르므로 따로 센다)
  get_equipment_status(CNC-001) -> 2회  -> 계속
  get_equipment_status(CNC-001) -> 3회  -> 중단   (같은 인자 세 번째)

5. 에러 복구 패턴

# Tool 에러 시 Agent가 자연스럽게 대처하도록
def search_manual(query: str) -> str:
    result = _search(query)
    if not result:
        # 에러가 아니라 "대안 제시"
        return f"""'{query}'에 대한 정확한 결과를 찾을 수 없습니다.

시도해볼 수 있는 검색어:
- 알람 코드로 검색 (예: E-4072)
- 증상으로 검색 (예: 진동, 온도, 유압)
- SOP로 검색 (예: SOP-금형교체)

또는 get_alarm_history로 해당 설비의 알람 이력을 먼저 확인하세요."""
        # -> Agent가 이 안내를 읽고 다른 접근을 시도한다

효과는 재서 말한다

위 다섯 가지를 적용하면 무엇이 달라지는지는 워크로드마다 다르다. 숫자를 말하려면 같은 질문 묶음을 적용 전후로 돌리고 다음 셋을 기록한다.

재는 것어디서 얻나
질문당 Tool 호출 횟수호출 로그의 길이
질문당 입력·출력 토큰회차마다 response.usage를 더한 값
질문당 응답 시간첫 호출 시작부터 최종 응답까지

여기에 기대 Tool 목록과 기대 답을 질문마다 미리 적어 두면, 호출이 줄면서 답이 부실해지지는 않았는지도 함께 볼 수 있다. 이 대조 없이 "정확도가 올랐다"고 쓰면 근거가 없는 문장이 된다.

적게 호출하고, 근거를 갖춰 답한다. 이것이 좋은 ReAct Agent다.

AI로 학습하기 — 꿀팁
제조 현장 ReAct 최적화 기법 심화AI 학습 팁

제조 현장의 실시간 데이터 환경에서 ReAct Agent 성능을 높이는 구체적인 기법을 탐구하세요.

공장 설비 이상 감지 ReAct Agent에서 발생하는 성능 저하 원인 3가지(예: Thought 루프 과다, Tool 중복 호출, 불필요한 관찰 축적)를 설명하고, 각 문제를 해결하는 프롬프트 엔지니어링 기법과 코드 수준 최적화 방법을 구체적 예시와 함께 설명해줘.
이 팁이 도움이 됐나요?
용어