mirror of
https://github.com/nad4-su/meeting-minutes.git
synced 2026-10-11 15:50:13 +09:00
feat: 회의록 섹션을 내용 기반으로 생성하고 액션 아이템에 담당자 표기 (#13)
고정 제목(## 주요 논의 사항)을 강요하던 프롬프트를, 회의가 실제로 다룬 주제에서 섹션 제목을 도출하도록 바꿨다. 제목만 훑어도 내용이 파악된다. - meeting·one_on_one: 본문 섹션 제목을 AI가 직접 짓도록 지시 - brainstorm: 카테고리도 미리 정해진 목록이 아님을 명시 - 액션 아이템에 (담당자)·기한 표기 요청 + 예시 제공 - COMMON_RULES 신설 — 환각 방지, 발화자 표기 활용, 영어 기술 용어 원문 유지(한영 코드 스위칭 대응). 프리셋에만 적용하고 custom 프롬프트는 사용자가 전적으로 제어하도록 유지 - LIVE_MODIFIER에 섹션 제목이 갱신될 수 있다는 안내 추가 버그 수정: 기존 meeting 프롬프트는 액션 아이템을 "담당자와 기한이 명확한 항목만"으로 제한해, 담당자를 정하지 않은 회의에서는 액션 아이템이 하나도 추출되지 않았다. 담당자가 불분명해도 포함하도록 변경. `- [ ]` 체크박스 형식은 그대로 유지해 parseActionItems와 호환된다. 테스트 102 → 113. Co-authored-by: csbae <csbae@RP-002.local> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
3 files changed
+166
-32
No files matched your search
@@ -164,3 +164,119 @@ describe('liveEnabledFor / depthAdjustableFor', () => {
|
||||
expect(depthAdjustableFor('custom')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('내용 기반 섹션 구조', () => {
|
||||
const transcript = '이번에는 가격 비교 사이트를 만들어 봅시다'
|
||||
|
||||
it('meeting은 섹션 제목을 직접 짓도록 지시한다', () => {
|
||||
const prompt = buildPrompt({
|
||||
templateId: 'meeting',
|
||||
depth: 'standard',
|
||||
transcript,
|
||||
})
|
||||
expect(prompt).toContain('섹션 제목을 직접 지어서')
|
||||
// 고정 제목을 쓰지 말라는 지시가 함께 있어야 한다
|
||||
expect(prompt).toContain('일반적인 제목은 쓰지 마세요')
|
||||
})
|
||||
|
||||
it('one_on_one도 주제별 제목을 직접 짓도록 지시한다', () => {
|
||||
const prompt = buildPrompt({
|
||||
templateId: 'one_on_one',
|
||||
depth: 'standard',
|
||||
transcript,
|
||||
})
|
||||
expect(prompt).toContain('제목을 직접 지어')
|
||||
})
|
||||
|
||||
it('raw는 구조적 제목을 덧붙이지 말라는 지시를 유지한다', () => {
|
||||
const prompt = buildPrompt({
|
||||
templateId: 'raw',
|
||||
depth: 'detailed',
|
||||
transcript,
|
||||
})
|
||||
expect(prompt).toContain('구조적 제목(## 섹션)을 덧붙이지 마세요')
|
||||
})
|
||||
})
|
||||
|
||||
describe('액션 아이템 담당자 표기', () => {
|
||||
const transcript = '다음 주까지 정리해 주세요'
|
||||
|
||||
it('담당자 표기를 요구한다', () => {
|
||||
const prompt = buildPrompt({
|
||||
templateId: 'meeting',
|
||||
depth: 'standard',
|
||||
transcript,
|
||||
})
|
||||
expect(prompt).toContain('(담당자)')
|
||||
})
|
||||
|
||||
it('담당자가 불분명해도 항목을 버리지 않도록 지시한다', () => {
|
||||
const prompt = buildPrompt({
|
||||
templateId: 'meeting',
|
||||
depth: 'standard',
|
||||
transcript,
|
||||
})
|
||||
expect(prompt).toContain('담당자가 불분명해도')
|
||||
})
|
||||
|
||||
it('체크박스 형식을 유지해 액션 아이템 파서와 호환된다', () => {
|
||||
for (const id of ['meeting', 'one_on_one', 'brainstorm'] as const) {
|
||||
const prompt = buildPrompt({ templateId: id, depth: 'standard', transcript })
|
||||
expect(prompt).toContain('- [ ]')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('공통 규칙', () => {
|
||||
const transcript = '테스트 발화'
|
||||
|
||||
it('프리셋 템플릿 전체에 공통 규칙이 붙는다', () => {
|
||||
for (const id of Object.keys(TEMPLATES) as (keyof typeof TEMPLATES)[]) {
|
||||
const prompt = buildPrompt({ templateId: id, depth: 'standard', transcript })
|
||||
expect(prompt).toContain('지어내지 마세요')
|
||||
expect(prompt).toContain('한국어로 작성하세요')
|
||||
}
|
||||
})
|
||||
|
||||
it('발화자 표기가 있으면 활용하도록 지시한다', () => {
|
||||
const prompt = buildPrompt({
|
||||
templateId: 'meeting',
|
||||
depth: 'standard',
|
||||
transcript,
|
||||
})
|
||||
expect(prompt).toContain('발화자 표기가 있다면')
|
||||
})
|
||||
|
||||
it('영어 기술 용어는 원문 표기를 유지하도록 지시한다', () => {
|
||||
const prompt = buildPrompt({
|
||||
templateId: 'meeting',
|
||||
depth: 'standard',
|
||||
transcript,
|
||||
})
|
||||
expect(prompt).toContain('원문 표기를 유지하세요')
|
||||
})
|
||||
|
||||
it('custom 프롬프트에는 공통 규칙을 덧붙이지 않는다', () => {
|
||||
const prompt = buildPrompt({
|
||||
templateId: 'custom',
|
||||
depth: 'standard',
|
||||
transcript,
|
||||
customPrompt: '한 줄로만 요약해줘',
|
||||
})
|
||||
expect(prompt).toContain('한 줄로만 요약해줘')
|
||||
expect(prompt).not.toContain('지어내지 마세요')
|
||||
})
|
||||
|
||||
it('custom 프롬프트가 비어 있으면 meeting 템플릿 + 공통 규칙으로 대체한다', () => {
|
||||
const prompt = buildPrompt({
|
||||
templateId: 'custom',
|
||||
depth: 'standard',
|
||||
transcript,
|
||||
customPrompt: ' ',
|
||||
})
|
||||
expect(prompt).toContain('회의록 작성 전문가')
|
||||
expect(prompt).toContain('지어내지 마세요')
|
||||
// 기존 동작 유지 — custom 경로에는 강도/라이브 모디파이어를 적용하지 않는다
|
||||
expect(prompt).not.toContain('작성 강도')
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user