10. 세 번째 프로젝트: 음성으로 명령하는 로봇
10. 세 번째 프로젝트: 음성으로 명령하는 로봇

말로 시키면 움직이는 순간
이제 로봇이 조금 더 로봇답게 느껴질 차례다. 버튼을 누르거나 코드를 직접 실행하는 대신, 사람처럼 말로 명령하고 로봇이 그것을 알아듣고 반응하게 만들어 보자.
이번 장의 목표는 간단하다. 마이크로 말을 듣고, 그 말을 텍스트로 바꾸고, AI가 뜻을 해석한 뒤, 실제 로봇 행동이나 설명으로 이어지게 만드는 것이다. 즉, STT(Speech to Text, 음성을 텍스트로 바꾸는 기술), LLM(대규모 언어 모델), TTS(Text to Speech, 텍스트를 음성으로 읽어주는 기술)를 한 줄로 꿰어 하나의 로봇 경험으로 만드는 프로젝트다.1
여기서 중요한 포인트는 단순히 "말하는 챗봇"을 만드는 것이 아니라는 점이다. 챗봇은 대화를 끝내고 화면에 답을 보여주면 일이 끝난다. 하지만 로봇은 다르다. 로봇의 답변은 바퀴를 굴리고, 고개를 돌리고, 카메라를 켜고, 주변을 살피는 행동으로 이어진다. 바로 이 지점에서 언어 능력이 물리 세계와 연결된다.
이번 프로젝트에서 만들 것
이번 프로젝트의 완성 형태는 다음과 같다.
사용자가 로봇에게 "앞으로 조금 가", "책상을 순찰해", "저 물체가 뭐야?", "멈춰"라고 말하면, 로봇은 그 말을 이해해서 적절한 기능을 실행한다. 이동 명령이면 바퀴를 움직이고, 시각 질문이면 카메라 화면을 분석하고, 작업이 끝나면 다시 사람 목소리처럼 결과를 말해 준다.
이 프로젝트는 사실 앞선 두 프로젝트를 합치는 느낌에 가깝다. 8장에서 만든 이동 로봇의 몸을 쓰고, 9장에서 만든 카메라 인식 기능의 눈을 빌려오며, 이번 장에서 음성 인터페이스라는 입과 귀를 붙이는 셈이다. 갑자기 로봇이 훨씬 살아 있는 물건처럼 느껴질 것이다.
왜 음성 로봇이 재미있는가
음성 인터페이스는 생각보다 강력하다. 키보드나 앱 버튼은 결국 사람이 기계의 언어를 배우는 방식이다. 반대로 음성 로봇은 기계가 사람의 언어를 배우는 쪽에 가깝다.
예를 들어 "왼쪽으로 30도 회전해"는 프로그래머에게는 쉬운 명령이지만, 일반 사용자에게는 다소 딱딱하다. 그런데 "조금 왼쪽 봐줘"는 훨씬 자연스럽다. LLM은 이런 애매하고 인간적인 표현을 구조화된 명령으로 바꿔 주는 데 강하다.2
하지만 여기서 착각하면 안 된다. LLM이 곧바로 모터를 돌리게 하면 위험하다. 언어 모델은 말을 잘하지, 안전한 실시간 모터 제어를 보장하지는 않는다. 그래서 이번 프로젝트의 핵심 설계 원칙은 하나다.
LLM은 생각하고, 로봇 제어기는 실행한다.
즉, LLM은 사용자의 의도를 해석하고 어떤 도구를 써야 할지 결정한다. 실제 모터 제어, 정지 조건, 장애물 확인, 시간 제한은 별도의 로봇 제어 코드가 담당한다. 이 분리가 되어 있어야 음성 로봇이 장난감이 아니라, 조금은 믿고 쓸 수 있는 시스템이 된다.3
전체 구조를 먼저 그려 보자
이번 프로젝트의 흐름은 아래처럼 이해하면 쉽다.
사용자가 마이크에 대고 말한다.
STT가 음성을 텍스트로 바꾼다.
LLM이 텍스트를 읽고 의도를 해석한다.
LLM은 정해진 로봇 기능 가운데 하나를 선택하거나 여러 단계를 계획한다.
로봇 제어기가 안전 검사 후 실제 동작을 수행한다.
결과를 다시 텍스트로 만들고, TTS가 그것을 음성으로 읽는다.
이 구조는 오늘날 많은 음성 에이전트에서 널리 쓰이는 STT → LLM → TTS 파이프라인과 같다. 이 방식은 각 부분을 독립적으로 바꿀 수 있어 유연하고, 실전에서 다루기 편하다.24
한마디로 정리하면 이렇다.
귀로 듣고, 머리로 해석하고, 몸으로 행동하고, 입으로 보고한다.
어떤 로봇으로 시작하면 좋은가
이번 프로젝트는 거대한 로봇이 아니어도 충분하다. 오히려 작은 책상 위 로봇이나 바퀴형 로봇이 더 좋다. 이유는 간단하다. 음성 인터페이스에서 중요한 것은 화려한 기구가 아니라 명령-행동-피드백의 연결을 분명하게 체험하는 것이기 때문이다.
가장 현실적인 구성은 다음 셋 중 하나다.
이동 로봇: "앞으로 가", "왼쪽으로 돌아", "순찰해", "멈춰" 같은 명령에 잘 어울린다.
카메라 달린 데스크 로봇: "뭐가 보여?", "컵 찾아줘", "QR 코드 읽어줘" 같은 질문에 강하다.
이동 + 카메라 결합형: 이번 장의 목표에 가장 잘 맞는다. 움직이면서 보고, 말로 설명할 수 있다.
스피커와 마이크는 USB 장치를 써도 되고, 블루투스는 초반에는 권장하지 않는다. 블루투스는 편하지만 지연과 연결 이슈가 종종 생긴다. 처음에는 유선 USB 마이크와 소형 스피커가 제일 마음 편하다.
준비물
이번 프로젝트는 꼭 비싼 장비가 필요하지 않다. 이미 8장과 9장을 따라왔다면 절반은 준비된 셈이다.
하드웨어는 바퀴형 로봇 또는 데스크 로봇 본체, 모터 드라이버, 카메라, 마이크, 스피커, 그리고 라즈베리파이·Jetson·미니 PC 같은 메인 컴퓨팅 보드가 있으면 된다. 마이크와 스피커는 가장 평범한 USB 장비면 충분하다.
소프트웨어는 Python이 가장 편하다. STT는 클라우드 API를 써도 되고, 로컬 Whisper 계열을 써도 된다. TTS는 OpenAI, Google, Gemini 계열 API처럼 품질 좋은 서비스를 써도 되고, 로컬 TTS 엔진을 붙여도 된다. 최근에는 자연어로 음성 스타일을 어느 정도 조절할 수 있는 TTS API도 제공된다.5
LLM은 클라우드 API를 사용해도 좋고, Jetson이나 PC에서 로컬 모델을 돌려도 된다. 특히 로컬 구성이 가능하면 개인정보 보호와 지연 시간 면에서 유리하다. Jetson 같은 엣지 장치는 이런 목적에 점점 더 잘 맞아 가고 있다.67
가장 먼저 정할 것: 대화 방식
음성 로봇을 만들 때 초보자가 가장 많이 놓치는 것이 있다. 바로 언제 듣고, 언제 말할지 정하는 일이다.
겉으로 보기엔 단순해 보여도, 실제로는 꽤 까다롭다. 로봇이 말하는 동안 자기 스피커 소리를 다시 마이크로 듣는 문제가 생긴다. 이른바 에코나 하울링 문제다. 또 사용자가 말을 끊는 순간, STT와 TTS가 동시에 경쟁하면 상태 관리가 꼬이기 쉽다. 실무에서는 그래서 생각보다 단순한 방식이 자주 쓰인다.89
가장 추천하는 방식은 핑퐁 방식이다.
사용자가 말할 차례에는 로봇이 듣기만 하고, 로봇이 답할 차례에는 사람 음성 인식을 잠시 멈춘다. 어찌 보면 대화가 조금 굼떠 보일 수 있지만, 구현은 훨씬 안정적이다. 특히 작은 개발 보드나 저가 오디오 장비에서는 이 방식이 성공 확률이 높다.89
조금 더 발전시키면 두 가지 선택지가 생긴다.
푸시 투 토크: 버튼을 누를 때만 듣는다. 가장 단순하고 안정적이다.
웨이크 워드: "로봇아" 같은 호출어를 들으면 대화를 시작한다. 더 자연스럽지만 구현 난이도가 오른다.
항상 듣기: 가장 멋져 보이지만 초반 프로젝트에는 추천하지 않는다. 오탐지, 프라이버시, 배터리 문제가 한꺼번에 온다.
처음 만드는 프로젝트라면 푸시 투 토크나 핑퐁 방식이 좋다. 책을 덮고 실제로 성공하는 것이, 늘 멋진 아키텍처보다 중요하다.
시스템을 세 층으로 나누면 구현이 쉬워진다
이 프로젝트를 한 파일에 몰아넣으면 금방 복잡해진다. 기능을 세 층으로 나누면 훨씬 관리하기 쉽다.
첫 번째는 음성 입출력 층이다. 마이크에서 소리를 받고, STT를 호출하고, TTS 음성을 재생한다. 이 층은 "듣고 말하기"만 담당한다.
두 번째는 언어 해석 층이다. 사용자의 문장을 읽고 무엇을 원하는지 판단한다. 여기서 LLM이 활약한다. 다만 자연어 대답만 만드는 것이 아니라, 아래와 같은 구조화된 결과를 내게 해야 한다.
{
"intent": "move_forward",
"distance_cm": 30,
"say": "30센티미터 앞으로 이동할게요."
}세 번째는 로봇 실행 층이다. 실제로 모터를 돌리고, 카메라를 보고, 정지 조건을 확인한다. 이 층은 LLM이 아니라 일반 코드가 맡는다. 예를 들어 move_forward(30) 같은 함수가 있고, 그 안에서 엔코더 확인, 장애물 감지, 시간 초과 처리, 긴급 정지를 수행한다.
이렇게 분리해 두면 나중에 STT를 Whisper에서 다른 서비스로 바꾸거나, LLM을 로컬 모델로 교체해도 로봇 제어 코드는 거의 그대로 유지할 수 있다.
음성 명령은 어떻게 해석할까
처음에는 "사용자 말 전체를 그냥 LLM에 보내고 답변을 받으면 되지 않을까?"라고 생각하기 쉽다. 물론 가능은 하다. 하지만 로봇에서는 그 방식이 불안정하다.
예를 들어 사용자가 "앞으로 조금만 가다가 장애물 있으면 멈춰"라고 말했을 때, 일반 챗봇 답변처럼 긴 문장이 나오면 제어 코드가 해석하기 어렵다. 그래서 LLM에게는 처음부터 역할을 분명히 주는 편이 좋다.
예를 들면 이런 식이다.
"너는 음성 로봇 명령 해석기다. 사용자의 말을 읽고, 허용된 명령만 JSON으로 반환하라. 허용 명령은 move_forward, move_backward, turn_left, turn_right, stop, describe_scene, patrol_desk이다."
이렇게 하면 LLM은 소설을 쓰는 대신, 선택지 안에서 얌전하게 행동하게 된다. 물론 완벽하지는 않지만 훨씬 다루기 쉬워진다.
여기서 중요한 것은 허용 명령 집합을 작게 시작하는 것이다. 처음부터 모든 한국어 표현을 다 받아들이려 하지 말고, 6개 정도의 기능으로 시작하자.
예를 들어 이번 프로젝트의 최소 기능은 이 정도면 충분하다.
이동: 앞으로 가기, 뒤로 가기, 좌회전, 우회전, 멈춤
시각: 앞을 설명하기, 특정 물체 찾기
루틴: 책상 순찰, 시작 위치로 돌아오기
이 정도만 구현해도 "아, 이게 말로 움직이는 로봇이구나"라는 느낌이 분명하게 난다.
챗봇과 로봇의 차이: 대답이 아니라 행동이 핵심
이번 장에서 꼭 짚고 넘어가야 할 것이 있다. 챗봇은 틀려도 민망하고 끝이지만, 로봇은 틀리면 부딪힐 수 있다.
그래서 로봇에서는 말의 해석과 행동 사이에 한 단계가 더 필요하다. 바로 안전 검사다.
예를 들어 사용자가 "앞으로 가"라고 말했더라도, 제어기는 바로 모터를 돌리지 말고 다음을 먼저 본다.
앞쪽 거리 센서 값이 너무 가깝지는 않은지, 배터리가 충분한지, 바퀴가 이미 막혀 있지는 않은지, 현재 다른 작업을 수행 중인지, 정지 명령이 들어와 있지는 않은지 확인한다. 이 검사를 통과했을 때만 행동을 실행한다.
이 원칙 하나만 지켜도 로봇 품질이 크게 올라간다. LLM이 똑똑해 보이는 것보다, 로봇이 엉뚱하게 움직이지 않는 것이 훨씬 중요하다.
프로젝트 구조 예시
이번 프로젝트는 아래 같은 모듈 구조로 짜면 좋다.
audio_input.py는 마이크 녹음과 STT를 담당한다. agent.py는 LLM 호출과 의도 해석을 담당한다. robot_api.py는 이동, 정지, 카메라 설명 같은 실제 기능을 제공한다. audio_output.py는 TTS 생성과 재생을 맡는다. 마지막으로 main.py가 전체 흐름을 연결한다.
로직은 다음처럼 단순하게 시작하면 된다.
버튼을 누르면 3초 동안 녹음한다.
STT로 텍스트를 만든다.
텍스트를 LLM에 보내 의도 JSON을 받는다.
안전 검사를 한다.
허용된 로봇 함수만 실행한다.
실행 결과를 한 문장으로 만든다.
TTS로 읽는다.
여기서 핵심은 "로봇 함수만 실행한다"는 부분이다. LLM이 생성한 임의의 파이썬 코드를 실행하면 안 된다. 무조건 미리 정의한 함수 목록 안에서만 행동하게 해야 한다.
STT는 어떤 것을 고르면 좋을까
STT는 생각보다 로봇 경험 전체를 많이 좌우한다. 아무리 LLM이 좋아도, 처음 받아 적은 문장이 틀리면 뒤의 모든 단계가 흔들린다.
초보자에게는 두 가지 길이 있다.
첫 번째는 클라우드 STT다. 설정이 쉽고 품질이 좋은 편이다. 인터넷이 필요하지만 빠르게 성공 경험을 만들기 좋다.
두 번째는 로컬 STT다. Whisper 계열을 많이 쓴다. 인터넷 없이 쓸 수 있고 프라이버시에 유리하지만, 하드웨어 성능이 중요하다. Jetson 같은 장치에서는 최적화된 구성이 꽤 유용하고, whisper.cpp처럼 가벼운 구현은 실제 상호작용 수준의 지연으로 맞추는 데 도움이 된다.710
처음에는 클라우드 STT로 시작하고, 나중에 로컬 Whisper로 옮기는 전략이 현실적이다. 프로젝트는 일단 굴러가야 재밌다.
TTS는 왜 생각보다 중요할까
TTS는 단순히 "말소리 내기"가 아니다. 사용자는 로봇의 지능을 TTS 목소리에서도 느낀다. 답변 내용이 좋아도, TTS가 너무 끊기거나 로봇 같으면 전체 인상이 뚝 떨어진다.
가능하면 답변은 짧고 또렷하게 만들자. 로봇이 한 번에 너무 길게 말하면 듣는 사람도 힘들고, 그동안 다음 명령을 받지 못해 시스템이 느려진다.
예를 들어 "책상 위에 컵과 책이 보입니다. 오른쪽에 파란색 컵이 있고…"처럼 길게 말하기보다, "컵 하나와 책 한 권이 보여요. 컵은 오른쪽에 있어요."처럼 짧게 정리하는 편이 좋다.
최근 TTS API는 목소리 톤, 스타일, 속도 같은 요소를 어느 정도 자연어로 제어할 수 있다. 덕분에 차분한 비서 같은 느낌이나 밝은 데스크 로봇 느낌을 쉽게 줄 수 있다.5
실제로 해보는 명령 설계
이번 프로젝트에서는 다음 여섯 문장을 대표 명령으로 삼아 보자.
"앞으로 가."
"왼쪽으로 돌아."
"멈춰."
"책상을 순찰해."
"앞에 뭐가 보여?"
"저 물체가 뭐야?"
처음 세 개는 이동 제어, 네 번째는 짧은 루틴 실행, 다섯 번째와 여섯 번째는 카메라 설명 기능이다. 여기서 "저 물체가 뭐야?"는 조금 애매하다. 사용자가 손가락으로 가리키는 것을 로봇이 정확히 알기 어렵기 때문이다. 그래서 초반에는 카메라 중앙에 있는 대표 물체를 설명하거나, 화면의 가장 큰 물체를 설명하는 방식으로 단순화하면 된다.
로봇 프로젝트에서는 이런 식의 현실적인 타협이 매우 중요하다. 사람은 "저거"라고 쉽게 말하지만, 로봇은 "저거"가 무엇인지 알아내기 위해 추가 센서나 포인팅 인식이 필요할 수 있다. 처음에는 문제를 줄여서 푸는 것이 맞다.
책상을 순찰하는 간단한 루틴 만들기
음성 로봇의 재미는 단순 명령보다 작은 루틴에서 더 잘 드러난다. 예를 들어 "책상을 순찰해"라는 명령을 받으면 다음처럼 동작하게 만들 수 있다.
로봇이 천천히 앞으로 움직이고, 1초 멈춘 뒤, 카메라 장면을 캡처하고, 다시 오른쪽으로 조금 회전하고, 또 장면을 캡처한다. 마지막에 "왼쪽엔 책, 정면엔 키보드, 오른쪽엔 컵이 보여요"처럼 짧게 요약해서 말하면 된다.
이 순간 사용자는 단순히 음성 명령을 넣었다는 느낌을 넘어서, 로봇이 상황을 살피고 보고하는 존재처럼 느끼게 된다. 이 체감 차이가 크다.
실패를 줄이는 아주 실용적인 규칙
음성 로봇은 멋있지만, 실패 포인트도 많다. 그래서 아래 규칙을 미리 넣어 두면 훨씬 안정적이다.
명령이 애매하면 바로 움직이지 말고 다시 묻는다.
한 번에 한 작업만 수행한다.
긴급 정지 명령은 항상 최우선으로 처리한다.
이동 명령에는 시간 제한이나 거리 제한을 둔다.
TTS 재생 중에는 STT를 잠시 멈춘다.
로그를 남겨서 어떤 문장이 어떤 행동으로 바뀌었는지 기록한다.
특히 다섯 번째는 정말 중요하다. 실제 음성 시스템에서는 STT와 TTS를 동시에 돌리면 스피커 소리가 다시 입력되어 루프가 생기기 쉽다. 많은 구현이 핑퐁 방식이나 하프 듀플렉스 구조를 택하는 이유가 여기에 있다.89
예시 시나리오로 보는 전체 흐름
한 번 장면을 상상해 보자.
사용자가 말한다. "로봇아, 책상을 순찰해."
마이크 입력이 STT를 거쳐 책상을 순찰해라는 텍스트가 된다. LLM은 이 문장을 patrol_desk 의도로 해석한다. 제어기는 현재 배터리와 장애물 상태를 확인한 뒤 순찰 루틴을 실행한다. 카메라가 장면을 몇 번 캡처하고, 물체 인식 모델이 컵과 책, 키보드를 찾는다. 마지막으로 LLM 또는 간단한 템플릿이 결과를 문장으로 정리한다. TTS가 "정면에 키보드, 오른쪽에 컵, 왼쪽에 책이 보여요."라고 말한다.
이 흐름에서 챗봇은 단지 말을 잘하는 부품이 아니다. 센서 데이터와 동작 결과를 받아 사람에게 이해하기 쉬운 형태로 연결하는 번역기 역할을 한다. 그리고 그 번역이 행동으로 닿는 순간, 우리는 비로소 AI 로봇다운 경험을 하게 된다.
로컬 AI로 확장할 수 있을까
가능하다. 그리고 개인 개발자에게 꽤 매력적인 방향이다.
최근에는 Jetson 같은 엣지 장치에서 소형 LLM, VLM, STT, TTS를 로컬로 돌리는 흐름이 점점 쉬워지고 있다. 이렇게 하면 음성 데이터와 카메라 영상이 외부 서버로 나가지 않아 프라이버시에 유리하고, 인터넷 지연도 줄일 수 있다.67
실제로 로컬 음성 파이프라인을 구성한 오픈소스 프로젝트들도 있다. 웨이크 워드, STT, LLM, TTS를 각각 독립 모듈로 두고 자연어 명령으로 로봇 기능을 호출하는 방식이다.311
다만 처음부터 전부 로컬로 하려 들면 설치와 최적화가 부담스러울 수 있다. 현실적인 순서는 이렇다.
처음에는 클라우드 STT + 클라우드 LLM + 클라우드 TTS로 개념을 완성한다. 그다음 STT를 로컬로 바꾸고, 이후 TTS를 로컬로 바꾸고, 마지막으로 LLM을 로컬 모델로 옮긴다. 이렇게 단계적으로 전환하면 중간에 길을 잃지 않는다.
이 프로젝트에서 꼭 얻어야 하는 감각
이번 장의 진짜 성과는 음성 인식 라이브러리를 하나 익히는 것이 아니다. 더 중요한 것은 자연어가 어떻게 로봇의 행동으로 번역되는지 몸으로 이해하는 것이다.
사람의 말은 본래 애매하다. "조금만 가", "저거 봐", "한 바퀴 돌아봐" 같은 문장은 컴퓨터에게는 모호하다. 그런데 LLM이 그 사이를 메워 주면, 우리는 훨씬 인간적인 인터페이스로 로봇을 다룰 수 있다. 동시에 그 모호함이 곧 위험이 될 수 있기 때문에, 실행 계층과 안전 계층이 별도로 필요하다는 사실도 배우게 된다.
즉, 이번 프로젝트는 단순한 음성 비서 만들기가 아니다. AI 에이전트와 로봇 제어를 연결하는 첫 번째 관문이다.
직접 만들어 볼 때의 권장 순서
처음부터 모든 기능을 한 번에 붙이지 말자. 아래 순서대로 가면 성공 확률이 높다.
먼저 버튼을 눌러 녹음하고 텍스트를 출력하는 STT만 완성한다. 그다음 텍스트 명령을 LLM 없이 규칙 기반으로 몇 개만 처리해 본다. 예를 들어 "앞으로 가"면 전진, "멈춰"면 정지처럼 단순 매핑으로 시작한다. 이후 LLM을 붙여 자연어 표현을 더 유연하게 받는다. 그다음 TTS를 연결해 결과를 말하게 만든다. 마지막에 카메라 설명과 순찰 루틴을 붙인다.
이 순서가 좋은 이유는 문제를 단계별로 분리할 수 있기 때문이다. 음성 인식이 틀리는 건지, LLM 해석이 이상한 건지, 모터 제어가 흔들리는 건지 한 번에 보면 헷갈린다. 하지만 층별로 붙이면 어디서 꼬였는지 금방 보인다.
마무리: 이제 로봇이 대답만 하지 않고 행동한다
이번 프로젝트는 책 전체에서 꽤 중요한 분기점이다. 여기까지 오면 로봇은 더 이상 센서를 읽고 모터를 돌리는 장치에 머물지 않는다. 사람의 말을 이해하고, 상황에 맞는 행동을 고르고, 결과를 다시 사람에게 설명하는 존재가 된다.
물론 아직 완벽한 비서 로봇은 아니다. 발음이 흐리면 못 알아들을 수도 있고, "저거" 같은 말은 여전히 애매하며, 긴 대화는 상태 관리가 까다롭다. 그래도 괜찮다. 우리는 지금 범용 가정용 로봇을 만드는 게 아니라, 개인 개발자가 혼자서도 구현 가능한 AI 로봇의 핵심 구조를 익히고 있기 때문이다.
그리고 그 핵심은 놀라울 정도로 단순한 한 문장으로 정리된다.
말을 듣고, 뜻을 해석하고, 안전하게 행동하고, 결과를 다시 말한다.
다음 장에서는 이 흐름을 손끝의 세계로 옮겨 본다. 이번에는 바퀴가 아니라 관절이다. 로봇팔로 물체를 집는 순간, AI 로봇은 또 한 번 더 현실로 가까워진다.
참고
1음성 AI 완전 정리 – TTS와 STT의 실전 활용법
2Designing Voice AI Workflows Using STT + NLP + TTS
4How to Choose STT and TTS for Voice Agents: Latency, Accuracy, Cost
5텍스트 음성 변환 생성 (TTS) | Gemini API
6Getting Started with Edge AI on NVIDIA Jetson: LLMs, VLMs, and Foundation Models for Robotics
7Real time Speech To Text for robots - Running whisper.cpp with CUDA on Jetson Orin Nano Super
8React Native에서 STT-TTS를 활용해 GPT와 음성으로 대화하도록 구현
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.