AI Prompt Engineering · Урок

SSML и управление просодикой

Speech Synthesis Markup Language: паузы, расстановка акцентов, скорость и высота тона.

Урок 2 из 413 шагов

«SSML и управление просодикой» — бесплатный урок AI Prompt Engineering на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Prompt Engineering, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Prompt Engineering содержит 4 уроков всего.

Что такое SSML

SSML — это язык разметки речи на основе XML, который обеспечивает детальный контроль над тем, как движки преобразования текста в речь читают текст. Он поддерживается облачным TTS от Гугл, Амазон Полли, TTS от Майкрософт Азур и многими другими системами.

Обычный текст даёт Вам только слова, а SSML позволяет управлять паузами, акцентом, скоростью, высотой тона, произношением и многим другим.

Базовая структура SSML

Все документы SSML заключаются в тег <speak>. Внутри него обычный текст сочетается с элементами разметки SSML. Движки TTS обрабатывают SSML и соответственно создают аудио.

# SSML document structure
SSML_BASIC = """
<speak>
  Welcome to the course.
  <break time="500ms"/>
  Today we will cover three topics.
  First, we will discuss SSML basics.
  <break time="300ms"/>
  Second, we will explore prosody control.
  <break time="300ms"/>
  And third, we will look at advanced features.
</speak>
"""

# Send to Google Cloud TTS
from google.cloud import texttospeech

client_tts = texttospeech.TextToSpeechClient()

input_text = texttospeech.SynthesisInput(ssml=SSML_BASIC)
voice = texttospeech.VoiceSelectionParams(
    language_code='en-US',
    ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL
)
audio_config = texttospeech.AudioConfig(
    audio_encoding=texttospeech.AudioEncoding.MP3
)
print('SSML document ready to synthesize')

Элемент паузы

<break> вставляет паузу в речь. Используйте его для создания естественного ритма, разделения элементов списка или добавления драматического эффекта. Атрибут time принимает миллисекунды (мс) или секунды (с).

# break element examples
BREAK_EXAMPLES = """
<speak>
  Are you ready?
  <break time="1s"/>
  Let us begin.

  The three rules are:
  number one,
  <break time="300ms"/>
  always test your code.
  <break time="200ms"/>
  Number two,
  <break time="300ms"/>
  write clear documentation.
  <break time="200ms"/>
  And number three,
  <break time="300ms"/>
  review before you ship.

  <break strength="x-strong"/>
  That is all for today.
</speak>
"""

# break strength values: none, x-weak, weak, medium, strong, x-strong
# These map to approximate pause durations defined by the engine
print('break time: explicit duration (e.g. 500ms)')
print('break strength: semantic pause level (weak/medium/strong)')

Элемент выделения

<emphasis> добавляет акцент к словам, заставляя движок произносить их громче, медленнее или более высоким тоном. Используйте его умеренно: чрезмерный акцент звучит неестественно.

EMPHASIS_EXAMPLES = """
<speak>
  This update is
  <emphasis level="strong">critically important</emphasis>.
  Please read it carefully.

  The deadline is
  <emphasis level="moderate">this Friday</emphasis>,
  not next week.

  We
  <emphasis level="reduced">recommend</emphasis>
  enabling this feature, but it is optional.
</speak>
"""

# emphasis level values:
# strong  — much more stress (louder, slower, higher pitch)
# moderate — some additional stress (default if level omitted)
# reduced — less stress (quieter, faster)
print('Use strong for critical information')
print('Use reduced for parenthetical or secondary information')

Элемент интонации: темп

<prosody rate> управляет скоростью речи. Замедляйте речь для важной информации и ускоряйте для второстепенных сведений или отказов от ответственности.

PROSODY_RATE_EXAMPLES = """
<speak>
  <prosody rate="slow">
    This is the most important thing to remember.
    Take a moment to let it sink in.
  </prosody>

  <prosody rate="medium">
    Now, for some context about how we got here.
  </prosody>

  <prosody rate="fast">
    And now a quick summary of less critical details that you
    can refer back to in the documentation.
  </prosody>
</speak>
"""

# rate values:
# x-slow, slow, medium (default), fast, x-fast
# Or percentage: rate="75%" (75% of normal speed)
# Or absolute: rate="200 words per minute"
print('Slow: for emphasis, complex information, or pauses for thought')
print('Fast: for disclaimers, secondary info, rapid listing')

Элемент интонации: высота тона

<prosody pitch> регулирует основную частоту голоса. Используйте его, чтобы обозначать изменения тональности: вопросы, воодушевление или мрачное содержание.

PROSODY_PITCH_EXAMPLES = """
<speak>
  <prosody pitch="high" rate="medium">
    Exciting news! We just launched a brand new feature!
  </prosody>

  <prosody pitch="low" rate="slow">
    Unfortunately, this service will be discontinued.
    We apologize for any inconvenience.
  </prosody>

  <prosody pitch="+20%">
    Did you know that our users save three hours per week on average?
  </prosody>

  <prosody pitch="-15%">
    Please review the terms and conditions carefully.
  </prosody>
</speak>
"""

# pitch values:
# x-low, low, medium, high, x-high
# Or relative: +20%, -15%
# Or semitones: +2st, -4st
print('High pitch: excitement, questions, announcements')
print('Low pitch: serious, cautionary, or somber content')

Элемент интерпретации

<say-as> сообщает движку TTS, как интерпретировать текст: как дату, номер телефона, денежную сумму, отдельные символы и так далее. Это надёжный способ исправить произношение чисел и специальных значений.

SAY_AS_EXAMPLES = """
<speak>
  Your appointment is on
  <say-as interpret-as="date" format="mdy">01/15/2025</say-as>.

  Call us at
  <say-as interpret-as="telephone">1-800-555-1234</say-as>.

  Your confirmation code is
  <say-as interpret-as="characters">XK7T9</say-as>.

  The total is
  <say-as interpret-as="currency" language="en-US">$47.50</say-as>.

  This is version
  <say-as interpret-as="characters">2.3.1</say-as>
  of the software.
</speak>
"""

# interpret-as values:
# characters  — spell out each character
# cardinal    — number as cardinal ("forty-seven")
# ordinal     — "forty-seventh"
# fraction    — "three halves"
# date        — format string controls order
# telephone   — phone number formatting
# currency    — monetary value with currency name
print('say-as is the most reliable way to control number pronunciation')

Элемент фонемы

<phoneme> задаёт явное фонетическое произношение слов, которые движок TTS регулярно произносит неправильно, например названий брендов, технических терминов или иностранных слов.

PHONEME_EXAMPLES = """
<speak>
  Welcome to
  <phoneme alphabet="ipa" ph="ent.ro.pi">Entropiq</phoneme>,
  the leading analytics platform.

  Our CEO,
  <phoneme alphabet="ipa" ph="joo.serf">Josef</phoneme>,
  will present the results.

  This API uses
  <phoneme alphabet="ipa" ph="kwer.i">GraphQL</phoneme>
  for data fetching.
</speak>
"""

# IPA (International Phonetic Alphabet) is the most precise
# x-sampa is an alternative ASCII-friendly phonetic alphabet
# Use an IPA converter tool to find the right phonemes:
# - https://tophonetics.com
# - Dictionary.com pronunciation guides use IPA
print('Use phoneme for brand names, technical terms, proper nouns')
print('Test with multiple phoneme values until it sounds right')

SSML с Амазон Полли

Амазон Полли поддерживает стандартный SSML и расширения, специфичные для этого сервиса. Использование интерфейса немного отличается от облачного TTS от Гугл, но сама разметка SSML одинакова.

import boto3

polly = boto3.client('polly', region_name='us-east-1')

SSML_CONTENT = """
<speak>
  <prosody rate="slow" pitch="low">
    Welcome to our quarterly earnings call.
  </prosody>
  <break time="1s"/>
  We are pleased to report
  <emphasis level="strong">record revenue</emphasis>
  of
  <say-as interpret-as="currency" language="en-US">$4200000</say-as>
  this quarter.
</speak>
"""

response = polly.synthesize_speech(
    Text=SSML_CONTENT,
    TextType='ssml',     # Tell Polly this is SSML
    OutputFormat='mp3',
    VoiceId='Joanna',    # US English female voice
)

if 'AudioStream' in response:
    with open('output.mp3', 'wb') as f:
        f.write(response['AudioStream'].read())
    print('Audio saved to output.mp3')

Создание SSML с помощью LLM

Вы можете использовать LLM, чтобы преобразовать обычный текст в сценарии речи с разметкой SSML. Это позволяет сначала писать содержание обычным способом, а затем обрабатывать его для оптимальной передачи через TTS.

import anthropic

client = anthropic.Anthropic(api_key='sk-ant-...')

SSML_GENERATION_PROMPT = (
    'Convert the following text into an SSML document for Google Cloud TTS.\n\n'
    'Rules:\n'
    '- Wrap the entire output in <speak> tags\n'
    '- Add <break time="500ms"/> between major points\n'
    '- Add <emphasis level="strong"> around key terms or critical information\n'
    '- Use <prosody rate="slow"> for important warnings or summaries\n'
    '- Use <say-as interpret-as="date"> for all dates\n'
    '- Use <say-as interpret-as="telephone"> for phone numbers\n'
    '- Return only the SSML, no explanation\n\n'
    'Text: {text}'
)

def text_to_ssml(text):
    prompt = SSML_GENERATION_PROMPT.format(text=text)
    r = client.messages.create(
        model='claude-opus-4-5',
        max_tokens=2000,
        messages=[{'role': 'user', 'content': prompt}]
    )
    return r.content[0].text

Проверка и тестирование SSML

Неправильно сформированный SSML вызывает ошибки интерфейса TTS или приводит к тому, что необработанные теги XML произносятся вслух. Всегда проверяйте SSML перед отправкой в рабочую среду.

import xml.etree.ElementTree as ET

def validate_ssml(ssml_string):
    """
    Basic SSML validation: checks XML is well-formed
    and has a <speak> root element.
    """
    try:
        root = ET.fromstring(ssml_string)
        if root.tag != 'speak':
            return False, 'Root element must be <speak>'

        # Check for common misuse patterns
        warnings = []
        for elem in root.iter():
            if elem.tag == 'break' and 'time' not in elem.attrib and 'strength' not in elem.attrib:
                warnings.append('<break> has no time or strength attribute')

        return True, warnings if warnings else 'Valid'

    except ET.ParseError as e:
        return False, f'XML parse error: {e}'

# Test
valid_ssml = '<speak>Hello <break time="500ms"/> world.</speak>'
bad_ssml = '<speak>Hello <break> world.</speak>'  # break not self-closed

print(validate_ssml(valid_ssml))
print(validate_ssml(bad_ssml))

Проверка знаний: интерпретация say-as

Каково основное назначение элемента SSML <say-as>?

Итоги: SSML и управление интонацией

SSML обеспечивает детальный контроль над выводом TTS. Основные элементы: <break> — паузы по времени или уровню воздействия; <emphasis> — уровни акцента: сильный, умеренный и сниженный; <prosody rate> — скорость речи; <prosody pitch> — частота голоса; <say-as> — смысловая интерпретация чисел, дат и номеров телефонов; <phoneme> — явное произношение в IPA. И облачный TTS от Гугл, и сервис Полли от Амазон поддерживают SSML с одним и тем же набором основных тегов. Используйте LLM для автоматического создания SSML из обычного текста и всегда проверяйте корректность XML перед отправкой в рабочую среду.

Можно начать бесплатно

Изучай AI Prompt Engineering с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
53
Уроки
199

Часто задаваемые вопросы

Урок «SSML и управление просодикой» бесплатный?

Да — полный текст урока «SSML и управление просодикой» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Prompt Engineering, подпишись на CoddyKit PRO. Курс AI Prompt Engineering содержит 4 уроков всего.

Чему я научусь в уроке «SSML и управление просодикой»?

Speech Synthesis Markup Language: паузы, расстановка акцентов, скорость и высота тона. Ты практикуешь AI Prompt Engineering с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать AI Prompt Engineering?

Предыдущий опыт не требуется. AI Prompt Engineering на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «SSML и управление просодикой»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке AI Prompt Engineering?

Да. Каждый урок AI Prompt Engineering включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Шаблоны запросов TTS для естественной речи
  2. SSML и управление просодикой
  3. Проектирование персоны голосового искусственного интеллекта
  4. Мультимодальные голосовые и текстовые агенты
← Назад к AI Prompt Engineering