LLM은 날짜 계산을 신뢰성 있게 수행할 수 없다 — 그리고 이제 데이터가 있다
요약
LLM이 날짜 산술(Date arithmetic) 작업에서 빈번하게 오류를 범한다는 사실을 입증하는 연구와 데이터셋을 소개합니다. 경과 일수와 서수적 일수의 혼동, 요일 계산 오류 등 구체적인 실패 사례와 이를 검증하기 위한 오픈 소스 벤치마크를 다룹니다.
핵심 포인트
- LLM은 단순한 날짜 계산에서도 확신에 찬 오답을 내놓는 경향이 있음
- 경과 일수와 서수적 일수를 구분하지 못하는 논리적 오류 발생
- 계산, 방향, 카테고리 오류 등 11개 카테고리의 날짜 산술 실패 유형 정의
- 오픈 소스 벤치마크 'date-math-bench'를 통한 모델 성능 검증 가능
날짜 산술(Date arithmetic)은 LLM에게 맡기기에 가장 안전한 작업처럼 보입니다. 모호함도 없고, 판단의 여지도 없으며, 그저 숫자를 세는 것뿐이니까요. 하지만 바로 그 점이 위험 요소입니다. 답변이 확신에 차 있고 최종적인 것처럼 보이기 때문에, 유보적이거나 불확실한 답변처럼 재검토를 거치지 않기 때문입니다.
이 일은 일상적인 대화 중에 포착된 두 가지 일화에서 시작되었습니다. 그리고 오픈 소스 테스트 하네스(test harness), 5개의 모델, 각 모델당 101개의 무작위 질문, 그리고 실제 재현 가능한 데이터셋으로 끝을 맺었습니다. 그 두 가지 모두를 소개합니다.
시작점: 두 가지 실제 실패 사례
실패 1 — 경과 일수(elapsed days) vs 서수적 일수(ordinal day count). 한 실행(run)이 7월 10일에 시작되었습니다. 오늘은 7월 28일입니다. 질문: 현재 실행의 몇 번째 날인가요?
답변은 다음과 같았습니다: 28일째.
틀렸습니다. 19일째입니다. 두 날짜 사이의 달력 차이(7월 28일 − 7월 10일 = 18일)가 두 수치가 서로 다른 양이라는 점을 인지하지 못한 채 일수(day count)로 직접 보고되었습니다. 시작일을 1일로 계산할 때 올바른 공식은 day_number = (end_date - start_date).days + 1입니다. 즉, 18 + 1 = 19가 됩니다. 경과 일수와 서수적 일수는 서로 교체하여 사용할 수 없으며, 그 차이는 항상 정확히 1입니다. 이는 대충 훑어볼 때 놓치기 쉬운 바로 그런 종류의 오류입니다.
실패 2 — 다음 요일을 잘못 계산함. 오늘이 7월 27일 월요일이라면, 화요일은 며칠인가요?
답변: 7월 29일. 이 또한 틀렸습니다. 화요일은 바로 다음 날인 7월 28일입니다. 여기에는 어떠한 미묘함도 없습니다. 가장 단순한 증가임에도 불구하고 여전히 틀린 결과가 나왔습니다.
하지만 두 개의 데이터 포인트는 패턴이 아니라 일화일 뿐입니다. 정직한 다음 단계는 그럴듯하게 들리는 네 가지 사례를 더 만들어내어 이를 트렌드라고 부르는 것이 아니었습니다. 실제로 테스트를 해보는 것이었습니다.
실제 테스트 구축
이 하네스(harness) — date-math-bench —는 한 가지 일을 수행합니다: 11개 카테고리에 걸쳐 새롭고 무작위화된 날짜 계산 (date-math) 질문을 생성하고, 각 질문을 모델에 독립적인 요청으로 전송하며(공유 컨텍스트나 프라이밍(priming) 없음), 코드 내에서 독립적으로 정답을 계산한 뒤, 모델의 가공되지 않은 응답을 정답과 대조하여 채점합니다. 모든 실행은 시드(seed)가 설정되어 재현 가능하며, 모든 결과는 단순히 요약되는 것이 아니라 아카이브됩니다.
11개의 카테고리는 하나의 버그에 대한 11가지 변형이 아니라, 진정으로 다른 세 가지 실패 형태를 포괄합니다:
- 계산 오류 (Counting errors) — 특정 사례를 계산하는 대신 암기된 상수를 사용함 (서수 일수 계산, 윤년 기간, 세기 윤년 규칙, 나이 계산)
- 방향 오류 (Directional errors) — 크기는 맞지만 방향이 틀림 (요일 증가, "N일 전", 역방향 월 산술)
- 카테고리 오류 (Category errors) — 한 종류의 날짜 연산을 그와 유사한 더 단순한 연산으로 취급함 (월말 이월, 영업일 대 달력 일수, 월의 n번째 요일, 윤년 생일이 평년으로 떨어지는 경우)
신뢰할 수 있는 수치에 도달하기까지 과정 중에 몇 가지 실제적인 수정 사항이 있었으며, 이를 솔직하게 밝힐 가치가 있습니다: 초기 버전은 응답의 어디에서든 첫 번째 숫자나 단어를 매칭하여 채점했는데, 이는 문제를 올바르게 추론했지만 풀이 과정을 보여줄 수 없었던 모델을 조용히 오답 처리했습니다. 즉, 모델이 정답을 계산했음에도 불구하고 추론 과정 중 앞선 숫자가 정규 표현식(regex)에 먼저 매칭되어 오답으로 표시된 것입니다. 수정 방법은 마지막 비어 있지 않은 줄을 먼저 채점하고, 해당 줄이 비어 있는 경우에만 전체 텍스트 검색을 수행하는 것이었습니다. 또한 추론 모델 (Qwen3-27B)은 다른 네 모델보다 훨씬 더 큰 토큰 예산(token budget)이 필요했습니다. 이 모델의 답변은 전체가 보이는 사고 사슬 (chain of thought) 이후에 도착하는데, 엄격한 토큰 제한은 최종 답변에 도달하기도 전에 문장 중간에서 답변을 끊어버렸으며, 이는 수학을 틀리는 것과는 다른 문제입니다. 이 두 가지 사항 모두 리포지토리(repo)에 문서화, 테스트 및 수정되었습니다.
실제 실행 결과
모델당 101개의 질문, 하나의 시드(seed), 완전한 재현 가능성 (SEED=2991818469). 키 에러(key errors)나 해결되지 않은 속도 제한(rate limits) 없이, 필터링된 내용도 전혀 없습니다.
| 모델 | 통과율 |
|---|---|
| Claude Sonnet 4.6 | 101/101 (100%) |
| ... |
특별히 언급할 만큼 눈에 띄는 두 가지 발견 사항이 있었습니다.
영업일(Business days)은 모델 간의 실제적인 사각지대입니다
Claude Haiku, GPT-4o-mini, Llama 3.3 70B라는 세 개의 서로 다른 모델이 모두 정확히 동일한 카테고리에서 큰 어려움을 겪은 반면, Claude Sonnet과 Qwen3-27B는 10/10의 완벽한 점수를 기록했습니다:
| 모델 | 영업일 점수 |
|---|---|
| Claude Sonnet 4.6 | 10/10 |
| ... |
대표적인 사례: "어떤 작업이 화요일에 시작되어 완료까지 영업일 기준 7일이 소요됩니다(시작일을 영업일 1일로 계산)... 이 작업은 무슨 요일에 끝납니까?" 예상 답안: 수요일. GPT-4o-mini는 월요일이라고 답했습니다. Claude Haiku는 화요일이라고 답했습니다. Llama는 목요일이라고 답했습니다. 동일한 질문에 대해 세 개의 서로 다른 모델이 세 개의 서로 다른 오답을 내놓았습니다. 이는 공유된 계산 버그가 아니라, 영업일(business days)과 달력상의 날짜(calendar days) 사이에서 독립적으로 발생한 진정한 카테고리 혼동입니다.
Llama의 서수 날짜 계산(ordinal-day-count) 오류는 모두 정확히 1만큼 차이가 납니다
이것은 프로젝트 전체를 가장 강력하게 확인해 주는 결과입니다. 이 프로젝트를 시작하게 만든 원래의 7월 19일/28일 일화와 동일한 카테고리인 "서수 날짜 계산(ordinal day count)" 카테고리에서 Llama가 기록한 5번의 실패는, 매번 정확히 1씩 적게 계산했습니다:
- 49 예상, 48 획득
- 49 예상, 48 획득
- 18 예상, 17 획득
- 50 예상, 49 획득
- 41 예상, 40 획득
이는 흩어져 있는 노이즈가 아닙니다. 해당 카테고리에서 다른 5번의 경우에는 정답을 맞혔음에도 불구하고, 5번의 실패 모두에서 동일하게 1만큼 차이가 나는 오류가 발생했습니다. 이는 Llama가 이런 종류의 산술을 못 하는 것이 아니라, 시작일을 포함하는 관례(inclusive-start-day convention)에 대해 매우 구체적이고 반복 가능한 방식으로 일관성이 없음을 의미합니다.
말 그대로 잘못된 날짜
Claude Haiku에게 2025년 3월 31일로부터 정확히 한 달 뒤의 날짜가 언제인지 묻자, 다음과 같이 답했습니다:
2025년 4월 31일
4월은 30일까지 있습니다. 이는 이월(month-end-rollover) 버그가 가장 순수한 형태로 나타난 경우입니다. 단순히 날짜가 틀린 것이 아니라, 불가능한 날짜인 것입니다.
가장 흥미로운 실패는 노력의 부족이 아니었다
Qwen3-27B에게 2026년 3월 셋째 주 화요일을 요청하자, 길고 신중하며 진정으로 인상적인 추론 과정을 생성했습니다. 답변을 두 번째 방법과 교차 확인하고,
- LLM에게 산문(prose) 형태로 날짜 계산을 요청하고 그 결과물을 신뢰하지 마세요. 코드로 계산하고(
datetime/ calendar-library 산술 연산, 문장이 아닌 방식), 눈으로 대충 확인하는 대신 스크립트로 검증하세요. - 중요한 공식들을 고정하고, 무언가를 배포하기 전에 모든 날짜 범위를 해당 공식에 따라 확인하세요: 시작 날짜가 포함되는 경우
day_number = (end - start).days + 1; 평일(business-day) 계산은 단순히 고정된 오프셋(offset)을 더하는 것이 아니라 실제로 주말 날짜를 건너뛰며 계산; 월(month) 더하기는 실제 캘린더 라이브러리를 통해 해결하여 4월 31일과 같은 잘못된 날짜가 생성되지 않도록 하세요. - 이러한 버그가 발생하는 경계 조건(edge conditions)을 가로지르는 명시적인 테스트 케이스를 작성하세요: 주말을 포함하는 범위, 월 경계를 넘는 범위, 윤년의 2월을 포함하는 범위, 그리고 동일한 질문의 "며칠 전" 버전과 "며칠 후" 버전.
- LLM으로부터 나온 "분명히 간단한 산술"은 검토 수준을 낮추는 것이 아니라, 오히려 더 높은 수준의 정밀도(higher-scrutiny) 카테고리로 취급하세요. 단순함이야말로 훑어볼 때 오류를 보이지 않게 만드는 바로 그 원인이며, 위에서 보여준 윤년 사례처럼 길고 자신감 넘치며 스스로 검증하는 추론 과정(reasoning trace) 또한 아무런 보장이 되지 않습니다.
전체 하네스(harness), 11개 카테고리 전체, 채점 로직(자체적인 버그와 수정 사항 포함), 그리고 위 모든 수치 뒤에 있는 원시 결과 파일은 오픈 소스로 공개되어 있습니다: github.com/antrixy/date-math-bench. 만약 증거를 바로 확인하고 싶다면, 이 포스트에서 인용한 정확한 실행 결과 — 모델당 101개 질문 전체, 시드(seed) 포함 — 는 여기에 커밋되어 있습니다: results/2026-07-29T14-51-30-450Z_seed2991818469_trials10.json. 직접 SEED=2991818469 npm test를 실행하면 동일한 질문 세트를 얻을 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기