4분
ReAct 최적화: 제조 현장 실전 팁
Day 3: ReAct 에이전트
ReAct 최적화: 제조 현장 실전 팁
AI Agent 기초 > 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 중복 호출, 불필요한 관찰 축적)를 설명하고, 각 문제를 해결하는 프롬프트 엔지니어링 기법과 코드 수준 최적화 방법을 구체적 예시와 함께 설명해줘.
이 팁이 도움이 됐나요?