제 2 장
요구사항 분석
1) 문제 정의
제 1 장의 배경을 시스템이 풀어야 할 문제로 좁히면 넷이다.
P1. 예측의 근거가 남지 않는다. 승자만 저장하면 그 예측이 무엇을 보고 나온 것인지 사후에 알 수 없다. 모델을 다시 불러 같은 답이 나오는지 확인하는 것은 근거의 재구성이 아니다 — 그 사이 코퍼스도 모델도 바뀐다.
P2. 결과를 읽고 낸 예측이 성능으로 집계된다. 대회 문서에는 경기 결과가 적혀 있다. 그것을 근거로 검색해 온 예측은 겉보기에 정확하고, 적중률만 세면 구별되지 않는다.
P3. 시간을 확인할 수 없는 자료가 섞인다. 글이 언제 쓰였는지 모르면 “그때 있던 정보”인지 판정할 수 없다. 모른다는 사실 자체가 기록돼야 하며, 모름을 통과로도 실격으로도 처리해서는 안 된다.
P4. 표본이 작은데 숫자가 커 보인다. 12건 중 12건을 맞히면 적중률 100%다. 분모 없이 그 백분율만 세우면 과장이 된다.
2) 사용자 요구사항
| # | 요구 | 근거 |
|---|---|---|
| U1 | 다가오는 PLE의 대진을 보고 경기별로 픽을 고를 수 있어야 한다 | 제품의 기본 동작 |
| U2 | 경기 형식에 따라 난이도가 다르므로 배점도 달라야 한다 | 6인 래더와 싱글을 같은 점수로 치면 순위가 운을 따른다 |
| U3 | 제출한 픽은 잠기고, 결과가 나오면 자동으로 채점돼야 한다 | 사후 수정이 가능하면 순위가 의미를 잃는다 |
| U4 | AI가 왜 그 선수를 골랐는지 근거 문장을 볼 수 있어야 한다 | 승자만 보여 주면 신뢰할 근거가 없다 |
| U5 | AI의 적중률을 믿어도 되는지를 함께 알 수 있어야 한다 | P2 · P4 |
| U6 | 선수·경기·챔피언십 기록을 찾아볼 수 있어야 한다 | 예측의 재료 |
U5가 이 프로젝트를 정의하는 요구다. 나머지 다섯은 예측 서비스라면 대체로 갖는 것이고, U5가 있어서 AI LAB이라는 화면 묶음이 따로 선다.
3) 기능 요구사항
예측·랭킹
- F1 대진표 관리 — 대진의 원본은 프론트 픽스처이고, 방문자가 페이지를 열 때 동기화 API로 DB에 반영된다. 위키에서 대진을 읽어 픽스처를 갱신하는 도구가 그 앞단에 있다.
- F2 픽 제출 — 경기 단위로 제출하며 제출 즉시 잠긴다.
- F3 채점·배점 — 경기 형식과 타이틀 여부로 점수가 결정된다(제 5 장 3절).
- F4 라이브 갱신 — 진행 중인 대회의 투표 현황을 서버가 밀어 준다.
데이터 센터
- F5 선수·경기·챔피언십 집계 — 같은 선수의 전적이 화면마다 달라지지 않도록 집계 규칙을 한 모듈에 둔다.
- F6 표본이 모자라면 숫자를 내지 않는다 — 0%로 채우지 않고 칸을 비운다.
AI LAB
- F7 예측 생성 — 세 에이전트가 각자 리포트를 내고 합성한다.
- F8 계보 기록 — 검색 질의 · 읽은 청크의 본문과 개정본 시각을 예측과 함께 저장한다.
- F9 자격 판정 — 여덟 규칙으로 제외·실격·보류를 가른다.
- F10 재현 — 저장된 값으로 질의 조립과 리포트 합성을 다시 돌려 대조한다.
- F11 누수 귀속 — 어느 문서가 어느 예측을 막았는지 보여 준다.
- F12 준비도 — 예측을 만들기 전에 그 대회의 코퍼스가 깨끗한지 본다.
4) 비기능 요구사항
| # | 요구 | 어떻게 강제하는가 |
|---|---|---|
| N1 | 도메인 로직이 프레임워크·DB를 모른다 | 헥사고날 레이어 + import-linter 계약 |
| N2 | 앱 사이의 의존은 허브를 통해서만 | 스타 토폴로지 계약 (스포크 ↔ 스포크 금지) |
| N3 | 없는 값을 지어내지 않는다 | 표본 부족 시 None 반환 · 화면이 사유를 적는다 |
| N4 | 판정 규칙은 한 곳에서만 정의된다 | 화면과 배치 스크립트가 같은 유스케이스를 부른다 |
| N5 | 쓰기 스크립트는 기본이 드라이런 | --apply 없이는 출력만 |
| N6 | 무료 LLM 등급의 하루 한도 안에서 돈다 | 모델별 분산 + 하루 경기 수 상한 |
| N7 | 회귀는 커밋 전에 막는다 | pre-commit 훅 10종 + GitHub Actions |
N3과 N4가 가장 자주 부딪히는 요구다. 화면이 “이 대회는 깨끗하다”고 말하는데 배치 스크립트가 따로 세어 건너뛰면, 둘 중 어느 쪽이 맞는지 아무도 모르는 상태가 된다. 그래서 자동 생성 스크립트는 준비도를 자기가 계산하지 않고 /ai-lab/readiness가 부르는 유스케이스를 그대로 부른다.