0명이 블로그에 접속중
2026-10-31 · LLM · SELF-HOSTED

셀프호스팅 기억 엔진 대정비 - 9모델 전쟁, 좀비 크론, 그리고 '캡은 보험일 뿐' 철학

TL;DR

  • 셀프호스팅 기억 엔진(Honcho)의 회상 회로(dialectic)를 3일간 총망아 교체했다: 9모델 실측 전쟁 → 좀비 크론 사고 → 설정 철학 전쟁
  • 최종 아키텍처: 기록은 glm-5.3-flash(정액 무료), 일상 회상은 haiku-5.5(실측 $0.0135/회), 깊은 조사(max)만 glm-5.3+thinking MAX(무료, 실측 178초)
  • 캡(턴수·출력 토큰)은 절약 도구가 아니라 발산 방지 보험이다 - 서버 허용 최대치로 통일하는 게 정답이었다
  • 가장 큰 교훈: 소스 기본값에는 "레벨별로 다른 모델"이라는 숨은 가정이 있다. 그 가정을 깨는 순간 기본값은 독이 된다

배경: 벤치 승리로 끝이 아니었다

지난 글에서 셀프호스팅 Honcho의 회상 백엔드 6-way 실측으로 haiku-5.5가 승리했음을 적었다. 그런데 벤치 우승은 시작의 절반이었다. 운영 적용 → 사고 → 설정 원칙 정립까지 가야 끝나는 게 자기 서버 관리다. 이 글은 그 후반전 기록이다.

9모델 전쟁의 전체 성적표

동일 프로토콜(3-팩트 회상 × 10회)로 실제 dialectic 파이프라인을 돌린 결과:

실험 모델 결과 판정
EXP3 recursive/flint-v1.0:free 정확도 71% 무료의 대가 - 비추천
EXP3b mistral-nemo ($0.03/M) 팩트 0% (합성 실패) 미채용
EXP3c nemotron-3-ultra-550b (로컬 게이트웨이) 120s 타임아웃 5/9 단일호출 안정성이 다중호출에서 증폭 붕괴
EXP3d qwen3.5-flash "정보 없음" 정직 거절로 스크리닝 탈락 → 컨텍스트 있으면 달라진다는 교훈으로 haiku 재검증 트리거
EXP3e haiku-5.5 20.9s · 팩트 30/30 · $0.0135/회 👑 우승
EXP3f haiku + Anthropic 네이티브 캐싱 캐싱 무효 cache_control 마커가 system에만 붙어 본류 미커버
EXP3g gpt-6-luna 13.7s 신기록, 비용 18% 품질 미달 - 속도 왕은 의미 없음
EXP3h haiku + thinking off 13.1s지만 정확도 100→62% thinking이 합성 품질의 핵심임을 실증

개인적으로 가장 인상 깊었던 건 EXP3e의 메타 정직성이다. 회상 답변에서 "F1 0.92라는 수치는 Honcho 실험 프롬프트에 적힌 문구다"라고 출처를 스스로 식별하고 내 발언과 구분했다. 없는 걸 지어내지 않는 성향이, 16K 기억 컨텍스트가 실리는 환경에선 정확성으로 승화됐다.

그리고 실험 전체를 관통하는 교훈: 단발 스크리닝 ≠ 파이프라인 성능. 원샷 3.8s짜리 free 모델이 16K 컨텍스트 dialectic에선 평균 86s·타임아웃 20%였다. 모델 선정은 반드시 실제 부하로 e2e 10회를 돌려야 한다.

좀비 크론: 자동화가 자기 설정을 되돌리는 사건

벤치 내내 가장 소름 돋는 장면. 실험 감시용으로 만들어뒀던 n8n 게이트가 흐지부지 종료됐는데, 그 안의 5분 크론이 아직 살아 있어서 밤 9시 20분에 스스로 부활해 진행 중인 실험의 .env를 "복구"(=되돌리기)했다. 재현 중인 실험이 원래 없던 설정으로 Kill 당하는 것.

대응은 원천 차단이 정답이다:

  1. n8n 정지 + 좀비 실행 전수 삭제 (잔좀비 스캔 포함)
  2. .env에 chattr +i (immutable) - 파일 단위 방화벽
  3. 벤치 인프라는 n8n → Windmill 이식 (Postgres durable 큐·스텝 단위 병렬)

교훈: 자동화의 감시자는 반드시 수명을 갖혀야 한다. 일회성 작업의 게이트가 무기한 크론으로 남으면, 언젠가 그게 주인을 문다.

적용 단계의 함정 2종

  1. API 키 경로: MODEL_CONFIG__API_KEY_ENV는 조용히 무시된다. 반드시 OVERRIDES__API_KEY_ENV. 증상은 401인데 원인은 설정 위치라 디버깅이 오래 걸렸다
  2. thinking 캡: haiku에서 thinking을 끄면 위 표대로 62% 붕괴. "기본값이 최적"이라는 걸 주석으로 못 박아둠

검증 도구의 함정

설정을 바꿨는데 진짜로 적용됐는지 확인하는 것도 함정 투성이었다.

  • docker exec -e VAR=x로 오버라이드 테스트가 안 통한다 - 앱이 기동 시 load_dotenv(override=True)로 마운트된 /app/.env를 항상 이긴다. 실효값 확인은 컨테이너 안에서 직접 settings를 introspect하는 수밖에 없다
  • env에 MAX_OUTPUT_TOKENS=null(전역 폴백 의도)을 쓰면 env_parse_none_str 미설정 탓에 검증 크래시로 서버가 안 뜬다. 동값 명시가 정답

소스 기본값의 숨은 가정: 턴 사다리 역전

Honcho dialectic 레벨(minimal~max)의 소스 기본 턴수는 1/5/2/4/10이다. low가 medium보다 2.5배 많은, 단조도 아닌 사다리. 최초 도입 커밋을 뒤져보니 답이 있었다:

# TODO: Fill in appropriate values for each reasoning level

개발자 본인도 손튜닝 임시값임을 남긴 코드. 그리고 이 값들의 전제는 레벨마다 다른 모델+thinking이다(원래 low=싸고 빠른 flash 모델이 검색을 5번 돌리는 티어). 나는 9모델 전쟁에서 모델을 통일했으니, 남는 건 턴수뿐 - 그 순간 사다리는 역전된 채로 굴러간다. "레벨을 올릴수록 좋아진다"는 기대가 설정값으로는 성립 안 되는 구조.

캡 철학: 보험은 모델 한계 근처에

여기서 내 원칙을 확정했다: 캡은 절약 도구가 아니라 발산 방지 보험이다.

  • output 토큰 캡을 낮춰도 절감은 0이다. 과금은 실제 생성분만 청구되고, 잘리는 순간 input+thinking 비용은 물고 답변 0개로 끝난다 - OpenAI·Anthropic·Gemini 공식 문서가 전부 같은 경고를 한다. Gemini는 아예 "max_output_tokens 줄이지 말고 thinking 레벨을 낮춰라"라고 쓰여 있다
  • haiku-5.5의 공식 max output은 128K. 다만 Honcho 설정 검증이 le=100000이라 100000이 서버 허용 최대치 → 전 레벨 100000 통일 (128000을 걸면 서버가 부팅을 거부한다)
  • 턴수도 같은 논리. 설정 검증 상한 le=50(툴 루프 하드캡 100)이니 전 레벨 50 통일. 요즘 모델은 adaptive하게 1~3턴에 스스로 종료하니 실제 지출은 그대로고, 50은 순수하게 최악성기 상한이다

출발점은 이 믿음이다: 요즘 모델은 적당한 추론과 적당한 턴수를 스스로 잘 고른다. 그렇다면 캡은 모델을 가르치는 도구가 아니라, 폭주할 때만 잡아주는 안전망이어야 한다.

effort 기본값은 명시돼 있다 (그런데)

"haiku는 thinking 기본이 최적"이라고만 알고 있었는데, 기본이 정확히 뭔지 조사했다. 공식 문서 답변: haiku-5.5(·opus 5.5)의 기본 effort는 medium - 그 외 모델은 high. thinking은 항상 켜져 있다(adaptive).

재미있는 건 다음 실측 모순이다. 공식은 "기본값을 명시하는 것과 생략은 완전히 동일하다"는데, dialectic 실측에서 effort medium 명시 96.8s vs 생략 20.9s - 4.5배 차이가 났다. adaptive의 본질은 "생각할지 말지부터 모델이 자판"하는 건데, effort를 명시하는 순간 그 자판이 고정되는 것으로 추정한다. 어느 쪽이든 미지정 유지가 정답이라는 결론은 더 단단해졌다.

최종 아키텍처와 비용

역할 모델 비용 실측
기록 (deriver/summary/dream) glm-5.3-flash + thinking max 정액플랜 무료 상시
일상 회상 (low) haiku-5.5 (thinking 미지정) $0.0135/회 15~21s
깊은 조사 (max) glm-5.3 + thinking MAX 무료(정액) 178s
검색 임베딩 qwen3-embedding:4b 로컬 Ollama 무료 -

daily 회상은 저렴하고 빠르게, "진짜 파고들어라" 요청은 무료 슬로우 티어로 보내는 구조. 턴수 50·출력 100000은 전 구간 공통 보험이다.

남은 것

  • 턴별 자동 주입(perTurn) OFF 2주 실험 - 11/13쯤 재평가
  • Honcho v3.0.3 → v3.0.9 (145커밋) 업그레이드 - 빌드·마이그레이션 이슈로 계속 보류 중

총정리: 남에게도 통하는 교훈

  1. 모델 벤치는 실제 파이프라인 부하로 e2e 10회. 단발 스크리닝은 오답을 낳는다
  2. 자동화 파이프라인엔 수명을 걸어라. 살아남은 크론은 언젠가 설정을 되돌린다
  3. 소스 기본값엔 가정이 숨어 있다. 그 가정을 깨는 배포(예: 모델 통일)를 하면 기본값을 다시 심사한다
  4. 캡은 보험이다. 보험료(필요량)를 계산해서 모델 한계 근처에 걸어라, 아슬아슬하게가 아니라
  5. 설정 검증은 앱의 실효값으로. env 변수 오버라이드는 dotenv override=True 앞에서 무력화된다
comments (0)
COUNTER
001065
TOTAL VIEWS
0007
TODAY