בניית מערכות קוליות שמבינות ומדברות עברית היא אתגר טכני משמעותי בגלל מיעוט מודלים קוליים לעברית, מגוון המבטאים, והצורך בעיצוב IVR מותאם לתרבות העסקית הישראלית.
יוצר: @skills-il
בניית בוטים קוליים ומערכות מענה קולי (IVR) בעברית. מכסה זיהוי דיבור (Whisper, Google, Azure), סינתזת דיבור (Google TTS, Amazon Polly, Azure), עיצוב תפריטי IVR לעסקים ישראליים, תמלול הודעות קוליות, טיפול במבטאים שונים, ואינטגרציה טלפונית עם מספרי +972.
npx skills-il add skills-il/developer-tools --skill hebrew-voice-bot-builderבניית בוטים קוליים ומערכות מענה קולי (IVR) ברמת פרודקשן לעסקים ישראליים. הסקיל מכסה את כל צינור הקול: זיהוי דיבור (STT), סינתזת דיבור (TTS), עיצוב תפריטי IVR, אינטגרציה טלפונית, ואתגרים ייחודיים לעברית כמו מבטאים שונים ודיבור מעורב עברית-אנגלית.
לפני הבנייה, צריך להחליט על הארכיטקטורה בהתאם לתרחיש:
| ארכיטקטורה | מתאים ל | רכיבים |
|---|---|---|
| IVR (מקלדת) | ניווט תפריטים, קווי תשלום, קביעת תורים | TTS + DTMF + טלפוניה |
| בוט קולי (שיחתי) | שירות לקוחות, מצב הזמנה, שאלות נפוצות | STT + LLM + TTS + טלפוניה |
| תמלול הודעות קוליות | טיפול בשיחות שלא נענו, ניתוב הודעות | STT + צינור התראות |
| היברידי | תהליכים מורכבים עם קלט קולי וגם מקלדת | STT + TTS + DTMF + טלפוניה |
החלטות מרכזיות:
Whisper מספק את הדיוק הטוב ביותר בתמלול עברית, במיוחד לדיבור מעורב עברית-אנגלית שנפוץ בסביבות הייטק ישראליות.
import openai
client = openai.OpenAI()
def transcribe_hebrew(audio_file_path: str) -> str:
"""תמלול קובץ אודיו בעברית באמצעות Whisper."""
with open(audio_file_path, "rb") as audio_file:
transcript = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
language="he", # כפיית זיהוי עברית
response_format="text",
)
return transcriptטיפים ל-Whisper בעברית:
language="he" במפורש כדי למנוע זיהוי שגוי כערביתזמן תגובה נמוך יותר מ-Whisper, מתאים לבוטים קוליים בזמן אמת.
from google.cloud import speech_v1
def transcribe_hebrew_google(audio_content: bytes) -> str:
"""תמלול עברית באמצעות Google Cloud STT."""
client = speech_v1.SpeechClient()
audio = speech_v1.RecognitionAudio(content=audio_content)
config = speech_v1.RecognitionConfig(
encoding=speech_v1.RecognitionConfig.AudioEncoding.LINEAR16,
sample_rate_hertz=16000,
language_code="he-IL",
enable_automatic_punctuation=True,
model="phone_call", # מודל מותאם לשיחות טלפון
)
response = client.recognize(config=config, audio=audio)
return " ".join(r.alternatives[0].transcript for r in response.results)ברמה ארגונית עם אפשרות לאימון מודלים מותאמים לאוצר מילים ספציפי.
import azure.cognitiveservices.speech as speechsdk
def transcribe_hebrew_azure(audio_file_path: str) -> str:
"""תמלול עברית באמצעות Azure Speech."""
speech_config = speechsdk.SpeechConfig(
subscription="YOUR_AZURE_KEY",
region="westeurope", # האזור הקרוב ביותר לישראל
)
speech_config.speech_recognition_language = "he-IL"
audio_config = speechsdk.AudioConfig(filename=audio_file_path)
recognizer = speechsdk.SpeechRecognizer(
speech_config=speech_config, audio_config=audio_config
)
result = recognizer.recognize_once()
if result.reason == speechsdk.ResultReason.RecognizedSpeech:
return result.text
return ""לטבלת השוואה מפורטת של ספקי STT, ראו references/hebrew-stt-models.md.
from google.cloud import texttospeech
def synthesize_hebrew(text: str, output_path: str, voice_gender: str = "female") -> None:
"""המרת טקסט עברי לדיבור באמצעות Google Cloud TTS."""
client = texttospeech.TextToSpeechClient()
input_text = texttospeech.SynthesisInput(text=text)
# קולות זמינים בעברית
voice_map = {
"female": "he-IL-Wavenet-A", # נקבה, איכות גבוהה
"male": "he-IL-Wavenet-B", # זכר, איכות גבוהה
"female_standard": "he-IL-Standard-A", # נקבה, עלות נמוכה
"male_standard": "he-IL-Standard-B", # זכר, עלות נמוכה
}
voice = texttospeech.VoiceSelectionParams(
language_code="he-IL",
name=voice_map.get(voice_gender, "he-IL-Wavenet-A"),
)
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.MP3,
speaking_rate=1.0,
)
response = client.synthesize_speech(
input=input_text, voice=voice, audio_config=audio_config
)
with open(output_path, "wb") as out:
out.write(response.audio_content)משתלם מבחינת עלות לנפחי TTS גבוהים.
import boto3
def synthesize_hebrew_polly(text: str, output_path: str) -> None:
"""המרת טקסט עברי לדיבור באמצעות Amazon Polly."""
polly = boto3.client("polly", region_name="eu-west-1")
response = polly.synthesize_speech(
Text=text,
OutputFormat="mp3",
VoiceId="Abigail", # קול נשי עברי
Engine="neural",
LanguageCode="he-IL",
)
with open(output_path, "wb") as out:
out.write(response["AudioStream"].read())הקולות העבריים באיכות הגבוהה ביותר, עם תמיכה ב-SSML לשליטה עדינה.
import azure.cognitiveservices.speech as speechsdk
def synthesize_hebrew_azure(text: str, output_path: str) -> None:
"""המרת טקסט עברי לדיבור באמצעות Azure Neural TTS."""
speech_config = speechsdk.SpeechConfig(
subscription="YOUR_AZURE_KEY",
region="westeurope",
)
# קולות עבריים: HilaNeural (נקבה), AvriNeural (זכר)
speech_config.speech_synthesis_voice_name = "he-IL-HilaNeural"
audio_config = speechsdk.AudioConfig(filename=output_path)
synthesizer = speechsdk.SpeechSynthesizer(
speech_config=speech_config, audio_config=audio_config
)
result = synthesizer.speak_text(text)
if result.reason != speechsdk.ResultReason.SynthesizingAudioCompleted:
raise RuntimeError(f"סינתזה נכשלה: {result.reason}")למערכות IVR ישראליות יש מוסכמות ספציפיות ששונות מהדפוס האמריקאי/האירופי.
שבוע העבודה בישראל הוא ראשון עד חמישי. מערכת ה-IVR חייבת להתחשב בזה:
from datetime import datetime
import pytz
ISRAEL_TZ = pytz.timezone("Asia/Jerusalem")
def get_business_status() -> dict:
"""קביעת סטטוס העסק לניתוב IVR."""
now = datetime.now(ISRAEL_TZ)
day = now.weekday() # 0=שני, 6=ראשון
hour = now.hour
if day == 5: # שבת
return {
"status": "closed",
"message_he": "שלום, אנחנו סגורים בשבת. נחזור אליכם ביום ראשון.",
}
elif day == 4: # שישי
if 9 <= hour < 13:
return {"status": "open", "message_he": "שלום, איך אפשר לעזור?"}
else:
return {"status": "closed", "message_he": "סגורים. שעות פעילות ביום שישי: 9:00-13:00."}
elif day == 6 or day <= 3: # ראשון עד חמישי
if 9 <= hour < 17:
return {"status": "open", "message_he": "שלום, איך אפשר לעזור?"}
else:
return {"status": "after_hours", "message_he": "שעות הפעילות: א'-ה' 9:00-17:00."}
return {"status": "closed", "message_he": "כרגע אנחנו סגורים."}IVR_MENU = {
"welcome": {
"prompt_he": "שלום, הגעתם ל{company_name}.",
"prompt_en": "For English, press 9.",
},
"main_menu": {
"prompt_he": (
"לשירות לקוחות, הקישו 1. "
"למכירות, הקישו 2. "
"לתמיכה טכנית, הקישו 3. "
"למצב הזמנה, הקישו 4. "
"לשמוע שוב, הקישו כוכבית."
),
"timeout_seconds": 8,
"max_retries": 3,
},
}| כלל | דוגמה | למה |
|---|---|---|
| שימוש בגוף שני רבים | "הקישו 1" ולא "תקיש 1" | טון מקצועי, נמנע ממגדר |
| פרומפטים עד 15 שניות | 3-4 אפשרויות מקסימום ברמה | מתקשרים מאבדים סבלנות |
| הכרזת שעות לפני הודעת סגור | "שעות הפעילות: א'-ה' 9-17" | מפחית ניסיונות חוזרים |
| אפשרות באנגלית | "For English, press 9" | 20% מהשיחות עשויות להעדיף אנגלית |
| "כוכבית" לכפתור * | "לחזרה, הקישו כוכבית" | מונח סטנדרטי בעברית |
| "סולמית" לכפתור # | "לאישור, הקישו סולמית" | מונח סטנדרטי בעברית |
| חזרה על התפריט ב-timeout | אחרי 8 שניות ללא קלט | מתקשרים צריכים זמן להקשיב |
| הודעה קולית מחוץ לשעות | "להשאיר הודעה, הקישו 1" | לוכד לידים מחוץ לשעות |
def process_voicemail(audio_path: str, caller_number: str) -> dict:
"""
עיבוד הקלטת הודעה קולית: תמלול, סיווג וניתוב.
"""
# שלב 1: תמלול באמצעות Whisper (הדיוק הטוב ביותר לעברית)
transcript = transcribe_hebrew(audio_path)
# שלב 2: זיהוי שפה (עברית, אנגלית, או מעורב)
language = detect_voicemail_language(transcript)
# שלב 3: סיווג כוונה
intent = classify_voicemail_intent(transcript)
# שלב 4: חילוץ ישויות (מספרי טלפון, מספרי הזמנה, שמות)
entities = extract_voicemail_entities(transcript)
# שלב 5: ניתוב לפי כוונה
routing = route_voicemail(intent, entities)
return {
"caller": caller_number,
"transcript": transcript,
"language": language,
"intent": intent,
"entities": entities,
"routing": routing,
}
# כוונות נפוצות בהודעות קוליות בעברית
VOICEMAIL_INTENTS = {
"callback_request": ["תתקשרו", "תחזרו", "חזרו אליי"],
"order_inquiry": ["הזמנה", "משלוח", "חבילה", "מעקב"],
"complaint": ["תלונה", "בעיה", "לא מרוצה"],
"appointment": ["תור", "פגישה", "לקבוע", "לתאם"],
}אנשי הייטק ישראלים עוברים תדיר בין עברית לאנגלית באמצע משפט (code-switching). הבוט חייב לטפל בזה בצורה חלקה.
def handle_mixed_speech(audio_path: str) -> dict:
"""
טיפול בדיבור מעורב עברית-אנגלית, נפוץ בהייטק הישראלי.
אסטרטגיה: שימוש ב-Whisper ללא הגדרת שפה לזיהוי אוטומטי.
"""
client = openai.OpenAI()
with open(audio_path, "rb") as f:
# בלי פרמטר language כדי ש-Whisper יטפל ב-code-switching
transcript = client.audio.transcriptions.create(
model="whisper-1",
file=f,
response_format="verbose_json",
)
return {
"full_transcript": transcript.text,
"segments": transcript.segments,
}
# מילים נפוצות בהייטק שנאמרות בעברית עם מבטא אנגלי
TECH_TERMS = {
"דיפלוי": "deploy",
"פושׁ": "push",
"קומיט": "commit",
"סרבר": "server",
"באג": "bug",
"פיצ'ר": "feature",
}from twilio.rest import Client
from twilio.twiml.voice_response import VoiceResponse, Gather
from flask import Flask, request
app = Flask(__name__)
@app.route("/voice/incoming", methods=["POST"])
def handle_incoming_call():
"""טיפול בשיחה נכנסת עם תפריט IVR בעברית."""
response = VoiceResponse()
response.say(
"שלום, הגעתם לשירות הלקוחות.",
language="he-IL",
voice="Google.he-IL-Wavenet-A",
)
gather = Gather(
num_digits=1,
action="/voice/menu-selection",
timeout=8,
language="he-IL",
)
gather.say(
"לשירות לקוחות, הקישו 1. למכירות, הקישו 2. לתמיכה טכנית, הקישו 3.",
language="he-IL",
voice="Google.he-IL-Wavenet-A",
)
response.append(gather)
response.redirect("/voice/incoming")
return str(response)
@app.route("/voice/voicemail", methods=["POST"])
def handle_voicemail():
"""הקלטת הודעה קולית עם הנחיות בעברית."""
response = VoiceResponse()
response.say(
"אנחנו כרגע לא זמינים. השאירו הודעה אחרי הצפצוף ונחזור אליכם בהקדם.",
language="he-IL",
voice="Google.he-IL-Wavenet-A",
)
response.record(max_length=120, play_beep=True)
return str(response)לדוברי עברית בישראל רקע מגוון של מבטאים שמשפיע על דיוק זיהוי הדיבור.
| סוג מבטא | מאפיינים | השפעה על STT |
|---|---|---|
| ישראלי סטנדרטי | הגייה ישראלית מודרנית, מיזוג א/ע, ללא הבחנה ח/כ | דיוק בסיסי, כל המודלים מתמודדים היטב |
| מבטא רוסי | "ר" קשה (גרונית לשיניית), סיבילנטים רכים | עלול להפחית דיוק ב-5-10%. להוסיף רוסית כשפה חלופית |
| מבטא ערבי | שמירת צלילים לועיים (ע, ח), עיצורים אמפטיים | בדרך כלל מטופל היטב במודלים מאומנים על נתונים ישראליים |
| מבטא אתיופי | דפוסי תנועות שונים, הטעמה שונה | עשוי לדרוש אימון מודל מותאם לדיוק גבוה |
| מבטא אנגלי | תנועות אנגליות/אמריקאיות על עברית, "ר" שונה | תוצאות מעורבות. Whisper מתמודד הכי טוב |
שיפור דיוק למבטאים לא סטנדרטיים:
להרצת סקריפט הדגמה לבדיקת STT בעברית:
python scripts/hebrew-stt-demo.py --helpהמשתמש אומר: "צריך מערכת IVR למסעדה בתל אביב. מתקשרים צריכים להזמין מקום, לבדוק שעות, ולשמוע את התפריט."
פעולות:
תוצאה: מערכת IVR מלאה עם פרומפטים בעברית, ניתוב מותאם לשעות פעילות, ותמלול הודעות.
המשתמש אומר: "צריך בוט קולי שיחתי לחנות האונליין שלנו. שיטפל במצב הזמנה, החזרות, ויעביר לנציג."
פעולות:
תוצאה: בוט קולי שמבין עברית מדוברת, מספק מידע על הזמנות, ומעביר לנציג בצורה חלקה.
המשתמש אומר: "רוצה לתמלל הודעות קוליות שנשארות על הקו העסקי ולשלוח אותן כטקסט למחלקה הרלוונטית."
פעולות:
תוצאה: צינור אוטומטי מהודעה קולית לטקסט שמתמלל הודעות בעברית ומנתב לפי כוונה.
scripts/hebrew-stt-demo.py -- סקריפט הדגמה לזיהוי דיבור בעברית באמצעות OpenAI Whisper. מייצר קובץ אודיו לדוגמה ומתמלל אותו בחזרה לטקסט. הרצה: python scripts/hebrew-stt-demo.py --helpreferences/hebrew-stt-models.md -- טבלת השוואה של מודלים לזיהוי דיבור בעברית (Whisper, Google Cloud STT, Azure Speech) עם בנצ'מרקים של דיוק, זמן תגובה, תמחור והמלצות לפי תרחיש. יש לעיין בו בעת בחירת ספק STT.references/ivr-design-patterns.md -- תבניות נפוצות של תהליכי IVR לעסקים ישראליים, כולל מסעדות, מרפאות, שירות לקוחות ומשרדי ממשלה. יש לעיין בו בעת עיצוב מבנה תפריט IVR.סיבה: מודל ה-STT מזהה בטעות עברית כערבית עקב טווחי תווים משותפים או פונמות דומות.
פתרון: להגדיר במפורש את השפה ל-"he-IL" (Google/Azure) או language="he" (Whisper). ב-Whisper, הוספת רמז בעברית גם עוזרת: prompt="שלום, ברוכים הבאים".
סיבה: שימוש בקולות Standard ולא Neural/Wavenet. פתרון: לעבור לקולות neural: Google Wavenet (he-IL-Wavenet-A/B), Azure Neural (he-IL-HilaNeural), או Amazon Polly Neural (Abigail). קולות neural יקרים יותר אבל טבעיים בהרבה.
סיבה: timeout קצר מדי, במיוחד למתקשרים מבוגרים או פרומפטים ארוכים בעברית. פתרון: להגדיל timeout ל-8-10 שניות. להוסיף אפשרות "לשמוע שוב, הקישו כוכבית". לקחת בחשבון שפרומפטים בעברית עלולים להיות ארוכים יותר מאנגלית.
סיבה: הזמינות של מספרים ישראליים משתנה. ל-Twilio מלאי מוגבל של +972 בהשוואה למספרים אמריקאיים. פתרון: לחפש מספרים מקומיים וגם חינמיים. לשקול Vonage כחלופה עם זמינות טובה יותר למספרים ישראליים. לנפחים גבוהים, ליצור קשר עם Twilio sales. אפשר גם לנייד מספרים ישראליים קיימים ל-Twilio.
סוכנים נתמכים
הגדר pipeline לזיהוי דיבור (STT) בעברית. השווה בין המודלים הזמינים (Whisper, Google Cloud Speech, Azure), התאם לזיהוי מונחים ישראליים ומספרי טלפון, והוסף טיפול במבטאים שונים.
עצב תפריט IVR בעברית עבור [סוג העסק] עם [מספר] מחלקות. כלול ברכת פתיחה, תפריט ראשי, ותתי-תפריטים. הקפד על עברית טבעית ולא רובוטית, שמירה על שפה עסקית מקצועית, ואפשרות לחזור לתפריט הראשי.
בנה pipeline לתמלול אוטומטי של הודעות קוליות בעברית. כלול זיהוי דיבור, ניקוד וסימני פיסוק, זיהוי שמות ומספרי טלפון, וסיכום אוטומטי של ההודעה. טפל בהודעות מעורבות עברית-אנגלית.
הגדר אינטגרציה של Twilio עם זיהוי דיבור וסינתזה קולית בעברית. כלול רכישת מספר ישראלי, הגדרת webhook לשיחות נכנסות, חיבור למודל STT בעברית, והגדרת TTS עם קול עברי טבעי.
ציון אמון
הסקיל יכול להריץ סקריפטים ופקודות על המערכת שלך.
נמצאו 1 התאמות בקוד
אימות מספרי תעודת זהות, ח"פ ומספרי רישום חברות
בניית צ'אטבוטים של AI עם תמיכה מקורית בעברית, כולל אינטגרציה עם WhatsApp Business API, בניית בוט לטלגרם, ווידג'ט צ'אט לאתרים, תבניות NLP בעברית, ורכיבי ממשק צ'אט RTL.
השוואת עלויות אחסון ענן לסטארטאפים ומפתחים ישראליים כולל AWS ישראל, Azure, GCP וספקים מקומיים
רוצים לבנות סקיל משלכם? נסו את יוצר הסקילס · הגשת סקיל