From 77bd211bce821bddd40b135028e959ad26a6bb78 Mon Sep 17 00:00:00 2001 From: Variet Agent Date: Wed, 18 Mar 2026 21:25:19 +0900 Subject: [PATCH] =?UTF-8?q?fix(prompt):=20anime=20=EB=B6=84=EB=A5=98=20?= =?UTF-8?q?=EC=A0=95=ED=99=95=EB=8F=84=20=EA=B0=95=ED=99=94=20(6/6=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=86=B5=EA=B3=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - NAS/자막/애니 키워드 포함시 task 대신 anime 우선 분류 - nextcloud 판단 기준 별도 섹션 추가 - anime/nextcloud 키워드 우선 규칙 명시 --- _test_classify.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++ prompts/unified.md | 14 +++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 _test_classify.py diff --git a/_test_classify.py b/_test_classify.py new file mode 100644 index 0000000..2ae221c --- /dev/null +++ b/_test_classify.py @@ -0,0 +1,55 @@ +"""분류 정확도 테스트.""" +import asyncio +import io +import json +import sys + +sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace") +sys.path.insert(0, ".") + +from core.gemini_caller import GeminiCaller + + +def extract_mode(raw): + start = raw.find("{") + if start == -1: + return "NO_JSON" + depth = 0 + for i in range(start, len(raw)): + if raw[i] == "{": + depth += 1 + elif raw[i] == "}": + depth -= 1 + if depth == 0: + try: + p = json.loads(raw[start : i + 1]) + return p.get("mode", "?") + except json.JSONDecodeError: + return "PARSE_ERR" + return "NO_CLOSE" + + +async def main(): + g = GeminiCaller() + tests = [ + ("anime", "nas에 애니 자막 나온거까지 최신화 해줘"), + ("anime", "이번 분기 신작 애니 편성표 보여줘"), + ("nextcloud", "클라우드에 pdf파일 몇개나 있어?"), + ("nextcloud", "오늘 일정 뭐야?"), + ("chat", "파이썬 리스트 정렬 어떻게 해?"), + ("chat", "3 더하기 5는?"), + ] + + ok = 0 + for expected, text in tests: + raw = await g.call("unified", f"## User Message\n{text}", timeout=60) + got = extract_mode(raw) + mark = "OK" if got == expected else "FAIL" + if mark == "OK": + ok += 1 + print(f" [{mark}] expected={expected} got={got} -- {text}") + + print(f"\nResult: {ok}/{len(tests)} passed") + + +asyncio.run(main()) diff --git a/prompts/unified.md b/prompts/unified.md index 9067f92..36458f4 100644 --- a/prompts/unified.md +++ b/prompts/unified.md @@ -13,17 +13,29 @@ - **판단 불가** → `mode: "clarify"` ### anime 판단 기준 -다음 키워드/의도가 포함되면 `anime`로 분류: +다음 키워드/의도가 **하나라도** 포함되면 반드시 `anime`로 분류 (task 아님): - 애니메이션/애니 자막 다운로드, 영상 다운로드 - 편성표 확인, 이번 분기 애니, 신작 - NAS에 저장, 토렌트, nyaa, 자막 수집 - 특정 애니 제목 언급 + 다운/검색/모아줘 등 +- 자막 최신화, NAS 최신화, 자막 업데이트 +- 애니 + 다운/저장/수집/최신/업데이트/목록/리스트 + +> **중요**: "NAS", "자막", "애니" 키워드가 포함된 요청은 코드 변경이 아닌 **도구 실행**이므로 **반드시 anime**입니다. task로 분류하면 안 됩니다. + +### nextcloud 판단 기준 +다음 키워드/의도가 포함되면 `nextcloud`로 분류: +- 파일, 클라우드, 문서, 드라이브 + 찾기/검색/열기/보여줘 +- 일정, 캘린더, 스케줄, 약속, 미팅 +- 메일, 이메일, 편지 +- 연락처, 명함 ### 추가 원칙 - **확신이 없으면 chat**으로 대응하세요. - "분석해줘", "제안해줘" 등은 **대부분 대화**입니다. - "만들어줘", "수정해줘" 등은 문맥을 보세요. 파일/코드 변경이면 task. - 에러/버그 수정 요청 → **task**. +- **anime/nextcloud 키워드가 있으면 해당 모드 우선** (task보다 우선) ## 출력 형식 (반드시 JSON)