<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ko">
	<id>https://devcafe.co.kr/w/index.php?action=history&amp;feed=atom&amp;title=%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%ED%8C%8C%EC%9D%B4_%EC%9D%8C%EC%84%B1%EC%9D%B8%EC%8B%9D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8_%EB%A7%8C%EB%93%A4%EA%B8%B0</id>
	<title>라즈베리파이 음성인식 프로그램 만들기 - 편집 역사</title>
	<link rel="self" type="application/atom+xml" href="https://devcafe.co.kr/w/index.php?action=history&amp;feed=atom&amp;title=%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%ED%8C%8C%EC%9D%B4_%EC%9D%8C%EC%84%B1%EC%9D%B8%EC%8B%9D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8_%EB%A7%8C%EB%93%A4%EA%B8%B0"/>
	<link rel="alternate" type="text/html" href="https://devcafe.co.kr/w/index.php?title=%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%ED%8C%8C%EC%9D%B4_%EC%9D%8C%EC%84%B1%EC%9D%B8%EC%8B%9D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8_%EB%A7%8C%EB%93%A4%EA%B8%B0&amp;action=history"/>
	<updated>2026-05-17T09:39:36Z</updated>
	<subtitle>이 문서의 편집 역사</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://devcafe.co.kr/w/index.php?title=%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%ED%8C%8C%EC%9D%B4_%EC%9D%8C%EC%84%B1%EC%9D%B8%EC%8B%9D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8_%EB%A7%8C%EB%93%A4%EA%B8%B0&amp;diff=2403&amp;oldid=prev</id>
		<title>Devcafe: /* 마이크 모듈 추가 */</title>
		<link rel="alternate" type="text/html" href="https://devcafe.co.kr/w/index.php?title=%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%ED%8C%8C%EC%9D%B4_%EC%9D%8C%EC%84%B1%EC%9D%B8%EC%8B%9D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8_%EB%A7%8C%EB%93%A4%EA%B8%B0&amp;diff=2403&amp;oldid=prev"/>
		<updated>2026-05-12T09:36:24Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;마이크 모듈 추가&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ko&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← 이전 판&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026년 5월 12일 (화) 18:36 판&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;1번째 줄:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;1번째 줄:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 마이크 모듈 추가 ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 마이크 모듈 추가 ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;INMP441(MS3625 모듈)을 Raspberry Pi Zero에 연결하는 핀맵입니다.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;배선 (INMP441 → RPi Zero)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|INMP441 핀 |RPi Zero 핀 (물리번호)                     |GPIO   |&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|----------|--------------------------------------|-------|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|VDD       |Pin 1 (3.3V)                          |-      |&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|GND       |Pin 6 (GND)                           |-      |&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|L/R       |Pin 6 (GND) → 좌채널 / Pin 1 (3.3V) → 우채널|-      |&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|WS (LRCLK)|Pin 35                                |GPIO 19|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|SCK (BCLK)|Pin 12                                |GPIO 18|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|SD (DOUT) |Pin 38                                |GPIO 20|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;마이크 하나만 쓸 경우 L/R은 보통 GND로 묶어 좌채널로 설정합니다. 두 개를 스테레오로 쓸 거면 한쪽은 GND(좌), 다른 쪽은 3.3V(우)로 묶고 SD 핀끼리 합쳐서 GPIO 20 한 줄로 보내면 됩니다.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;납땜 팁&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	•	RPi Zero가 W(헤더 없는) 버전이면 먼저 40핀 헤더를 납땜하거나, 위 6개 홀에 직접 와이어를 연결. WH 버전이면 헤더에 듀폰 점퍼선으로 먼저 테스트 후 영구 연결 권장.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	•	와이어는 가능한 한 짧게(15cm 이내) — I2S 클럭이 길어지면 노이즈 탑니다. 길게 빼야 하면 차폐선 또는 트위스트 페어로.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	•	0.5mm 무연 솔더 + 인두 온도 320~340℃. 패드와 와이어 양쪽 다 미리 주석도금(pre-tinning) 후 접합하면 깔끔합니다.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	•	INMP441 모듈 핀이 2.54mm 피치라 헤더핀 꽂아서 점퍼선으로 먼저 동작 확인하고, 안정되면 직결 납땜하는 게 안전합니다.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	•	납땜 후 멀티미터로 VDD-GND 단락 여부, 각 신호선 도통 먼저 확인하고 전원 인가.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;연결 후 활성화 (/boot/config.txt)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;source lang=bash&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;dtparam=i2s=on&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;dtoverlay=googlevoicehat-soundcard&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/source&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;또는 dtoverlay=i2s-mmap 후 arecord -l로 카드 인식 확인. arecord -D plughw:1 -c 1 -r 48000 -f S32_LE test.wav 로 녹음 테스트 하시면 됩니다.​​​​​​​​​​​​​​​​&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 프로그램 소스 ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 프로그램 소스 ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Devcafe</name></author>
	</entry>
	<entry>
		<id>https://devcafe.co.kr/w/index.php?title=%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%ED%8C%8C%EC%9D%B4_%EC%9D%8C%EC%84%B1%EC%9D%B8%EC%8B%9D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8_%EB%A7%8C%EB%93%A4%EA%B8%B0&amp;diff=2402&amp;oldid=prev</id>
		<title>2026년 5월 12일 (화) 09:35에 Devcafe님의 편집</title>
		<link rel="alternate" type="text/html" href="https://devcafe.co.kr/w/index.php?title=%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%ED%8C%8C%EC%9D%B4_%EC%9D%8C%EC%84%B1%EC%9D%B8%EC%8B%9D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8_%EB%A7%8C%EB%93%A4%EA%B8%B0&amp;diff=2402&amp;oldid=prev"/>
		<updated>2026-05-12T09:35:25Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ko&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← 이전 판&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026년 5월 12일 (화) 18:35 판&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;1번째 줄:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;1번째 줄:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=== 마이크 모듈 추가 ===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=== 프로그램 소스 ===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=python&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=python&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#!/usr/bin/env python3&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#!/usr/bin/env python3&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Devcafe</name></author>
	</entry>
	<entry>
		<id>https://devcafe.co.kr/w/index.php?title=%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%ED%8C%8C%EC%9D%B4_%EC%9D%8C%EC%84%B1%EC%9D%B8%EC%8B%9D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8_%EB%A7%8C%EB%93%A4%EA%B8%B0&amp;diff=2401&amp;oldid=prev</id>
		<title>Devcafe: 새 문서: &lt;source lang=python&gt; #!/usr/bin/env python3  # -*- coding: utf-8 -*-  “”” INMP441 I2S 마이크 → Whisper STT → Claude 응답 Raspberry Pi Zero WH + INMP441 환경 기준 “””  import os import sys import time import wave import audioop import tempfile import subprocess from pathlib import Path  from openai import OpenAI import anthropic  # ============================================================  # 환경설정  # =============================================...</title>
		<link rel="alternate" type="text/html" href="https://devcafe.co.kr/w/index.php?title=%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%ED%8C%8C%EC%9D%B4_%EC%9D%8C%EC%84%B1%EC%9D%B8%EC%8B%9D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8_%EB%A7%8C%EB%93%A4%EA%B8%B0&amp;diff=2401&amp;oldid=prev"/>
		<updated>2026-05-12T09:34:21Z</updated>

		<summary type="html">&lt;p&gt;새 문서: &amp;lt;source lang=python&amp;gt; #!/usr/bin/env python3  # -*- coding: utf-8 -*-  “”” INMP441 I2S 마이크 → Whisper STT → Claude 응답 Raspberry Pi Zero WH + INMP441 환경 기준 “””  import os import sys import time import wave import audioop import tempfile import subprocess from pathlib import Path  from openai import OpenAI import anthropic  # ============================================================  # 환경설정  # =============================================...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;새 문서&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
“””&lt;br /&gt;
INMP441 I2S 마이크 → Whisper STT → Claude 응답&lt;br /&gt;
Raspberry Pi Zero WH + INMP441 환경 기준&lt;br /&gt;
“””&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import time&lt;br /&gt;
import wave&lt;br /&gt;
import audioop&lt;br /&gt;
import tempfile&lt;br /&gt;
import subprocess&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
&lt;br /&gt;
from openai import OpenAI&lt;br /&gt;
import anthropic&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
# 환경설정&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
OPENAI_API_KEY = os.getenv(“OPENAI_API_KEY”)&lt;br /&gt;
ANTHROPIC_API_KEY = os.getenv(“ANTHROPIC_API_KEY”)&lt;br /&gt;
&lt;br /&gt;
# arecord 디바이스 (arecord -l 로 확인 후 카드 번호 맞추기)&lt;br /&gt;
&lt;br /&gt;
ALSA_DEVICE = os.getenv(“ALSA_DEVICE”, “plughw:1,0”)&lt;br /&gt;
&lt;br /&gt;
# 오디오 포맷&lt;br /&gt;
&lt;br /&gt;
SAMPLE_RATE = 16000      # Whisper 권장값&lt;br /&gt;
CHANNELS = 1&lt;br /&gt;
SAMPLE_WIDTH = 2         # 16-bit PCM (plughw가 32→16 자동 변환)&lt;br /&gt;
&lt;br /&gt;
# VAD (Voice Activity Detection) 파라미터&lt;br /&gt;
&lt;br /&gt;
CHUNK_MS = 100                       # 100ms 단위로 검사&lt;br /&gt;
CHUNK_BYTES = int(SAMPLE_RATE * CHUNK_MS / 1000) * SAMPLE_WIDTH&lt;br /&gt;
SILENCE_RMS_THRESHOLD = 600          # 환경에 맞춰 튜닝 (조용한 방 300, 시끄러우면 1000+)&lt;br /&gt;
START_RMS_THRESHOLD = 900            # 발화 시작 판단 임계치&lt;br /&gt;
SILENCE_END_SEC = 1.5                # 이만큼 무음 지속 시 발화 종료로 판단&lt;br /&gt;
MAX_RECORD_SEC = 30                  # 최대 녹음 길이&lt;br /&gt;
MIN_SPEECH_SEC = 0.4                 # 너무 짧은 입력은 무시&lt;br /&gt;
&lt;br /&gt;
# Claude 모델&lt;br /&gt;
&lt;br /&gt;
CLAUDE_MODEL = “claude-opus-4-5”&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
# 1) I2S 마이크에서 발화 단위로 녹음&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
def record_utterance(out_wav: str) -&amp;gt; bool:&lt;br /&gt;
“””&lt;br /&gt;
arecord를 파이프로 띄워 실시간으로 RMS를 측정하면서&lt;br /&gt;
- 발화 시작이 감지되면 버퍼링 시작&lt;br /&gt;
- 무음이 SILENCE_END_SEC 이상 지속되면 종료&lt;br /&gt;
“””&lt;br /&gt;
cmd = [&lt;br /&gt;
“arecord”,&lt;br /&gt;
“-D”, ALSA_DEVICE,&lt;br /&gt;
“-c”, str(CHANNELS),&lt;br /&gt;
“-r”, str(SAMPLE_RATE),&lt;br /&gt;
“-f”, “S16_LE”,&lt;br /&gt;
“-t”, “raw”,&lt;br /&gt;
“-q”,&lt;br /&gt;
]&lt;br /&gt;
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
print(&amp;quot;🎤 듣는 중... (말씀하세요)&amp;quot;, flush=True)&lt;br /&gt;
frames = []&lt;br /&gt;
started = False&lt;br /&gt;
silence_chunks = 0&lt;br /&gt;
silence_limit = int(SILENCE_END_SEC * 1000 / CHUNK_MS)&lt;br /&gt;
start_time = None&lt;br /&gt;
pre_buffer = []                  # 발화 직전 짧은 구간도 함께 저장 (앞 음 잘림 방지)&lt;br /&gt;
pre_buffer_max = 3               # 약 300ms&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    while True:&lt;br /&gt;
        data = proc.stdout.read(CHUNK_BYTES)&lt;br /&gt;
        if not data or len(data) &amp;lt; CHUNK_BYTES:&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
        rms = audioop.rms(data, SAMPLE_WIDTH)&lt;br /&gt;
&lt;br /&gt;
        if not started:&lt;br /&gt;
            pre_buffer.append(data)&lt;br /&gt;
            if len(pre_buffer) &amp;gt; pre_buffer_max:&lt;br /&gt;
                pre_buffer.pop(0)&lt;br /&gt;
            if rms &amp;gt; START_RMS_THRESHOLD:&lt;br /&gt;
                started = True&lt;br /&gt;
                start_time = time.time()&lt;br /&gt;
                frames.extend(pre_buffer)&lt;br /&gt;
                frames.append(data)&lt;br /&gt;
                print(&amp;quot;🔴 녹음 시작&amp;quot;, flush=True)&lt;br /&gt;
        else:&lt;br /&gt;
            frames.append(data)&lt;br /&gt;
            if rms &amp;lt; SILENCE_RMS_THRESHOLD:&lt;br /&gt;
                silence_chunks += 1&lt;br /&gt;
            else:&lt;br /&gt;
                silence_chunks = 0&lt;br /&gt;
&lt;br /&gt;
            if silence_chunks &amp;gt;= silence_limit:&lt;br /&gt;
                print(&amp;quot;⏹️  녹음 종료&amp;quot;, flush=True)&lt;br /&gt;
                break&lt;br /&gt;
            if time.time() - start_time &amp;gt; MAX_RECORD_SEC:&lt;br /&gt;
                print(&amp;quot;⏹️  최대 길이 도달&amp;quot;, flush=True)&lt;br /&gt;
                break&lt;br /&gt;
finally:&lt;br /&gt;
    proc.terminate()&lt;br /&gt;
    try:&lt;br /&gt;
        proc.wait(timeout=1)&lt;br /&gt;
    except subprocess.TimeoutExpired:&lt;br /&gt;
        proc.kill()&lt;br /&gt;
&lt;br /&gt;
if not started:&lt;br /&gt;
    return False&lt;br /&gt;
&lt;br /&gt;
duration = (len(frames) * CHUNK_BYTES) / (SAMPLE_RATE * SAMPLE_WIDTH)&lt;br /&gt;
if duration &amp;lt; MIN_SPEECH_SEC:&lt;br /&gt;
    return False&lt;br /&gt;
&lt;br /&gt;
with wave.open(out_wav, &amp;quot;wb&amp;quot;) as wf:&lt;br /&gt;
    wf.setnchannels(CHANNELS)&lt;br /&gt;
    wf.setsampwidth(SAMPLE_WIDTH)&lt;br /&gt;
    wf.setframerate(SAMPLE_RATE)&lt;br /&gt;
    wf.writeframes(b&amp;quot;&amp;quot;.join(frames))&lt;br /&gt;
return True&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
# 2) Whisper API로 STT (한국어 + 영어 코드스위칭 자동)&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
def transcribe(audio_path: str) -&amp;gt; str:&lt;br /&gt;
client = OpenAI(api_key=OPENAI_API_KEY)&lt;br /&gt;
with open(audio_path, “rb”) as f:&lt;br /&gt;
result = client.audio.transcriptions.create(&lt;br /&gt;
model=“whisper-1”,&lt;br /&gt;
file=f,&lt;br /&gt;
language=“ko”,   # 주 언어 힌트. 영어 단어 섞여 있으면 자동 인식&lt;br /&gt;
prompt=“한국어 위주이고 영어 기술 용어가 섞일 수 있습니다. “&lt;br /&gt;
“예: Oracle, RAC, Raspberry Pi, GPIO, INMP441.”,&lt;br /&gt;
temperature=0.0,&lt;br /&gt;
)&lt;br /&gt;
return result.text.strip()&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
# 3) Claude API에 전달해서 응답 받기&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
def ask_claude(user_text: str, history: list) -&amp;gt; str:&lt;br /&gt;
client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)&lt;br /&gt;
history.append({“role”: “user”, “content”: user_text})&lt;br /&gt;
msg = client.messages.create(&lt;br /&gt;
model=CLAUDE_MODEL,&lt;br /&gt;
max_tokens=1024,&lt;br /&gt;
system=(“당신은 한국어로 답하는 음성 비서입니다. “&lt;br /&gt;
“사용자의 발화는 음성인식 결과라 오타·동음이의어가 있을 수 있으니 “&lt;br /&gt;
“맥락으로 보정해서 이해해 주세요. 간결하게 답하세요.”),&lt;br /&gt;
messages=history,&lt;br /&gt;
)&lt;br /&gt;
answer = msg.content[0].text&lt;br /&gt;
history.append({“role”: “assistant”, “content”: answer})&lt;br /&gt;
# 컨텍스트 비대화 방지: 최근 10턴만 유지&lt;br /&gt;
if len(history) &amp;gt; 20:&lt;br /&gt;
del history[: len(history) - 20]&lt;br /&gt;
return answer&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
# 메인 루프&lt;br /&gt;
&lt;br /&gt;
# ============================================================&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
if not OPENAI_API_KEY:&lt;br /&gt;
sys.exit(“환경변수 OPENAI_API_KEY 가 필요합니다.”)&lt;br /&gt;
if not ANTHROPIC_API_KEY:&lt;br /&gt;
sys.exit(“환경변수 ANTHROPIC_API_KEY 가 필요합니다.”)&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
print(&amp;quot;=&amp;quot; * 60)&lt;br /&gt;
print(&amp;quot; INMP441 → Whisper → Claude 음성 어시스턴트&amp;quot;)&lt;br /&gt;
print(f&amp;quot;  device   : {ALSA_DEVICE}&amp;quot;)&lt;br /&gt;
print(f&amp;quot;  model    : {CLAUDE_MODEL}&amp;quot;)&lt;br /&gt;
print(&amp;quot;  Ctrl+C 로 종료&amp;quot;)&lt;br /&gt;
print(&amp;quot;=&amp;quot; * 60)&lt;br /&gt;
&lt;br /&gt;
history = []&lt;br /&gt;
while True:&lt;br /&gt;
    try:&lt;br /&gt;
        with tempfile.NamedTemporaryFile(suffix=&amp;quot;.wav&amp;quot;, delete=False) as tmp:&lt;br /&gt;
            wav_path = tmp.name&lt;br /&gt;
&lt;br /&gt;
        ok = record_utterance(wav_path)&lt;br /&gt;
        if not ok:&lt;br /&gt;
            Path(wav_path).unlink(missing_ok=True)&lt;br /&gt;
            continue&lt;br /&gt;
&lt;br /&gt;
        print(&amp;quot;🔄 STT 변환 중...&amp;quot;, flush=True)&lt;br /&gt;
        text = transcribe(wav_path)&lt;br /&gt;
        Path(wav_path).unlink(missing_ok=True)&lt;br /&gt;
&lt;br /&gt;
        if not text:&lt;br /&gt;
            print(&amp;quot;(인식 실패)\n&amp;quot;)&lt;br /&gt;
            continue&lt;br /&gt;
&lt;br /&gt;
        print(f&amp;quot;📝 사용자: {text}&amp;quot;, flush=True)&lt;br /&gt;
&lt;br /&gt;
        print(&amp;quot;🤖 Claude 응답 생성 중...&amp;quot;, flush=True)&lt;br /&gt;
        answer = ask_claude(text, history)&lt;br /&gt;
        print(f&amp;quot;💬 Claude: {answer}&amp;quot;)&lt;br /&gt;
        print(&amp;quot;-&amp;quot; * 60)&lt;br /&gt;
&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        print(&amp;quot;\n종료합니다.&amp;quot;)&lt;br /&gt;
        break&lt;br /&gt;
    except Exception as e:&lt;br /&gt;
        print(f&amp;quot;⚠️  오류: {type(e).__name__}: {e}&amp;quot;)&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
if **name** == “**main**”:&lt;br /&gt;
main()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Devcafe</name></author>
	</entry>
</feed>