Skip to Content
Tax ChatAI 세무 상담 (tax-chat)

AI 세무 상담 (tax-chat)

얼마집 AI 세무 상담은 재개발·재건축 소유자를 위한 세무 Q&A 서비스입니다. Claude Haiku 4.5 + 세금 계산 도구 + 법령 PDF 주입으로 구성됩니다.

도메인 지식

세무 코드를 수정할 때 반드시 알아야 하는 한국 세법 맥락입니다.

양도소득세

  • 1세대 1주택 비과세 경계: 실거래가 12억원이 기준선. 이하이면 전액 비과세, 초과 시 초과분에 대해서만 과세. 이 12억 기준은 법 개정으로 변경될 수 있음 (2021년 이전에는 9억이었음).
  • 장기보유특별공제 이중 구조: 1세대 1주택은 보유기간 공제(최대 40%) + 거주기간 공제(최대 40%) = 최대 80%. 일반 부동산은 보유기간 공제만(최대 30%). 이 두 로직이 코드에서 분기됨.
  • 단기매매 중과: 1년 미만 70%, 1~2년 60%. 이건 누진세율이 아니라 단일세율이므로 applyBracket()을 쓰지 않음.
  • 다주택자 중과: 기본세율 + 중과세율(2주택 +20%, 3주택+ +30%). 장기보유특별공제 미적용. 조정대상지역 한정.

취득세

  • 조정대상지역 2주택 중과(8%) 한시 유예: 2022.12.21 이후 유예 중으로 일반세율 적용. 유예 종료 시 route.tscalculate_acquisition_tax 로직 수정 필요 — 현재 2주택 조정대상지역에서 일반세율을 적용하는 분기가 이 유예를 반영한 것임.
  • 6억~9억 구간 비례세율: (취득가액 × 2/3억 - 3) / 100 — 단순 구간이 아니라 연속 함수이므로 TaxBracket으로 표현하지 않고 inline 계산 유지.

종합부동산세

  • 공정시장가액비율: 현재 60%. 이 비율은 매년 변경 가능 (과거 100% → 95% → 60% 변동 이력). route.tscalculate_property_tax에서 fairMarketRatio = 0.60으로 하드코딩되어 있으므로, 변경 시 이 값과 prompt.ts의 종부세 텍스트 모두 수정 필요.
  • 기본공제: 1세대 1주택자 12억원, 그 외 9억원. 이것도 법 개정 대상.

재산세 (지방세)

종부세와 이름만 비슷할 뿐 다른 세목이다. 도구도 calculate_local_property_tax로 따로 있다 (calculate_property_tax는 종부세 전용). 세율·과세표준·부가세가 전부 다르므로 섞지 말 것.

  • 누진세율이다: 표준세율 “3억 초과 0.4%“는 단일세율이 아니라 과세표준 × 0.4% - 630,000원이다. 누진공제를 빼먹으면 과다 계산된다 — 2026-08-27에 모델이 정확히 이 실수를 해서 사용자에게 지적받았다(HMH-8947).
  • 1세대 1주택은 기준선이 두 개고 서로 다르다:
    • 특례세율(지방세법 제111조의2) → 시가표준액 9억원 이하만
    • 공정시장가액비율 43/44/45% (시행령 제109조①2 단서) → 9억 초과도 포함
    • 즉 공시 12억 1주택은 “표준세율 + 45% 비율”이라는 조합이 된다.
  • 공정시장가액비율에 연도가 박혀 있다: 시행령 조문이 “2026년도에 납세의무가 성립하는” 이라고 명시한다. 매년 개정되므로 LOCAL_PROPERTY_TAX_1HOUSE_FAIR_MARKET_RATIOS는 해마다 시행령을 다시 확인해야 한다.
  • 고지액 = 본세 + 도시지역분 + 지방교육세: 도시지역분은 과세표준의 0.14%(제112조①2), 지방교육세는 본세의 20%(제151조①6, 도시지역분 제외). 본세만 답하면 실제 고지서와 어긋난다.
  • 주택에는 세부담상한(150%)을 걸지 않는다: 제122조 단서가 “다만, 주택의 경우에는 적용하지 아니한다”라고 명시한다(각 호는 2023.3.14 삭제). 주택은 세액이 아니라 과세표준에 상한을 건다 — 과세표준상한액 = 직전 연도 과세표준 상당액 + (당해 과세표준 × 5%)(제110조③ + 시행령 제109조의2). 직전 연도 과세표준 상당액은 직전 연도 시가표준액 × 당해 연도 공정시장가액비율이므로, 필요한 입력은 작년 ‘납부세액’이 아니라 작년 ‘공시가격’이다. ⚠️ 종부세(calculate_property_tax)는 여전히 세부담상한 150%가 있다 — 다른 세목이니 섞지 말 것.
  • 공유 지분은 누진세율 적용 “후”에 안분한다: 지분을 과세표준에 먼저 곱하면 낮은 누진구간이 걸려 과소 산출된다. 제107조①2가 건물·토지 소유자가 다른 경우에 대해 “그 주택에 대한 산출세액을 …비율로 안분계산”이라고 정한 것과 같은 순서다.

증여세

  • 10년 합산과세: “동일인” 기준. 아버지와 어머니는 별도 동일인으로, 각각 5천만원 공제 적용(직계존비속 성년 기준). 단, 배우자의 직계존속은 동일인 취급에 주의가 필요함.
  • 혼인·출산 증여재산 공제 (2024.1.1~ 시행): 직계존속→직계비속 증여 시, 혼인신고일 전후 2년 이내 또는 자녀 출산·입양일로부터 2년 이내인 경우 기본 인적공제 외 1억원 추가 공제. calculate_gift_taxmarriage_or_childbirth 파라미터로 적용. 추가공제 상수: taxRates.tsGIFT_MARRIAGE_CHILDBIRTH_EXTRA_EXEMPTION.
  • 부담부증여: 수증자가 인수하는 채무 부분은 증여세가 아닌 양도소득세 과세 대상. 현재 calculate_gift_tax는 안내 메시지만 제공하고 양도세 연계 계산은 하지 않음.
  • 증여 시가 기준: 증여일 전후 6개월(비상장주식은 전후 3개월) 내 매매사례가액, 감정가액, 수용·공매가액 순으로 적용.

주택 수 판단

  • 관리처분인가 이후의 입주권은 주택 수에 포함
  • 분양권은 2021.1.1. 이후 취득분부터 주택 수 포함
  • 법인 명의 주택은 1세대 1주택 비과세 제외, 다주택자 판정에 미포함
  • 상속주택 소수 지분(15~20% 이하)은 주택으로 미판정되는 특례 존재

외부 API 제약

국토교통부 RTMS (실거래가)

  • 월 단위 조회만 가능: DEAL_YMD 파라미터가 YYYYMM 형식. 일 단위 필터링 불가.
  • 아파트 전용: RTMSDataSvcAptTrade 엔드포인트는 아파트만. 빌라(RTMSDataSvcRHTrade), 오피스텔(RTMSDataSvcOffiTrade)은 별도 엔드포인트.
  • XML 응답: JSON이 아님. <item> 태그를 정규식으로 파싱하는 구조.
  • 법정동코드 5자리 필요: Kakao 지오코딩으로 b_code를 얻은 뒤 앞 5자리(lawdCd)로 조회.
  • 데이터 지연: 실거래 신고 후 30일 이내 등록이므로 최근 1개월 데이터는 불완전할 수 있음.

Kakao Maps (지오코딩)

  • “반포자이 아파트” 같은 키워드 검색 시 동명 아파트가 여러 곳 나올 수 있음. 현재는 첫 번째 결과만 사용.
  • 키워드 검색(/v2/local/search/keyword) → 주소 검색(/v2/local/search/address) 2단계로 b_code를 추출.

공시가격 API (향후 연동 예정)

  • 매년 4월경 공시. 그 전에는 전년도 데이터만 존재하므로 fallback 필요.
  • MOLIT_API_KEY로 접근 가능.

세율 변경 시 수정 가이드

세율은 features/tax-chat/lib/taxRates.ts 한 곳에서 관리됩니다.

taxRates.ts 수정 → prompt.ts가 자동으로 프롬프트 텍스트 재생성 → route.ts의 tool들이 applyBracket()으로 동일 데이터 참조

taxRates.ts에 없는 하드코딩 값들 (별도 수정 필요):

위치설명
route.ts calculate_capital_gain_tax12000000001세대 1주택 비과세 한도 12억
route.ts calculate_capital_gain_tax0.70, 0.60단기매매 중과세율
route.ts calculate_capital_gain_tax0.30, 0.20다주택자 중과 가산세율
route.ts calculate_capital_gain_tax2500000양도소득 기본공제 250만원
route.ts calculate_property_tax0.60종부세 공정시장가액비율
route.ts calculate_property_tax1200000000, 900000000종부세 기본공제
route.ts calculate_acquisition_tax0.08, 0.12다주택 취득세 중과세율
taxRates.ts GIFT_MARRIAGE_CHILDBIRTH_EXTRA_EXEMPTION100_000_000혼인·출산 증여재산 추가공제 1억원
prompt.ts LONG_TERM_HOLDING_TEXT공제율 테이블장기보유특별공제율 (구간이 복잡하여 별도 관리)

검증 시나리오

세금 계산 로직 수정 후 반드시 확인해야 하는 케이스입니다.

양도소득세

시나리오입력기대 결과
1주택 비과세매도 12억, 취득 6억, 보유 3년, is_acquired_in_adjusted_area=false세금 0원
1주택 고가주택매도 15억, 취득 6억, 보유 5년, 거주 3년, is_acquired_in_adjusted_area=false초과분만 과세, 장특공 적용
조정대상지역 거주요건매도 12억, 취득 6억, 보유 3년, is_acquired_in_adjusted_area=true, 거주 0년비과세 아님 — 전액 과세
조정대상지역 미지정위와 동일하되 is_acquired_in_adjusted_area 생략needs_input 반환 (비과세 단정 금지)
날짜 역전취득 2025-01-01, 양도 2024-01-01needs_input='sale_date'
존재하지 않는 날짜취득 2024-02-30needs_input='acquisition_date'
단기매매 1년 미만매도 5억, 취득 4억, 보유 6개월70% 단일세율
다주택 중과매도 10억, 취득 5억, 3주택, 조정대상기본세율 + 30%

증여세

시나리오입력기대 결과
배우자 10억gift_value=10억, spouse과세표준 4억, 세액 7천만원
성년자녀 3억gift_value=3억, lineal_adult과세표준 2.5억, 세액 4천만원
공제 이하gift_value=5천만, lineal_adult세금 0원
혼인·출산 공제gift_value=1.5억, lineal_adult, marriage_or_childbirth=true, gift_direction='from_ascendant'과세표준 0원 (5천만+1억=1.5억 공제), 세금 0원
혼인·출산 방향 역전위와 동일하되 gift_direction='from_descendant'추가공제 미적용 — 기본공제 5천만만
혼인·출산 방향 미지정위와 동일하되 gift_direction 생략needs_input='gift_direction'
혼인·출산 비해당 관계gift_value=1.5억, other_relative, marriage_or_childbirth=true추가공제 미적용, 과세표준 1.4억
10년 합산gift_value=3억, previous_gifts=2억, lineal_adult합산 5억-5천만=4.5억 기준

조정대상지역 판정 (isAdjustedArea)

시 단위 입력은 조정대상지역으로 보지 않습니다. 같은 시 안에서도 구마다 지정 여부가 다르기 때문입니다.

입력기대 결과
수원 · 용인 · 성남 · 안양false — 시 단위로는 판정하지 않음
분당구 · 수지구 · 장안구true — 구 이름이 유일하면 시를 생략해도 매칭
강남 · 과천true — 말미 행정단위 생략 허용
중랑구중랑구중구로 오매칭되지 않음

종합부동산세

시나리오입력기대 결과
1주택 공제 이하공시가격 11억, 1주택자세금 0원 (12억 공제)
1주택 과세공시가격 15억, 1주택자과세표준 3억, 공정비율 60% 적용

재산세 (computeLocalPropertyTax)

시나리오입력기대 결과
8/27 사고 케이스공시 7.4억, 1주택비율 45%, 특례세율, 본세 535,500원, 총 1,108,800원
특례세율 상한 초과공시 12억, 1주택표준세율 + 비율 45% (두 기준선이 다름)
다주택공시 7.4억, 1주택 아님비율 60%, 표준세율, 본세 1,146,000원
과세표준상한위 + 직전연도 공시 5억과세표준 241,650,000원으로 제한, 본세 303,300원
공유 지분 50%위 + share_ratio=0.5과세표준은 전체 유지, 본세만 절반 안분
도시지역분 비대상위 + is_urban_area=false도시지역분 0원
공시가격 미입력assessed_value=0needs_input='assessed_value' (0원 아님)

법령 코퍼스 (public/laws)

법령은 도구가 아니라 시스템 프롬프트에 사전 주입됩니다. RAG·벡터 검색이 아니라 pdfTextExtractor.ts의 키워드 매칭으로 파일을 고르고, LAW_INJECTION_BYTE_BUDGET(80,000B) 안에서 담습니다. 코퍼스는 apps/api/public/laws/apps/app/public/laws/ 양쪽에 동일하게 둡니다 (apps/api/next.config.tsoutputFileTracingIncludes가 이 경로를 서버리스 번들에 넣습니다).

디렉토리성격주입 우선순위
0_종합부동산세법 · 4_양도소득세 · 5_소득세법 · 6_상속증여세법 · 7_지방세법 · 8_조세특례제한법세법0 (먼저)
1_재건축_재개발 · 2_토지거래_허가 · 3_투기과열지구절차법1

예산이 빠듯할 때 절차법 전문이 세법 발췌를 밀어내지 않도록 (우선순위, 크기) 순으로 채웁니다. 세액 답변의 근거는 세법이기 때문입니다(HMH-8943).

어떤 메시지로 고르는가 — 대화 전체 폴백

키워드 매칭은 마지막 사용자 메시지를 먼저 봅니다. 여기서 아무 문서도 못 고르면 (law_path='none') 그때만 대화 전체 사용자 메시지 합본으로 한 번 더 고릅니다 (getTaxLawContextWithSession). 복구된 턴은 tools_used.law_sticky=true 로 남습니다.

사용자는 법률 용어가 아니라 구어체로 말하기 때문입니다. “처제가 나한데 현금 4억원을 계좌이체로 주면 세금이 나오나” 에는 증여 가 없습니다. 그래서 계산에 필요한 값을 건네는 후속 턴일수록 매칭이 깨져 법령 0바이트로 답하고, 모델은 조문 번호를 기억으로 지어냅니다. 실측으로 응답턴의 19%가 law_path='none' 이었고 그중 80%는 대화 전체를 보면 매칭됐습니다 (HMH-9303). 모델 선택(selectTaxChatModel)은 이미 대화 전체를 보는데 법령 선택만 마지막 메시지를 보던 비대칭이 원인이었습니다.

1차에서 고른 턴은 재조회하지 않습니다 — 이미 매칭된 턴의 주입량·지연·프롬프트 캐시 특성을 그대로 두기 위해서입니다. 대화 전체를 봐도 매칭이 없으면 'none' 을 유지하고 법령을 억지로 끌어오지 않습니다(잡담·기록 삭제 요청 등).

세법 발췌 갱신 (매년)

5_~8_ 디렉토리는 국가법령정보센터 OPEN API에서 조문 단위로 뽑아 생성합니다. 손으로 편집하지 마세요 — 다음 갱신 때 덮어써집니다. 세법은 통상 연말 공포·1월 시행이므로 개정 후 아래를 실행합니다.

yarn tax-law:fetch --dry-run # 파일 크기만 확인 yarn tax-law:fetch # apps/api·apps/app 양쪽에 생성
  • 뽑을 조문 목록은 scripts/fetch-tax-law-excerpts.tsEXCERPTS에 있습니다. 개정으로 조문 번호가 바뀌면 여기를 고칩니다(없는 조문이면 스크립트가 실패합니다).
  • 법령 전문은 넣지 않습니다. 소득세법 1.3MB·조특법 2.8MB로 예산을 통째로 넘깁니다.
  • 발췌본에 요약·의역·해석을 넣지 않습니다. 이 파일이 곧 모델의 인용 근거이므로, 사람이 쓴 해석이 섞이면 “근거 있는 답변”이라는 전제가 깨집니다.
  • 파일을 추가·개명하면 pdfTextExtractor.tsLAW_FILE_RULES(filenameContains)도 함께 고칩니다. apps/app/src/features/tax-chat/lib/lawContext.test.ts가 실제 코퍼스를 읽어 이 계약을 검증합니다.

공시가격 데이터 적재 (assessed_prices)

get_assessed_value 도구가 사용하는 정식 공시가격 데이터의 Supabase 적재·운영 가이드는 별도 페이지에서 다룹니다:

Last updated on