IT기술/랭체인 (langchain)

LangChain 오류 해결 완벽 가이드: 일반적인 문제와 트러블슈팅 방법

후스파 2025. 7. 6. 20:35
반응형

LangChain에서 발생하는 일반적인 오류와 그 해결 방법을 살펴보도록 하겠습니다.


설치 및 모듈 관련 문제

ModuleNotFoundError

증상: 'langchain' 모듈을 찾을 수 없다는 오류 발생

ModuleNotFoundError: No module named 'langchain'
ModuleNotFoundError: No module named 'langchain.agents'
ModuleNotFoundError: No module named 'langchain.document_loaders'

해결방법:

# 1. LangChain 패키지 설치
pip install langchain

# 2. 최신 버전으로 업그레이드
pip install langchain --upgrade

# 3. 특정 버전 설치 (2025년 기준)
pip install langchain==0.1.20

# 4. 전체 LangChain 생태계 설치
pip install langchain langchain-community langchain-openai langchain-anthropic

추가 확인사항:

# Python 환경 확인
import sys
print(sys.executable)
print(sys.version)

# 설치된 패키지 확인
pip show langchain

# 가상환경 활성화 확인
which python
which pip

ImportError 및 AttributeError

# 구버전 방식 (오류 발생)
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI

# 신버전 방식 (권장)
from langchain_openai import OpenAI, ChatOpenAI
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.vectorstores import FAISS

API 연결 문제

인증 오류 (AuthenticationError)

증상: API 키 관련 오류 발생

AuthenticationError: Invalid API key provided

해결방법:

import os
from dotenv import load_dotenv

# 1. 환경 변수 설정
load_dotenv()

# 2. API 키 확인
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
    raise ValueError("OPENAI_API_KEY가 설정되지 않았습니다.")

# 3. 올바른 API 키 형식 확인
print(f"API Key 시작: {api_key[:10]}...")

# 4. LangChain에서 API 키 사용
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    api_key=api_key,  # 명시적으로 API 키 전달
    model="gpt-3.5-turbo"
)

.env 파일 설정:

# .env 파일
OPENAI_API_KEY=sk-your-actual-api-key-here
ANTHROPIC_API_KEY=your-anthropic-key
HUGGINGFACE_API_KEY=your-hf-key

연결 시간 초과 (TimeoutError)

증상: LangChain 서비스에 연결할 수 없음

TimeoutError: Request timed out

해결방법:

from langchain_openai import ChatOpenAI
import httpx

# 1. 타임아웃 설정 증가
llm = ChatOpenAI(
    model="gpt-3.5-turbo",
    timeout=60,  # 60초로 증가
    max_retries=3  # 재시도 횟수 설정
)

# 2. 커스텀 HTTP 클라이언트 사용
custom_client = httpx.Client(
    timeout=httpx.Timeout(60.0),
    limits=httpx.Limits(max_connections=10)
)

llm = ChatOpenAI(
    model="gpt-3.5-turbo",
    http_client=custom_client
)

# 3. 재시도 로직 구현
import time
from tenacity import retry, stop_after_attempt, wait_exponential

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=4, max=10)
)
def robust_llm_call(prompt):
    try:
        return llm.invoke(prompt)
    except Exception as e:
        print(f"API 호출 실패: {e}")
        raise

데이터 형식 오류

JSONDecodeError

증상: JSON 데이터 처리 중 오류 발생

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

해결방법:

import json
from langchain.schema import BaseOutputParser

class SafeJSONParser(BaseOutputParser):
    """안전한 JSON 파싱을 위한 커스텀 파서"""

    def parse(self, text: str) -> dict:
        try:
            # JSON 형식 정리
            cleaned_text = text.strip()
            if cleaned_text.startswith('```
                cleaned_text = cleaned_text[7:]
            if cleaned_text.endswith('```'):
                cleaned_text = cleaned_text[:-3]

            return json.loads(cleaned_text)
        except json.JSONDecodeError as e:
            print(f"JSON 파싱 오류: {e}")
            print(f"원본 텍스트: {text}")

            # 기본값 반환 또는 텍스트 그대로 반환
            return {"error": "JSON 파싱 실패", "raw_text": text}

# 사용 예시
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI

prompt = PromptTemplate(
    input_variables=["question"],
    template="""
    다음 질문에 대해 JSON 형식으로 답변해주세요:
    {question}

    응답 형식:
    {{
        "answer": "답변 내용",
        "confidence": 0.95
    }}
    """
)

llm = ChatOpenAI(model="gpt-3.5-turbo")
parser = SafeJSONParser()

chain = prompt | llm | parser
result = chain.invoke({"question": "파이썬의 장점은?"})

속도 제한 (Rate Limiting) 문제

RateLimitError

증상: API 요청 한도 초과로 인한 오류

RateLimitError: Rate limit reached for requests

해결방법:

import time
import random
from typing import List
from langchain_openai import ChatOpenAI

class RateLimitedLLM:
    def __init__(self, model="gpt-3.5-turbo", requests_per_minute=60):
        self.llm = ChatOpenAI(model=model)
        self.requests_per_minute = requests_per_minute
        self.min_interval = 60.0 / requests_per_minute
        self.last_request_time = 0

    def invoke_with_rate_limit(self, prompt):
        """속도 제한을 고려한 LLM 호출"""
        current_time = time.time()
        time_since_last = current_time - self.last_request_time

        if time_since_last  50:
                # 특수 문자 정리
                cleaned_content = doc.page_content.replace('\x00', '')
                doc.page_content = cleaned_content
                valid_docs.append(doc)

        return valid_docs

# 사용 예시
loader = RobustDocumentLoader()

try:
    documents = loader.load_document("example.pdf")
    validated_docs = loader.validate_document_content(documents)
    print(f"성공적으로 로드된 문서 수: {len(validated_docs)}")
except Exception as e:
    print(f"문서 로딩 실패: {e}")

AttributeError 및 NotImplementedError

버전 호환성 문제

증상: 객체에 특정 속성이나 메서드가 없다는 오류 발생

AttributeError: 'RunnableSequence' object has no attribute 'input_schema'
NotImplementedError: Saving not supported for this chain type

해결방법:

# 1. 버전 확인 및 업그레이드
import langchain
print(f"LangChain 버전: {langchain.__version__}")

# 2. 호환성 래퍼 클래스 생성
from langchain.schema.runnable import Runnable

class CompatibilityWrapper:
    @staticmethod
    def safe_get_attribute(obj, attr_name, default=None):
        """안전한 속성 접근"""
        try:
            return getattr(obj, attr_name, default)
        except AttributeError:
            print(f"속성 '{attr_name}'을 찾을 수 없습니다. 기본값 사용: {default}")
            return default

    @staticmethod
    def safe_method_call(obj, method_name, *args, **kwargs):
        """안전한 메서드 호출"""
        try:
            method = getattr(obj, method_name)
            return method(*args, **kwargs)
        except (AttributeError, NotImplementedError) as e:
            print(f"메서드 '{method_name}' 호출 실패: {e}")
            return None

# 3. 버전별 분기 처리
def create_chain_with_compatibility():
    """버전 호환성을 고려한 체인 생성"""
    try:
        # 새로운 방식 시도
        from langchain.chains import create_retrieval_chain
        from langchain.chains.combine_documents import create_stuff_documents_chain

        # 새로운 API 사용
        return "new_api"
    except ImportError:
        # 구버전 방식으로 폴백
        from langchain.chains import RetrievalQA

        # 구버전 API 사용
        return "old_api"

# 4. 마이그레이션 가이드
def migrate_deprecated_code():
    """구버전 코드를 신버전으로 마이그레이션"""

    # 구버전 (Deprecated)
    # from langchain.llms import OpenAI
    # llm = OpenAI()

    # 신버전 (Recommended)
    from langchain_openai import OpenAI
    llm = OpenAI()

    # 구버전 체인 생성
    # from langchain.chains import LLMChain
    # chain = LLMChain(llm=llm, prompt=prompt)

    # 신버전 체인 생성
    from langchain.schema.runnable import RunnablePassthrough
    chain = prompt | llm | RunnablePassthrough()

    return chain

일반적인 트러블슈팅 팁

디버깅 도구 및 로깅

import logging
from langchain.callbacks import StdOutCallbackHandler
from langchain.globals import set_debug, set_verbose

# 1. LangChain 디버그 모드 활성화
set_debug(True)
set_verbose(True)

# 2. 로깅 설정
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# 3. 커스텀 콜백 핸들러
class DebugCallbackHandler(StdOutCallbackHandler):
    def on_llm_start(self, serialized, prompts, **kwargs):
        print(f"LLM 시작 - 프롬프트: {prompts[0][:100]}...")

    def on_llm_end(self, response, **kwargs):
        print(f"LLM 완료 - 응답: {response.generations[0][0].text[:100]}...")

    def on_llm_error(self, error, **kwargs):
        print(f"LLM 오류: {error}")

# 4. 환경 진단 함수
def diagnose_environment():
    """개발 환경 진단"""
    import sys
    import platform

    print("=== 환경 진단 ===")
    print(f"Python 버전: {sys.version}")
    print(f"플랫폼: {platform.platform()}")
    print(f"LangChain 버전: {langchain.__version__}")

    # 필수 패키지 확인
    required_packages = [
        'openai', 'anthropic', 'tiktoken', 
        'faiss-cpu', 'chromadb', 'pinecone-client'
    ]

    for package in required_packages:
        try:
            __import__(package)
            print(f"{package}: 설치됨")
        except ImportError:
            print(f"{package}: 설치되지 않음")

    # 환경 변수 확인
    env_vars = ['OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'PINECONE_API_KEY']
    for var in env_vars:
        value = os.getenv(var)
        if value:
            print(f"{var}: 설정됨 ({value[:10]}...)")
        else:
            print(f"{var}: 설정되지 않음")

# 실행
diagnose_environment()

성능 모니터링

import time
import psutil
from functools import wraps

def monitor_performance(func):
    """성능 모니터링 데코레이터"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        start_memory = psutil.Process().memory_info().rss / 1024 / 1024  # MB

        try:
            result = func(*args, **kwargs)
            success = True
        except Exception as e:
            result = None
            success = False
            print(f"함수 실행 오류: {e}")

        end_time = time.time()
        end_memory = psutil.Process().memory_info().rss / 1024 / 1024  # MB

        print(f"=== 성능 리포트 ===")
        print(f"함수: {func.__name__}")
        print(f"실행 시간: {end_time - start_time:.2f}초")
        print(f"메모리 사용량: {end_memory - start_memory:.2f}MB")
        print(f"성공 여부: {success}")

        return result

    return wrapper

# 사용 예시
@monitor_performance
def test_llm_call():
    llm = ChatOpenAI(model="gpt-3.5-turbo")
    return llm.invoke("안녕하세요!")

test_llm_call()

마무리

이러한 방법들을 통해 LangChain 애플리케이션 개발 시 발생하는 대부분의 일반적인 오류를 해결할 수 있습니다.
문제가 지속될 경우 LangChain 개발팀에 문의하거나 커뮤니티의 도움을 받는 것도 좋은 방법입니다.
핵심 포인트:

  • 최신 버전 사용: 정기적인 업데이트로 버그 수정과 새 기능 활용
  • 환경 변수 관리: API 키와 설정의 안전한 관리
  • 오류 처리 로직: 예외 상황에 대한 적절한 대응 방안
  • 성능 모니터링: 리소스 사용량과 응답 시간 추적
  • 디버깅 도구 활용: 로깅과 콜백을 통한 문제 진단
반응형