LLM 제공자 어댑터: 스트리밍·도구·폴백 계약 설계

English version

TECH INSIGHT / EXPLAINED

두 번째 LLM을 붙일 때 생기는 문제는 URL 변경보다 응답 의미의 차이입니다. 같은 스트리밍이라도 도구 인자 조립, 종료 신호, 사용량 계산이 다릅니다. 이 차이를 호출부마다 해결하지 않도록 어댑터에 계약을 모읍니다.

세 엔지니어가 다른 연결 단자를 하나의 어댑터로 모으고 응답 조각을 검증한다.
개념을 설명하는 AI 제작 일러스트. 세 엔지니어가 다른 연결 단자를 하나의 어댑터로 모으고 응답 조각을 검증한다.

실제 프로젝트의 로컬 실행 화면

기존 프로젝트의 화면 또는 함수를 로컬에서 실행해 촬영했습니다. 개인정보 없는 샘플 입력을 사용했으며, 실행한 범위는 각 이미지 아래에 설명했습니다.

GoClaw 원본 제공자 관리 화면을 로컬 실행했습니다. Ollama 유형의 샘플 항목과 활성화 상태를 표시한 UI 예시이며, 모델 서버 호출·스트리밍·폴백은 실행하지 않았습니다.
GoClaw 원본 제공자 관리 화면을 로컬 실행했습니다. Ollama 유형의 샘플 항목과 활성화 상태를 표시한 UI 예시이며, 모델 서버 호출·스트리밍·폴백은 실행하지 않았습니다.

공통 계약과 선택 기능을 분리한다

기본 요청·응답 형식에는 메시지, 도구 호출, 종료 상태, 사용량, 제공자 원본 메타데이터를 둡니다. 스트리밍·이미지·도구 호출을 모두 지원한다고 가정하지 말고 모델·endpoint별 능력표로 확인하세요. 필수 기능이 없으면 명시적 오류를 내고, 선택적인 표시 기능만 합의된 방식으로 축소합니다.

어댑터마다 지원 모델·endpoint·미지원 기능을 기록하고 활성화 전에 계약 테스트를 통과시킵니다. 직렬화 변환은 네트워크 전송과 분리하면 저장해 둔 익명화 응답으로 검증할 수 있습니다.

SSE는 data 한 줄이 아니라 이벤트 단위다

표준 SSE에서는 빈 줄이 이벤트를 구분하고 여러 data 줄을 개행으로 합칩니다. 다음 입력은 데이터가 first line\nsecond line인 하나의 이벤트입니다. HTTP 읽기 청크 경계는 SSE 이벤트 경계와도 다릅니다.

event: example
data: first line
data: second line

마지막 data 줄 다음의 빈 줄까지가 이벤트입니다. 위 코드 블록 끝의 빈 줄을 유지해야 하며, 빈 줄 없이 EOF에 도달한 미완료 이벤트는 전달되지 않습니다.

프레이밍 계층이 이벤트를 조립한 뒤 제공자 어댑터가 의미를 해석해야 합니다. Claude 스트림에는 message_stop 종료 이벤트가 있습니다. 연결이 끊어졌다는 사실만으로 정상 완료를 판정하면 중간 실패를 성공으로 오인합니다. 종료·오류·사용량 이벤트를 '텍스트가 없다'는 이유로 버리지 마세요.

도구 인자는 완료 후 검증한다

JSON 문자열 조각이 여러 이벤트로 나뉘거나 서로 다른 도구 호출이 번갈아 올 수 있습니다. 도구 호출 ID와 블록 인덱스로 조립하고 완료 이벤트 후 JSON·스키마를 검증합니다. 원본 ID를 임의로 바꾸면 다음 도구 결과와의 연결이 깨질 수 있으니 원본 ID와 내부 식별자의 대응표를 유지하세요.

Go bufio.Scanner를 쓰면 최대 토큰 크기와 오류를 처리해야 합니다. 무제한 버퍼를 허용하지 말고 최대 이벤트 크기·전체 응답 크기·읽기 시간을 제한합니다. 한도 초과는 명시적 불완전 응답입니다.

교체와 폴백도 접근 정책이다

테넌트 키가 없을 때 공용 키를 쓰는 동작은 자동 편의 기능이 아니라 비용·데이터 처리 정책입니다. 허용된 경우에만 폴백하고 사용한 제공자와 과금 주체를 기록하세요. 실행 중인 요청이 사용하는 이전 클라이언트를 레지스트리 교체 순간 닫지 말고 참조 수나 유예 종료로 수명을 관리합니다. 느린 Close를 전역 잠금 안에서 실행하지 않습니다.

회귀 파일 다섯 개부터

여러 data 줄, 청크 중간에서 나뉜 UTF-8, 두 도구의 교차 조각, 정상 종료 없는 EOF, 텍스트 이후의 usage 이벤트를 각각 fixture로 만드세요. 이 다섯 가지가 '텍스트는 보이는데 최종 응답이 틀리는' 오류를 드러내는 출발점입니다.

참고 자료

내용·예제 검토: 2026-09-29

댓글