본문으로 건너뛰기

중복 규칙을 버리는 AST 린터 설계

poly는 기존 린터와 겹치지 않는 AST 규칙만 실제 코드 corpus로 검증해 배포 여부를 결정합니다.

이 요약은 AI가 원문을 분석해 생성했습니다. 정확한 내용은 원문 기준으로 확인하세요.

TL;DR

작성자는 ruff, oxc, biome, mago를 라이브러리로 결합하고 ast-grep 규칙을 더한 linter poly에서, 기존 백엔드가 이미 검사하는 규칙은 중복 배제하는 품질 기준을 적용합니다. ruff의 22개 selector group과 oxlint 설정이 이미 많은 AI 생성 코드 문제를 포괄하므로, assertion 없는 테스트나 전체가 NotImplementedError인 함수처럼 실제 미검출 항목만 남겼습니다. 26개 규칙 중 13개는 비활성 상태이며, Rust의 todo!() 규칙은 324건 중 320건이 생성된 FFI glue에서 나와 실제 코드 적용성이 낮았고 다른 규칙은 5,475건 중 94.4%가 벤더 FFI 바인딩에 몰렸습니다. 규칙의 문법적 정확성보다 생성 파일, 외부 바인딩, 테스트 디렉터리처럼 독자가 소유하지 않는 경로를 걸러 실제 corpus에서 활성화 여부를 판단하는 일이 더 중요하다는 결론입니다.

실용적 조언

  • 기존 toolchain 위에 guardrail을 추가할 때는 먼저 각 백엔드가 담당하는 metric과 규칙을 언어별 표로 정리해야 합니다. 이미 검사하는 지표에 새 AST 규칙을 덧붙이지 말고 deferral로 제외해야 같은 코드 줄에 중복 경고가 쌓이지 않습니다. 이렇게 남은 미검출 영역만 규칙 후보로 삼아야 유지보수 범위와 출력량을 줄일 수 있습니다.
  • 새 규칙은 샘플 코드가 아니라 실제 저장소 corpus에서 생성 파일, 벤더 바인딩, 테스트 경로를 구분해 측정해야 합니다. 모든 finding이 문법적으로 정확해도 관리 대상이 아닌 경로에 몰리면 기본값을 비활성으로 두어야 합니다. 규칙 파일 안에 발생 건수, 표본의 실제 결함 비율, 코드 소유권별 분포를 기록하면 활성화 판단을 재현할 수 있습니다.

섹션별 상세

01
작성자는 ruff, oxc, biome, mago를 셸 명령으로 호출하지 않고 라이브러리로 컴파일한 linter에 ast-grep 규칙 팩을 얹었습니다. 규칙 팩은 컴파일되지만 구현이 비어 있는 함수, assertion이 없는 테스트, 조용히 버려지는 오류, 이유 없는 suppression comment처럼 agent output에서 생기는 실패 유형을 겨냥합니다. 다만 ruff의 C901과 PLR0913, oxlint의 max-depth와 max-params처럼 tier-1 backend가 이미 다루는 지표는 언어별 deferral table로 제외합니다. 이 방식은 같은 줄에 중복 finding을 내보내지 않지만, 처음 만들고 싶은 규칙 대부분을 포기해야 한다는 비용도 동반합니다.
02
ruff 기본 설정만으로 22개 selector group이 활성화되어 stray print, 예외 처리 오류, try/except/pass, 복잡도 문제를 이미 포착합니다. oxlint도 correctness, suspicious, pedantic, complexity를 켜면 no-debugger, no-console, no-explicit-any와 @ts-expect-error 설명 요구까지 검사합니다. 따라서 작성자가 스케치한 대부분의 AI slop detector는 기존 도구와 겹쳤고, JavaScript와 TypeScript에서는 assertion 없는 테스트 본문과 throw new Error("Not implemented")만 있는 함수, 빈 .catch(() => {})가 미검출 영역으로 남았습니다. Python에서는 assert와 pytest.raises가 없는 test_ 함수, abstract method가 아닌 곳의 전체 raise NotImplementedError가 같은 범주에 들어갑니다.
03
규칙을 작성하는 것보다 기본 활성화 여부를 정하는 과정에 실제 corpus 측정값을 붙였습니다. Rust의 todo!()와 unimplemented!() 규칙은 324건을 냈지만 320건이 생성된 FFI glue에 있었고, 수동 작성 코드의 4건 중 3건만 실제 stub이며 1건은 mock이었습니다. 그 결과 4건 표본에서 계산된 25% 오탐률만으로 규칙을 켜지 않았습니다. 다른 규칙은 모든 finding이 safety comment 누락으로 정확했지만, 테스트와 생성 경로를 제외한 5,475건 중 94.4%가 벤더 FFI 바인딩에 몰리고 first-party 코드는 약 1%여서 비활성 상태로 남겼습니다.
04
생성 파일, 벤더 바인딩, 테스트 디렉터리에서 발생하는 noise는 코드 패턴보다 경로와 소유권에 더 크게 좌우됩니다. AST 패턴만으로는 생성 결과가 아닌 코드나 독자가 관리하는 경로라는 조건을 표현하기 어렵기 때문에, 문법적으로 맞는 finding도 실제 수정 작업으로 연결되지 않을 수 있습니다. 작성자는 26개 규칙 가운데 13개를 끈 채 각 규칙 파일에 판단 근거가 된 corpus 수치를 기록했습니다. 모든 규칙을 배포하는 대신 측정 결과가 부정적이면 배포하지 않는 태도가 agent guardrail의 핵심 기준으로 남습니다.

용어 해설

린터(Linter)
소스 코드를 규칙과 대조해 오류, 위험한 패턴, 품질 문제를 찾아내는 정적 분석 도구입니다. 이 글에서는 여러 언어용 백엔드를 결합해 AI agent가 만든 코드의 빈 구현과 무의미한 테스트를 포착하는 데 쓰입니다.
AST 기반 패턴 검색(ast-grep)
텍스트 문자열이 아니라 추상 구문 트리의 구조를 기준으로 코드 패턴을 찾는 도구입니다. poly는 ast-grep 규칙 팩을 추가해 함수 전체가 예외만 던지는 구현이나 assertion 없는 테스트처럼 기존 린터가 놓치는 구조를 검사합니다.
오탐률(False Positive Rate)
문제가 아닌 코드를 문제로 판정한 비율입니다. 글에서는 Rust 코드의 4개 수동 작성 사례 중 1개가 mock이어서 25%가 나왔지만, 표본이 4개뿐이므로 규칙 활성화의 근거로 충분하지 않다고 판단합니다.
벤더 제공 FFI 바인딩(Vendored FFI Bindings)
외부 프로젝트나 생성기가 제공해 저장소에 함께 포함된 언어 간 호출용 연결 코드입니다. 실제 소유자가 수정하는 first-party 코드와 달리 경고를 읽는 개발자의 관리 대상이 아닌 경우가 많아, 패턴이 맞아도 실용적인 조치 대상으로 이어지지 않을 수 있습니다.

언급된 도구

ruff중립

Python 코드의 출력, 예외 처리, 복잡도와 같은 정적 품질 문제를 검사하는 백엔드

oxc중립

JavaScript와 TypeScript 생태계용 린팅 백엔드로 사용되는 도구

biome중립

linter에 결합되는 코드 품질 검사 도구

mago중립

여러 언어용 linter 백엔드 가운데 하나로 결합된 도구

ast-grep중립

기존 백엔드가 포착하지 못한 AST 구조 패턴을 검사하는 규칙 엔진

oxlint중립

JavaScript와 TypeScript의 correctness, suspicious, pedantic, complexity 규칙을 실행하는 linter

언급된 리소스

AI 분석 전체 내용 보기

AI 요약 · 북마크 · 개인 피드 설정 — 무료

출처 · 인용 안내

원문 발행 2026. 08. 31.수집 2026. 09. 01.출처 타입 REDDIT

인용 시 "요약 출처: AI Trends (aitrends.kr)"를 표기하고, 사실 확인은 원문 보기 기준으로 진행해 주세요. 자세한 기준은 운영 정책을 참고해 주세요.