0Pricing
AI Prompt Engineering · 课时

SSML 与韵律控制

语音合成标记语言:停顿、重音、语速和音高。

SSML 与韵律控制 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Prompt Engineering 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Prompt Engineering 课程共包含 4 节课。

什么是 SSML

SSML(语音合成标记语言)是一种基于 XML 的语言,可以让您细致控制文本转语音引擎朗读文本的方式。Google Cloud TTS、Amazon Polly、Microsoft Azure 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 元素

<break> 会在语音中插入停顿。您可以使用它来创造自然节奏、分隔列表项或增加戏剧效果。time 属性接受毫秒(ms)或秒(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)')

emphasis 元素

<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 元素:速率

<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 元素:音调

<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 元素

<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 元素

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

使用 Amazon Polly 的 SSML

Amazon Polly 支持标准 SSML 以及 Polly 特有的扩展功能。其 API 用法与 Google Cloud 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')

使用 LLM 生成 SSML

您可以使用 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 API 错误,或退回到将原始 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))

知识检查:SSML say-as

SSML 的 <say-as> 元素的主要用途是什么?

回顾:SSML 与韵律控制

SSML 可以细致控制 TTS 输出。关键元素包括:<break>(按时间或强度控制停顿)、<emphasis>(重音级别:强、中等、弱化)、<prosody rate>(说话速度)、<prosody pitch>(声音频率)、<say-as>(对数字、日期和电话号码进行语义解读),以及 <phoneme>(明确指定 IPA 发音)。Google Cloud TTS 和 Amazon Polly 都支持 SSML,并支持相同的核心标签集。请使用 LLM 根据纯文本自动生成 SSML,并在发送到生产环境之前,务必验证 XML 的格式是否正确。

常见问题解答

「SSML 与韵律控制」课时是免费的吗?

是的 — 「SSML 与韵律控制」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。

「SSML 与韵律控制」这节课中我会学到什么?

语音合成标记语言:停顿、重音、语速和音高。 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Prompt Engineering 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「SSML 与韵律控制」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Prompt Engineering 课中编写并运行代码吗?

能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 适用于自然语音的 TTS 提示词模式
  2. SSML 与韵律控制
  3. 语音人工智能人格设计
  4. 多模态语音与文本代理
← 返回 AI Prompt Engineering