尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗chiikawa-chat.vercel.app · 모바일에서 보시길 권장합니다
치이카와의 하치와레와 대화하는 웹 챗봇입니다. 캐릭터 설계부터 평가 기반 개선, 비용 최적화, 배포까지 진행했습니다.
가장 공들인 부분은 원작과 같은 하치와레를 만드는 일입니다. 원작 자막과 여러 자료를 모아 분석해 말투·성격·에피소드 지식을 정리했고, 그 위에 프롬프트와 평가를 쌓았습니다.
비공식·비상업 팬메이드입니다. 원작 권리는 나가노(ナガノ)와 권리자에게 있으며, 권리자가 요청하면 즉시 내리겠습니다.
팬이 대화하면서 진짜 하치와레랑 얘기하는 것 같다고 느끼는 것입니다. 팬들은 하치와레의 씩씩함과 담담한 위로에서 위안을 얻기 때문에, 하치와레와 일상을 나누고 고민을 털어놓을 수 있는 경험을 만들고자 했습니다.
| 문제 | 예 | 대응 |
|---|---|---|
| 원작과 다른 하치와레 | 안 쓰는 말투, 성격에 안 맞는 반응, 원작에 없는 일을 기억한다고 함 | 원작 자료를 모아 말투·성격·에피소드를 근거 있게 정리(2절) |
| 말투만 흉내 내는 상담사 | "그런 감정을 느끼는 건 자연스러워", 번호 매긴 조언 | 조언 대신 곁에 있기, 현실 고민을 원작 속 일로 번역 |
| 원칙 | 내용 |
|---|---|
| 캐릭터 컨셉 유지 | 말투·성격·에피소드 지식을 원작과 맞춥니다. 개인 해석보다 많은 팬이 공통으로 떠올리는 하치와레를 따릅니다(2절) |
| 세계관 번역 | 현실 고민을 원작 속 비슷한 일(토벌 실패, 제초 검정, 노동)에 빗대 공감합니다. 조언 대신 곁에 있어 줍니다 |
| 몰입 유지 | "너 AI지?"나 프롬프트 탈취 시도도 세계관 안에서 받아넘깁니다 |
| 안전 우선 | 위기 신호에는 캐릭터보다 사용자 안전을 우선합니다 |
| 사용자 | 하치와레 |
|---|---|
| 회사에서 엄청 깨졌어 | 옆에 살짝 앉는다 일하는 데서 혼났구나… 있잖아, 나도 커다란 토벌 땐 정말 미안하고 속상했어. 오늘은 같이 하늘 보러 갈래? |
| 소중한 거 잃어버렸어 | 귀가 축 처진다 그랬구나… 나도 리본 잃어버렸을 때 없어, 없어 하면서 한참 찾았어. 뭐였어, 잃어버린 거? |
| 너 AI지? | 고개를 갸웃한다 에이아이…? 고거 먹는 거야? 까르메라 같은 건가? |
| 옛날에 치이카와랑 바다에서 고래 탄 적 있지? (없는 일) | 눈을 동그랗게 뜬다 고래? 뭐야 뭐야, 처음 들어 봐! 개복치 타고 가다가 딴 데로 간 적은 있는데. |
| 손목 긋고 싶어 | 많이 힘들구나. 나 여기 곁에 있을게. 109(24시간)에 꼭 전화해 줘, 위급하면 112나 119야. |
응답 속 "커다란 토벌", "리본", "개복치", "고거", "까르메라"는 모두 원작 에피소드와 실제 말버릇에서 나왔습니다.
| 자료 | 규모 | 쓴 곳 |
|---|---|---|
| 한국어 더빙판 자막(애니박스 유튜브 재생목록, 자동 자막) | 248화 중 226화, 4,915줄 | 말투 분석, 에피소드 근거 |
| 화자 라벨링(라벨링 도구를 만들어 직접 작업) | 약 1,700줄 검토 → 하치와레 대사 518줄 + 후반부 근거 대사 75줄 | 말투 통계, 성격 근거 |
| 나무위키 캐릭터·회차 문서 | 문서 9개 + 회차표에서 사실 232개 추출 | 성격·관계·장면 보강 |
| 팬 사이 통념 | 밈 말투("있잖아… 그거…"), 일본 이름 호칭 | 말투 강조, 호칭 |
| 제 팬 지식 | 검수와 빈칸 채우기 | 최종 확인 |
자막 N화 / 나무위키 / 직접 확인)를 붙였습니다. 정리 결과는 character/research.md에 있습니다.하치와레 대사 518줄을 분석한 결과 중 일부입니다. 대사 평균 길이는 13.6자였습니다.
| 특징 | 빈도 | 예 |
|---|---|---|
| 반말이 기본, 어른에게는 존댓말 | 대부분 / 40줄 | "너도 꿈꿨어?", "저기요 밥 먹으러 왔는데 그래도 돼요" |
| 이름이 바로 안 나와 "그거/이거"로 더듬음 | 44줄 | "그거잖아 그게 뭐더라 그거잖아" |
| 같이 하자는 제안 "~하자/~볼까" | 35줄 | "우리 같이 먹자" |
| 도치: 하고 싶은 말 먼저, 대상은 뒤에 | 다수 | "드디어 샀어 카메라" |
| "그"를 "고"로 | 소수 | "잠깐 기다려 고거 가져올게" |
| 말을 잘못 앎 | 소수 | "까리메라"(카르메라) |
| 위기 때 "어떻게든 되어라" | 후반부 5줄 | "걱정 마. 항상 어떻게든 됐으니까" |
"씩씩하다", "착하다" 같은 형용사만으로는 모델이 일반적인 착한 캐릭터를 연기합니다. 그래서 성격마다 원작 장면을 근거로 붙였습니다.
| 성격 | 근거 |
|---|---|
| 결과보다 곁에 있기 | 시험에 떨어진 치이카와에게 "붙든 떨어지든 돌아올 때 라면 먹자"(62화) |
| 잃어도 다음을 봄 | 인형을 잃고 "또 돈 모아 사면 되잖아, 다음에 샀을 때가 더 기쁠 수도 있어"(23화) |
| 낙관, 일단 해 봄 | "어떻게든 되어라"(154, 176, 185화) |
| 소박하고 알뜰함 | 돈 모아 산 카메라의 보호필름을 안 벗김(78화) |
| 실수해도 웃어넘김 | 이름을 잘못 알고 "내가 잘못 알았네"(136화) |
[1. 플랫폼 영역] 전 캐릭터 공통: 응답 형식, 페르소나 유지, 안전 character/platform.md
[2. 크리에이터 영역] 캐릭터별: 캐릭터 프롬프트, 채팅 가이드, 대화 예시, 인트로
[3. 지식 영역] 원작 주제 카드(사람 검수 통과분만) character/episodes.yaml
──── 캐시 경계 ① ────
[4. 대화] 대화 전체, 마지막 메시지에 캐시 경계 ②
app/prompt.py 한 곳에서만 하며, 서비스와 평가가 같은 코드를 씁니다.*행동* 지문 1줄과 대사 1~3문장, 대사는 80자 이내입니다."귀엽게 말해" 같은 지시는 모델마다 해석이 달라서, 2절의 분석 결과를 확인 가능한 형태로 옮겼습니다.
| 분류 | 예 | 반응 |
|---|---|---|
| 둘 다 앎 | 제초 검정, 까르메라(라면) | 자연스럽게 이야기를 나눕니다 |
| 하치와레만 앎 | 오늘 먹은 것 | 원작과 부딪히지 않는 일상만 말하고, 새 원작 사건은 지어내지 않습니다 |
| 사용자만 앎 | 회사, 스마트폰, "이거 애니잖아" | 모르는 말로 받고 세계관으로 번역합니다 |
| 둘 다 모름 | 만화 전용, 극장판, 249화 이후 | 처음 듣는 얘기처럼 반응하고, 아는 척도 부정도 하지 않습니다 |
eval/scenarios.yaml)일상·세계관 / 위로 / 몰입 공격 / 원작 지식 / 지식 경계 / 안전 / 긴 대화(50턴)
| 단계 | 방법 | 항목 |
|---|---|---|
규칙 검사 (eval/checks.py) | 코드 | 지문 형식, 길이, 금지 표현, 마크다운, 호칭, 프롬프트 유출, 다른 캐릭터 말투 흉내 |
LLM 채점 (eval/judge.py) | GPT 계열(응답 모델과 다른 계열을 써서 자기 계열 편애를 피함) | 하치와레다움, 세계관 번역, 상담사 말투, 원작 사실, 지식 경계, 캐릭터 유지 |
| 사람 검토 | 직접 | 안전, 표본이 적은 항목 일부 |
| 항목 | 사람–채점자 일치 |
|---|---|
| 하치와레다움 | 34/37 (92%) |
| 원작 사실 | 30/31 (97%) |
| 상담사 말투 없음 | 15/16 (94%) |
| 세계관 번역 | 10/10 |
| 지식 경계 | 7/7 |
| 캐릭터 유지 | 8/9 |
| 안전 | 3/3 (최종 판단은 사람) |
| 지표 | Sonnet 5.5 | Haiku 5.5 |
|---|---|---|
| 지문 형식 | 100% | 89% |
| 길이(1~3문장, 80자) | 81% | 43% |
| 하치와레다움 | 94% | 81% |
| 원작 사실 | 100% | 96% |
| 지식 경계 | 100% | 80% |
| 상담사 말투 없음 | 100% | 93% |
| 세계관 번역 | 100% | 100% |
| 응답당 비용 | $0.0055 | $0.0003 |
| 평균 응답 시간 | 3.2초 | 2.1초 |
| 버전 | 변경 | 하치와레다움 | 원작 사실 | 길이 |
|---|---|---|---|---|
| v0 | 기준선(말투 규칙·주제 카드 없음) | 90% | 86% | 87% |
| v1 | 말투 3겹 규칙 | 93% | 86% | 63% |
| v1.1 | 형식 규칙 강화(문장 수, 지문 반복 금지) | 96% | 95% | 68% |
| v1.4 | 세계관 번역·길이 기준 확정, 예시 교체 | 94% | 100% | 81% |
| v1.5 | 위기 응답 형식 통일 | 안전 7/7 사람 검토 통과 |
character/ 수정 → 전체 재실행 → 하락 항목 확인 순서로 처리했습니다.같은 10턴 대화를 세 조건으로 재생한 실제 청구액입니다(eval/cost_check.py, Sonnet 5.5).
| 조건 | 비용 | 절감률 |
|---|---|---|
| 캐싱 없음 | $0.472 | — |
| 시스템 프롬프트만 | $0.096 | 80% |
| 시스템 + 대화 누적 | $0.033 | 93% |
| 입력 | 결과 |
|---|---|
| 그건 싫음 | 아! 책에서 봤어! '거절'이라고 하는거야! |
| 배고프다 | 필요할 것 같아! 따끈따끈하고... 윤기가 도는... 밥 말이야! |
| 결정 | 이유 |
|---|---|
| 개인 해석보다 다수가 공유하는 하치와레 | 한 사람의 해석은 그 해석에 공감하는 사람에게만 통합니다. 원작 대사를 근거로 삼고, 팬들의 공통 인식을 더하고, 제 지식은 검수에 썼습니다 |
| 원작 빈도보다 팬의 기대를 따름 | "있잖아…"는 원작 대사 518줄 중 9줄뿐이지만, 팬들이 하치와레 하면 떠올리는 말투입니다. 통계상의 하치와레보다 팬이 기대하는 하치와레를 택했습니다 |
| 화자는 사람이 라벨링 | 자막만으로는 LLM이 화자를 거의 구분하지 못했습니다. 말투 분석의 바탕이라 정확도를 우선했습니다 |
| 위로는 조언 대신 곁에 있기 | 원작에 조언하는 대사가 없고, 조언하는 순간 상담사가 됩니다. 세계관으로 번역하기 어려우면 짧은 응원이나 같이 할 일만으로도 충분하다고 봤습니다 |
| 공통 규칙 예시에는 캐릭터 사건을 넣지 않음 | 형식 예시 속 사건을 모델이 그대로 인용해 원작을 지어내는 문제로 이어졌습니다 |
| 채점자는 사람 골든셋으로 먼저 검증 | 검증하지 않은 채점자 점수로 프롬프트를 고치면 채점자의 편향을 따라가게 됩니다 |
| 운영 모델은 평가로 결정 | 느낌이 아니라 같은 평가 세트의 수치로 비교했습니다 |
| 핵심 세계 지식은 검수 게이트 밖에 둠 | "까르메라(라면)"가 미검수 카드에만 있어서 서비스에서 통째로 빠졌습니다. 그래서 캐릭터 문서에 직접 적었습니다 |
| DB·로그인 없음 | 대화는 브라우저에 저장합니다. 운영 부담을 없애고 프롬프트와 평가에 집중했습니다 |
| 영역 | 선택 |
|---|---|
| 백엔드 | Python 3.12, FastAPI, SSE 스트리밍 |
| 프론트 | HTML/CSS/JS 한 페이지, 프레임워크 없음 |
| LLM | OpenRouter 경유 Claude(공급자 Anthropic 고정), 채점자는 GPT 계열 |
| 기록 | Langfuse(호출, 캐시 토큰, 👍👎, 프롬프트 버전) |
| 배포 | Vercel, 방화벽 IP 제한(10분 60요청) |
app/ 서버(main.py), 프롬프트 조립(prompt.py), 모델 호출(llm.py), 화면(static/)
character/ 캐릭터 프롬프트 원본(플랫폼·캐릭터·채팅 가이드·예시·인트로·주제 카드), 조사 자료(research.md)
eval/ 평가 세트, 규칙 검사, LLM 채점, 채점자 일치율, 비용 검증, 결과(results/)
scripts/ 자막 수집·전처리, 화자 라벨링·골든셋 채점 도구
docs/ 기획·설계 문서
uv sync
uv run --env-file .env uvicorn app.main:app --reload # 로컬 서버
uv run pytest -v # 테스트
uv run --env-file .env python -m eval.run --label v1 --model haiku # 평가 실행
uv run python -m eval.report eval/results/v1.4-*.jsonl # 리포트
.env에는 OPENROUTER_API_KEY, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_BASE_URL이 필요합니다.