AI Prompt Engineering · Lekcja

SSML i kontrola prozodii

Speech Synthesis Markup Language: pauzy, akcentowanie, tempo i wysokość głosu.

Lekcja 2 z 413 kroki

SSML i kontrola prozodii to bezpłatna lekcja AI Prompt Engineering na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Prompt Engineering, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.

Czym jest SSML

SSML (Speech Synthesis Markup Language) to oparty na XML język, który zapewnia szczegółową kontrolę nad sposobem odczytywania tekstu przez silniki zamiany tekstu na mowę. Jest obsługiwany przez Google Cloud TTS, Amazon Polly, Microsoft Azure TTS i wiele innych usług.

Podczas gdy zwykły tekst udostępnia wyłącznie słowa, SSML pozwala sterować pauzami, akcentem, szybkością, wysokością głosu, wymową i innymi właściwościami.

Podstawowa struktura SSML

Wszystkie dokumenty SSML są umieszczone wewnątrz tagu <speak>. W środku można łączyć zwykły tekst z elementami znaczników SSML. Silniki TTS przetwarzają kod SSML i odpowiednio generują dźwięk.

# 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')

Element break

<break> wstawia pauzę w mowie. Należy go używać do tworzenia naturalnego rytmu, oddzielania elementów listy lub uzyskania efektu dramaturgicznego. Atrybut time przyjmuje milisekundy (ms) lub sekundy (s).

# 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)')

Element emphasis

<emphasis> dodaje akcent do słów, sprawiając, że silnik wypowiada je głośniej, wolniej lub z wyższą wysokością głosu. Należy używać go oszczędnie, ponieważ nadmierny akcent brzmi nienaturalnie.

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')

Element prosody: rate

<prosody rate> kontroluje szybkość mówienia. Należy zwolnić przy ważnych informacjach, a przyspieszyć przy szczegółach drugorzędnych lub zastrzeżeniach.

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')

Element prosody: pitch

<prosody pitch> dostosowuje częstotliwość podstawową głosu. Należy używać go do sygnalizowania zmian tonu, takich jak pytania, podekscytowanie lub treści poważne.

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')

Element say-as

<say-as> informuje silnik TTS, jak interpretować tekst — jako datę, numer telefonu, walutę, znaki i tak dalej. Jest to niezawodne rozwiązanie w przypadku liczb i wartości specjalnych.

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')

Element phoneme

<phoneme> zapewnia jawną wymowę fonetyczną słów, które silnik TTS regularnie wymawia niepoprawnie, takich jak nazwy marek, terminy techniczne lub słowa obcojęzyczne.

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 z Amazon Polly

Amazon Polly obsługuje standard SSML oraz rozszerzenia właściwe dla Polly. Sposób korzystania z API nieco różni się od Google Cloud TTS, ale same znaczniki SSML są takie same.

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')

Generowanie SSML za pomocą LLM

LLM może służyć do konwertowania zwykłego tekstu na skrypty mowy opatrzone znacznikami SSML. Dzięki temu treść można pisać w zwykły sposób, a następnie przetwarzać ją pod kątem optymalnego odczytu 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

Walidacja i testowanie SSML

Niepoprawny kod SSML powoduje błędy API TTS lub sprawia, że silnik odczytuje na głos surowe tagi XML. Przed wysłaniem kodu do środowiska produkcyjnego należy zawsze go zwalidować.

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))

Sprawdzenie wiedzy: SSML say-as

Jaki jest główny cel elementu SSML <say-as>?

Podsumowanie: SSML i sterowanie prozodią

SSML zapewnia szczegółową kontrolę nad wynikowym dźwiękiem TTS. Najważniejsze elementy to: <break> (pauzy określane czasem lub siłą), <emphasis> (poziomy akcentu: strong/moderate/reduced), <prosody rate> (szybkość mówienia), <prosody pitch> (częstotliwość głosu), <say-as> (interpretacja semantyczna liczb, dat i numerów telefonów) oraz <phoneme> (jawna wymowa w standardzie IPA). Zarówno Google Cloud TTS, jak i Amazon Polly obsługują SSML z tym samym podstawowym zestawem tagów. LLM można używać do automatycznego generowania SSML ze zwykłego tekstu, a przed wysłaniem kodu do środowiska produkcyjnego należy zawsze zwalidować poprawność strukturalną XML.

Bezpłatny start

Ucz się AI Prompt Engineering dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
53
Lekcje
199

Często zadawane pytania

Czy lekcja „SSML i kontrola prozodii” jest bezpłatna?

Tak — pełny tekst „SSML i kontrola prozodii” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Prompt Engineering, przejdź na CoddyKit PRO. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.

Co nauczysz się w „SSML i kontrola prozodii”?

Speech Synthesis Markup Language: pauzy, akcentowanie, tempo i wysokość głosu. Ćwiczysz AI Prompt Engineering z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć AI Prompt Engineering?

Nie wymagamy żadnego doświadczenia. AI Prompt Engineering w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „SSML i kontrola prozodii”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji AI Prompt Engineering?

Tak. Każda lekcja AI Prompt Engineering zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wzorce promptów TTS dla naturalnej mowy
  2. SSML i kontrola prozodii
  3. Projektowanie person głosowych AI
  4. Multimodalni agenci głosowi i tekstowi
← Powrót do AI Prompt Engineering