OpenAI와 함께하는 음성 에이전트 구축 워크숍 요약
오프닝 및 준비 안내
Dominik Kundel은 OpenAI에서 개발자 경험을 담당하고 있으며, 음성 에이전트에 대해 2시간 동안 함께 이야기할 것임을 알리며 강연을 시작합니다.
참가자들에게는 미리 QR 코드를 통해 필요한 의존성(dependencies)을 설치할 것을 안내합니다. 인터넷 상황에 따라 시간이 걸릴 수 있으니, 15분 동안의 도입 설명 시간 동안 설치를 권장합니다.
"여러분 모두 안녕하세요. 저는 도미닉이고, OpenAI에서 개발자 경험을 담당하고 있습니다. 오늘 여러분과 음성 에이전트에 대해 이야기하게 되어 정말 기대됩니다."
에이전트의 정의와 OpenAI Agents SDK 소개
도미닉은 에이전트라는 용어가 다양하게 쓰이기 때문에, 이 강연에서의 정의를 명확히 합니다.
- 에이전트란?
- 사용자를 대신해 독립적으로 작업을 수행하는 시스템
- 모델(예: GPT)이 지침(instructions)과 도구(tools)에 접근해 목표를 달성
- 이 모든 것이 런타임에 캡슐화되어 생명주기를 관리
"우리가 말하는 에이전트란, 사용자를 대신해 독립적으로 작업을 수행하는 시스템입니다."
이어서, OpenAI Agents SDK for TypeScript의 출시 소식을 전합니다.
이 SDK는 Python용 Agents SDK와 동일한 패턴을 따르며, 다음과 같은 기능을 제공합니다.
- 핸드오프(handoffs)
- 가드레일(guard rails)
- 스트리밍 입출력
- 도구(tool) 지원
- MCP 지원
- 트레이싱(tracing) 기능: 에이전트의 동작을 추적 및 재생 가능
- Human-in-the-loop: 사람의 승인이 필요한 경우 일시 중지 및 재개 가능
- 네이티브 음성 에이전트 지원: 음성 입출력, 인터럽트(중단), WebRTC 및 WebSocket 지원
"오늘 TypeScript용 OpenAI Agents SDK를 출시했습니다. Python용을 써보셨다면, 오늘은 TypeScript 버전이 나왔다는 소식입니다."
음성 에이전트의 필요성과 장점
도미닉은 음성 에이전트가 왜 중요한지, 그리고 어떤 장점이 있는지 설명합니다.
- 접근성: 더 많은 사람들이 기술을 쉽게 사용할 수 있음
- 정보 밀도: 음성은 텍스트보다 더 많은 정보를, 더 빠르게 전달 가능 (감정, 억양 등)
- 현실 세계와의 연결: API가 없는 비즈니스에도 음성 에이전트가 직접 전화해 대화 가능
"음성 에이전트와 대화하는 것은 마법 같은 경험입니다. 단순한 텍스트보다 훨씬 더 많은 정보를, 더 빠르게 전달할 수 있습니다."
음성 에이전트 아키텍처: 두 가지 접근법
1. 체인(Chained) 방식: 텍스트 기반 에이전트 래핑
-
구성
- 음성 → 텍스트: Speech-to-Text 모델로 음성을 텍스트로 변환
- 텍스트 에이전트: 기존 텍스트 기반 에이전트가 동작
- 텍스트 → 음성: Text-to-Speech로 응답을 음성으로 변환
-
장점
- 기존 텍스트 에이전트를 쉽게 재활용 가능
- 다양한 최신 LLM 모델 사용 가능
- 입출력 텍스트를 직접 확인하며 디버깅 용이
-
단점
- 턴 감지(turn detection): 사용자가 중간에 끊었을 때, 실제 들은 부분과 모델의 인식이 달라질 수 있음
- 지연(latency): 각 단계마다 지연이 누적됨
- 음성 맥락 손실: 억양, 감정 등 음성 정보가 일부 손실
"모든 모델이 텍스트를 주된 입력으로 사용하기 때문에, 체인 방식은 다양한 모델을 쉽게 활용할 수 있습니다. 하지만 각 단계마다 지연이 발생하고, 음성의 맥락이 일부 사라집니다."
2. 음성-음성(Speech-to-Speech) 방식
-
구성
- 오디오를 직접 입력받아, 오디오로 바로 응답하는 모델 사용 (중간에 텍스트 변환 없음)
-
장점
- 지연 최소화: 중간 변환 과정이 없어 빠름
- 자연스러운 대화: 억양, 감정 등 맥락을 더 잘 이해
- 더 유연한 인터럽트 처리
-
단점
- 기존 텍스트 기반 기능 재활용이 어려움
- 복잡한 상태 관리, 의사결정이 다소 제한적
"음성-음성 방식은 훨씬 더 자연스럽고 빠른 대화를 가능하게 합니다. 하지만 기존 텍스트 기반 기능을 재활용하기는 어렵습니다."
3. 도구 위임(Delegation) 방식
- 프론트라인 에이전트가 사용자의 음성을 실시간으로 처리하고, 복잡한 작업은 더 똑똑한 백엔드 에이전트(예: GPT-4 mini 등)에 도구 호출(tool call)로 위임
"프론트라인 에이전트가 사용자의 음성을 실시간으로 처리하고, 복잡한 작업은 더 똑똑한 백엔드 에이전트에 위임할 수 있습니다."
실시간 데모: 음성 에이전트의 실제 동작
도미닉은 실시간 에이전트 데모를 보여주며, 음성으로 대화하고 도구를 호출하는 과정을 시연합니다.
-
날씨 확인 예시
"오늘 샌프란시스코의 날씨가 어떤지 알려줘."
"샌프란시스코의 날씨를 확인해드릴게요. 잠시만 기다려주세요. 바로 도와드릴 수 있습니다. 위치를 알려주실 수 있나요?"
"샌프란시스코요."
"맑고 쾌적한 하루를 즐기세요. 더 필요한 게 있으신가요?"
-
환불 요청 예시
"최근에 스케이트보드를 샀는데, 사용해보니 너무 어렵더라고요. 약간 긁혔는데 환불해줄 수 있나요?"
"환불 요청을 평가하겠습니다."
"스케이트보드가 손상된 상태로 도착했으므로 전액 환불이 가능합니다. 바로 처리해드리겠습니다."
-
트레이스(Trace) UI 활용
- 대화 내역, 오디오, 도구 호출 내역을 시각적으로 확인 및 재생 가능
"트레이스 UI를 통해 프론트엔드와 백엔드에서 무슨 일이 일어났는지 전체 그림을 볼 수 있습니다."
음성 에이전트 개발의 베스트 프랙티스
도미닉은 음성 에이전트 개발 시 유의할 점을 세 가지로 정리합니다.
-
작고 명확한 목표로 시작하기
- 성능 측정이 어렵기 때문에, 처음에는 한 가지 문제에 집중
- 필요한 도구만 제한적으로 제공
"음성 에이전트의 성능을 평가하는 것은 텍스트 에이전트보다 훨씬 어렵습니다. 처음에는 명확한 목표에 집중하세요."
-
초기부터 평가(evals)와 가드레일(guard rails) 구축
- 신뢰할 수 있는 결과를 얻고, 점진적으로 복잡성을 늘릴 수 있음
- 트레이스 API, 대시보드 등 활용
"Lemonade 같은 고객사는 자체 대시보드를 만들어, 전체 고객 경험을 끝까지 추적하고 반복적으로 개선합니다."
-
프롬프트로 톤, 감정, 역할, 성격까지 제어
- openai.fm에서 다양한 음성 스타일 예시 확인 가능
- 프롬프트와 지침을 통해 모델의 대화 흐름, 성격, 감정 등을 세밀하게 조정
"텍스트-음성 모델도 생성형이기 때문에, 프롬프트로 감정, 역할, 성격을 자유롭게 지정할 수 있습니다."
실습: 텍스트 에이전트에서 음성 에이전트로
1. 텍스트 기반 에이전트 만들기
- Agent 클래스를 import하여, 이름과 지침을 지정해 에이전트 생성
- run 함수로 에이전트 실행, 결과 출력
- 도구(tool) 추가: 예를 들어, 날씨 정보를 가져오는 도구를 추가하고, ZOD로 파라미터 스키마를 정의해 타입 안정성 확보
"에이전트가 진짜 에이전트가 되려면, 도구를 실행할 수 있어야 합니다."
2. 실시간(Real-time) 음성 에이전트 만들기
"실시간 세션이 모든 이벤트를 자동으로 처리해주기 때문에, 복잡한 이벤트 관리를 직접 할 필요가 없습니다."
3. 대화 내역(Transcript) 표시
- 실시간 모델도 기본적으로 대화 내역을 자동으로 기록
- 인터럽트 발생 시, 실제로 읽은 부분만 남기고 나머지는 제거
"모델이 실제로 읽지 않은 텍스트가 남아 있지 않도록, 인터럽트 시 대화 내역을 정확히 관리합니다."
실시간 음성 에이전트의 고급 기능
1. 도구(tool)와 백엔드 연동
- HTTP 등 다양한 방식으로 백엔드 시스템과 연동 가능
- 장기 작업은 task ID를 반환하고, 상태 확인 도구를 별도로 두는 방식 추천
2. Human-in-the-loop (사람 승인)
- 도구 실행 전, 사람이 승인해야 하는 경우를 쉽게 구현 가능
- 승인 요청 이벤트를 받아, UI에서 직접 승인/거부 처리
"브라우저에서 도구 실행 전, 사용자의 승인을 받아야 하는 경우에도 쉽게 구현할 수 있습니다."
3. 핸드오프(Handoff)
- 특정 상황에서 다른 에이전트로 대화 흐름을 넘김
- 예: 일반 에이전트 → 날씨 전문 에이전트로 전환
- 한 세션 내에서 음성(voice)는 바꿀 수 없지만, 억양/톤/성격은 프롬프트로 변경 가능
"첫 번째로 말을 시작한 에이전트의 목소리는 세션 내내 유지됩니다. 하지만 억양이나 성격은 프롬프트로 바꿀 수 있습니다."
4. 백엔드 에이전트와의 위임(Delegation)
- 복잡한 작업(예: 수수께끼 만들기 등)은 백엔드에서 별도의 에이전트로 처리
- 프론트엔드에서 도구 호출 → 백엔드 에이전트 실행 → 결과 반환
"복잡한 추론이 필요한 작업은 백엔드 에이전트에 위임해, 음성 에이전트의 부담을 줄일 수 있습니다."
Q&A: 실무적인 질문과 답변
주요 질문 및 답변 요약
- 대화 내역 저장: 기본적으로 메모리에 저장, 필요시 별도 저장 가능
- 비용: 토큰 단위로 과금, 사용 모델/옵션에 따라 다름
- 오디오 포맷: PCM16 외에도 다양한 포맷 지원
- 다중 에이전트 위임: 병렬 도구 호출 등으로 가능하지만, 복잡성 증가에 유의
- 음성 맥락/기억: 세션 컨텍스트로 관리, 장기 기억은 별도 구현 필요
- 저조한 언어 능력/다국어 입력: 일부 고객사(예: 언어 학습 서비스)에서 사용, 특별한 베스트 프랙티스는 아직 없음
- 인터럽트 콜백: 인터럽트 발생 시, 최신 대화 내역(history)로 접근 가능
- 가드레일(Guard Rails): 입력/출력 모두에 적용 가능, 정책 위반 시 자동 인터럽트
- Wake word(웨이크 워드) 감지: 내장되어 있지 않으나, 자체 구현 가능
- 커스텀 음성: 현재는 프리셋 음성만 지원, 향후 안전성 검토 후 추가 예정
"음성 에이전트의 비용은 토큰 단위로 과금되며, 사용 모델과 옵션에 따라 달라집니다."
"현재는 커스텀 음성 업로드는 지원하지 않지만, 더 안전한 방식이 마련되면 추가할 계획입니다."
자연스러운 대화와 감정 표현
- 음성-음성 모델은 프롬프트를 통해 감정, 억양, 대화 흐름, 심지어 '음~' 같은 반응까지 자연스럽게 표현 가능
- openai.fm에서 다양한 스타일의 예시를 직접 들어볼 수 있음
"음성-음성 모델은 프롬프트만 잘 주면, 지루한 10대처럼 말하거나, 감정을 담아 대화하는 등 매우 자연스러운 대화가 가능합니다."
평가(Evaluation)와 테스트
- 음성 에이전트 평가는 텍스트보다 더 어렵기 때문에, 명확한 목표 설정과 사람 리뷰가 중요
- 트레이스 대시보드 등으로 실제 대화 내역을 반복적으로 확인하며 개선
- Promptful 등 외부 평가 도구와 연동도 가능
"명확한 목표를 설정하고, 사람이 직접 리뷰하는 것이 음성 에이전트 평가의 좋은 출발점입니다."
마무리 및 자료 공유
도미닉은 슬랙 채널을 통해 모든 자료와 링크, 슬라이드를 공유할 예정임을 안내하며, 추가 질문을 받습니다.
"오늘 저와 함께해주셔서 감사합니다. 슬랙 채널에 모든 자료를 올려둘 테니, 언제든 참고하세요!"
핵심 키워드 정리
- 음성 에이전트(Voice Agent)
- OpenAI Agents SDK (TypeScript, Python)
- 실시간 API (WebRTC, WebSocket)
- 도구 호출(Tool Call), 핸드오프(Handoff), Human-in-the-loop
- 가드레일(Guard Rails), 트레이스(Trace)
- 음성-음성(Speech-to-Speech), 체인(Chained) 방식
- 프롬프트 기반 감정/성격/톤 제어
- 평가(Evaluation), 대화 내역(Transcript), 인터럽트(Interrupt)
- 커스텀 음성, 웨이크 워드, 다국어/저조한 언어 입력
마치며
이 워크숍은 OpenAI Agents SDK를 활용해 음성 에이전트를 쉽고 강력하게 구축하는 방법을 실습과 함께 상세히 안내합니다.
음성 에이전트의 구조, 장단점, 실시간 처리, 도구 연동, 평가 및 실제 개발 팁까지, 실무에 바로 적용할 수 있는 다양한 인사이트를 얻을 수 있습니다.
궁금한 점은 슬랙 채널에서 언제든 질문할 수 있습니다! 🚀
"여러분과 함께한 이 시간이 정말 즐거웠습니다. 감사합니다!"