9.3.3 Python mypy 및 pyright 기반의 타입 불일치 탐지 오라클
파이썬의 타입 힌트 의무화(Type Hint Enforcement)가 무사히 적발망을 통과했다면, 이제 오라클 설계자는 그 힌트들이 ’논리적으로 호환 가능한지(Logically Compatible)’를 심사할 차례다. LLM은 함수 매개변수에 age: int라고 꼬리표(Hint)를 잘 붙여놓고도, 정작 코드를 작성할 때는 age.append(20)처럼 정수에 리스트(List) 전용 메서드를 호출하는 궤변을 태연하게 늘어놓곤 한다.
이러한 모순을 런타임 이전에 깨부수기 위해, 오라클 파이프라인의 백엔드에는 정적 타입 분석기(Static Type Analyzer)인 mypy 또는 마이크로소프트의 pyright가 CI/CD 연동 미들웨어로 탑재되어야 한다.
1. Mypy 파이프라인 연동과 에러 캡처(Error Capture) 전략
Mypy는 파이썬 코드를 텍스트로 읽어들여 자체적인 추론 엔진(Inference Engine)을 돌려 타입 간의 충돌을 찾아내는 표준적인 툴이다. 오라클 시스템은 Mypy를 쉘 스크립트로 단순 실행하는 것에 만족해서는 안 되며, 파이썬 기반의 오라클 데몬(Daemon) 내부에서 직접 Mypy API를 호출하여 구조화된 피드백을 실시간으로 가로채야(Intercept) 한다.
from mypy import api
def run_type_oracle(file_path: str) -> bool:
# mypy를 프로그래밍 방식으로 실행하고, JSON 포맷으로 에러를 떨어뜨리도록 유도
normal_report, error_report, exit_status = api.run([
'--strict', # Any 사용을 전면 금지하는 엄격한 룰
'--show-error-codes', # LLM이 이해하기 쉬운 에러 코드 명시
file_path
])
if exit_status == 0:
print("Type Oracle Passed: 타입 호환성이 완벽하게 일증되었습니다.")
return True
else:
print("Type Oracle Failed: 타입 불일치 발견")
# normal_report에는 파싱된 상세 에러 내용이 담겨있다
print(normal_report)
return False
이 코드는 단순하다. 그러나 --strict 플래그를 통해 LLM이 남발한 Any 타입이나 타입이 명시되지 않은 제네릭(Generic)을 모두 치명적 에러로 격상시킴으로써, AI가 생성한 코드를 인간 시니어 개발자보다 더 깐깐한 기준표 위에 올려버린다.
2. Pyright의 속도 우위와 In-memory 분석 환경
규모가 큰 엔터프라이즈 코드 생성 파이프라인에서는 속도가 생명이다. Mypy가 파이썬으로 작성되어 대형 코드베이스를 검사할 때 성능 저하를 겪는다면, Node.js 위에서 구동되는 마이크로소프트의 pyright는 압도적인 파싱 타임과 풍부한 타입 추론 기능을 제공한다.
Pyright의 진정한 강점은 CLI를 직접 때릴 필요 없이, 언어 서버 프로토콜(LSP, Language Server Protocol) 레이어와 결합하여 디스크가 아닌 메모리 상(In-memory)에서 실시간 타입 체킹이 가능하다는 점이다.
- 오라클 파이프라인은 Pyright LSP 인스턴스를 백그라운드에 띄워둔다.
- LLM이 수천 토큰의 코드를 쏟아낼 때마다, 오라클은 파일 시스템에 접근할 필요 없이 LSP의
textDocument/didChange이벤트를 통해 메모리 상의 파이썬 코드를 업데이트한다. - Pyright는 즉각적으로
textDocument/publishDiagnostics이벤트를 응답하며 타입 에러를 반환한다.
이러한 LSP 기반의 스트리밍(Streaming) 타입 검열은 분석 속도를 비약적으로 끌어올리며, 오라클이 수십 개의 AI 에이전트(Agent)들이 비동기적으로 뱉어내는 코드를 병목 없이 쳐낼 수 있는 고가용성 구조를 보장한다.
3. 에러 포장(Error Wrapping)을 통한 프롬프트 역주입
Mypy나 Pyright가 잡은 에러를 단순히 exit(1) 처리하고 끝내서는 안 된다. 오라클 설계의 백미는, 이 도구들이 뱉어낸 에러를 LLM이 가장 맛있게(?) 씹어먹을 수 있는 형태로 재가공하는 데 있다.
"error: "int" has no attribute "append" [attr-defined]"라는 mypy 에러 문구를 추출했다면, 오라클은 아래와 같이 컨텍스트가 부여된 프롬프트로 래핑(Wrapping)하여 반환해야 한다.
[System] 당신이 작성한 코드의 42번째 줄에서 정적 타입 에러가 발생했습니다.
[Error Code] attr-defined
[Message]int타입(age 변수 지정)은append속성을 가지지 않습니다.
[Action] 이 타입 충돌을 해소하기 위해 리스트 타입으로 강제 형변환하거나 로직을 전면 재수정하여 코드를 다시 출력하세요.
Python 생태계에 mypy와 pyright를 오라클로 이식하는 것은 자율 주행 자동차에 라이다(LiDAR) 센서를 다는 것과 같다. 이 센서들은 보이지 않는 메모리 할당의 어둠 속에서 객체지향의 계약 위반을 스캔하여, 런타임에 차량이 벽을 들이받기 전에 정확히 핸들을 꺾도록 통제한다.