고객 피드백을 분석하고 오디오를 합성하는 애플리케이션 만들기

고객 피드백을 분석하고 오디오를 합성하는 애플리케이션 만들기 (Create an application that analyzes customer feedback and synthesizes audio)

다음 코드 예제들은 고객 댓글 카드를 분석하고, 원래 언어에서 번역하며, 감정(sentiment)을 판단하고, 번역된 텍스트로 오디오 파일을 생성하는 애플리케이션을 만드는 방법을 보여줘요.

출처: AWS Lambda 개발자 안내서

본문

예제 애플리케이션 개요

이 예제 애플리케이션은 고객 피드백 카드를 분석하고 저장해요. 구체적으로 뉴욕의 가상 호텔의 필요를 충족합니다. 호텔은 다양한 언어로 된 손님의 피드백을 물리적 댓글 카드 형태로 받아요. 그 피드백은 웹 클라이언트를 통해 앱에 업로드됩니다.

댓글 카드 이미지가 업로드되면 다음 단계가 발생합니다.

  1. Amazon Textract로 이미지에서 텍스트를 추출합니다.
  2. Amazon Comprehend가 추출된 텍스트의 감정과 언어를 판단합니다.
  3. Amazon Translate로 추출된 텍스트를 영어로 번역합니다.
  4. Amazon Polly가 추출된 텍스트에서 오디오 파일을 합성합니다.

전체 앱은 AWS CDK로 배포할 수 있어요. 소스 코드와 배포 지침은 GitHub의 프로젝트를 참고하세요.

이 예제에서 사용된 서비스

  • Amazon Comprehend
  • Lambda
  • Amazon Polly
  • Amazon Textract
  • Amazon Translate

(.NET SDK, Java SDK 2.x, Ruby SDK 예제는 동일한 애플리케이션 흐름을 보여주며, 전체 소스는 GitHub 참고.)

JavaScript 예제 — SDK for JavaScript (v3)

다음 발췌는 AWS SDK for JavaScript가 Lambda 함수 안에서 어떻게 사용되는지 보여줘요.

1. 텍스트 추출 (Amazon Textract)

import {
  DetectDocumentTextCommand,
  TextractClient,
} from "@aws-sdk/client-textract";

/**
 * Fetch the S3 object from the event and analyze it using Amazon Textract.
 *
 * @param {import("@types/aws-lambda").EventBridgeEvent<"Object Created">} eventBridgeS3Event
 */
export const handler = async (eventBridgeS3Event) => {
  const textractClient = new TextractClient();

  const detectDocumentTextCommand = new DetectDocumentTextCommand({
    Document: {
      S3Object: {
        Bucket: eventBridgeS3Event.bucket,
        Name: eventBridgeS3Event.object,
      },
    },
  });

  // Textract returns a list of blocks. A block can be a line, a page, word, etc.
  // Each block also contains geometry of the detected text.
  // For more information on the Block type, see https://docs.aws.amazon.com/textract/latest/dg/API_Block.html.
  const { Blocks } = await textractClient.send(detectDocumentTextCommand);

  // For the purpose of this example, we are only interested in words.
  const extractedWords = Blocks.filter((b) => b.BlockType === "WORD").map(
    (b) => b.Text,
  );

  return extractedWords.join(" ");
};

2. 언어·감정 판단 (Amazon Comprehend)

import {
  ComprehendClient,
  DetectDominantLanguageCommand,
  DetectSentimentCommand,
} from "@aws-sdk/client-comprehend";

/**
 * Determine the language and sentiment of the extracted text.
 *
 * @param {{ source_text: string}} extractTextOutput
 */
export const handler = async (extractTextOutput) => {
  const comprehendClient = new ComprehendClient({});

  const detectDominantLanguageCommand = new DetectDominantLanguageCommand({
    Text: extractTextOutput.source_text,
  });

  // The source language is required for sentiment analysis and
  // translation in the next step.
  const { Languages } = await comprehendClient.send(
    detectDominantLanguageCommand,
  );

  const languageCode = Languages[0].LanguageCode;

  const detectSentimentCommand = new DetectSentimentCommand({
    Text: extractTextOutput.source_text,
    LanguageCode: languageCode,
  });

  const { Sentiment } = await comprehendClient.send(detectSentimentCommand);

  return {
    sentiment: Sentiment,
    language_code: languageCode,
  };
};

3. 영어로 번역 (Amazon Translate)

import {
  TranslateClient,
  TranslateTextCommand,
} from "@aws-sdk/client-translate";

/**
 * Translate the extracted text to English.
 *
 * @param {{ extracted_text: string, source_language_code: string}} textAndSourceLanguage
 */
export const handler = async (textAndSourceLanguage) => {
  const translateClient = new TranslateClient({});

  const translateCommand = new TranslateTextCommand({
    SourceLanguageCode: textAndSourceLanguage.source_language_code,
    TargetLanguageCode: "en",
    Text: textAndSourceLanguage.extracted_text,
  });

  const { TranslatedText } = await translateClient.send(translateCommand);

  return { translated_text: TranslatedText };
};

4. 오디오 합성 (Amazon Polly)

import { PollyClient, SynthesizeSpeechCommand } from "@aws-sdk/client-polly";
import { S3Client } from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";

/**
 * Synthesize an audio file from text.
 *
 * @param {{ bucket: string, translated_text: string, object: string}} sourceDestinationConfig
 */
export const handler = async (sourceDestinationConfig) => {
  const pollyClient = new PollyClient({});

  const synthesizeSpeechCommand = new SynthesizeSpeechCommand({
    Engine: "neural",
    Text: sourceDestinationConfig.translated_text,
    VoiceId: "Ruth",
    OutputFormat: "mp3",
  });

  const { AudioStream } = await pollyClient.send(synthesizeSpeechCommand);

  const audioKey = `${sourceDestinationConfig.object}.mp3`;

  // Store the audio file in S3.
  const s3Client = new S3Client();
  const upload = new Upload({
    client: s3Client,
    params: {
      Bucket: sourceDestinationConfig.bucket,
      Key: audioKey,
      Body: AudioStream,
      ContentType: "audio/mp3",
    },
  });

  await upload.done();
  return audioKey;
};

AWS SDK 개발자 가이드와 코드 예제의 전체 목록은 AWS SDK로 Lambda 사용하기를 참고하세요.

더 알아보기 (Learn more)