1P by GN⁺ 3시간전 | ★ favorite | 댓글 1개
  • Forge는 자체 호스팅 LLM의 도구 호출을 위한 신뢰성 계층으로, 다단계 에이전트 워크플로우에서 작은 로컬 모델의 안정성을 높이는 데 초점을 둠
  • 핵심 기능은 잘못된 도구 호출을 복구하는 rescue parsing, 재시도 유도, 필수 단계 강제, VRAM 인식 토큰 예산, 계층형 컨텍스트 압축으로 구성됨
  • 현재 상위 자체 호스팅 구성인 Ministral-3 8B Instruct Q8 on llama-server는 26개 평가 시나리오에서 86.5%, 가장 어려운 티어에서 76%를 기록함
  • 사용 방식은 세 가지로, WorkflowRunner로 전체 에이전트 루프를 맡기거나, Guardrails middleware를 기존 오케스트레이션 루프에 넣거나, OpenAI 호환 프록시 서버로 투명하게 적용 가능함
  • WorkflowRunner는 시스템 프롬프트, 도구 실행, 컨텍스트 압축, 가드레일을 관리하며, SlotWorker는 공유 GPU 추론 슬롯에 우선순위 큐와 자동 선점 기능을 추가함
  • 프록시 서버는 python -m forge.proxy로 실행되며, opencode, Continue, aider 같은 OpenAI 호환 클라이언트와 로컬 모델 서버 사이에 들어가 가드레일을 적용함
  • 프록시는 도구가 있는 요청에 합성 respond 도구를 자동 주입해 모델이 일반 텍스트 대신 respond(message="...")를 호출하게 만들고, 응답에서는 이를 제거해 클라이언트에는 정상 텍스트 응답처럼 보이게 함
  • 지원 백엔드는 Ollama, llama-server(llama.cpp), Llamafile, Anthropic이며, llama-server는 최고 성능과 제어를, Ollama는 쉬운 설정을, Llamafile은 단일 바이너리 실행을, Anthropic은 프런티어 기준선과 하이브리드 워크플로우를 담당함
  • 설치는 pip install forge-guardrails로 가능하고, Anthropic 클라이언트는 pip install "forge-guardrails[anthropic]"로 추가하며, 요구 사항은 Python 3.12+와 실행 중인 LLM 백엔드임
  • 평가 하네스는 26개 시나리오로 모델과 백엔드 조합의 다단계 도구 호출 안정성을 측정하며, OG-18 기준 티어와 8개 advanced_reasoning 티어로 나뉨
  • 테스트 구성에는 LLM 백엔드가 필요 없는 865개 결정적 단위 테스트와 실제 백엔드 대상 평가 하네스가 포함됨
  • Forge 가드레일 프레임워크와 ablation study는 Forge: A Reliability Layer for Self-Hosted LLM Tool-Calling로 출판됐으며, 라이선스는 MIT

댓글과 토론

Hacker News 의견들
  • 이 분야 작업을 좋아하고 도움이 되지만, 클라우드 기반 LLM은 피하고 주로 4B~30A3B 매개변수 로컬 모델을 씀
    그래서 최신 LLM 성능이나 정확도 감각은 부족해도, 로컬 모델에서 기대할 수 있는 수준과 병목은 잘 안다고 봄
    글은 대충 훑고 초록을 읽었는데, 간단한 조정으로 10배 빨라지거나 느려질 수 있다는 언급은 있으면서 지표와 데이터는 거의 정확도에만 집중돼 보임. 속도를 다뤄야 함
    특히 에이전트형 워크플로와 로컬 모델에서는 함수/도구 호출 정확도가 개인적으로는 QwenCoder3 무렵부터 지난 6~12개월간 큰 문제가 아니었고, 핵심은 문맥 관리와 시간 영향임. 에이전트가 프롬프트를 자주 바꾸면 프롬프트 캐싱 같은 시간 최적화가 깨짐
    여기에 가드레일과 재시도 같은 계층과 래퍼가 추가되는 듯한데, 로컬 모델에서 특히 에이전트 용도로는 지연 때문에 못 쓸 수준이 될 수 있음
    이미 정면으로 다뤘다면 미안하지만, 시간 영향 이야기가 너무 적어서 실제 개선폭을 숨기거나 부풀리는 것처럼 느껴짐. 속도 경험을 듣고 싶음. 다른 사람들이 이걸 제기하지 않은 것도 조금 걱정되는데, 내가 뭘 잘못하고 있거나 다들 로컬 모델을 실제로 안 쓰는 건가 싶음

  • 제대로 된 하네스만 있으면 작은 로컬 모델도 놀라울 정도로 잘할 수 있다고 계속 말해왔음
    모든 걸 시도할 수 있는 시스템이라면, 그 사이에 틀린 결과를 내지 못하게 막기만 하면 결국 맞힐 수 있음

    • 문제는 주니어에게 무제한 시간을 주고 목표에 도달할 때까지 여러 방식을 계속 시도하라고 했을 때와 비슷한 품질이 나온다는 데 있음
      작업이 충분히 복잡하면 최신 모델도 이 문제가 있고, 작은 모델에서는 더 크게 증폭됨
    • 그 프레이밍이 마음에 듦. 이 작업을 하면서 작은 모델들이 꽤 인상적이었음
      추론도 상당히 괜찮고 많은 경우에는 충분함. 가끔 궤도로 다시 밀어주기만 하면 알아서 풀어냄
    • 제대로 이해했다면, 모델이 맞힐 수 있는 이유는 자신이 틀렸을 때를 알기 때문임
  • 내가 시간을 내서 만들고 싶었던 걸 훨씬 더 잘 만들어줘서 반가움. 질문 하나는, 예를 들어 재시도 루프에서 병렬화 여지가 있느냐는 것임
    로컬 모델은 일반적으로 소비자용 하드웨어에서도 제한된 수, 대략 두 자릿수 정도의 동시 요청을 꽤 잘 처리할 수 있고, 이러면 유효 토큰/초가 10배 이상 오를 수 있음
    이런 걸 활용하는 워크플로를 한동안 생각해왔고, ‘이 오류를 고쳐라’가 완벽하진 않아도 적용처가 될 수 있어 보임. 어떻게 보는지 궁금함

  • 이 영역에서 몇 가지 아이디어가 있어 내 하네스에 넣는 중임. 내 하네스가 꽤 특화돼 있어서 일반화 가능한지는 잘 모르겠음
    문제를 계획된 실행으로 쪼개고, 실행 에이전트가 어떤 도구를 호출할지와 성공 실행 기준 같은 명시적 목표를 포함한 초기 계획을 제공함. 하네스는 그 계획을 순서대로 실행함
    도구 호출이 포함된 각 단계에서는 도구 호출을 구성 요소로 쪼갬. 하네스가 현재 도구 인수에 대해 유효한 매개변수 값을 에이전트에게 물어보고, 도구 정의에는 각 인수별 검증기가 있음. 검증에 실패하면 하네스가 대화를 되감고 실패 이유를 다음 시도에 주입함
    인수에 대한 유효한 응답이 나오면 다음 인수로 넘어가고, 모든 인수가 채워지면 도구를 호출함. 에이전트의 초기 기대값과 실제값, 발생한 오류를 함께 넘기고 결과에 만족하는지 묻음
    만족하지 않으면 에이전트가 이유를 제시하고, 하네스는 대화를 되감아 재시도 이유를 넣은 뒤 도구 호출 과정을 처음부터 다시 시작함
    에이전트는 초기 계획의 결함을 발견하면 재계획을 요청할 수 있고, 하네스도 연속 실패가 너무 많으면 재계획을 시도함
    이 방식은 도구 호출 실패를 줄이는 데 꽤 효과적임. 장점 하나는 하위 에이전트가 실수 없는 완벽한 대화 기록을 받는다는 점임. 다만 실제 작업 완료율이 더 좋은지는 아직 벤치마크하지 않았음

    • 작은 모델 기반 에이전트형 코딩 하네스에서도 비슷한 철학의 실험을 했고, forge 위에 만들었음
      대화 되감기와 관련해서는 주 에이전트, 즉 사용자와 대화하는 에이전트에 비슷한 도구 호출 접기를 구현했음. 작업이 끝나면 도구 호출 기록을 접어서 문맥을 깨끗하게 유지했는데, 크기보다 위생에 가까웠음
      하네스가 모델을 캐묻는 부분은 조금 다르고, 그 접근은 시도해보지 않았음. Forge는 전용 오류 모드를 피하려고 모델의 자기수정에 의존하지만, 스키마 같은 것을 기반으로 질문 과정을 추상화하고 자동화할 수 있다면 가능해 보임
      전반적으로 깨끗한 대화 기록이라는 측면은 좋지만, 인수가 많은 도구에서는 “일단 실패하게 두고 한 번 밀어주기”보다 왕복이 훨씬 많아질 수 있어 보임. 그래도 더 어려운 시나리오나 작업에는 흥미로운 아이디어임
    • Strix Halo를 쓰고 있고 긴 문맥에서 느려지기 때문에 같은 접근을 생각했음. 이 방식이면 1만 토큰 미만 문맥을 유지할 수 있을 듯함
      작은 모델로 50k 토큰/초 이상이 가능하다면 상당히 클 것임
      다만 지금은 회사 일과 다른 프로젝트에 묶여 있어서, 가능한지 보려고 프롬프트 수십 개만 시험해본 상태임
    • 호기심으로 gemma4를 써서 직접 만들고 있는데, 생각보다 멀리 가고 있어서 놀람
  • 훌륭함. 지금은 비용 때문에 로컬 추론은 못 쓰지만, OpenRouter로 작은 모델을 쓸 때 도구 호출이 걱정이었음
    pytest 우선의 인수 테스트 프레임워크 Dokimasia(do-kee-ma-see-ah)를 만들고 있는데 의견을 듣고 싶음: https://github.com/deevus/dokimasia
    인수 테스트가 Forge에 필요한 것은 아닐 수 있지만, AI 도구를 깊게 만들고 있으니 생각이 있을 것 같았음

    • 흥미로운 아이디어임. 본질적으로 AI 생태계에 있는 여러 통합 유형, 예를 들면 MCP나 skills 등을 테스트하기 위한 추상화 계층을 정식화하는 것처럼 보임
      Forge보다 한 단계 위에 있는 듯하고, 실제 워크플로와 그 안에서 드러나는 통합 지점, 예를 들어 어떤 도구가 MCP 접근을 제공하는지를 테스트하는 쪽에 가까움
      둘을 함께 겹쳐 쓰는 것도 큰 문제는 없을 것 같음
      궁금한 건 이런 모델들의 비결정성을 어떻게 다루느냐임. 어떤 때는 도구 호출을 제대로 하고, 어떤 때는 잘못된 JSON을 뱉음. 테스트 모음이 여러 번 시도하나?
  • 도구 호출의 모호성은 최전선 모델 규모에서도 겪음. Claude Code, Codex, Gemini CLI를 매일 병렬로 개발에 쓰는데, 가장 흔한 실패 모드는 grep/find가 종료 코드 1, 즉 일치 항목 없음으로 끝날 때임
    모델이 이를 “검색은 실행됐고 찾지 못했다”가 아니라 “도구가 실패했다”로 읽고, 포기하거나 검색 범위를 넓히는 대신 문법만 살짝 바꿔 재시도함
    재시도-넛지 계층은 내가 한 시간에도 여러 번 수동으로 하는 일과 거의 1:1로 대응함. “아니, 도구 실패가 아니라 그 파일에 그 패턴이 없는 거야. X를 해봐” 같은 것임
    이걸 프레임워크 수준에서 인코딩하는 방향이 맞아 보임
    이런 가드레일이 긴 작업에서 작은 최전선 모델과의 격차를 줄이는지도 봤는지 궁금함. 직감으로는 Sonnet에서 87→99 차이가 약 50단계를 넘어서면 그대로 유지되진 않을 것 같음. 그 이후에는 재시도 의미론보다 문맥 드리프트가 더 지배적이기 때문임

    • 적어도 큰 최전선 모델에서는 확실히 그 지점에서 앞서감. 다만 시간 때문에 그 결과를 정식화하진 못했음
      필요한 단서로, forge는 기술적으로 모델 품질이 아니라 도구 호출 실행에 관심이 있음. 실제 답은 이렇다
      14B급 작은 모델에서 제한 요인은 유효 주의력이었음. 훈련 문맥 창 크기 안에 충분히 들어와 있어도 어느 지점을 넘으면 성능 저하가 보이기 시작함. 정확한 숫자는 없지만 Opus 같은 모델은 그 지점에서 훨씬 오래 계속 갈 수 있음
      언젠가 forge에 직접 써볼 수도 있는 도구 호출 메시지 기록 접기 기능도 만들었음. 본질적으로 메시지 기록을 지능적으로 정리해서 모델이 추적을 덜 잃게 하는 방식임
      그래도 에이전트형 코딩 하네스의 코딩 평가 모음에는 리팩터링 작업과 기능 추가 작업이 있고, 모두 실제 샌드박스 저장소에서 수행됨. 작은 모델도 50~60회 도구 호출까지 밀어붙이면서 그런 작업을 해낼 수 있음. 다만 같은 세션에서 그런 일을 두 개 이상 맡기진 않을 것 같음
  • 조금 다른 이야기지만, Texas Instruments에 있다면 TI Explorer Lisp 머신의 지식재산권 상태가 어떻게 됐는지 알아볼 수 있을지 궁금함
    Genera의 지식재산권 소유자는 알고 있지만, TI의 Lisp OS에 대해서는 알아내지 못했음

    • Genera의 지식재산권은 누가 갖고 있음?
  • “에이전트 안전” 스택을 더 넓게 생각하는 사람들에게는 이 방향이 Kontext의 kontext-cli(github.com/kontext-dev/kontext-cli)나 OneCLI(github.com/onecli/onecli) 같은 것들과 상호 보완적으로 느껴짐

  • “같은 Mistral-Nemo 12B 가중치가 llama-server의 네이티브 함수 호출에서는 7% 정확도, Llamafile의 프롬프트 모드에서는 83%”라는 부분이 있음
    Llamafile은 그냥 모델과 llama.cpp를 단일 바이너리로 묶은 것이라고 생각했는데, 이 차이는 Llamafile이 기본 시스템 프롬프트를 주입하는 것과 원시 llama-server 엔드포인트를 하네스 없이 호출하는 것의 차이인가?
    이건 사과와 애플파이를 비교하는 것처럼 보이고, 중간 재료가 빠져 있음

    • 나도 놀랐음. 글에서는 극단적이지만 실제인 예를 들었음. 이 경우에는 네이티브 함수 호출 템플릿이 작동했을 가능성이 큼
      하지만 그걸로는 Lamaserver 프롬프트와 llamafile 사이의 약 +4%p 차이나, llamaserver 네이티브와 llamafile의 거의 중간에 놓이는 Ollama의 약 +30%p 차이는 설명되지 않음
      서빙 백엔드는 거의 모든 모델 계열에 영향을 줬고, 이 부분은 실제로 거의 이야기되는 걸 본 적이 없었음
  • 이건 진짜 훌륭한 방향임. 1비트 bonsai 모델에서도 말도 안 되게 좋은 결과가 나오고 lmstudio와도 잘 맞음
    이제 남는 장비에 7900XTX를 꽂아 지하실에 두고, 터무니없는 목표를 던져놓은 뒤 잊어버리는 게 완전히 현실적인 일이 됐음