9.2.4 금지된 문법 패턴 및 비효율적 구조(Anti-pattern) 자동 탐지
LLM이 코드를 생성할 때 흔히 저지르는 또 다른 죄악은, 컴파일은 완벽하게 통과하지만 실제 프로덕션 서버에 올라갔을 때 자원을 고갈시키거나 유지보수 불가능한 스파게티로 전락하는 **안티 패턴(Anti-pattern)**을 양산한다는 점이다. 방대한 오픈소스 생태계를 긁어모아 학습한 탓에, AI 모델은 구형 라이브러리의 파편화된 코드나 성능 효율성이 극도로 떨어지는 O(N²) 수준의 낡은 루프 구조를 그럴듯하게 복사-붙여넣기(Copy-Paste)하려는 습성을 버리지 못한다.
단위 테스트(Unit Test) 오라클은 “정답이 올바르게 나왔느냐“에만 관심이 있으므로 이러한 내부 구조의 썩음을 감지할 수 없다. 오직 AST 파싱 기반의 정적 분석 오라클만이 트리의 순회를 통해 코드가 ‘어떻게’ 동작하는지를 해부하고, 금지된 문법 패턴(Banned Syntax Patterns)을 선제적으로 타격하여 도려낼 수 있다.
1. N+1 쿼리 및 루프 내 I/O 안티 패턴 탐지
가장 치명적인 성능 저하를 일으키는 패턴은 반복문 내부에서 네트워크 호출이나 데이터베이스 쿼리를 수행하는 경우다(N+1 쿼리 문제). AI는 데이터를 리스트로 만났을 때 일단 for 루프를 돌리고 그 안에서 생각하려는 편향성을 띈다.
- 오라클은 AST 트리의
ForStatement나WhileStatement계열 노드를 진입점(Entry Point)으로 삼는다. - 해당 노드의 본문(Body) 블록 트리 내부로 깊이 파고들어가며
CallExpression(함수 호출) 노드를 탐색한다. - 만약 추출된 호출된 함수명이
db.execute(),requests.get(),axios.post()등 I/O 바운드(I/O-Bound) 연산으로 사전에 등록된 블랙리스트(Blacklist)와 일치한다면, 오라클은 심각한 경고(Fatal Error)를 발생시킨다.
“Line 45: 반복문 내부에서 데이터베이스 쿼리(db.execute)가 호출되었습니다. 이는 심각한 성능 저하를 유발합니다. IN 구문이나 Bulk 연산을 밖으로 빼내어 코드를 재구성하세요.”
이러한 피드백 루프는 AI가 작성한 코드가 엔터프라이즈의 트래픽을 견딜 수 있는 효율적인 아키텍처로 진화하도록 강제한다.
2. 보안적 취약점을 야기하는 금지된 내장 함수 색출
파이썬의 eval()이나 exec(), 자바스크립트의 비동기 우회 문법 등은 오픈소스 스크립트에서는 가끔 허용될지 모르나, 상용 시스템에서는 절대 섞여 들어와서는 안 되는 독극물과 같다.
LLM은 종종 동적 제어가 필요한 상황에서 가장 쉽고 멍청한 방법인 eval() 문법에 의존하려는 경향을 보인다. 정규표현식은 "evaluate"라는 안전한 변수명과 eval() 호출을 헷갈려하지만, AST 분석기에서는 오직 CallExpression의 식별자(Identifier) 노드 속성이 정확히 "eval"로 찍혀 있을 때만 반응한다. 이 결함 없는 탐지망을 통해 시스템은 어떠한 우회로도 허락하지 않고 보안 안티 패턴을 원천 봉쇄할 수 있다.
3. 빈 Catch 블록(Empty Catch Block) 에러 은닉 방지
초보 개발자들과 LLM이 가장 자주 공유하는 최악의 습관은 try-catch 블록으로 예외를 잡아놓고, 정작 catch 블록 안을 비워두거나(Empty) pass 로 넘겨버림으로써 에러를 시스템 깊숙한 곳으로 은닉(Swallow)해버리는 행위다.
AST 오라클은 TryStatement 노드를 순회할 때, 반드시 그 자식 노드인 CatchClause (혹은 ExceptHandler in Python)로 진입한다. 그리고 해당 노드의 속성에 담긴 연산 리스트(body array)의 길이가 0이거나 단지 Pass 노드 하나만 덩그러니 들어있는지를 산술적으로 계산한다. 아무런 로깅(Logging) 연산이나 에스컬레이션(Escalation) 전이 구문 없이 에러를 삼켜버린 정황이 포착되면, 오라클은 즉시 코드를 반송(Reject)하여 견고한 에러 핸들링을 강제한다.
결국 AST를 심판의 무기로 삼는다는 것은, LLM이 ’정답 도출’이라는 결과지상주의에 빠져 코드의 우아함과 효율성, 안정성을 내다 버리는 행위를 결정론적이고 시스템적인 폭력으로 막아낸다는 것을 의미한다.