
LLM을 사용하는 도구를 '테스트 가능한' 상태로 유지하는 설계: 탐지는 규칙(Rule), 설명은 LLM으로 분리
요약
LLM 기반 도구의 비결정론적 특성을 극복하기 위해 탐지 로직과 LLM 설명을 분리하는 설계 방식을 제안합니다. 탐지는 규칙 기반으로 고정하여 테스트 가능성을 확보하고, LLM은 결과의 풍부화(Enrichment) 용도로만 사용하여 시스템의 안정성을 높입니다.
핵심 포인트
- 탐지(Rule)와 설명(LLM)의 분리를 통한 테스트 가능성 확보
- CI 환경에서 결과의 일관성을 유지하기 위한 결정론적 설계
- LLM 장애 시에도 기본값으로 작동하는 Fail-soft 구조 구현
- 성능 저하를 인지할 수 있도록 명시적인 오류 로그 기록 필요
공개 리포지토리: https://github.com/mabuix/iac-guard
지난번(기사 ①)에는 Terraform의 비용/보안 문제를 지적하는 도구인 iac-guard의 전체적인 모습을 작성했습니다. 이번에는 그중에서 가장 고민했던 부분, "LLM을 사용하고 있음에도 어떻게 테스트 가능한 상태를 유지할 것인가"를 깊이 있게 다룹니다.
AI 도구의 가장 큰 고민거리
LLM을 도입한 도구를 작성할 때 무서운 점은 매번 출력이 달라진다는 것입니다. 동일한 입력이라도 문구가 흔들리고, 네트워크나 API의 상태에 따라 실패하기도 합니다. 이대로라면 "이 도구가 제대로 작동하고 있는가?"를 자동으로 확인할 수 없습니다.
iac-guard는 문제를 "탐지(Detection)\
if errCount > 0 {
fmt.Fprintf(os.Stderr,
"llm enrichment failed for %d/%d findings (using rule defaults); first error: %v\n",
...
교훈은 "조용히 성능 저하(Degradation)가 발생하면, 성능이 저하되었다는 사실조차 인지할 수 없다"는 것입니다. Fail-soft(장애 시 기능 축소)와 오류를 묵인하는 것은 엄연히 다르다는 당연한 사실을 뼈저리게 깨달았습니다.
분리함으로써 얻은 것
- 테스트 가능 (Testable): 탐지(②)는 LLM 없이 입출력이 고정됩니다. 따라서 정밀도(Precision)/재현율(Recall)에 대한 평가(Eval)를 그대로 작성할 수 있습니다.
- CI에서의 안정성:
--llm옵션이 없다면 매번 동일한 결과가 나옵니다. CI(지속적 통합) 결과가 흔들리지 않습니다. - API 키 없이 작동: 누구나
go install을 통해 즉시 테스트해 볼 수 있습니다. - 외부 API가 중단되어도 작동: LLM이 작동하지 않더라도 규칙 기본값(Rule defaults)에 따라 결과가 출력됩니다.
"AI를 통합한다"고 하면 모든 것을 LLM에 의존하고 싶어지지만, 확실하게 수행할 수 있는 부분은 코드로 처리하고, LLM은 "사람이 읽었을 때 유용한 문구"를 만드는 데 집중해야 합니다. 이러한 경계 설정이 추후 테스트와 운영을 훨씬 수월하게 만들어 주었습니다.
요약
- 탐지는 결정론적(Deterministic)으로 고정하고, LLM은 사후에 덧붙이는 풍부화(Enrichment) 레이어로 분리합니다.
Analyzer인터페이스를 통해 교체 가능한 구조로 만들고, 기본값은 오프라인 Mock으로 설정합니다. LLM이 실패하더라도 기본값을 반환하되, 조용히 성능 저하를 일으키지 말고 실패를 로그에 남겨야 합니다.
다음 글에서는 ②의 "규칙을 통한 탐지"의 토대가 되는 Go를 이용한 HCL 정적 분석( .tf 파일에서 속성을 안전하게 추출하는 방법)에 대해 작성할 예정입니다.
코드는 여기에서 확인하세요 👉 https://github.com/mabuix/iac-guard
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기