우리 아이 영어 발음, AI 선생님이 봐드릴게요! (feat. n8n으로 만든 자동 피드백 시스템)

"선생님, 제가 Rice라고 했는데 친구가 Lice(이가 벼룩)라고 들었대요ㅠㅠ"

30명 수업에서 한 명 한 명 발음 체크하기... 진짜 하고 싶어도 시간이 없죠. 특히 우리 아이들이 힘들어하는 R, W, F 발음은 "다시 해봐!" 100번보다 "이렇게 해봐!" 한 번이 필요해요.

그래서 만들었어요!

카톡 보내듯 텔레그램에 녹음 파일 전송 → AI가 "어? 너 R을 L처럼 발음했네?" 바로 체크
"우르르~ 강아지처럼 해봐!" 우리 선생님 꿀팁까지 포함된 성적표가 이메일로 슝~!

이제 새벽에 연습해도, 100번 틀려도 괜찮아요. 지치지 않는 AI 선생님이 항상 곁에 있으니까요!

영어 발음 교육에서 가장 큰 어려움은 개인별 맞춤 피드백을 제공하는 것이에요.

특히 한국인 학습자들이 어려워하는 R, W, F 발음 등은 반복적인 연습과 구체적인 교정 지침이 필요한데요.

이를 해결하기 위해 AI 기반 영어 발음 평가 자동화 시스템을 구축했어요. 학생이 텔레그램으로 녹음 파일을 전송하면, 자동으로 STT 분석 → AI 평가 → 맞춤형 피드백 보고서를 생성하여 이메일로 전송하는 완전 자동화 시스템이랍니다.

목표:

  • 24/7 즉시 피드백 제공

  • 개인별 발음 특성에 맞는 구체적 조언

  • 교사의 전문 지식과 AI의 분석 능력 결합 (RAG 방식)

  • 학습 데이터 축적을 통한 장기적 개선 추적

사용 도구:

  • n8n: 워크플로우 자동화 플랫폼

  • Google Gemini API: AI 분석 및 피드백 생성

  • Google Speech-to-Text API: 음성을 텍스트로 변환 (신뢰도 점수 포함)

  • Google Sheets: 발음 교정 팁 데이터베이스 (RAG)

  • Telegram Bot: 파일 수신 인터페이스

  • Google Drive & Cloud Storage: 파일 저장소

  • Gmail: 보고서 전송

워크플로우 구성

1. 파일 수신 워크플로우 (Telegram → Google Drive)

1-1. Telegram Trigger 설정

// Trigger On: {{ ["message"] }}
// 모든 업로드된 파일을 캐치
전보 트리거의 스크린 샷

1-2. 녹음파일ID추출 노드 - 파일 ID 추출

return [{
  json: {
    file_id: $json.message.voice.file_id
  }
}];
iPad에서 코드 편집기의 스크린 샷

1-3. Get a file - 텔레그램에서 파일 정보 가져오기

  • File ID: {{ $json.file_id }}

    파일 얻기 화면의 스크린 샷

1-4. Upload file - Google Drive에 저장

  • Bucket Name: english-pronunciation

  • Object Name: {{$json["name"]}}

  • Input Data Field Name: data

    Google 드라이브에서 업로드 파일 옵션의 스크린 샷

2. 메인 발음평가 워크플로우

2-1. Google Drive Trigger

  • Google Drive에 새 파일 업로드 시 자동 실행

    • 이 부분은 생략가능함. 하나의 워크플로우에 2개의 트리거는 동시에 발동하지 못하기 때문임.

2-2. Download file (1-4번에 이어서)

  • 업로드된 음성 파일 다운로드

    Google 드라이브 계정 설정의 스크린 샷

2-3. Create an object - Google Cloud Storage에 저장

  • STT API 사용을 위해 Cloud Storage에 저장

  • Bucket: english-pronunciation

  • Object Name: {{$json["name"]}}

    Adobe Adobe Adobe Adobe Ado에서 물체를 만드는 방법

2-4. HTTP Request - STT API 호출

HTTP 요청 설정의 스크린 샷

JSON 부분 아래 복붙!

{
  "config": {
    "encoding": "OGG_OPUS",
    "sampleRateHertz": 48000,
    "languageCode": "en-US"
  },
  "audio": {
    "uri": "gs://{{$node["Create an object"].json["bucket"]}}/{{$node["Create an object"].json["name"]}}"
  }
}

2-5. 발음결과처리 노드 - STT 결과 처리 및 신뢰도 분석

코드 편집기의 스크린 샷

자바스크립트 내용은 아래 예시 참조!

const res = $input.first().json.results;

let fullTranscript = '';
let totalConfidence = 0;

res.forEach(r => {
  const alt = r.alternatives[0];
  fullTranscript += alt.transcript + ' ';
  totalConfidence += alt.confidence;
});

fullTranscript = fullTranscript.trim();

return [{
  json: {
    transcript: fullTranscript,
    confidence: (totalConfidence / res.length).toFixed(6)  // 평균값
  }
}];



2-6. Append row in sheet - 평가 기록 저장

  • Document: n8n test

  • Sheet: 시트1

  • Values to Send:

    • 1열: {{ $json.transcript }}

    • 2열: {{ $json.confidence }}

    • 3열: {{ new Date().toISOString() }}

      문서에 템플릿을 적용 할 수있는 앱의 스크린 샷

2-7. AI Agent 설정 (RAG 핵심)

AI Agent 프롬프트:

너는 초등학생을 위한 영어 발음 코치야 🎧

학생의 발음을 분석할 때 다음 단계를 따라줘:

1. **발음 문제 감지**: 학생이 발음한 문장에서 어려워하는 발음을 찾아줘
   - R/L 구분 문제 (예: rice → lice)
   - W 발음 문제 (예: wolf → 울프)
   - F/P 구분 문제 (예: coffee → 코피)
   - 기타 한국인이 어려워하는 발음

2. **키워드 추출**: 발견한 발음 문제를 아래 키워드로 분류해줘
   - "R/L" - R과 L 구분 문제
   - "W" - W 발음 문제  
   - "F" - F 발음 문제
   - "TH" - TH 발음 문제
   - "V" - V 발음 문제
   - "Z" - Z 발음 문제

3. **CoachingTips 도구 사용**: 
   - 위에서 찾은 키워드로 CoachingTips 시트를 검색해줘
   - 검색할 때는 정확한 키워드(예: "L", "R/L", "W")를 사용해
   - 해당 키워드의 Tip을 가져와서 학생에게 전달해줘

[입력 정보]
- 학생이 발음한 문장: {{$node["발음결과처리"].json["transcript"]}}
- 신뢰도 지수: {{$node["발음결과처리"].json["confidence"]}}

[역할]
1. 신뢰도 지수를 설명해줘. (예: 0.89 → "아주 좋아요! 거의 정확했어요 😊")
2. 학생의 발음에서 문제점을 찾아 키워드로 추출해줘 (R/L, W, F, TH, V, Z 등)
3. CoachingTips 도구를 사용해서 해당 키워드의 Tip을 검색하고 알려줘
   - 반드시 시트의 Keyword 열과 정확히 일치하는 값으로 검색
   - 예: "really"를 "leally"로 발음 → "R/L" 키워드로 검색
4. 매칭되는 팁이 없다면, 한국인이 자주 틀리는 발음 팁을 알려줘
5. 초등학생이 따라 하기 쉬운 연습법을 추가로 제시해줘
6. 마지막에 응원의 메시지를 남겨줘!

[예시 응답 형식]
🎯 신뢰도: 0.75 → "잘했어요! 조금만 더 연습하면 완벽해질 거예요! 💪"

🔍 발견한 발음 포인트: L 발음이 어려웠구나!

💡 **꿀팁**: "라라라라라 를 다섯번 외치쇼ㅋㅋㅋㅋ"

🎮 연습 방법: 거울 보면서 혀끝을 윗니 뒤에 대고 "을~" 소리 내보기!

응원 메시지: 너무 잘하고 있어! 내일은 더 잘할 거야~ 화이팅! 🌟

[신뢰도 지수 설명 가이드]
- 0.9 이상: "완벽해요! 원어민 수준이에요! 🏆"
- 0.8~0.9: "아주 좋아요! 거의 정확했어요 😊"
- 0.7~0.8: "잘했어요! 조금만 더 연습하면 완벽! 💪"
- 0.6~0.7: "괜찮아요! 천천히 다시 해보자 🙂"
- 0.6 미만: "어려웠구나~ 선생님이랑 같이 연습해보자! 🤗"

[톤]
- 말투는 초등학생 친구처럼 친근하게 😊
- 중요한 팁은 **굵게**, 한글 발음은 "따옴표"로
- 이모지 적절히 사용 (🗣 👂 🎯 👏 🌟 💪 등)
- 어려운 용어 대신 쉬운 말 사용
- 실수해도 괜찮다는 격려 꼭 포함!
iPad에 문자 메시지를 보여주는 iPad 화면

AI Agent Tools 구성:

  1. Google Gemini Chat Model - AI 응답 생성

  2. Simple Memory - 대화 컨텍스트 저장

  3. Get row(s) in sheet - CoachingTips 조회

    • Column: Keyword

    • Value: AI가 자동으로 판단하여 필요한 키워드 검색

      Google Gemini 채팅 모델의 스크린 샷
      간단한 메모리 설정의 스크린 샷
      Google Analytics Dashboard의 스크린 샷
      • 코칭 팁 시트 예시:

      Microsoft Excel 스프레드 시트의 스크린 샷

2-8. 보고서작성 노드 - 보고서 HTML 생성

iPad에서 코드 편집기의 스크린 샷
// 1) 각 노드에서 데이터 가져오기
const aiOutputRaw    = $input.first().json.output || "AI 코치 메시지를 불러올 수 없습니다.";
const studentName    = $node["Telegram Trigger"].json.message?.from?.first_name || "학생";
const evaluationDate = new Date().toLocaleDateString('ko-KR');

// 2) HTTP Request (STT) 결과 가져오기
const sttResponse = $node["HTTP Request"].json;

// 3) 모든 세그먼트 합치기
const segments = sttResponse.results
  ?.map(r => r.alternatives?.[0]?.transcript || "")
  || [];
const fullTranscript = segments.join(" ").trim();

// 4) confidence 평균 계산
const confidences = sttResponse.results
  ?.map(r => parseFloat(r.alternatives?.[0]?.confidence || 0))
  || [0];
const avgConfidence = confidences.reduce((sum, c) => sum + c, 0) / confidences.length;
const overallScore = Math.round(avgConfidence * 100);

// 5) transcript 와 confidence 덮어쓰기
const transcript = fullTranscript;
const confidence = overallScore;

// 6) Helper: 색상과 등급 결정
function getScoreColor(score) {
  if (score >= 90) return '#28a745';
  if (score >= 80) return '#ffc107';
  if (score >= 70) return '#fd7e14';
  return '#dc3545';
}
function getGrade(score) {
  if (score >= 90) return 'A';
  if (score >= 80) return 'B';
  if (score >= 70) return 'C';
  return 'D';
}

// 7) AI 코칭 메시지 포맷팅: **굵게** → <strong>, 줄바꿈 → <br>
const formattedOutput = aiOutputRaw
  .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
  .replace(/\n/g, '<br>');

// 8) 전체 HTML 템플릿
const htmlTemplate = `
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>${studentName} - 영어 발음 평가 보고서</title>
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&display=swap');
    * { margin:0; padding:0; box-sizing:border-box; }
    body { font-family:'Noto Sans KR',sans-serif; background:#f8f9fa; }
    .report-container { max-width:800px; margin:40px auto; background:#fff; border-radius:15px; box-shadow:0 10px 30px rgba(0,0,0,0.1); overflow:hidden; }
    .header { background:linear-gradient(135deg,#667eea 0%,#764ba2 100%); color:#fff; padding:40px 30px; text-align:center; position:relative; }
    .header::before, .header::after { content:'🌟'; position:absolute; top:20px; font-size:24px; }
    .header::before { left:30px; } .header::after { right:30px; }
    .header h1 { font-size:32px; font-weight:700; margin-bottom:10px; }
    .header .subtitle { font-size:16px; opacity:0.9; }
    .student-info { background:rgba(255,255,255,0.2); display:inline-block; padding:10px 20px; border-radius:25px; margin-top:15px; }
    .content { padding:30px; }
    .score-section { text-align:center; margin-bottom:40px; }
    .score-number { font-size:72px; font-weight:700; color:${getScoreColor(confidence)}; }
    .score-label { font-size:18px; color:#6c757d; margin-top:5px; }
    .score-grade { display:inline-block; margin-top:15px; background:${getScoreColor(confidence)}; color:#fff; padding:8px 16px; border-radius:20px; font-size:16px; }
    .transcript-section { background:#e3f2fd; padding:20px; border-left:5px solid #2196f3; border-radius:10px; margin-bottom:40px; font-style:italic; }
    .coaching-section { margin-bottom:40px; }
    .coaching-section h2 { font-size:20px; color:#155724; margin-bottom:15px; display:flex; align-items:center; }
    .coaching-section h2::before { content:'🎯'; margin-right:10px; }
    .coaching-content { background:linear-gradient(135deg,#e8f5e8 0%,#f0f8f0 100%); padding:25px; border-radius:15px; border:2px solid #c3e6cb; line-height:1.8; }
    .tips-section { background:#fff3cd; padding:25px; border-radius:10px; border-left:5px solid #ffc107; margin-bottom:40px; }
    .tips-section h2 { font-size:18px; color:#856404; margin-bottom:15px; display:flex; align-items:center; }
    .tips-section h2::before { content:'💡'; margin-right:10px; }
    .tips-section ul { list-style:disc; padding-left:20px; line-height:1.8; }
    .footer { background:#f8f9fa; text-align:center; padding:20px; font-size:12px; color:#6c757d; border-top:1px solid #dee2e6; }
  </style>
</head>
<body>
  <div class="report-container">
    <div class="header">
      <h1>영어 발음 평가 보고서</h1>
      <p class="subtitle">English Pronunciation Assessment Report</p>
      <div class="student-info">${studentName} | ${evaluationDate}</div>
    </div>
    <div class="content">
      <div class="score-section">
        <div class="score-number">${confidence}</div>
        <div class="score-label">신뢰도 지수 (Confidence)</div>
        <div class="score-grade">등급 ${getGrade(confidence)}</div>
      </div>
      ${ transcript ? `
      <div class="transcript-section">
        발음한 문장: "${transcript}"
      </div>` : '' }
      <div class="coaching-section">
        <h2>AI 맞춤형 코칭</h2>
        <div class="coaching-content">${formattedOutput}</div>
      </div>
      <div class="tips-section">
        <h2>추천 연습 방법</h2>
        <ul>
          <li>매일 10분씩 영어 동화책 소리내어 읽기</li>
          <li>좋아하는 영어 동요·팝송 따라 부르기</li>
          <li>거울 보며 입 모양과 혀 위치 연습하기</li>
          <li>영어 발음 앱으로 재미있게 학습하기</li>
        </ul>
      </div>
    </div>
    <div class="footer">
      이 보고서는 Google Speech-to-Text AI 분석 기반으로 자동 생성되었습니다.<br>
      더 나은 영어 발음을 위해 꾸준히 연습해보세요! 💪
    </div>
  </div>
</body>
</html>
`;

// 9) 결과 반환
return [{
  json: {
    html:         htmlTemplate,
    studentName,
    transcript,
    confidence,
    overallScore,
    evaluationDate,
    fileName: `${studentName.replace(/\s+/g,'_')}_발음평가_${evaluationDate.replace(/\./g,'')}.pdf`
  }
}];

2-9. Send a message - Gmail로 최종 보고서 전송

  • To: [email protected] 받는사람 이메일주소

  • Subject: {{$json.studentName}}의 영어 발음 평가 보고서

  • Email Type: HTML

  • Message: {{ $json.html }}

    iPhone에서 메시지 보내기 버튼의 스크린 샷

Google Sheets RAG 데이터베이스

CoachingTips 시트 구조 예시:

Keyword

Tip

R

R 발음할 때는 '우' 소리를 먼저 짧게 내세요. 그 다음 재빠르게 다음 소리로 잇기!

W

W 발음할 때는 '워' 소리를 내세요! Wolf는 '울프'가 아니라 '워~울프' 소리에 가까워요!

L

L 발음할 때는 라라라라라 를 다섯번 외치쇼ㅋㅋㅋㅋ

결과

기계 학습 시스템의 프로세스를 보여주는 다이어그램

배운 점과 나만의 꿀팁

  1. RAG 구현의 핵심은 데이터 구조화

    • Google Sheets를 지식베이스로 활용하면 비개발자도 쉽게 내용 수정 가능

    • AI Agent가 자동으로 필요한 키워드를 판단하여 검색

  2. STT API 설정 최적화

    • enableWordTimeOffsets로 단어별 타이밍 분석 가능

  3. 파일 처리 워크플로우 분리

    • Google Drive를 중간 저장소로 활용하여 안정성 확보

  4. AI Agent "Defined automatically by the model" 활용

    • 처음에는 명시적 값 전달이 필요하다고 생각했으나

    • AI가 프롬프트를 이해하고 자동으로 적절한 키워드를 찾아 검색

과정 중에 겪은 시행착오

  1. AI Agent가 Google Sheets 데이터를 못 가져오는 문제

    • 원인: 프롬프트에서 도구 사용 지시가 명확하지 않음

    • 해결: "CoachingTips 시트를 참고해서"라는 명확한 지시 추가

  2. STT 신뢰도 점수 계산

    • 문제: 여러 results의 confidence를 어떻게 통합할지

    • 해결: 평균값 계산으로 전체 신뢰도 산출

  3. 텔레그램 음성 파일 처리

    • 문제: 음성 메시지의 file_id 추출 위치

    • 해결: message.voice.file_id 경로 확인

도움이 필요한 부분

  • 다양한 억양과 발음 속도에 대한 STT 정확도 개선 방법

  • 발음 개선 추이를 시각화하는 대시보드 구현

앞으로의 계획

  1. 평가 지표 고도화

    • 억양, 강세, 리듬 평가 추가

    • 단어별 신뢰도 점수 세분화

  2. 학습 추적 시스템

    • 개인별 발전 그래프 자동 생성

    • 반복적으로 틀리는 패턴 자동 감지 및 맞춤 커리큘럼 제안

  3. 다채널 확장

    • 웹 인터페이스 추가

도움 받은 글

  • n8n AI Agent 공식 문서

  • Google Cloud Speech-to-Text API 가이드

  • RAG (Retrieval-Augmented Generation) 개념 설명 자료

  • n8n Community Forum의 워크플로우 최적화 팁


"선생님, 저 Wolf를 '울프'라고 했더니 친구들이 놀려요ㅠㅠ"

이제는 밤 10시에도, 아침 7시에도 언제든 녹음만 보내면 3분 뒤에 답장이 와요! 📱

"워~울프! 늑대가 울부짖듯이 해봐! 넌 벌써 70점이야! 대단해!"

마치 포켓몬GO 같아요! 🎮

  • 언제 어디서나 연습 가능

  • 바로바로 점수 확인

  • 레벨업하는 재미!

진짜 신기한 건, AI 선생님이 우리 진짜 선생님의 꿀팁을 외우고 있다는 거예요. "라라라라라~ 다섯 번!" 같은 우리만의 비법도 알려준대요 ㅋㅋㅋ

이제 영어 발음이 무서운 게 아니라 재밌는 게임이 됐어요!

3
2개의 답글

👉 이 게시글도 읽어보세요