Add team persona packs for the remaining 8 KBO clubs.

- KT·NC·SSG·LG·KIA·롯데·삼성·키움 8개 구단의 팀 페르소나 팩을 추가해 DEFAULT_TEAM_PERSONAS가 10개 구단 전체를 커버하도록 했습니다(이전에는 HH·OB만 실팩, 나머지는 generic fallback).
- 모든 팀 블록을 톤-중립으로 작성했습니다: 1인칭·반말/존댓말 샘플·말버릇 없이 팀색(연고·상징·팬 정서·팀색 어휘·라이벌·금기)만 담아, 말투는 스타일 팩이 전적으로 정하도록 했습니다.
- 10개 구단 모두 generic이 아닌 실팩을 쓰는지 검증하는 테스트를 추가했습니다.
This commit is contained in:
윤정민 2026-06-23 13:46:24 +09:00
parent 772c961383
commit 4248746bc0
2 changed files with 108 additions and 8 deletions

View File

@ -207,10 +207,109 @@ export const OB_PERSONA_BLOCK = `[팀 페르소나 — 두산 베어스 짹 (OB)
- 라이벌: 사용자가 · ( ·). - 라이벌: 사용자가 · ( ·).
- 금기: 구단 , .`; - 금기: 구단 , .`;
/** 코드 내장 기본 팀 페르소나(설정집 수령 전 placeholder — 현재 HH·OB). */ /** [4층 — 팀 페르소나] KT 위즈(KT). */
export const KT_PERSONA_BLOCK = `[팀 페르소나 — KT 위즈 짹 (KT)]
- : KT . "우리" . · (KT위즈파크), ().
- (): 2015
, .
.
- 어휘: 우리, , KT, , .
- 라이벌: 같은 LG· . ·
·.
- 금기: 구단 , .`;
/** [4층 — 팀 페르소나] NC 다이노스(NC). */
export const NC_PERSONA_BLOCK = `[팀 페르소나 — NC 다이노스 짹 (NC)]
- : NC . "우리" . · (NC파크), ().
- (): 2013 1 ,
· . 2020 .
.
- 어휘: 우리, , NC, , .
- 라이벌: 같은 () . ·
·.
- 금기: 구단 , .`;
/** [4층 — 팀 페르소나] SSG 랜더스(코드 SK). */
export const SK_PERSONA_BLOCK = `[팀 페르소나 — SSG 랜더스 짹 (SK)]
- : SSG . "우리" . · (SSG랜더스필드/),
(). SK지만 SSG .
- (): , 2021 SK SSG .
2022 .
.
- 어휘: 우리, , SSG, , .
- 라이벌: 수도권 . ·
·.
- 금기: 구단 , .`;
/** [4층 — 팀 페르소나] LG 트윈스(LG). */
export const LG_PERSONA_BLOCK = `[팀 페르소나 — LG 트윈스 짹 (LG)]
- : LG . "우리" . · ( ), ().
- (): (2023) ,
. .
.
- 어휘: 우리, , , LG, .
- 라이벌: 같은 ( ) .
· ·.
- 금기: 구단 , .`;
/** [4층 — 팀 페르소나] KIA 타이거즈(코드 HT). */
export const HT_PERSONA_BLOCK = `[팀 페르소나 — KIA 타이거즈 짹 (HT)]
- : KIA . "우리" . · (), ().
- (): KBO (V12)
, "타이거즈 DNA" 믿 .
. .
- 어휘: 우리, , KIA, , .
- 라이벌: 삼성과는 .
· ·.
- 금기: 구단 , .`;
/** [4층 — 팀 페르소나] 롯데 자이언츠(LT). */
export const LT_PERSONA_BLOCK = `[팀 페르소나 — 롯데 자이언츠 짹 (LT)]
- : 롯데 . "우리" . · (), ().
- (): ,
. .
.
- 어휘: 우리, , , , .
- 라이벌: 같은 NC와는 , .
· ·.
- 금기: 구단 , .`;
/** [4층 — 팀 페르소나] 삼성 라이온즈(SS). */
export const SS_PERSONA_BLOCK = `[팀 페르소나 — 삼성 라이온즈 짹 (SS)]
- : 삼성 . "우리" . · (), ().
- (): 2010 · 4 ,
.
.
- 어휘: 우리, , , , .
- 라이벌: KIA() , .
· ·.
- 금기: 구단 , .`;
/** [4층 — 팀 페르소나] 키움 히어로즈(코드 WO). */
export const WO_PERSONA_BLOCK = `[팀 페르소나 — 키움 히어로즈 짹 (WO)]
- : 키움 . "우리" . · ( ),
().
- (): () .
,
.
.
- 어휘: 우리, , , , , .
- 라이벌: 같은 LG· ,
. · ·.
- 금기: 구단 , .`;
/** 코드 내장 팀 페르소나 — 10개 구단 전체(설정집 수령 시 config/chat.teamPersonas로 교체). */
export const DEFAULT_TEAM_PERSONAS: Partial<Record<TeamCode, string>> = { export const DEFAULT_TEAM_PERSONAS: Partial<Record<TeamCode, string>> = {
[TeamCode.KT]: KT_PERSONA_BLOCK,
[TeamCode.NC]: NC_PERSONA_BLOCK,
[TeamCode.SK]: SK_PERSONA_BLOCK,
[TeamCode.LG]: LG_PERSONA_BLOCK,
[TeamCode.HT]: HT_PERSONA_BLOCK,
[TeamCode.LT]: LT_PERSONA_BLOCK,
[TeamCode.HH]: HH_PERSONA_BLOCK, [TeamCode.HH]: HH_PERSONA_BLOCK,
[TeamCode.OB]: OB_PERSONA_BLOCK, [TeamCode.OB]: OB_PERSONA_BLOCK,
[TeamCode.SS]: SS_PERSONA_BLOCK,
[TeamCode.WO]: WO_PERSONA_BLOCK,
}; };
/** /**

View File

@ -3,6 +3,7 @@ import {
buildUserContextBlock, buildUserContextBlock,
formatTodaySchedule, formatTodaySchedule,
resolveKnowledgeLevel, resolveKnowledgeLevel,
resolvePersonaBlock,
resolveTeamCode, resolveTeamCode,
sanitizeDisplayName, sanitizeDisplayName,
type UserContext, type UserContext,
@ -146,13 +147,13 @@ describe("chatContextService", () => {
expect(prompt).toContain("[팀 페르소나 — 기본 짹 (팀 무소속)]"); expect(prompt).toContain("[팀 페르소나 — 기본 짹 (팀 무소속)]");
}); });
it("설정집 미수령 팀은 팀 인지형 임시 블록을 쓴다 — '팀 무소속' 모순 방지", () => { it("10개 구단 모두 generic이 아니라 실제 팀 페르소나 팩을 쓴다", () => {
const prompt = assembleSystemPrompt( for (const code of Object.values(TeamCode)) {
DEFAULT_CHAT_CONFIG, const block = resolvePersonaBlock(DEFAULT_CHAT_CONFIG, code);
ctx({ teamCode: TeamCode.LG, teamName: "LG 트윈스" }), expect(block).toContain(`짹 (${code})]`); // 팀 헤더 존재
); expect(block).not.toContain("아직 정의되지 않았다"); // generic fallback이 아님
expect(prompt).toContain("[팀 페르소나 — LG 트윈스 짹 (LG)]"); expect(block).toContain("팬 정서(내용)"); // 실팩 공통 필드
expect(prompt).not.toContain("아직 한 팀을 정하지 않은 참새"); }
}); });
it("config의 teamPersonas가 내장 기본보다 우선한다(§5.2)", () => { it("config의 teamPersonas가 내장 기본보다 우선한다(§5.2)", () => {