Skip to main content

phone-agent

AI 실시간 음성 전화 에이전트 (OpenAI Realtime API 전용). Twilio + OpenAI Realtime API만 사용. Deepgram, ElevenLabs 불필요. 서버 파일은 반드시 scripts/server_realtime.py를 사용할 것 (server.py 아님). 사용 시점: (1) 'AI 전화 걸어줘', '모닝콜 해줘' 등 전화 관련 요청, (2) '전화 서버 시작', 'phone agent 시작', (3) 특정 번호로 전화 발신 요청, (4) AI 전화 페르소나 설정/변경

Source facts

Repository
jkf87/phone-agent
Last source activity
October 20, 2026 at 08:03
Detected SKILL.md language
Korean
Stars
9
Forks
1

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
phone-agent
description
AI 실시간 음성 전화 에이전트 (OpenAI Realtime API 전용). Twilio + OpenAI Realtime API만 사용. Deepgram, ElevenLabs 불필요. 서버 파일은 반드시 scripts/server_realtime.py를 사용할 것 (server.py 아님). 사용 시점: (1) 'AI 전화 걸어줘', '모닝콜 해줘' 등 전화 관련 요청, (2) '전화 서버 시작', 'phone agent 시작', (3) 특정 번호로 전화 발신 요청, (4) AI 전화 페르소나 설정/변경
# Phone Agent (OpenAI Realtime API 전용) OpenAI Realtime API + Twilio로 AI가 실시간 음성 전화를 걸고 대화하는 스킬. **중요: 이 스킬은 Deepgram, ElevenLabs를 사용하지 않음.** OpenAI Realtime API가 음성 인식 + AI 대화 + 음성 합성을 모두 처리. 필요한 API 키는 OpenAI + Twilio 두 개뿐. ## 사전 요구사항 - Python 3.11+ - ngrok (authtoken 설정 필수, 무료 계정 동시 1세션 제한) - Twilio 계정 (전화번호 + Customer Profile Approved + Geo Permissions: South Korea) - OpenAI API Key (Realtime API 지원) ## 초기 설정 (최초 1회) ```bash bash scripts/setup.sh ``` 자동 처리: Python 패키지 설치 → ngrok 확인 → .env 템플릿 생성 Mac, Linux/WSL, Windows(WSL) 모두 지원. setup.sh 실행 후 `.env` 파일에 API 키를 채워넣으면 준비 완료. ## 환경변수 (.env) 스킬 디렉토리의 `.env` 파일 (setup.sh가 자동 생성): ``` OPENAI_API_KEY="sk-..." TWILIO_ACCOUNT_SID="ACxxxxxxxx" TWILIO_AUTH_TOKEN="xxxxxxxx" TWILIO_PHONE_NUMBER_SID="PNxxxxxxxx" NGROK_AUTHTOKEN="2xxx..." # dashboard.ngrok.com → Your Authtoken PORT=8082 MY_PHONE="+821012345678" # (선택) make-call.sh에서 기본 수신번호로 사용 ``` **Deepgram, ElevenLabs 키는 필요 없음.** `PUBLIC_URL_REALTIME`은 start.sh가 자동 설정. `NGROK_AUTHTOKEN`을 .env에 넣으면 ngrok config 없이 자동 인증. ## 워크플로우 ### 1. 서버 시작 ```bash bash scripts/start.sh ``` 자동 처리: 의존성 체크(없으면 자동 설치) → ngrok 시작 → URL 감지 → Twilio Webhook 업데이트 → `scripts/server_realtime.py` 실행 **주의: server.py가 아닌 server_realtime.py를 실행해야 함.** start.sh가 올바른 파일을 자동 실행. ### 2. 전화 발신 서버 실행 중 상태에서: ```bash bash scripts/make-call.sh +821012345678 ``` 또는 수동으로: ```bash NGROK_URL=$(curl -s http://localhost:4040/api/tunnels | python3 -c " import json, sys d = json.load(sys.stdin) ts = [t['public_url'] for t in d.get('tunnels',[]) if t.get('proto')=='https'] print(ts[0] if ts else '') ") source .env curl -X POST "https://api.twilio.com/2010-04-01/Accounts/${TWILIO_ACCOUNT_SID}/Calls.json" \ --data-urlencode "To=+821012345678" \ --data-urlencode "From=$(curl -s "https://api.twilio.com/2010-04-01/Accounts/${TWILIO_ACCOUNT_SID}/IncomingPhoneNumbers/${TWILIO_PHONE_NUMBER_SID}.json" -u "${TWILIO_ACCOUNT_SID}:${TWILIO_AUTH_TOKEN}" | python3 -c "import json,sys;print(json.load(sys.stdin).get('phone_number',''))")" \ --data-urlencode "Url=${NGROK_URL}/incoming" \ --data-urlencode "Timeout=30" \ -u "${TWILIO_ACCOUNT_SID}:${TWILIO_AUTH_TOKEN}" ``` 한국 번호 변환: `010-1234-5678` → `+821012345678` (0 제거, +82 추가) ### 3. 페르소나 변경 `scripts/server_realtime.py`의 `SYSTEM_PROMPT` 수정 후 start.sh 재실행: ```python SYSTEM_PROMPT = """당신은 AI 비서 '하나'예요. 반말로 친근하게 대화해주세요.""" ``` ### 4. 보이스 변경 `scripts/server_realtime.py`의 `VOICE` 변수 변경: | Voice | 특징 | |-------|------| | `shimmer` | 밝고 에너지 넘치는 (기본값) | | `alloy` | 중성적, 균형 | | `echo` | 차분한 남성 | | `coral` | 따뜻하고 친근한 | | `sage` | 부드럽고 차분한 | | `ash`, `ballad`, `verse`, `marin`, `cedar` | 기타 | ## 핵심 기술 포인트 오디오 포맷: **g711_ulaw** (Twilio와 OpenAI가 동일 포맷 사용) - Twilio mu-law 8kHz ↔ OpenAI g711_ulaw: 변환 없이 직접 패스스루 - audioop 불필요 (Python 3.13+ 호환 문제 없음) - 칙칙 소리 원인이었던 `audioop.ratecv` 상태 관리 문제 해결 ## 문제 해결 | 증상 | 해결 | |------|------| | 칙칙 소리 | g711_ulaw 포맷 사용 확인 (pcm16은 변환 필요해 칙칙거림) | | 스페인어/영어로 대답 | voice 이름 유효한지 확인 (fable 등 구형 제거됨), SYSTEM_PROMPT가 한국어인지 확인 | | error 10005 | Twilio Customer Profile 생성 + 지원팀 Voice 활성화 요청 | | 국제전화 수신거부 | 수신자가 통신사에서 국제전화 수신 허용 | | .env 값 비어있음 | `bash scripts/setup.sh` 실행 후 .env에 API 키 채우기 | | ngrok 없음 | Mac: `brew install ngrok` / Linux: `snap install ngrok` 또는 직접 다운로드 | | ngrok 세션 제한 | 무료 계정 동시 1세션. 다른 기기 ngrok 종료 또는 dashboard.ngrok.com/agents에서 세션 종료 | | application error + 5초 끊김 | server_realtime.py 실행 확인 (server.py 아님) | ## 비용 월 약 $17.5 (~24,000원): Twilio 번호 $1 + 통화 ~$3.3 (66분×$0.05) + OpenAI Realtime ~$13.2 (66분×$0.20) 기준: 하루 3분, 평일 22일 사용 (gpt-4o-mini-realtime-preview) --- ## 🧠 메모리 연동 (Memory Integration) 전화 AI가 사용자 정보와 작업 내역을 기억해서 **진짜 내 에이전트처럼** 대화하는 기능. ### 작동 원리 ``` 통화 연결 → USER.md + MEMORY.md 읽기 → 시스템 프롬프트에 포함 → 대화 ``` ### 필수 파일 (워크스페이스 루트) **1. USER.md** - 사용자 프로필 ```markdown # USER.md - About Your Human ## 기본 정보 - **이름:** 코난쌤 - **호칭:** 코난쌤 / ㅇㅇ - **타임존:** Asia/Seoul ## 관심 분야 - 바이브코딩, 생성형 AI 교육 - AI 에이전트 개발 ## 주요 활동 - 교원대학교/세종시교육청 AI 연수 - 유튜브: https://www.youtube.com/@conanssam ``` **2. MEMORY.md** - 작업 내역 및 기억 ```markdown # MEMORY.md - 장기 기억 ## 2026-02-28 (토) ### 작업 내역 - phone-agent 스킬 설치 - ngrok 업그레이드 (3.16.1 → 3.36.1) - 통화 로그 텍스트 변환 기능 추가 ### 테스트 결과 - 전화 발신/수신: ✅ 성공 ``` ### 코드 수정 사항 `scripts/server_realtime.py`에 추가된 함수: ```python # 메모리 파일 경로 WORKSPACE_DIR = os.path.expanduser("~/.openclaw/workspace-m1clawbot") MEMORY_FILE = os.path.join(WORKSPACE_DIR, "MEMORY.md") USER_FILE = os.path.join(WORKSPACE_DIR, "USER.md") def load_memory_context() -> str: """메모리 파일에서 컨텍스트 로드""" context_parts = [] # USER.md if os.path.exists(USER_FILE): with open(USER_FILE, "r", encoding="utf-8") as f: content = f.read().strip() if content: lines = content.split('\n') body_lines = [l for l in lines if not l.startswith('# USER.md')] user_content = '\n'.join(body_lines).strip() if user_content: context_parts.append(f"[사용자 정보]\n{user_content}") # MEMORY.md (최근 2000자만) if os.path.exists(MEMORY_FILE): with open(MEMORY_FILE, "r", encoding="utf-8") as f: content = f.read().strip() if content: context_parts.append(f"[최근 기억]\n{content[-2000:]}") return "\n\n".join(context_parts) if context_parts else "" def build_system_prompt() -> str: """메모리 기반으로 시스템 프롬프트 생성""" memory_context = load_memory_context() base_prompt = """당신은 OpenClaw AI 어시스턴트예요. 성격: - 솔직하고 간결해요 - 친근하고 반말로 대화해요 - 의견이 있어요 규칙: - 전화 연결되면 자연스럽게 안부 - 2-3문장으로 짧고 자연스럽게 대답 - 한국 시간(Asia/Seoul) 기준""" if memory_context: base_prompt += f"\n\n[현재 컨텍스트]\n{memory_context}" return base_prompt ``` ### 테스트 결과 ``` [User] 어제 뭐 했어? [AI] 어제는 전화 기능을 테스트했어. 통화 로그 변환도 잘 되고... [User] 내 유튜브 채널 이름 뭐야? [AI] 너의 유튜브 채널 이름은 '코난쌤TV'야. [User] 내가 누구게? [AI] 넌 코난쌤이잖아! AI 교육 강사고 유튜버야. ``` ### 다른 에이전트와 연동 다른 OpenClaw 에이전트에서도 동일하게: 1. **WORKSPACE_DIR** 경로 변경 2. **USER.md, MEMORY.md** 파일 생성 3. **build_system_prompt()** 함수 사용 예시: ```python # 에이전트 A의 워크스페이스 WORKSPACE_DIR = "/Users/xxx/.openclaw/workspace-agent-a" # 에이전트 B의 워크스페이스 WORKSPACE_DIR = "/Users/xxx/.openclaw/workspace-agent-b" ``` 각 에이전트가 자신의 USER.md/MEMORY.md를 읽어서 **각자 다른 페르소나와 기억**으로 전화 가능! --- ## 📞 통화 로그 및 요청 처리 ### 통화 로그 저장 통화 종료 시 자동으로 `scripts/call_logs/`에 저장: ``` call_logs/ ├── 2026-02-28_23-49-32.json # 통화 로그 └── requests_processed.json # 추출된 요청 ``` ### 요청 자동 추출 `scripts/call_processor.py`가 통화 내용에서 요청 추출: - **reminder**: "내일 7시에 모닝콜 해줘" - **todo**: "마트에서 우유 사와" - **calendar**: "다음 주 월요일에 회의 있어" - **call_back**: "나중에 다시 전화해줘" ### 요청 처리 워크플로우 ``` 통화 종료 → 로그 저장 → GPT-4o-mini로 요청 추출 → JSON 저장 → (향후) 실제 실행 ``` --- ## 🚀 추천 사용 시나리오 1. **모닝콜** - 설정 시간에 전화해서 당일 일정/날씨 알림 2. **일정 리마인더** - 연수/강의 30분 전 알림 3. **작업 완료 알림** - 백그라운드 작업 완료시 전화 4. **긴급 알림** - 중요 이메일/시스템 장애시 즉시 전화 5. **하루 마무리** - 저녁에 미완료 TODO 체크
View on GitHub