8B 모델이 도구 호출(Tool-calling)을 안정적으로 수행하도록 만드는 GBNF 문법 컴파일러를 제작했습니다 - 작동 원리 심층 분석
요약
8B 규모의 소형 모델이 도구 호출(Tool-calling) 시 발생하는 JSON 형식 오류를 해결하기 위해 GBNF 문법 컴파일러를 활용하는 방법을 소개합니다. JSON Schema를 GBNF 규칙으로 변환하여 샘플러 단계에서 문법을 강제함으로써 출력의 신뢰도를 높이는 기술적 접근을 다룹니다.
핵심 포인트
- GBNF를 사용하여 특정 도구의 JSON Schema를 문법 규칙으로 컴파일
- 샘플러 단계에서 유효한 키, 타입, 열거형 값을 강제하여 오류 방지
- 시맨틱 라우터를 통해 현재 턴에 필요한 도구로 문법 범위를 제한
- 소형 모델(8B)에서도 높은 도구 호출 신뢰도 확보 가능
저는 llama.cpp에서 실행되며 Obsidian 호환 보관소(vault)를 메모리로 사용하는 Rust 기반의 로컬 에이전트(Eris)를 구축해 왔습니다. 약 50개의 도구(보관소 읽기/쓰기, 메모리, 리마인더, 웹 페치, 이메일, 캘린더, 비전)를 포함합니다. 가장 큰 고충은 작은 모델들이 유효한 도구 호출(tool-calling) JSON을 출력하도록 만드는 것이었습니다. 여러분도 잘 아시다시피, 모델이 JSON을 코드 펜스(code fences)로 감싸거나, 도구 이름을 지어내거나, 닫는 중괄호를 잊거나, 객체 뒤에 불필요한 설명을 덧붙이는 등의 문제가 발생합니다.
저의 해결책은 다음과 같습니다: 세션 시작 시 각 도구의 JSON Schema를 GBNF 규칙으로 컴파일합니다. 이렇게 하면 샘플러(sampler)가 단순히 '유효한 JSON'뿐만 아니라, '해당 특정 도구에 정확히 맞는 키, 타입, 열거형(enum) 값을 가진 유효한 JSON'을 강제하게 됩니다. 그 후 각 LLM 호출 전에, 시맨틱 라우터(semantic router)가 이번 턴에 매칭한 도구들로만 문법을 좁힙니다. 8B 모델이 50개 대신 3개의 도구 사이에서 선택하게 되면 훨씬 더 신뢰도가 높아집니다.
프로젝트의 실제 코드를 포함하여 이 모든 것이 어떻게 작동하는지에 대한 상세한 기술 포스트를 작성했습니다: https://eris-system.dev/blog/gbnf-grammars. 4080(16GB VRAM)에서 Gemma 4 12B를 실행 중입니다. 채팅 + 약 32k 컨텍스트 + 비전 용도로 매우 잘 작동합니다. 저장소: https://github.com/janpauldahlke/eris (Apache 2.0). 문법 컴파일러, 복구 루프(recovery loop) 또는 아키텍처에 대한 질문은 언제든 환영합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 r/LocalLLaMA의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기