Contents
see ListLLM 기능은 모델 호출보다 실패 처리가 먼저입니다
사내 검색, 상담 요약, 문서 작성처럼 LLM을 서비스에 연결할 때 가장 흔한 운영 문제는 모델의 답변 품질만이 아닙니다. 요청이 오래 걸리거나, 네트워크가 끊기거나, 일시적인 할당량 제한이 발생하거나, 사람이 읽기에는 자연스럽지만 프로그램이 처리할 수 없는 형식으로 응답하는 일이 반복됩니다. 이러한 문제를 호출 지점마다 임시로 처리하면 장애 양상이 달라질 때마다 API 서버 전체가 불안정해집니다. LLM 호출을 외부 의존성으로 보고 시간 제한, 제한된 재시도, 결과 검증, 관측 정보를 하나의 경계에 모아야 합니다.
목표는 실패를 없애는 것이 아니라 실패가 사용자 요청과 운영 비용으로 번지는 범위를 줄이는 것입니다. 예를 들어 답변 생성이 지연되면 웹 요청을 계속 붙잡지 않고 정해진 시간에 중단하며, 일시 오류만 재시도하고, 재시도한 이유와 횟수를 기록합니다. 또 후속 시스템이 처리할 값은 자유 텍스트가 아닌 검증 가능한 JSON 구조로 받도록 설계합니다.
요청별 시간 예산을 먼저 정합니다
사용자가 화면에서 기다리는 동기 요청과 비동기 배치 작업은 같은 타임아웃을 사용하면 안 됩니다. 화면용 요약 기능이라면 전체 API 응답 예산이 10초일 때 LLM에는 6~8초만 할당하고, 검색·DB 조회·응답 직렬화에 남은 시간을 보장하는 편이 안전합니다. 긴 보고서 작성이나 대량 분류는 큐에 넣어 작업 상태를 반환하고, 워커에서 더 긴 시간 예산을 씁니다.
- 연결 시간과 전체 응답 시간을 구분해 설정합니다.
- 상위 HTTP 요청의 마감 시간보다 LLM 타임아웃을 짧게 둡니다.
- 사용자 취소나 브라우저 연결 종료가 발생하면 하위 호출도 취소합니다.
- 타임아웃 오류를 성공 응답처럼 캐시하지 않습니다.
Node.js에서는 AbortController를 사용하면 fetch와 같은 표준 API에 취소 신호를 전달할 수 있습니다. 아래 예시는 8초가 지나면 호출을 중단하고, 실패 종류를 호출자에게 구분해 전달하는 최소 경계입니다.
async function callModel(body) { const c = new AbortController(); const t = setTimeout(() => c.abort(), 8000); try { const r = await fetch(process.env.LLM_API_URL, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body), signal: c.signal }); if (!r.ok) { const e = new Error('LLM HTTP ' + r.status); e.retryable = r.status === 429 || r.status >= 500; throw e; } return r.json(); } finally { clearTimeout(t); } }재시도는 적게, 조건부로 수행합니다
모든 실패에 재시도하는 방식은 장애 중인 공급자와 자신의 서버에 동시에 부하를 더합니다. HTTP 429, 502, 503, 504처럼 일시적일 가능성이 높은 상태와 연결 재설정 같은 네트워크 오류만 재시도 후보로 두는 것이 좋습니다. 인증 오류, 요청 형식 오류, 안전 정책 거절, 입력 길이 초과는 수정 없이 다시 보내도 해결되지 않으므로 즉시 실패 처리해야 합니다.
재시도 횟수는 대화형 요청에서 보통 1~2회면 충분합니다. 각 시도 사이에는 지수 백오프와 무작위 지연을 적용해 같은 시각에 몰린 요청이 다시 한꺼번에 공급자에게 도착하는 현상을 줄입니다. 단, 남은 전체 시간 예산보다 긴 대기 시간은 사용하지 않아야 합니다. 사용자가 결과를 기다리는 요청에서 세 번 이상 재시도하는 것보다, 대체 안내와 재실행 경로를 제공하는 편이 서비스 경험에 유리합니다.
구조화 출력은 반드시 서버에서 검증합니다
분류 결과, 추출 항목, 워크플로 입력처럼 기계가 이어서 처리할 데이터는 프롬프트에 JSON 예시를 넣는 것만으로 충분하지 않습니다. 모델은 설명 문장, 누락 필드, 예상하지 못한 타입을 반환할 수 있습니다. 제공사가 JSON Schema 또는 structured output 기능을 제공하면 우선 사용하고, 서버에서도 스키마 검증을 수행해야 합니다. 모델 응답은 신뢰할 수 없는 외부 입력이라는 전제로 다루는 것이 핵심입니다.
예를 들어 고객 문의를 담당 부서와 우선순위로 분류한다면 허용 값 목록, 최대 문자열 길이, 기본값을 코드에 명시합니다. 검증이 실패한 원문을 바로 업무 시스템에 저장하거나 SQL·셸 명령으로 연결하지 말고, 안전한 재질문 또는 사람 검토 대기열로 보내야 합니다. 특히 도구 호출 결과의 URL, 파일 경로, 권한 관련 값은 별도 허용 목록을 통과시켜야 합니다.
운영 화면에서 확인할 지표를 남깁니다
모델명이나 프롬프트 전체를 무분별하게 로그에 남기면 개인정보와 비용 정보가 섞일 수 있습니다. 대신 요청 ID, 기능명, 모델 식별자, 입력·출력 토큰 수, 소요 시간, HTTP 상태, 재시도 횟수, 검증 성공 여부처럼 운영에 필요한 최소 메타데이터를 구조화 로그와 메트릭으로 남깁니다. 입력과 출력 원문이 필요한 경우에는 민감정보 마스킹, 접근 권한, 보관 기간을 별도로 정합니다.
- p50·p95 응답 시간과 타임아웃 비율을 기능별로 봅니다.
- 429와 5xx 비율을 공급자·모델별로 분리합니다.
- JSON 스키마 검증 실패율을 프롬프트 버전과 함께 추적합니다.
- 재시도 후 성공률과 요청당 평균 비용을 함께 확인합니다.
적용 체크리스트
- 동기 요청과 비동기 작업의 시간 예산을 분리했는지 확인합니다.
- 취소 신호가 LLM 호출까지 전달되는지 점검합니다.
- 재시도 대상 오류와 최대 횟수를 명시했는지 확인합니다.
- 후속 자동 처리 데이터에 서버 측 스키마 검증을 적용합니다.
- 민감 원문을 제외한 지연·오류·비용 지표를 수집합니다.
ai
| No | 작성일 | Title |
|---|---|---|
| 2081 | 2026. 01. 13. | Claude Code Hooks 완벽 가이드 - 자동화된 이벤트 핸들링 |
| 2080 | 2026. 01. 13. | Claude Code Skills 완벽 가이드 - 자동화된 전문 지식 시스템 |
| 2079 | 2026. 01. 13. | Claude Code CLAUDE.md 완벽 가이드 - 프로젝트 설정의 핵심 |
| 1993 | 2025. 11. 30. | AI Agent 개발 - AutoGPT, CrewAI, LangGraph |
| 1992 | 2025. 11. 30. | Fine-tuning vs RAG - 언제 무엇을 선택할까 |
| 1991 | 2025. 11. 30. | AI 코드 리뷰 자동화 - GitHub Actions와 LLM 연동 |
| 1990 | 2025. 11. 30. | Vector Database 비교 - Pinecone, Chroma, Weaviate |
| 1989 | 2025. 11. 30. | AI 이미지 생성 - DALL-E, Midjourney, Stable Diffusion |
| 1988 | 2025. 11. 30. | 로컬 LLM 실행하기 - Ollama와 LM Studio |
| 1987 | 2025. 11. 30. | OpenAI API 활용 - 함수 호출과 Assistant API |