Add style override to the debug chat probe.
- 디버그 chatProbe·chatProbeSheet에 style 쿼리 파라미터를 추가해, prod config(config/chat.stylePack)를 바꾸지 않고도 스타일을 A/B로 검증할 수 있게 했습니다. - chatProbeService의 buildProbeEnv/runChatProbe/runChatProbeBatch에 styleOverride를 연결하고, 프로브 시트 메타·마크다운에 적용 스타일을 표기했습니다.
This commit is contained in:
parent
4e98532f6c
commit
9f7666a73f
@ -98,8 +98,11 @@ export const debug = onRequest({ timeoutSeconds: 300 }, async (req, res) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const model = typeof req.query.model === "string" ? req.query.model : undefined;
|
const model = typeof req.query.model === "string" ? req.query.model : undefined;
|
||||||
logger.info(`debug.chatProbe triggered (uid=${uid}, model=${model ?? "default"})`);
|
const style = typeof req.query.style === "string" ? req.query.style : undefined;
|
||||||
const result = await runChatProbe(uid, q, model);
|
logger.info(
|
||||||
|
`debug.chatProbe triggered (uid=${uid}, model=${model ?? "default"}, style=${style ?? "default"})`,
|
||||||
|
);
|
||||||
|
const result = await runChatProbe(uid, q, model, style);
|
||||||
res.status(200).json(result);
|
res.status(200).json(result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -115,8 +118,11 @@ export const debug = onRequest({ timeoutSeconds: 300 }, async (req, res) => {
|
|||||||
}
|
}
|
||||||
const format = typeof req.query.format === "string" ? req.query.format : "json";
|
const format = typeof req.query.format === "string" ? req.query.format : "json";
|
||||||
const model = typeof req.query.model === "string" ? req.query.model : undefined;
|
const model = typeof req.query.model === "string" ? req.query.model : undefined;
|
||||||
logger.info(`debug.chatProbeSheet triggered (uid=${uid}, model=${model ?? "default"})`);
|
const style = typeof req.query.style === "string" ? req.query.style : undefined;
|
||||||
const sheet = await runChatProbeBatch(uid, undefined, model);
|
logger.info(
|
||||||
|
`debug.chatProbeSheet triggered (uid=${uid}, model=${model ?? "default"}, style=${style ?? "default"})`,
|
||||||
|
);
|
||||||
|
const sheet = await runChatProbeBatch(uid, undefined, model, style);
|
||||||
if (format === "md" || format === "markdown") {
|
if (format === "md" || format === "markdown") {
|
||||||
res.status(200).type("text/markdown; charset=utf-8").send(renderProbeMarkdown(sheet));
|
res.status(200).type("text/markdown; charset=utf-8").send(renderProbeMarkdown(sheet));
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -56,6 +56,7 @@ export interface ChatProbeMeta {
|
|||||||
date: string;
|
date: string;
|
||||||
provider: string;
|
provider: string;
|
||||||
model: string;
|
model: string;
|
||||||
|
stylePack: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChatProbeSheet {
|
export interface ChatProbeSheet {
|
||||||
@ -92,15 +93,18 @@ interface ProbeEnv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** uid 1명 기준으로 시스템 프롬프트·도구 컨텍스트·provider를 한 번만 준비한다. */
|
/** uid 1명 기준으로 시스템 프롬프트·도구 컨텍스트·provider를 한 번만 준비한다. */
|
||||||
async function buildProbeEnv(uid: string, modelOverride?: string): Promise<ProbeEnv> {
|
async function buildProbeEnv(
|
||||||
|
uid: string,
|
||||||
|
modelOverride?: string,
|
||||||
|
styleOverride?: string,
|
||||||
|
): Promise<ProbeEnv> {
|
||||||
// 프로브는 검수 도구이므로 항상 최신 config를 읽는다 — 5분 캐시 우회.
|
// 프로브는 검수 도구이므로 항상 최신 config를 읽는다 — 5분 캐시 우회.
|
||||||
invalidateChatConfigCache();
|
invalidateChatConfigCache();
|
||||||
const base = await getChatConfig();
|
const base = await getChatConfig();
|
||||||
// A/B용 모델 오버라이드 — 모델만 바꾸고 나머지 provider 설정(공평 타임아웃 등)은 공유.
|
// A/B 오버라이드 — 모델·스타일만 바꾸고 나머지 설정은 공유. 미지정 시 라이브 기본.
|
||||||
// 미지정 시 라이브 기본(lite).
|
let config: ChatConfig = base;
|
||||||
const config: ChatConfig = modelOverride ?
|
if (modelOverride) config = { ...config, provider: { ...config.provider, model: modelOverride } };
|
||||||
{ ...base, provider: { ...base.provider, model: modelOverride } } :
|
if (styleOverride) config = { ...config, stylePack: styleOverride };
|
||||||
base;
|
|
||||||
const user = await getUser(uid);
|
const user = await getUser(uid);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new HttpError(404, `user not found: ${uid}`, "USER_NOT_FOUND");
|
throw new HttpError(404, `user not found: ${uid}`, "USER_NOT_FOUND");
|
||||||
@ -126,6 +130,7 @@ async function buildProbeEnv(uid: string, modelOverride?: string): Promise<Probe
|
|||||||
date,
|
date,
|
||||||
provider: config.provider.name,
|
provider: config.provider.name,
|
||||||
model: config.provider.model,
|
model: config.provider.model,
|
||||||
|
stylePack: config.stylePack,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -189,8 +194,9 @@ export async function runChatProbe(
|
|||||||
uid: string,
|
uid: string,
|
||||||
message: string,
|
message: string,
|
||||||
modelOverride?: string,
|
modelOverride?: string,
|
||||||
|
styleOverride?: string,
|
||||||
): Promise<ProbeResult> {
|
): Promise<ProbeResult> {
|
||||||
const env = await buildProbeEnv(uid, modelOverride);
|
const env = await buildProbeEnv(uid, modelOverride, styleOverride);
|
||||||
return runOne(env, message);
|
return runOne(env, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,8 +205,9 @@ export async function runChatProbeBatch(
|
|||||||
uid: string,
|
uid: string,
|
||||||
prompts?: Array<{ q: string; expect?: string }>,
|
prompts?: Array<{ q: string; expect?: string }>,
|
||||||
modelOverride?: string,
|
modelOverride?: string,
|
||||||
|
styleOverride?: string,
|
||||||
): Promise<ChatProbeSheet> {
|
): Promise<ChatProbeSheet> {
|
||||||
const env = await buildProbeEnv(uid, modelOverride);
|
const env = await buildProbeEnv(uid, modelOverride, styleOverride);
|
||||||
const set = prompts ?? DEFAULT_PROBE_PROMPTS;
|
const set = prompts ?? DEFAULT_PROBE_PROMPTS;
|
||||||
// 순차 실행 — 동시 호출 부하로 인한 예산 초과 아티팩트를 피하고 실제 채팅(1건씩)에
|
// 순차 실행 — 동시 호출 부하로 인한 예산 초과 아티팩트를 피하고 실제 채팅(1건씩)에
|
||||||
// 가깝게 둔다. 각 프로브가 25초 예산을 온전히 쓰도록 보장.
|
// 가깝게 둔다. 각 프로브가 25초 예산을 온전히 쓰도록 보장.
|
||||||
@ -233,7 +240,7 @@ export function renderProbeMarkdown(sheet: ChatProbeSheet): string {
|
|||||||
lines.push(`- 생성: ${meta.generatedAt}`);
|
lines.push(`- 생성: ${meta.generatedAt}`);
|
||||||
lines.push(`- uid: \`${meta.uid}\` / 유저: ${meta.displayName}`);
|
lines.push(`- uid: \`${meta.uid}\` / 유저: ${meta.displayName}`);
|
||||||
lines.push(`- 응원팀: ${meta.favoriteTeamName} (${meta.favoriteTeamCode ?? "—"})`);
|
lines.push(`- 응원팀: ${meta.favoriteTeamName} (${meta.favoriteTeamCode ?? "—"})`);
|
||||||
lines.push(`- 모델: ${meta.provider}/${meta.model} / 기준 날짜(KST): ${meta.date}`);
|
lines.push(`- 모델: ${meta.provider}/${meta.model} / 스타일: ${meta.stylePack} / 기준 날짜(KST): ${meta.date}`);
|
||||||
lines.push(
|
lines.push(
|
||||||
`- 토큰 합계: 입력 ${sheet.totals.inputTokens.toLocaleString()} / ` +
|
`- 토큰 합계: 입력 ${sheet.totals.inputTokens.toLocaleString()} / ` +
|
||||||
`출력 ${sheet.totals.outputTokens.toLocaleString()} / ` +
|
`출력 ${sheet.totals.outputTokens.toLocaleString()} / ` +
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user