virtual-insanity
← 뒤로

800 운영/810 런북/LLM-폴백-장애.md

seedling

LLM 폴백 장애

증상

  • LLM 호출 시 모든 프로바이더에서 에러 반환 (Copilot 401 → OpenRouter timeout → Ollama 연결 실패)
  • 파이프라인 작업이 model call failed 에러로 중단
  • MODEL_COOLDOWN_UNTIL 이 미래 시간으로 설정되어 정상 프로바이더도 스킵됨
  • 텔레그램 응답에 "LLM 호출 실패" 또는 빈 응답

원인

  1. Copilot 토큰 만료 (401) — 인증 토큰 갱신 필요
  2. OpenRouter API 키 무효/잔액 소진 — 과금 이슈
  3. Ollama 프로세스 다운 — 로컬 Ollama 서버 미실행
  4. 쿨다운 타이머 잔존 — 이전 장애 시 설정된 MODEL_COOLDOWN_UNTIL이 남아있음
  5. 네트워크 문제 — 외부 API 호출 불가

해결 단계

1. 폴백 체인 상태 확인

# 현재 쿨다운 상태 확인
python3 -c "
import os, json

state_path = os.path.expanduser('~/.openclaw/workspace/memory/orchestrator_state.json')
with open(state_path) as f:
    state = json.load(f)

cooldowns = state.get('model_cooldowns', {})
if cooldowns:
    for provider, until in cooldowns.items():
        print(f'  {provider}: cooldown until {until}')
else:
    print('  No active cooldowns')
"

2. Copilot 확인 (1순위)

# Copilot 토큰 유효성 테스트
python3 ~/.openclaw/workspace/scripts/shared/llm.py --test copilot 2>&1 | tail -5

# 401 에러 시: 토큰 갱신
openclaw config set llm.copilot.token "NEW_TOKEN_HERE"

3. OpenRouter 확인 (2순위)

# OpenRouter API 키 및 잔액 확인
curl -s https://openrouter.ai/api/v1/auth/key \
  -H "Authorization: Bearer $(openclaw config get llm.openrouter.apiKey)" \
  | python3 -m json.tool

# 키 갱신 필요 시
openclaw config set llm.openrouter.apiKey "NEW_KEY_HERE"

4. Ollama 확인 (3순위)

# Ollama 프로세스 확인
pgrep -f ollama && echo "Ollama running" || echo "Ollama NOT running"

# Ollama 시작
ollama serve &

# 모델 목록 확인
ollama list

# Ollama 직접 호출 테스트
curl -s http://127.0.0.1:11434/api/generate \
  -d '{"model":"llama3","prompt":"hello","stream":false}' | head -c 200

5. MODEL_COOLDOWN_UNTIL 초기화

# 모든 쿨다운 타이머 제거
python3 -c "
import json, os, tempfile

state_path = os.path.expanduser('~/.openclaw/workspace/memory/orchestrator_state.json')

with open(state_path) as f:
    state = json.load(f)

if 'model_cooldowns' in state:
    cleared = list(state['model_cooldowns'].keys())
    state['model_cooldowns'] = {}
    print(f'Cleared cooldowns for: {cleared}')
else:
    print('No cooldowns to clear')

tmp_fd, tmp_path = tempfile.mkstemp(dir=os.path.dirname(state_path))
with os.fdopen(tmp_fd, 'w') as tmp:
    json.dump(state, tmp, indent=2, ensure_ascii=False)
os.replace(tmp_path, state_path)
print('orchestrator_state.json updated')
"

6. Ollama 폴백 프록시 재시작 (필요 시)

# 폴백 프록시 확인 및 재시작
python3 ~/.openclaw/workspace/scripts/ollama_failover.sh

확인 방법

# LLM 호출 테스트 (폴백 체인 전체)
python3 -c "
from shared.llm import call_model
result = call_model('ping test', model='auto')
print(f'Response: {result[:100]}...' if result else 'FAILED')
" 2>&1

# 쿨다운 상태 재확인
python3 -c "
import json
with open('$HOME/.openclaw/workspace/memory/orchestrator_state.json') as f:
    state = json.load(f)
print('Cooldowns:', state.get('model_cooldowns', {}))
"

# 헬스체크
python3 ~/.openclaw/workspace/scripts/health_check.py