
LLM 기반 앱은 “어디서” 틀렸는지 보기가 어렵습니다. 모델, 프롬프트, 체인, 툴 호출, 파서… 층이 많죠. 이 글은 LangChain 공식 문서(How to Debug)를 바탕으로 바로 써먹을 디버깅 루틴을 정리했습니다.
왜 디버깅이 더 어렵나?
- 결정적 로직(deterministic)보다 확률적 출력 확률이 큼 → 같은 입력도 결과가 흔들림
- 체인/에이전트 내부에 여러 단계(프롬프트→모델→툴→파서)가 얽힘
- 에러가 나도 “어느 지점에서 깨졌는지” 로그가 부족한 경우가 많음
이 때문에 “흐름을 먼저 보는 로그” → “내부를 다 까보는 로그” → “운영 시각화/추적” 순서로 계층화가 필요합니다.
최근에 가졌던 경험은 gpt-4o-mini 같이 api로 제공하는 모델들은 파싱이 잘되지만 오픈 소스 언어모델로 하면 한국어가 깨지거나 값을 잘 못 생성해줘서 이상한 값을 만들어주는 현상을 발견했습니다.
물론 흔한 일이지만 저런 디버그 기능이 없으니 찾기가 어려웠던 경험이 있어서 글을 쓰고 정리하게 되었습니다.
디버깅 3단계 개요
| 모드 | 핵심 | 장점 | 단점 | 추천 상황 |
| Verbose Mode | 주요 이벤트만 출력 | 가볍고 빠름, 흐름 파악용 | 세부 정보 부족 | 초기 개발, 간단한 체인 흐름 확인 |
| Debug Mode | 모든 입력/출력/내부 호출 로깅 | 어디서/무엇이/왜 깨졌는지 추적 | 로그가 많아 복잡, 느려질 수 있음 | 복잡한 체인·에이전트, 파서 오류 추적 |
| LangSmith Tracing | 외부에 이벤트 저장·시각화 | 운영/협업에 최적, 히스토리 축적 | 셋업 필요, 네트워크 의존 | 스테이징·운영, 장기 분석/평가 |
1) Verbose Mode — 가볍게 흐름 훑기
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.globals import set_verbose
# 1) Verbose 모드 활성화
set_verbose(True)
# 2) 간단한 프롬프트와 체인 구성
prompt = PromptTemplate.from_template("질문: {question}")
llm = ChatOpenAI(model="gpt-4o-mini")
chain = LLMChain(llm=llm, prompt=prompt)
# 3) 실행 → 단계별 흐름이 콘솔에 출력됨
response = chain.run({"question": "한국의 수도는 어디야?"})
print("응답:", response)
언제 쓸까?
- 새 체인을 붙였는데 “흐름이 맞게 흘러가는지” 확인할 때
- 비용/속도 영향 최소화하며 대략적 동작만 볼 때
체크포인트
- 모델 호출 횟수 비정상 급증? → 프롬프트 루프/재시도 과다 여부 점검
- 예상치 못한 툴 호출? → 라우팅/에이전트 정책 확인
2) Debug Mode — 내부까지 다 까보기
from langchain.globals import set_debug, set_verbose
set_debug(True)
set_verbose(False) # (선택) 중복 로그 줄이기
# 2) 간단한 프롬프트와 체인 구성
prompt = PromptTemplate.from_template("질문: {question}")
llm = ChatOpenAI(model="gpt-4o-mini")
chain = LLMChain(llm=llm, prompt=prompt)
# 3) 실행 → 단계별 흐름이 콘솔에 출력됨
response = chain.run({"question": "한국의 수도는 어디야?"})
print("응답:", response)
언제 쓸까?
- JSON 파서가 자주 깨짐 → “LLM 출력”과 “파서 전후” 비교
- 멀티스텝 체인에서 특정 단계만 결과가 비정상일 때
- 벤치마크/테스트 중 오작동 구간 핀포인트가 필요할 때
디버깅 포인트
- 프롬프트-출력 불일치: 지시문의 강도/예시(few-shot) 수/온도 등의 영향
- 툴 호출 실패: 요청 파라미터/타임아웃/예외 처리 누락
- 토큰 초과: 시스템/히스토리/문맥 길이 관리 (요약·윈도우링)
3) LangSmith Tracing — 운영급 추적/시각화
목표: 호출 히스토리를 외부에 저장하고, UI로 단계별 시각화/비교/공유.
# 노트북/파이썬 환경에서
import os, getpass
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = getpass.getpass()
언제 쓸까?
- 스테이징/운영에서 이슈 재현 & 원인분석
- 팀 단위 협업(로그 공유, 리그레션 비교)
- 장기간의 프롬프트/모델 변경 영향 추적
Tip
- PII/민감정보 마스킹 전략을 함께 설계
- 샘플링률(전부/부분) 조정으로 비용·프라이버시 균형
흔한 문제와 빠른 처방
- JSON 파싱 실패
- 처방: 출력 가이드를 엄격화(예: with_structured_output()), 실패 시 원문 저장→후처리 재시도
- 툴 호출 파라미터 오류
- 처방: 스키마 밸리데이션, 예외 메시지/스택 추적을 Debug 모드로 확보
- 비용 폭증
- 처방: Verbose/Tracing으로 호출 수 상위 지점 식별 → 컨텍스트 축소, 캐시/요약 도입
- 일관성 부족(재현 어려움)
- 처방: seed/온도, 프롬프트 버전, 의존 리소스 버전 고정. 호출 스냅샷을 Tracing으로 보존
추천 운영 루틴
- 개발 초반: set_verbose(True)로 흐름 확인
- 이슈 발생: set_debug(True)로 내부 로깅 확대
- 릴리즈/운영: Tracing 활성화 + 대시보드/알람 연동
- 회귀 방지: 실패 사례를 테스트 세트로 편입, 정기 평가
자주 묻는 질문(FAQ)
Q1. Debug와 Verbose를 동시에 켜면?
A. 정보량이 겹칩니다. 보통 Debug만 켜고 Verbose는 끄는 편이 깔끔합니다.
Q2. 로컬만으로 충분할까요?
A. 개인 개발엔 충분하지만, 팀/운영 단계에선 Tracing이 강력합니다(재현·공유·장기 분석).
Q3. 비용/성능에 영향은?
A. Debug/Tracing은 오버헤드가 있습니다. 이슈 재현 시에만 켜고, 평상시엔 Verbose/샘플링으로 최소화하세요.
https://python.langchain.com/docs/how_to/debugging/
How to debug your LLM apps | 🦜️🔗 LangChain
Like building any type of software, at some point you'll need to debug when building with LLMs. A model call will fail, or model output will be misformatted, or there will be some nested model calls and it won't be clear where along the way an incorrect ou
python.langchain.com
'관심있는 주제 > LLM' 카테고리의 다른 글
| 논문 리뷰-단일 시맨틱 검색의 한계-On the Theoretical Limitations ofEmbedding-Based Retrieval (2) | 2025.12.20 |
|---|---|
| OpenAI-Context Engineering 가이드(2025.09) 공부해보기 (1) | 2025.11.02 |
| MemOS: LLM 의 "Memory Operating System" 메모리 관련된 개념 이해하기 (4) | 2025.07.12 |
| MemOS: 대형 언어 모델을 위한 메모리 운영체제-논문 리뷰 및 정리 (5) | 2025.07.12 |
| 프롬프트 최적화 오픈소스 정리 (1) | 2025.05.07 |