5.6.3 수치 계산 및 데이터 변환 로직의 외부 코드 실행(Code Execution) 검증
거대 언어 모델(LLM)의 가장 뼈아픈 한계는, 그들이 텍스트를 기가 막히게 잘 다루는 ’문과생’일 뿐, 숫자를 다루는 데는 치명적인 결함을 가진 ’수포자’라는 점이다. 트랜스포머(Transformer) 아키텍처는 다음 토큰을 확률적으로 예측할 뿐, 대수학적 연산을 수행할 수 있는 ALU(Arithmetic Logic Unit)를 내부에 탑재하고 있지 않다. 따라서 345 × 123 같은 사칙연산이나 날짜 형식을 변환하는 사소한 로직조차도 LLM에게 단독으로 맡기는 것은 재플(Disaster)을 초래한다.
이러한 수학적 환각을 방지하기 위해 최신 AI 에이전트들은 도구 사용(Tool Use) 혹은 코드 실행(Code Execution) 능력을 활용하여 계산의 책임을 파이썬과 같은 외부 인터프리터(Interpreter)로 떠넘긴다. 결정론적 오라클은 이 ‘위임 과정’ 자체가 완벽하게 통제되고 있는지를 검증하는 수학 선생님이 되어야 한다.
1. 수치 계산을 위한 ‘절대 공식’ 오라클
할인율 계산, 세금 징수, 재고 관리 등 숫자 하나에 비즈니스의 존망이 걸린 시스템에서는 LLM이 스스로 산출한 결괏값을 결코 신뢰해서는 안 된다. 오라클은 LLM에게 중간 과정으로서 수치가 아닌 **계산을 위한 ’공식(Formula)’과 ‘변수(Variables)’**만을 추출하도록 강제하고, 오라클 러너(Oracle Runner)가 이를 가로채어 직접 연산을 수행하고 대조해야 한다.
# LLM이 도출한 중간 JSON 응답
llm_step_response = {
"variables": {"original_price": 50000, "discount_rate": 0.15},
"formula": "original_price * (1 - discount_rate)",
"llm_calculated_result": 42000 # 모델이 스스로 암산해버린 틀린 결과
}
def test_math_execution_oracle(llm_step_response):
# 1. LLM이 암산한 결과는 신뢰 불가능하므로 철저히 무시한다.
# 2. 결정론적인 파이썬 환경에서 안전하게 수식을 실행(eval 대체제 활용 권장)
import ast
import operator
# (보안을 위해 간단한 AST 파서 기반 연산기를 구동한다고 가정)
deterministic_result = secure_math_eval(
formula=llm_step_response["formula"],
variables=llm_step_response["variables"]
)
# 3. 오라클 검증: 우리가 결정론적으로 계산한 값이 진짜 정답과 일치하는지 확인
assert deterministic_result == 42500, "할인율 수식 결괏값이 기댓값과 다릅니다."
오라클 시스템은 LLM이 생성한 formula와 variables가 올바른 구문인지, 변수 타입이 숫자인지 검증한 뒤, 직접 파이썬 런타임에서 이를 구동하여 절대적인 진리(Deterministic Truth)를 찾아낸다.
2. 외부 툴(Tool) 호출 시그니처 검증
만약 OpenAI의 Code Interpreter나 Function Calling을 이용하여 모델이 스스로 파이썬 코드를 실행했다면, 유닛 테스트는 모델이 반환한 ‘함수 호출 시그니처(Function Call Signature)’ 자체를 오라클의 먹잇감으로 삼아야 한다.
- 함수 명칭 검증: “환율을 계산하라“는 프롬프트를 받았을 때 LLM이 환각으로 존재하지 않는
get_exchange_rate_v2()를 호출하려 했는지 검토한다. - 파라미터 타입 및 범위 검증:
calculate_tax(amount="100달러")처럼 숫자 매개변수 자리에 자연어를 섞어 넣지 않았는지, 즉 시스템이 제공한 스키마를 완벽한 정규성으로 지켜냈는지 Pydantic 모델을 통해 단언(Assert)한다.
3. 코드 생성(Code Generation) 텍스트의 컴파일 가능성 검사
모델이 직접 파이썬이나 SQL 코드를 짜서 응답하는 경우, 테스트 오라클은 반환된 코드 문자열이 **문법적으로 컴파일 가능한지(Syntactically Valid)**를 중간 과정에서 반드시 검사해야 한다.
import ast
def test_syntax_validity_oracle(llm_generated_python_code):
try:
# 코드를 실행하지 않고 AST(Abstract Syntax Tree)로 파싱만 시도
ast.parse(llm_generated_python_code)
except SyntaxError as e:
assert False, f"LLM이 생성한 코드가 파이썬 문법 규칙을 위반했습니다: {e}"
LLM의 연산은 기본적으로 확률론적 근사치(Approximation)에 가깝다. 오라클의 가장 중요한 임무는, 모델이 수학과 코딩이라는 가장 엄격한 결정론적 세계에 손을 대려 할 때, 그 손을 쳐내고 안전한 소프트웨어 인터페이스로 데이터만 예쁘게 전달하도록 강제하는 것이다. 외부 코드 실행 검증은 LLM의 한계를 파이썬의 무결성으로 감싸 안는 가장 현실적인 타협점이다.