허진혁Backend Developer
전체 프로젝트

2026.09 / AI 도구 활용 개발 · Codex, Claude

My Rate (RealRate)

개인 우대조건을 반영한 적금 세후 이자 비교 서비스

Codex·Claude를 활용해 개발하고, 추출 데이터의 오류와 계산 규칙을 검증하는 과정을 정리했습니다.

TypeScript · Next.js · React · Claude APIGitHub

01 / DATA VALIDATION · TypeScript, Claude API

AI 추출 결과를 검증 가능한 상품 데이터로

문제AI가 원문을 정확히 인용해도, 상호배타 조건을 중복 합산하거나 다른 의미의 조건 코드를 배정할 수 있었습니다.

AI 추출 데이터의 검증 흐름
자동 검사
공시 원문 → AI 구조화
원문 근거 · 우대 합계 검사
검수 우선순위 표시

자동 검사는 의미 오류 전체를 탐지하지 못함

전량 검수와 빌드
43개 상품 원문 대조
11개 상품 오류 수정
미검수 상품이 있으면 빌드 실패

최종 검수 표시 43/43 · 원문 근거 일치 105/105

원문 근거가 있다는 사실만으로
추출한 조건의 의미까지 맞지는 않았습니다.

  • 근거 검사: 공백을 정규화한 뒤 원문에 없는 인용을 폐기합니다.
  • 검수 우선순위: 조건별 우대율 합계가 대표 옵션의 우대폭을 넘으면 검수 대상으로 표시합니다. 작업 기록에는 자동 검사를 통과한 상품을 포함한 전량 대조 결과가 남아 있습니다.
  • 빌드 차단: 데이터를 조립할 때 reviewed: false로 시작하고, 검수 완료 표시가 없는 상품이 있으면 next build 실행 전에 실패하는 구조입니다.
  • 실행 경로 분리: Claude API는 배치 추출에 사용합니다. 사용자 계산은 검수된 JSON으로 수행하며 런타임 LLM 호출에 의존하지 않습니다.
자동 표시 7건과 실제 오류 11건이 다른 이유

자동 표시 7건 중 2건은 원문 자체가 여러 조건 중 일부를 선택하는 구조인 정상 상품이었습니다. 실제 오류 11건 중 5건만 합계 검사로 잡혔고, 나머지 6건은 불명확한 우대율 추정이나 조건 코드 오배정 등 산술 검사로 탐지할 수 없는 오류였습니다.

작업 기록에서는 자동 표시 건수와 실제 오류 건수를 구분합니다. 원문 대조 결과를 기준으로 11개 상품의 추출 결과가 수정됐습니다.

TypeScript · 핵심 발췌
const sumRateBp = conditions.reduce(
  (acc, c) => acc + c.rateBp, 0
);
const overGap = sumRateBp > gapBp;
const result = overGap
  ? conditions.map(c => ({ ...c, confidence: 'low' as const }))
  : conditions;
const unreviewed = data.products.filter(p => !p.reviewed);
if (unreviewed.length > 0) {
  // 검수 미완료 상품이 있으면 빌드 중단
  process.exit(1);
}

scripts/lib/pipeline.tsscripts/check-reviewed.ts의 핵심 로직입니다. 빌드 명령은 npm run check:reviewed && next build로 연결돼 있습니다.

11 / 43원문 대조에서 오류가 확인돼 수정한 상품
43 / 43최종 데이터의 검수 완료 표시
105 / 105원문과 인용 근거가 일치하는 조건

오류 발견·수정은 2026-09-03 작업 기록 기준입니다. 2026-09-15 포트폴리오 작성 과정에서 Codex가 202608 기준월 JSON의 검수 표시와 공백 정규화 후 원문 인용 일치를 재확인한 결과입니다. 인용 일치가 의미 정확도 100%를 뜻하지는 않습니다.

검증 지표와 오류 유형 기록 ↗

02 / CALCULATION · TypeScript, React

개인별 적용금리와 세후 이자의 계산 규칙 보장

문제광고 최고금리에는 사용자가 충족하지 못한 조건까지 포함돼, 실제 받을 이자 기준의 순위와 차이가 발생했습니다.

개인별 세후 이자 비교 흐름
개인별 적용금리
만기 · 적립 방식 선택
충족 조건만 정수 bp 합산
공시 최고금리 상한 적용

OTHER · 0bp · 미해석 우대폭은 합산 제외

세후 이자 비교
단리 또는 월복리 계산
세전 이자 반올림 · 세금 절사
세후 이자 기준 정렬

같은 이자는 기본금리 · 상품 코드 순으로 정렬

충족한 조건으로 금리를 계산하고,
같은 납입 조건의 세후 이자로 비교했습니다.

  • 금리 합산: 1bp = 0.01%p의 정수 단위를 사용하고, 기본금리와 공시 최고금리 사이로 결과를 제한합니다.
  • 불확실성 처리: OTHER·0bp 조건과 미해석 우대폭은 개인별 금리에 더하지 않고, 원문과 미해석 우대폭을 화면에 표시합니다.
  • 계산 분리: 적용금리·단리 및 월복리 이자·순위 로직을 순수 함수로 분리한 구조입니다. 세전 이자를 한 번 반올림한 뒤 세금을 절사하고 세후 이자를 구합니다.
  • 재현 가능한 순서: 세후 이자 → 기본금리 → 상품 코드 순으로 동률을 처리하고, 입력 조건을 공유 URL로 복원합니다.
추가 조건의 효과도 같은 계산기로 검증

미충족 조건을 하나씩 추가한 세후 이자와 현재 이자의 차이를 구해, 증가액 상위 3개를 제시합니다. 이미 최고금리에 도달해 추가 이자가 없는 조건은 제외합니다. 각 증가액은 현재 상태에서 해당 조건 하나만 추가한 값이며, 여러 추천의 합산 효과를 의미하지 않습니다.

TypeScript · 핵심 발췌
const baseRateBp = toBp(option.baseRate);
const maxRateBp = toBp(option.maxRate);
const appliedBp = applied.reduce(
  (sum, condition) => sum + condition.rateBp, 0
);
const unclampedRateBp = baseRateBp + appliedBp;
const myRateBp = Math.max(
  baseRateBp, Math.min(unclampedRateBp, maxRateBp)
);
const pretaxInterest = Math.round(rawPretaxInterest);
const tax = Math.floor(pretaxInterest * TAX_RATE);
const afterTaxInterest = pretaxInterest - tax;

lib/my-rate.tslib/interest.ts 발췌. 이자 계산 경계에서 myRateBp / 10000으로 연이율을 변환합니다. 이자 계산은 부동소수점 기반이며, 정수 bp는 금리 합산에 적용했습니다.

66 / 66계산·순위·UI·공유 URL 테스트 통과
3.6%실데이터 예시의 개인별 1위 적용금리
98,982원해당 상품의 계산된 세후 이자

2026-09-15 포트폴리오 작성 과정에서 Codex가 node --import tsx --test lib/**/*.test.ts를 재실행한 결과입니다. 최고금리 상한, 미해석 우대 제외, 단리·월복리 고정 기대값, 조건 변경과 동률 정렬을 검증합니다.

예시는 202608 공시 데이터, 월 50만 원·12개월·정액적립·급여이체 선택 기준입니다. 광고 최고금리 1위 상품은 최고 4.1%지만 해당 조건의 적용금리는 2.2%여서 개인별 세후 이자 1위와 달랐습니다. 실제 가입·지급 실적은 아닙니다.

실데이터 순위 회귀 테스트 ↗