v2.2.323: /naver-trend contains 모드 — "분야 + 포함단어 + 기간"으로 검색어 뽑기

`/naver-trend 경제 방법 8월1일부터 오늘까지` → 경제 분야 인기 검색어 중
"방법"이 들어간 것을 검색량 상위 10개로.

- contains 모드(intentParser): topic/containsWord/limit 추출 + 포함 단어를
  가진 후보 최대 30개 제안. 포함 여부는 LLM을 믿지 않고 keywordContains()로
  코드에서 재검사(공백 무시, 단어 자체만인 후보 제외). 후보가 얇으면
  generateContainingKeywords()로 보충. containsWord가 비면 discover로 강등.
- rankKeywordsAnchored: 검색어트렌드 ratio는 "요청 하나 안에서" 최댓값=100인
  상대값이라 5개씩 끊어 호출하면 6위 이하 순위가 무의미했다. 첫 배치 최댓값을
  앵커로 잡아 모든 배치에 끼워 넣고 되돌린 뒤 1위=100으로 재정규화. 정렬은
  하루치 최신값 대신 구간 평균(avgRatio).
- dateRange.ts 신설: 기간을 LLM에 맡기지 않고 규칙으로 확정 —
  "8월1일부터 오늘까지", "8/1~8/10", "최근 일주일", "지난 30일", "최근 한 달".
  연도 생략 시 미래면 작년. 범위 연결어 없는 날짜 나열/버전 문자열은 미인식.
- 날짜 UTC 밀림 수정: toISOString() → ymdLocal() (KST 새벽에 "오늘"이 하루 전으로
  밀리던 문제). 긴 구간은 timeUnit을 week/month로 자동 하향.

검증: tsc 무오류 + jest 1044 통과(신규 24) + esbuild 정상.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-11 21:43:08 +09:00
co-authored by Claude Opus 5
parent b61e06ef41
commit 0b315b9c6a
16 changed files with 767 additions and 45 deletions
+10
View File
@@ -1,5 +1,15 @@
# Astra Patch Notes
## v2.2.323 (2026-08-11)
### 🔎 `/naver-trend` contains 모드 — "분야 + 포함단어 + 기간"으로 검색어 뽑기
사용자 요청: `/naver-trend 경제 방법 8월1일부터 오늘까지` 처럼 쓰면 경제 분야 인기 검색어 중 "방법"이 들어간 것을 검색량 상위 10개로 달라. 기존엔 `<카테고리> <기간>` 조회만 가능했다.
- **contains 모드 추가(intentParser)**: `compare`/`discover` 에 이어 세 번째 모드. LLM 이 `topic`(분야)·`containsWord`(포함 단어)·`limit` 을 뽑고, 그 분야에서 실제 검색될 법하면서 해당 단어를 포함하는 후보를 최대 30개 제안한다. **포함 여부는 LLM 을 믿지 않고 `keywordContains()` 로 코드에서 재검사**(공백 무시, 단어 자체만인 후보 제외). 후보가 얇으면 `generateContainingKeywords()` 로 한 번 더 채운 뒤 검증에 들어간다. `containsWord` 가 비면 필터 없이 조회되는 사고를 막으려 discover 로 강등.
- **배치 경계를 넘는 순위 보정(`rankKeywordsAnchored`)**: 검색어트렌드 ratio 는 *요청 하나 안에서* 최댓값을 100 으로 두는 상대값이라, 기존 `rankKeywords` 처럼 5개씩 끊어 호출하면 배치마다 기준이 달라져 6위 이하 순위가 사실상 무의미했다(후보 30개를 줄 세우려면 치명적). 첫 배치 최댓값 키워드를 **앵커로 잡아 이후 모든 배치에 끼워 넣고 `앵커의 1배치 값 / 현재 배치 값` 으로 배치 전체를 되돌린 뒤** 1위=100 으로 재정규화한다. 정렬 기준도 하루치 최신값이 아니라 조회 구간 평균(`avgRatio`) — 기간 질문의 대표값은 이쪽이다.
- **한국어 기간 파서 신설(`dateRange.ts`)**: 기간은 결과 전체를 좌우하는 축인데 LLM 이 "오늘"과 연도 추론을 자주 틀린다. `8월1일부터 오늘까지` · `8/1~8/10` · `2026년 8월 1일부터` · `최근 일주일` · `지난 30일` · `최근 한 달` 을 규칙으로 먼저 확정하고, 못 읽은 경우에만 LLM 판정으로 넘긴다. 연도 생략 시 미래 날짜면 작년으로 해석. 범위 연결어(부터/~/까지) 없는 날짜 나열이나 버전 문자열(`2.2.322`)은 기간으로 오독하지 않는다.
- **날짜 UTC 밀림 수정**: `toISOString().slice(0,10)` 은 UTC 로 잘려 KST 새벽 0~9시에 "오늘"이 하루 전으로 밀렸다 — 로컬 시간 기준 `ymdLocal()` 로 교체. 긴 구간은 timeUnit 을 자동으로 week/month 로 낮춘다(일 단위로 뽑으면 포인트가 수백 개).
- **한계 명시**: 네이버엔 "분야 안의 인기 검색어 목록" API 가 없다(지정 키워드의 상대 지수만 반환). 후보 생성은 LLM, 검증·랭킹은 실제 API 인 2단 구조이므로 "후보에 없던 검색어는 순위에 나올 수 없음"을 결과 하단에 고정 표시.
검증: tsc 무오류 + jest 1044 통과(신규 24) + esbuild 정상.
## v2.2.322 (2026-08-05)
### 🛍️ 네이버 트렌드 — 구체적 모델명 제안 + ratio 라벨 명확화
사용자 피드백: 인기 키워드 결과에 "노트북"처럼 카테고리명만 반복돼 실제 쓸 정보가 없음(구체적 모델까지 알고 싶음) + "클릭률"까지 보고 싶음.