26Y27h1

QK·2026년 7월 27일
import os
import sys
import json
import requests

def debug_llm_connection(base_url: str, model_name: str = None):
    """
    [디버거 1]: LLM 서버 접속 전 엔드포인트 및 모델 라우트 정밀 점검 (Pre-flight)
    """
    print(f"\n🔍 [LLM Debugger] Target Base URL: {base_url}")
    
    # 1. Base URL 트레일링 슬래시 정리
    base_url = base_url.rstrip('/')
    
    # 2. 대표적인 모델 목록 조회 엔드포인트 테스트
    test_endpoints = [
        f"{base_url}/models",         # OpenAI / vLLM / LiteLLM 규격
        f"{base_url}/v1/models",      # /v1 래퍼 규격
        f"{base_url}/api/tags"        # Ollama 규격
    ]
    
    success = False
    print("📡 [1/2] 엔드포인트 라우팅 헬스체크 진행 중...")
    for ep in test_endpoints:
        try:
            res = requests.get(ep, timeout=5)
            print(f"   👉 GET {ep} ➡️ HTTP Status: {res.status_code}")
            if res.status_code == 200:
                print(f"      ✅ 정상 응답 수신! (응답 요약: {res.text[:100]}...)")
                success = True
                break
        except Exception as e:
            print(f"      ❌ 접속 실패 ({ep}): {str(e)}")
            
    if not success:
        print("\n🚨 [404 원인 추정]: 등록된 API 엔드포인트 경로를 찾지 못했습니다.")
        print("   - URL 끝에 '/v1' 이 빠졌는지 확인하세요. (예: http://llm-server:8000 ➡️ http://llm-server:8000/v1)")
        print("   - Ollama 사용 시: http://localhost:11434/v1 또는 http://localhost:11434/api/chat")
        print("   - vLLM/LiteLLM 사용 시: http://localhost:8000/v1\n")

def invoke_llm_with_trace(base_url: str, model: str, prompt: str, api_key: str = "EMPTY"):
    """
    [디버거 2]: 404 발생 시 Request URL과 Server Raw Response를 정밀 트레이싱하는 LLM 호출기
    """
    base_url = base_url.rstrip('/')
    
    # OpenAI Chat Completions 호환 표준 경로 설정
    if not base_url.endswith("/v1"):
        endpoint_url = f"{base_url}/v1/chat/completions"
    else:
        endpoint_url = f"{base_url}/chat/completions"
        
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}"
    }
    
    payload = {
        "model": model,
        "messages": [
            {"role": "system", "content": "You are an expert SRE and Cloud Infrastructure Architect."},
            {"role": "user", "content": prompt}
        ],
        "temperature": 0.2
    }
    
    print(f"\n🚀 [LLM Request Dispatch]")
    print(f"   - Target Endpoint : {endpoint_url}")
    print(f"   - Target Model    : {model}")
    
    try:
        response = requests.post(
            endpoint_url, 
            headers=headers, 
            data=json.dumps(payload), 
            timeout=60
        )
        
        # 404 등 HTTP 에러 상세 로깅
        response.raise_for_status()
        
        res_json = response.json()
        print("✅ [LLM 호출 성공]")
        return res_json['choices'][0]['message']['content']

    except requests.exceptions.HTTPError as http_err:
        print(f"\n💥 [HTTP 에러 발생] Status Code: {response.status_code}")
        print(f"   - Full Requested URL : {response.url}")
        print(f"   - Request Headers    : {headers}")
        print(f"   - Request Payload    : {json.dumps(payload, indent=2)}")
        print(f"   - Server Raw Response: {response.text}") # 404의 실제 원인 메시지 출력
        raise http_err
    except Exception as err:
        print(f"\n💥 [일반 통신 에러 발생]: {str(err)}")
        raise err


# ==========================================
# step5 메인 실행부 적용 방식 예시
# ==========================================
if __name__ == "__main__":
    # 환경변수 또는 설정값 로드
    LLM_BASE_URL = os.getenv("LLM_BASE_URL", "http://llm-service.internal.zone:8000")
    LLM_MODEL_NAME = os.getenv("LLM_MODEL_NAME", "meta-llama/Llama-3-8B-Instruct")
    
    # 1. 사전 진단 가동
    debug_llm_connection(LLM_BASE_URL, LLM_MODEL_NAME)
    
    # 2. 테스트 디스패치 실행
    test_prompt = "Perform a brief RCA analysis for CPU throttled pods."
    try:
        result = invoke_llm_with_trace(
            base_url=LLM_BASE_URL,
            model=LLM_MODEL_NAME,
            prompt=test_prompt
        )
        print(f"\n🤖 [LLM Response Preview]:\n{result[:200]}...")
    except Exception as e:
        print("\n❌ [Step5 LLM 연동 중단] 위 출력된 Target Endpoint 및 Server Raw Response를 확인하세요.")
profile
engineer

0개의 댓글