Files
CODE_ASSISTANT/specs/003-token-cost/spec.md
T
2026-09-16 17:22:14 +09:00

9.9 KiB

Feature Specification: 토큰 수·비용 표시 (token-cost)

Feature Branch: feat/token-cost (미생성 — spec 단계)

Created: 2026-08-09

Status: Draft

Input: User description: "토큰 수, 토큰 비용" (docs/orders/20260727.md 미완료 항목)

배경 (현재 상태)

이미 있는 것:

  • 답변(assistant) 말풍선 아래에 총 3.2k tok · 4.1s — 그 호출의 전체 토큰(input+output)과 소요시간
  • 챗 헤더에 세션 컨텍스트 게이지 — 현재 점유 / 한도(기본 128k), 70%↑ 주황·90%↑ 빨강

없는 것:

  • 돈이 얼마 나갔는지가 어디에도 안 보임. 메시지 계약에 비용 필드(costUsd)가 자리는 있는데 화면에서 한 번도 안 씀
  • 입력 토큰 / 출력 토큰이 따로 안 보임 — 합계만 보임
  • 대화 하나를 통틀어 누적 얼마 썼는지 안 보임 (헤더 게이지는 "직전 호출 점유량"이지 누적이 아님)

그래서 이 feature 의 본체는 비용 노출이고, 토큰 표시는 거기에 붙는 보강.

User Scenarios & Testing (mandatory)

User Story 1 - 답변마다 얼마 썼는지 보기 (Priority: P1)

사용자가 질문을 하고 답변을 받으면, 그 답변 바로 아래에 토큰 수와 함께 이 한 번의 답변에 든 비용이 보인다. 답변이 길어지거나 컨텍스트가 커졌을 때 "방금 게 비쌌구나"를 그 자리에서 안다.

Why this priority: 비용을 아예 못 보는 게 지금의 유일한 진짜 결핍. 이거 하나만 있어도 "내가 쓰는 만큼 돈이 나간다"는 감각이 생겨서 MVP 로 성립함.

Independent Test: 대화 하나 보내고 답변 말풍선 아래에 비용이 찍히는지, 새로고침 후 그 대화를 다시 열어도 같은 값이 남아있는지로 단독 검증 가능.

Acceptance Scenarios:

  1. Given 사용자가 챗에 질문을 보내 답변이 끝난 상태, When 답변 말풍선 아래를 보면, Then 토큰 수·비용·소요시간이 한 줄로 보인다
  2. Given 예전에 나눈 대화, When 그 대화를 다시 열면, Then 각 답변에 그때의 비용이 그대로 보인다 (다시 계산하지 않음)
  3. Given 비용 정보가 없는 답변(옛 데이터·서버가 값을 안 줌), When 그 답변을 보면, Then 비용 칸만 빠지고 토큰·시간은 그대로 보인다 (빈칸이나 0 을 억지로 안 보여줌)

User Story 2 - 이 대화에 지금까지 얼마 썼는지 보기 (Priority: P2)

사용자가 대화창 위쪽에서 이 대화방 전체의 누적 토큰과 누적 비용을 본다. 길게 이어온 대화가 얼마나 비싼지 한눈에 판단하고, 새 대화로 갈아탈지 정한다.

Why this priority: 답변별 비용(US1)만 있으면 사용자가 머리로 더해야 함. 누적이 있어야 "이 대화 접고 새로 팔까"라는 결정을 할 수 있음. 다만 US1 없이 이것만 있으면 어디서 비쌌는지 못 짚어서 후순위.

Independent Test: 한 대화에서 3번 질문한 뒤 헤더의 누적값이 세 답변 비용의 합과 맞는지로 검증.

Acceptance Scenarios:

  1. Given 답변이 3개 쌓인 대화, When 헤더를 보면, Then 누적 토큰과 누적 비용이 보이고, 그 값은 각 답변에 찍힌 값의 합과 같다
  2. Given 대화 도중 새 답변이 끝남, When 그 순간, Then 누적값이 바로 늘어난다 (새로고침 필요 없음)
  3. Given 새 대화를 시작, When 아직 답변이 없으면, Then 누적값은 0 이거나 표시되지 않는다
  4. Given 비용을 모르는 답변이 섞인 대화, When 누적을 보면, Then 아는 것만 더한 값임을 사용자가 알 수 있다 (예: 표기 또는 안내 문구)

User Story 3 - 입력/출력 나눠 보기 (Priority: P3)

사용자가 토큰 표시에 마우스를 올리면 입력 토큰과 출력 토큰이 따로 보인다. 비용이 컨텍스트(입력) 때문인지 긴 답변(출력) 때문인지 구분한다.

Why this priority: 진단용 정보라 없어도 기능은 성립. 화면을 안 어지럽히려면 평소엔 숨기고 올렸을 때만 보이는 게 맞음.

Independent Test: 답변의 토큰 표시에 hover 해서 입력·출력 값이 나뉘어 나오는지로 검증.

Acceptance Scenarios:

  1. Given 답변에 토큰 수가 찍혀 있음, When 그 위에 마우스를 올리면, Then 입력 N / 출력 M 이 따로 보인다
  2. Given 입력·출력 중 하나만 알려진 답변, When hover 하면, Then 아는 쪽만 보인다

Edge Cases

  • 답변 도중 사용자가 중지를 눌러 스트림이 끊긴 경우 — 그때까지의 비용을 보여줄지, 아무것도 안 보여줄지
  • 비용이 아주 작을 때(반올림하면 0 이 되는 값) — $0.00 으로 보이면 공짜처럼 오해되므로 <$0.01 같은 표기 필요
  • 비용이 0 인 게 진짜일 때(무료 모델·캐시 히트) — 위와 구분되어야 함
  • 서버가 비용을 안 내려주는 경우 — 전체 기능이 조용히 빈칸이 되어야 하고 에러나 깨진 UI 가 되면 안 됨
  • 대화 도중 모델이 바뀐 경우 — 답변마다 단가가 다르므로 누적은 답변별 값의 단순 합이어야 함(대표 단가로 재계산 금지)
  • 통신이 끊겼다가 폴링으로 답변이 뒤늦게 복구된 경우 — 비용도 같이 복구되어야 하고 중복 합산되면 안 됨

Requirements (mandatory)

Functional Requirements

  • FR-001: 시스템은 완료된 각 답변에 대해 그 호출의 비용을 답변 옆(아래)에 보여줘야 한다
  • FR-002: 시스템은 각 답변의 토큰 수를 계속 보여줘야 한다 (기존 표시 유지)
  • FR-003: 시스템은 비용 값을 서버가 알려준 값 그대로 보여줘야 하며, 화면에서 임의로 다시 계산하지 않는다 [NEEDS CLARIFICATION: 비용을 서버가 실제로 내려주는가? 안 내려주면 화면에서 모델별 단가표로 계산해야 하는데 그건 범위가 달라짐]
  • FR-004: 비용을 모르는 답변은 비용 부분만 생략하고 나머지 정보는 정상 표시해야 한다 (0 으로 대체 금지)
  • FR-005: 시스템은 반올림하면 0 이 되는 아주 작은 비용을 "0" 이 아닌 별도 표기(예: 최소 표시 단위 미만)로 보여줘야 한다
  • FR-006: 시스템은 대화방 단위 누적 토큰·누적 비용을 대화 화면 상단에서 보여줘야 한다
  • FR-007: 누적값은 새 답변이 끝나는 즉시 갱신되어야 한다
  • FR-008: 누적값은 개별 답변 값들의 단순 합이어야 하며, 값이 없는 답변은 합에서 빠지되 사용자가 "일부 누락"임을 알 수 있어야 한다
  • FR-009: 예전 대화를 다시 열면 저장된 토큰·비용이 그대로 복원되어야 한다
  • FR-010: 사용자는 토큰 표시에서 입력 토큰과 출력 토큰을 나눠 확인할 수 있어야 한다
  • FR-011: 비용 표시 화폐 단위는 일관되어야 한다 [NEEDS CLARIFICATION: 달러 그대로 보여줄지, 원화로 바꿔 보여줄지 — 원화면 환율 출처와 갱신 주기가 추가 범위]
  • FR-012: 이 기능은 기존 컨텍스트 점유 게이지(현재 점유 / 한도)와 공존해야 하며, 둘의 의미가 헷갈리지 않게 구분되어 보여야 한다
  • FR-013: [NEEDS CLARIFICATION: 대화방을 넘어선 기간 단위 사용량(오늘/이번달 총 얼마)까지 이번 범위인지 — 이건 화면·저장·집계가 따로 필요해서 범위가 크게 달라짐]

Key Entities

  • 답변 사용량: 답변 하나에 딸린 값 — 입력 토큰, 출력 토큰, 비용, 소요시간. 답변과 함께 저장되어 다시 열어도 남음
  • 대화 누적 사용량: 한 대화방 안 모든 답변 사용량의 합. 저장되는 값이 아니라 그때그때 더해서 보여주는 값
  • 컨텍스트 점유량: (기존) 다음 호출에 실릴 대화 길이 / 한도. 누적 사용량과 다른 개념 — 누적은 계속 늘고, 점유량은 늘었다 줄 수 있음

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: 답변이 끝난 뒤 사용자가 추가 조작 없이 그 답변의 비용을 확인할 수 있다 (클릭·이동 0회)
  • SC-002: 사용자가 대화 하나의 총 지출을 확인하는 데 3초 이내, 화면 이동 없이 가능하다
  • SC-003: 표시된 답변별 비용의 합과 화면에 표시된 누적 비용이 100% 일치한다
  • SC-004: 비용 정보가 전혀 없는 환경에서도 대화 기능은 아무 문제 없이 동작하고, 화면에 깨진 표시나 오류 문구가 나오지 않는다
  • SC-005: 예전 대화를 다시 열었을 때 표시되는 토큰·비용이 당시 값과 100% 일치한다
  • SC-006: 비용 표시가 추가되어도 답변 렌더링 체감 속도에 눈에 띄는 지연이 없다

Assumptions

  • 이 기능은 읽기 전용 표시다. 예산 한도 설정·초과 시 차단·경고 알림 같은 건 이번 범위 밖
  • 사용량 값의 진실원천은 서버다. 화면은 받은 값을 보여주기만 하고 스스로 토큰을 세지 않는다
  • 사용자는 자기 대화만 본다. 다른 사람 사용량이나 팀 전체 집계는 범위 밖
  • 기존 컨텍스트 점유 게이지는 그대로 둔다. 이번 작업은 거기에 비용을 얹는 것이지 갈아엎는 게 아님
  • 표시 위치·모양은 기존 답변 하단 메타 줄과 헤더를 재사용한다. 새 패널·새 화면은 만들지 않음
  • 비용이 화면에서 계산되어야 한다면(FR-003 이 아니라고 판명되면) 모델별 단가표를 어딘가 두고 관리해야 하며, 그건 별도 범위로 다시 잡는다