9.2.3 AI가 생성한 필수 함수 및 클래스 존재 여부 판별 로직
오라클 시스템이 단순히 구문 오류(Syntax Error)를 막아내는 방패를 넘어, AI에게 특정 아키텍처를 강제하는 통제관(Controller)으로 동작하기 위해서는 AST의 노드를 검색(Search)하고 판별(Evaluate)하는 단계로 나아가야 한다.
“데이터베이스에 연결하는 DatabaseConnector 클래스를 만들고, 그 안에 connect()라는 메서드를 반드시 구현하라“는 프롬프트를 LLM에게 던졌을 때, LLM이 클래스 이름을 DbConnection으로 짓거나 메서드 이름을 init_db()로 제멋대로 작명하는 환각은 흔하게 발생한다. 정규표현식은 이러한 세밀한 계약(Contract) 위반을 잡아내는 데 한계가 뚜렷하다. 주석이나 엉뚱한 변수명에 connect()라는 문자열이 섞여 있으면 정규표현식은 눈속임을 당해 검증 패스(Pass) 판정을 내리기 십상이기 때문이다.
반면, AST 구조를 활용한 오라클 엔진은 이 계약 위반을 0.01초 안에 결정론적으로 색출하여 LLM의 손목을 꺾어버린다.
1. 노드 방문자(NodeVisitor) 기반의 클래스-메서드 교차 검증
오라클은 생성된 코드의 AST 전체 트리를 최상단 루트(Root)부터 훑으며 내려가는 NodeVisitor 인스턴스를 가동한다. 이 방문자는 코드가 텍스트로 보일 때는 알 수 없었던 명확한 계층구조를 따라서 순회한다.
ClassDeclaration(클래스 선언부) 노드에 도달하면, 오라클은 해당 노드의 메타데이터인name속성이"DatabaseConnector"인지 확인한다.- 만약 일치한다면, 오라클은 트리 탐색의 범위를 해당 클래스 노드의 자식 트리(Children Tree)로 좁힌다(Scope Narrowing).
- 자식 트리를 깊이 우선 탐색(DFS, Depth-First Search)하며
MethodDeclaration(메서드 선언부) 노드들을 전부 스캔(Scan)한다. - 순회 결과,
name속성이"connect"인 메서드 노드가 단 하나라도 발견되면 상태 트리거를True로 바꾸고 무결성 훈장을 수여한다.
# 파이썬 커스텀 AST Validator의 논리적 뼈대 예시
import ast
class RequiredMethodScanner(ast.NodeVisitor):
def __init__(self, target_class, target_method):
self.target_class = target_class
self.target_method = target_method
self.class_found = False
self.method_found = False
self._current_class = None
def visit_ClassDef(self, node):
if node.name == self.target_class:
self.class_found = True
self._current_class = node.name
self.generic_visit(node) # 자식 노드 순회 시작
self._current_class = None
else:
# 다른 클래스면 깊게 순회하지 않고 PASS (효율성 확보)
self.generic_visit(node)
def visit_FunctionDef(self, node):
if self._current_class == self.target_class and node.name == self.target_method:
self.method_found = True
self.generic_visit(node)
이러한 Visitor 패턴은 소스 코드의 문자열 길이와 관계없이 오직 논리적인 트리 결절(Node)들 단위로 최단 경로만을 밟고 지나가기 때문에 연산 비용이 극도로 저렴하다.
2. 인터페이스(Interface) 및 상속(Inheritance) 속성 검증
엔터프라이즈 환경에서는 단순히 클래스를 정의하는 것만으로는 부족하다. 다형성(Polymorphism)을 보장하기 위해 반드시 특정 추상 클래스(Abstract Class)나 인터페이스(Interface)를 상속해야 하는 경우가 빈번하다.
AST 객체는 자신이 누구를 가리키는지 부모에 대한 의존성 배열(bases 혹은 implementedTypes)을 무조건 가지고 있다. 오라클은 LLM이 생성한 클래스 노드를 쪼개어, 상속 리스트(Inheritance List)에 사내 표준 인터페이스(예: abstract class BaseController)가 정확히 배열의 인덱스로 존재하는지 검사한다.
LLM이 아무리 그럴듯한 비즈니스 로직을 서술했더라도, 이 상속 노드 검문소에서 적발되면 오라클은 Interface Missing Error를 발생시키며 코드를 파기한다.
AST 기반의 식별자(Identifier) 강제 로직은 오라클로 하여금 “AI의 창의성“이라는 변명에 휘둘리지 않고 파이프라인 전반에 강력한 API 데이터 컨트랙트(Data Contract)를 보장하도록 만드는 가장 무자비하고 단호한 검문소가 된다.