fix(prompt): plan/implement manager hint 도 가짜 팀 narration 금지
자기야 발견: 다랑이/이랑이 (review/deploy) 의 manager 가 가짜 팀 분배를
출력하던 건 이전 커밋에서 고쳤는데, 하랑이/나랑이 (plan/implement) 의
manager 도 똑같이 "수석 1명은... 선임 2명은... 신입 2명은..." 를 풀어서
narration 하고 있었음. 분해는 sister-agent 의 planner.ts 가 complexity
score 로 결정론적으로 결정하지 LLM 의 prose 가 결정하지 않는데, manager
LLM 이 prose 로 가짜 team plan 을 출력해서:
- 토큰 낭비 (실제로 spawn 에 영향 0)
- 사용자 혼란 ("진짜 그렇게 팀이 구성됐나?" 오해)
- 다음 stage 의 priorStages 노이즈 증가
수정 — plan/implement manager hint 를 stage 별로 짧게 재작성:
plan/manager:
1) MVP 범위 한 줄
2) 명시적 비범위 한 줄
3) 통과 기준 한 줄
명령형/단정형 강제. "수석/선임/신입" 단어 사용 금지.
implement/manager:
1) 기술 스택 / 런타임 한 줄
2) 파일 구조 1~2 줄
3) 핵심 구현 결정 한 줄
같은 제약.
추가로 principal/lead/junior 의 plan/implement hint 에도 "팀 narration 금지"
한 줄을 박아 일관성 유지. junior 의 implement code 출력에도 코드 블록 안에
가짜 팀 prose 를 섞지 말라는 가드 추가.
실제 분해는 코드 (planner.ts) 가 한다는 사실을 prompt 자체에 명시.
This commit is contained in:
@@ -106,18 +106,44 @@ function roleOutputHint(role: Role, stage: PromptContext["stage"]): string {
|
||||
}
|
||||
|
||||
// ── plan / implement ─────────────────────────────────────────
|
||||
// IMPORTANT: 팀 분배 (수석/선임/신입 N명...) narration 은 금지다.
|
||||
// 하위 노드의 spawn 트리는 sister-agent 의 planner.ts 가 complexity score 로
|
||||
// 결정론적으로 결정한다. LLM manager 는 spawn 결정에 영향을 주지 않으며,
|
||||
// "수석 1명을 붙일게" 같은 prose 는 빈 약속 + 토큰 낭비 + 사용자 혼란이다.
|
||||
// 대신 manager 는 이 stage 의 진짜 결정 (범위/스택/파일 경계) 만 짧게.
|
||||
if (role === "manager") {
|
||||
return `이 작업을 어떻게 분해할지, 어떤 팀(수석/선임/신입)을 어디에 배치할지 한 문단으로 결정해.`;
|
||||
if (stage === "plan") {
|
||||
return [
|
||||
`너는 이 단계의 최종 결정권자다. 팀(수석/선임/신입)이 자동으로 붙으니 분배 narration 은 절대 하지 마.`,
|
||||
`대신 다음 3 가지만 짧게 결정해서 답해:`,
|
||||
`1) MVP 범위: 무엇을 포함하나 한 줄`,
|
||||
`2) 명시적 비범위: 의도적으로 제외할 것 한 줄`,
|
||||
`3) 통과 기준: 무엇이 동작해야 끝났다고 보는지 한 줄`,
|
||||
`각 줄은 명령형/단정형으로. "수석/선임/신입" 단어 사용 금지.`,
|
||||
].join("\n");
|
||||
}
|
||||
if (stage === "implement") {
|
||||
return [
|
||||
`너는 이 단계의 최종 결정권자다. 팀(수석/선임/신입)이 자동으로 붙으니 분배 narration 은 절대 하지 마.`,
|
||||
`대신 다음 3 가지만 짧게 결정해서 답해:`,
|
||||
`1) 기술 스택 / 런타임 한 줄 (예: "vanilla HTML+JS, localStorage")`,
|
||||
`2) 파일 구조 1~2 줄 (어떤 파일이 만들어지는지)`,
|
||||
`3) 핵심 구현 결정 한 줄 (상태 관리 방식, 데이터 형태 등)`,
|
||||
`각 줄은 명령형/단정형으로. "수석/선임/신입" 단어 사용 금지.`,
|
||||
].join("\n");
|
||||
}
|
||||
// Other stages handled above by reviewHintForRole / deployHintForRole
|
||||
return `이 단계의 핵심 결정 한 문단으로.`;
|
||||
}
|
||||
if (role === "principal") {
|
||||
return `${STAGE_KOREAN[stage]} 단계에서 구체적으로 어떤 리스크가 있고, 어떻게 분해되어야 하는지 bullet 으로 제시해.`;
|
||||
return `${STAGE_KOREAN[stage]} 단계의 기술적 리스크와 핵심 결정 사항을 bullet 으로 1~3 개. "수석/선임/신입" 같은 팀 narration 금지 — 시스템이 자동으로 분배한다.`;
|
||||
}
|
||||
if (role === "lead") {
|
||||
return `이 작업을 신입에게 어떻게 나눠줄지, 검증 포인트는 무엇인지 bullet 으로 정리해.`;
|
||||
return `${STAGE_KOREAN[stage]} 단계에서 검증해야 할 핵심 포인트를 bullet 1~3 개. 팀 분배 narration 금지.`;
|
||||
}
|
||||
// junior
|
||||
if (stage === "plan") {
|
||||
return `이 프로젝트의 핵심 plan 을 마크다운 bullet 형식으로 작성해.`;
|
||||
return `이 프로젝트의 핵심 plan 을 마크다운 bullet 형식으로 작성해. "수석/선임/신입" 단어 사용 금지.`;
|
||||
}
|
||||
if (stage === "implement") {
|
||||
return [
|
||||
@@ -128,6 +154,7 @@ function roleOutputHint(role: Role, stage: PromptContext["stage"]): string {
|
||||
"```",
|
||||
`경로는 프로젝트 루트 기준 상대 경로. 언어 태그 콜론 뒤에 경로.`,
|
||||
`여러 파일이 필요하면 각각 별도 블록으로. 설명은 최소화.`,
|
||||
`"수석/선임/신입" 같은 팀 narration 은 코드 출력 안에 포함하지 마.`,
|
||||
].join("\n");
|
||||
}
|
||||
return `결과를 명확히 제출해.`;
|
||||
|
||||
Reference in New Issue
Block a user