포스트

LangChain을 빼면 LLM 앱이 쉬워질까: 직접 HTTP, Token, Schema를 관리하는 비용

LangChain 같은 프레임워크를 빼면 호출 경로는 잘 보이지만, 재시도, 한도, 스키마, 관측성까지 팀이 직접 소유하므로 LLM 앱이 자동으로 쉬워지는 것은 아닙니다.

From Scratch는 모든 것을 다시 짠다는 뜻이 아니다

프레임워크의 추상화가 문제인 순간은 오류가 어느 단계에서 생겼는지 보이지 않을 때입니다. 프롬프트가 어떻게 합쳐졌는지, 몇 토큰이 전달됐는지, 모델 응답이 어느 파서에서 깨졌는지 추적하기 어렵다면 얇은 직접 구현이 더 이해하기 쉽습니다.

반대로 문서 로더, 재시도, rate limit, 여러 모델 어댑터를 이미 안정적으로 제공받고 있다면 이를 모두 새로 만드는 것은 통제권이 아니라 유지보수 부채가 될 수 있습니다. “프레임워크 사용 여부”보다 각 단계의 입력, 출력, 실패를 팀이 설명할 수 있는지가 기준입니다.

직접 관리할 만한 최소 경계는 다음 네 가지입니다.

  • 버전이 붙은 프롬프트와 모델 설정
  • 요청 전에 계산한 토큰 예산
  • 명시적인 HTTP 요청과 응답 기록
  • Pydantic 같은 스키마로 검증한 구조화 출력

나머지 기능은 직접 구현과 검증 비용이 충분히 낮을 때만 안으로 가져오는 편이 낫습니다.

보이는 파이프라인은 실패 지점도 보여야 한다

원문은 tiktoken으로 토큰을 세고, HTTP 호출을 명시하며, Pydantic과 Instructor로 응답 스키마를 검증하는 구성을 제시합니다. 장점은 프롬프트 → 토큰 제한 → 모델 호출 → 파싱이라는 순서를 코드에서 그대로 읽을 수 있다는 점입니다.

다만 토큰이 많을 때 앞부분만 남기는 단순 절단은 중요한 근거를 버리거나 문장, 코드 중간을 자를 수 있습니다. 낮은 temperature도 같은 응답을 보장하지 않습니다. 구조화 출력이 스키마를 통과했다고 내용까지 사실인 것도 아닙니다. 입력 축약 정책, 근거 검증, 실패 응답을 별도 단계로 설계해야 합니다.

원문의 코드는 학습용 스냅샷이지 완전한 운영 예제가 아닙니다. 패키지와 API 버전, 인증, 타임아웃, 재시도와 backoff, rate limit, 스트리밍 중단, 공급자 오류, 로그의 비밀값 제거가 빠져 있습니다. 복사해 “프레임워크 없는 프로덕션 스택”으로 부르기보다 각 누락을 체크리스트로 삼는 것이 맞습니다.

직접 구현하면 새로 맡게 되는 운영 책임

호출 한 번은 짧은 코드로 만들 수 있지만 운영 환경의 상태는 짧지 않습니다.

영역직접 정해야 할 것
신뢰성타임아웃, 재시도 가능 오류, 중복 실행 방지
비용모델별 단가가 아니라 요청별 토큰 예산과 상한
품질프롬프트, 모델 버전별 평가 세트와 회귀 기준
보안로그 마스킹, 데이터 보존, 도구 실행 권한
호환성API와 스키마 변경 시 마이그레이션
관측성요청 ID, 단계별 지연, 파싱 실패 원인

프레임워크가 이 항목을 숨겨 불편했다면 직접 구현은 도움이 됩니다. 하지만 프레임워크가 대신 처리하던 항목을 목록에서 지우면 장애가 났을 때 더 큰 블랙박스가 됩니다. 라이브러리를 줄이는 목표는 코드 줄 수가 아니라 실패를 재현할 수 있는 경계여야 합니다.

두 번 구현해 더 작은 쪽을 고른다

새 프로젝트에서는 대표 요청 하나를 두 방식으로 만들어 비교할 수 있습니다. 프레임워크 버전과 얇은 직접 호출 버전에서 다음을 기록합니다.

  1. 최종 프롬프트와 토큰 수를 재현할 수 있는가
  2. 잘못된 JSON, 429, 타임아웃을 의도적으로 만들었을 때 복구되는가
  3. 모델이나 공급자를 바꾸는 데 어떤 코드가 달라지는가
  4. 신규 개발자가 호출 흐름을 설명하는 데 얼마나 걸리는가
  5. 필요한 기능을 추가할 때 테스트할 표면이 얼마나 늘어나는가

단순한 분류, 추출처럼 호출 경로가 짧고 모델 공급자도 하나라면 직접 HTTP와 스키마 검증이 명료할 수 있습니다. 여러 검색기와 도구, 상태ful 워크플로를 조합하고 이미 프레임워크 운영 지식이 있다면 검증된 구성요소를 남기는 편이 싸게 먹힐 수 있습니다.

결론적으로 From Scratch의 핵심은 프레임워크를 거부하는 태도가 아닙니다. 프롬프트, 토큰, 호출, 검증 중 문제가 생겼을 때 반드시 볼 수 있어야 하는 층을 직접 소유하고, 나머지는 교체 가능한 의존성으로 두는 설계입니다.

토큰 예산은 자르기보다 배분 규칙으로 만든다

컨텍스트 한도를 넘었다고 입력 뒤를 일정 길이로 자르면 질문, 근거와 출력 지시 중 무엇이 사라졌는지 알 수 없습니다. 먼저 시스템 규칙, 사용자 요청, 검색 근거, 대화 기록, 예상 출력에 각각 예산을 배정하는 편이 낫습니다. 초과하면 오래된 대화를 요약하거나 검색 문서를 재선별하고, 필수 근거가 빠질 때는 응답 생성을 중단해야 합니다.

예산은 모델의 최대 컨텍스트만 보고 잡지 않습니다. 긴 입력은 비용과 지연을 늘리고 중요한 단서가 묻힐 수 있습니다. 운영 로그에는 입력 구성요소별 토큰 수, 잘린 항목, 모델이 실제로 받은 최종 메시지와 출력 상한을 남겨야 합니다. 개인정보나 비밀값 때문에 원문 로그를 보관할 수 없다면 해시, 길이, 문서 ID처럼 재현에 필요한 최소 메타데이터를 사용합니다.

모델을 바꿀 때 tokenizer도 달라질 수 있습니다. 한 공급자의 토큰 계산을 다른 모델에 그대로 적용하지 말고, 해당 API가 제공하는 사용량과 사전 계산 오차를 비교합니다. 예산 초과가 발생했을 때 자동으로 더 비싼 장문 모델로 올리는 정책은 편리하지만 비용 상한과 사용자 동의 없이 적용하면 예측 불가능한 청구로 이어질 수 있습니다.

구조화 출력은 문법, 의미, 근거의 세 단계로 검증한다

Pydantic 스키마가 보장하는 것은 필드와 타입이 기대한 모양이라는 점입니다. 날짜 문자열이 실제 달력에 유효한지, 상품 ID가 데이터베이스에 존재하는지, 요약의 수치가 제공된 문서와 일치하는지는 별도 검사입니다. 따라서 JSON 파싱 성공을 곧바로 업무 성공으로 기록하면 안 됩니다.

첫 단계는 JSON과 필수 필드 검증, 두 번째는 범위, 상호 제약 같은 도메인 검증, 세 번째는 원자료와의 근거 검증입니다. 예를 들어 환불 요청이라면 금액이 0보다 큰지만 볼 것이 아니라 주문 잔액 이하인지 확인해야 합니다. 모델이 근거 문서 ID를 함께 반환하게 하고 허용된 ID인지 검사하면 추적성이 좋아집니다.

검증 실패 때 같은 프롬프트를 무한 재시도하지 않습니다. 오류 종류와 잘못된 필드를 짧게 알려 한두 번 수정 요청하고, 계속 실패하면 사람이 처리하거나 보수적인 기본 경로로 보냅니다. 쓰기 작업은 스키마가 맞아도 승인 전에는 실행하지 않는 경계를 유지합니다.

재시도는 네트워크 오류와 업무 실행을 구분한다

429와 일시적인 5xx는 backoff 뒤 재시도할 수 있지만, 이미 외부 도구가 결제, 메일, 티켓 생성을 수행한 뒤 응답만 끊겼다면 같은 요청을 반복하면 중복이 생깁니다. 모델 호출과 도구 실행에 idempotency key를 붙이고, 재시도 전에 이전 결과를 조회할 수 있어야 합니다. 파싱 실패는 공급자 장애와 다른 정책으로 다룹니다.

스트리밍도 예외가 아닙니다. 일부 문장을 사용자에게 보낸 뒤 연결이 끊기면 처음부터 재생성한 답이 앞부분과 달라질 수 있습니다. 표시한 범위, 완료 상태와 재개 정책을 명확히 하고, 구조화 응답은 전체 검증 전까지 실행 입력으로 사용하지 않는 편이 안전합니다.

간단한 직접 호출 래퍼라도 timeout, 재시도 대상 상태 코드, 최대 시도 수, circuit breaker와 전체 요청 마감 시간을 설정해야 합니다. 각 공급자 SDK가 이미 검증한 동작을 다시 구현할 때는 코드가 짧다는 이유보다 실패 테스트가 충분한지를 기준으로 삼아야 합니다.

관측성과 평가가 없으면 얇은 코드도 블랙박스다

한 요청을 추적할 수 있는 ID를 사용자 입력, 검색, 모델 호출, 파서와 도구 실행에 이어 붙입니다. 단계별 지연, 모델, 프롬프트 버전, 입력, 출력 토큰, 검증 실패 이유와 재시도 횟수를 기록하면 비용 급증과 품질 회귀를 같은 사건으로 조사할 수 있습니다. 원문 프롬프트를 저장할 수 없는 환경에서는 민감정보를 제거한 템플릿 버전과 입력 ID를 남깁니다.

평가는 실제 업무에서 익명화한 대표 사례와 실패 사례로 만듭니다. 정상 답변만 모으면 빈 검색 결과, 충돌하는 근거, 긴 문서, 잘못된 JSON과 API 시간초과를 놓칩니다. 변경 전후에 정확도뿐 아니라 거부해야 할 때 거부하는 비율, p95 지연과 요청당 비용을 비교해야 합니다.

프레임워크를 뺀 뒤 장애 원인 파악 시간이 줄고 테스트 표면이 관리 가능하다면 직접 구현의 가치가 있습니다. 반대로 공급자 추가 때마다 인증, 스트리밍, 오류 매핑을 다시 고친다면 작은 내부 인터페이스 뒤에 검증된 SDK나 프레임워크 어댑터를 남기는 편이 더 투명할 수 있습니다.

원문과 버전 확인

함께 읽으면 이해가 이어지는 글

자주 묻는 질문

LangChain을 제거하면 LLM 응답 품질이 좋아지나요?

자동으로 좋아지지 않습니다. 호출 경로를 더 잘 관찰할 수는 있지만 품질은 프롬프트, 근거, 모델, 평가 방식에 좌우됩니다.

프레임워크 없이 가장 먼저 직접 소유할 부분은 무엇인가요?

최종 프롬프트와 모델 설정, 요청별 토큰 예산, 구조화 출력 검증, 요청 ID가 연결된 오류 기록부터 소유하는 편이 좋습니다.

직접 구현과 프레임워크 유지 중 무엇이 더 저렴한가요?

대표 요청과 장애 시나리오를 두 방식으로 구현해 변경 시간, 운영 인력, 호환성 테스트까지 비교해야 판단할 수 있습니다.

THE END / OPSOAI

여기까지 읽었습니다

핵심 장면을 한 번 더 떠올려 보세요. 이해가 남았다면 이 책은 제 역할을 다했습니다.

다른 책 고르기
표지 1 —

←→ 키와 좌우 스와이프를 지원합니다. 읽던 페이지는 이 기기에 저장됩니다.

CONTENTS

이 책의 목차

    12개 장 19 분읽는 시간