본문 바로가기

EP 빌드로그

EP.22 허브가 스스로 판단하게 만든 첫 단계: 2-모델 긴급도 판정

이번 회차 요약: 판단은 넘기되, 조치는 코드가 쥔다

이전까지 개선 루프에는 결정론 방식의 triage인 propose.py까지만 있었습니다. 결정론 triage로 상위 문제까지는 뽑았지만, "이게 얼마나 급한가"라는 긴급도 판단은 여전히 사람 몫이었죠.

오너의 아이디어는 "허브가 알아서 판단·조치"였습니다. 이번 1단계는 그 아이디어를 안전 설계로 옮긴 첫 단계로, 이 회차에서는 긴급도 판정과 알림만 구현했고 자동 수정은 넣지 않았습니다. 판단(긴급도)과 조치(자율화)를 분리해, 판정·알림까지만 하는 형태로 착지시킨 셈입니다.


왜 두 모델인가: 만드는 놈과 채점하는 놈을 나눈다

루프 엔지니어링에는 검증 단계가 필요합니다. 핵심 원칙은 "만드는 쪽과 채점하는 쪽을 분리"하고, 판단에 다양성을 확보하는 것입니다.

그래서 improvement_judge.py는 상위 문제에 대해 GPT와 Claude 두 모델에게 각각 긴급도(A/B/C)를 물어 교차 판정합니다. 한 모델의 편향이나 오탐을 다른 모델이 견제하도록 한 구조입니다.

  • Claude: anthropic SDK 사용, 모델은 환경변수로 override 가능
  • GPT: openai SDK 사용, 모델은 환경변수로 지정
  • API 키: 공용 정본 .env(RULE-009), SDK는 지연 import

합의 규칙: 만장일치일 때만 강하게 움직인다

두 모델의 답을 하나로 합치는 consensus() 규칙은 단순하지만 의도가 분명합니다.

AAA (알림)
CCC (폐기)
ACB (conflict 태그)
그 외 조합-B

정리하면 알람은 만장일치(A), 폐기도 만장일치(C), 이견은 B로 착지시킵니다. A↔C처럼 강한 이견은 conflict 태그를 붙여 남깁니다. 이렇게 하면 한쪽으로 쏠린 오탐도, 급한 신호를 놓치는 유실도 함께 줄일 수 있다는 게 이번 설계의 판단입니다.


절대 안 죽는 폴백 설계

LLM 호출은 언제든 실패할 수 있습니다. 그래서 실패를 등급 강등으로 흡수하도록 설계했습니다.

  • 한쪽 API 실패 → 최대 B로 제한
  • 둘 다 실패 → 결정론 폴백으로 처리, 루프는 절대 죽지 않음

A(가장 급함)는 두 모델이 모두 살아서 모두 A라고 할 때만 나옵니다. 즉 불확실할수록 조용해지는 방향으로 기울여 두었습니다.


돈에 닿는 경로는 LLM에 안 맡긴다 (RULE-002)

이번 단계에서 가장 중요한 안전 장치입니다. propose.pyENABLE_HUB_LLM_JUDGE(기본 off)가 켜졌을 때만 상위 N개를 판정하고 A 알림을 보내며 등급 태그를 표기합니다. collect.pypropose.py 자체는 stdlib만 유지합니다.

기본값을 off로 둔 이유는 LLM 호출이 유료 크레딧을 쓰기 때문입니다. 그리고 무엇보다, 이번 단계는 판정·알림까지만이고 자동 수정은 하지 않습니다(RULE-002).


배운 점: 자동화를 두 축으로 쪼갠다

자가발전 루프의 안전 열쇠는 "무엇을 자동화하는가"를 두 축으로 나누는 것이었습니다.

  • 긴급도: LLM이 판단, 알림 속도를 결정
  • 자율화 등급: 코드가 판단, 돈에 닿는지를 결정

위험도 판단을 LLM에 맡기지 않고 코드(경로·키워드)로 고정했기 때문에, A로 판정된 급한 문제라도 돈 경로에서는 자동 수정을 하지 않습니다. 설계 정본은 ai-automation-control/docs/improvement-loop-design.md에 두었고, 이번 범위에서 테스트는 8건입니다.

다음 과제: 설계 문서에는 2·3단계가 등급0 자동수정, 등급1 원클릭, 등급2 영구 사람 게이트로 정의되어 있습니다. 이번 단계는 관찰과 알림까지이며, 등급별 조치는 문서상 다음 단계 항목으로 정의된 상태입니다.

반응형