Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание
Эта функция сейчас доступна в общедоступной предварительной версии. Эта версия предварительного просмотра предоставляется без соглашения об уровне обслуживания и не рекомендуется для продуктивной эксплуатации. Некоторые функции могут не поддерживаться или могут иметь ограниченные возможности. Дополнительные сведения см. в разделе Supplemental Terms of Use for Microsoft Azure Previews.
Узнайте, как использовать Voice Live с Microsoft Foundry Agent Service с помощью пакета SDK для VoiceLive на Python. В этой статье мы расширяем краткое руководство по созданию агента голосовой связи с помощью службы агента Foundry и Voice Live, добавляя расширенные функции и параметры интеграции.
Справочная документация Пакет (PyPi) | Дополнительные примеры на GitHub
Создание и запуск приложений для использования Voice Live с агентами для бесед в режиме реального времени.
Агенты предоставляют несколько преимуществ:
- Используйте централизованную конфигурацию в самом агенте вместо кода сеанса.
- Обрабатывайте сложную логику и диалоговое поведение для облегчения обновлений.
- Автоматически подключитесь с помощью идентификатора агента.
- Поддержка нескольких вариантов без изменения клиентского кода.
Сведения об использовании Voice Live без агентов Foundry см. в кратком руководстве по API Voice Live.
Совет
Вам не нужно развертывать звуковую модель с Microsoft Foundry для использования Voice Live. Voice Live полностью управляется и автоматически развертывает модель для вас. Сведения о доступности модели см. в документации по Voice Live.
Необходимые условия
Примечание
Этот документ ссылается на портал Microsoft Foundry (new) и последнюю версию службы агента Foundry.
- Подписка Azure. Создайте его бесплатно.
- Python версии 3.10 или более поздней. Если у вас нет подходящей версии Python, вы можете выполнить инструкции, описанные в руководстве по VS Code Python для простого способа установки Python в операционной системе.
- Необходимые языковые среды выполнения, глобальные инструменты и расширения Visual Studio Code, как описано в Подготовьте вашу среду разработки.
- Ресурс Microsoft Foundry создан в одном из поддерживаемых регионов. Для получения дополнительной информации о доступности регионов см. документацию Voice Live.
- Модель, развернутая в Microsoft Foundry. Если у вас нет модели, сначала выполните Quickstart: настройте ресурсы Microsoft Foundry.
- Назначьте роль
Azure AI Userучетной записи пользователя. Роли можно назначить на портале Azure в разделе Access control (IAM)>Add role assignment.
Подготовка среды и создание агента
Выполните Быстрый запуск: создание голосового агента с помощью службы Foundry Agent и Voice Live, чтобы настроить вашу среду, конфигурировать агента с настройками Voice Live и протестировать ваш первый разговор.
Концепции интеграции агента
Используйте эти понятия, чтобы понять, как служба агента Voice Live и Foundry работают вместе в примере Python.
Контракт конфигурации агента
Укажите agent_config в настройках сеанса для идентификации целевого агента и проекта. Как минимум, включите agent_name и project_name. Добавьте agent_version, когда хотите закрепить поведение в определенной версии.
Модель проверки подлинности для режима агента
Используйте Microsoft Entra ID учетные данные для режима агента. Вызов агента в этом потоке не поддерживает аутентификацию с использованием ключей, поэтому настройте AzureCliCredential (или другие учетные данные токена Entra) для локальной разработки и развертывания.
Закрепление версий API
Чтобы поведение оставалось предсказуемым при предварительных обновлениях, закрепите поддерживаемое api_version в клиенте. Используйте одну и ту же версию последовательно в примерах быстрого старта и инструкциях, чтобы избежать дрейфа схемы.
Выравнивание бесед и трассировки
Рассматривайте поток агента и записи трассировки как историю текстовых сообщений, а не точную историю воспроизведения. Если ваше приложение допускает прерывание или усечение, включите обработку с учётом усечения, чтобы сохранённая история более точно соответствовала тому, что пользователь на самом деле слышал.
Подключение к определенной версии агента
Зафиксируйте агента на конкретной версии, чтобы обеспечить управляемые развертывания. Это позволяет рабочей среде использовать стабильные версии при тестировании новых итераций разработки.
AGENT_VERSION Задайте переменную среды или передайте agent_version параметр при инициализации помощника:
def __init__(
self,
endpoint: str,
credential: Union[AzureKeyCredential, AsyncTokenCredential],
voice: str,
agent_name: str,
project_name: str,
agent_version: Optional[str] = None,
conversation_id: Optional[str] = None,
foundry_resource_override: Optional[str] = None,
agent_authentication_identity_client_id: Optional[str] = None,
):
self.endpoint = endpoint
self.credential = credential
self.voice = voice
# Build AgentSessionConfig internally
self.agent_config: AgentSessionConfig = {
"agent_name": agent_name,
"agent_version": agent_version if agent_version else None,
"project_name": project_name,
"conversation_id": conversation_id if conversation_id else None,
"foundry_resource_override": foundry_resource_override if foundry_resource_override else None,
"authentication_identity_client_id": agent_authentication_identity_client_id if agent_authentication_identity_client_id and foundry_resource_override else None,
}
# Connect using AgentSessionConfig (new SDK pattern)
async with connect(
endpoint=self.endpoint,
credential=self.credential,
api_version="2026-01-01-preview",
agent_config=self.agent_config,
) as connection:
def main() -> None:
"""Main function."""
endpoint = os.environ.get("VOICELIVE_ENDPOINT", "")
voice_name = os.environ.get("VOICE_NAME", "en-US-Ava:DragonHDLatestNeural")
agent_name = os.environ.get("AGENT_NAME", "")
agent_version = os.environ.get("AGENT_VERSION")
project_name = os.environ.get("PROJECT_NAME", "")
conversation_id = os.environ.get("CONVERSATION_ID")
foundry_resource_override = os.environ.get("FOUNDRY_RESOURCE_OVERRIDE")
agent_authentication_identity_client_id = os.environ.get("AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID")
print("Environment variables:")
print(f"VOICELIVE_ENDPOINT: {endpoint}")
print(f"VOICE_NAME: {voice_name}")
print(f"AGENT_NAME: {agent_name}")
print(f"AGENT_VERSION: {agent_version}")
print(f"PROJECT_NAME: {project_name}")
print(f"CONVERSATION_ID: {conversation_id}")
print(f"FOUNDRY_RESOURCE_OVERRIDE: {foundry_resource_override}")
print(f"AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID: {agent_authentication_identity_client_id}")
if not endpoint or not agent_name or not project_name:
sys.exit("Set VOICELIVE_ENDPOINT, AGENT_NAME, and PROJECT_NAME in your .env file.")
# Create client with appropriate credential (Entra ID required for Agent mode)
credential = AzureCliCredential()
logger.info("Using Azure token credential")
# Create and start voice assistant
assistant = BasicVoiceAssistant(
endpoint=endpoint,
credential=credential,
voice=voice_name,
agent_name=agent_name,
agent_version=agent_version,
project_name=project_name,
conversation_id=conversation_id,
В этом примере конфигурация версии применяется в трех местах:
- В
main()AGENT_VERSIONсчитывается из среды. - В вызове
BasicVoiceAssistant(...)agent_versionпередается конструктору класса. - В
BasicVoiceAssistant.__init__значение добавляется вself.agent_config, а затем отправляется в Voice Live черезconnect(..., agent_config=self.agent_config).
Значение agent_version соответствует строке версии, возвращаемой при создании или обновлении агента с помощью пакета SDK агента Foundry. Если это не указано, Voice Live подключается к последней версии агента.
Подключение к какому-либо агенту в другом ресурсе Foundry
Настройте Voice Live для подключения к агенту в другом ресурсе Foundry для обработки звука. Это полезно, когда:
- Агент развертывается в регионе с различной доступностью функций.
- Вы хотите разделить среды разработки и промежуточного хранения из рабочей среды
- В организации используются различные ресурсы для разных рабочих нагрузок
Чтобы подключиться к агенту в другом ресурсе, настройте две дополнительные переменные среды:
-
FOUNDRY_RESOURCE_OVERRIDE: имя ресурса Foundry, в котором размещается проект агента (например,my-agent-resource). -
AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID: идентификатор клиента управляемой идентичности ресурса Voice Live, необходимый для проверки подлинности межресурсных взаимодействий.
conversation_id: Optional[str] = None,
foundry_resource_override: Optional[str] = None,
agent_authentication_identity_client_id: Optional[str] = None,
):
self.endpoint = endpoint
self.credential = credential
self.voice = voice
# Build AgentSessionConfig internally
self.agent_config: AgentSessionConfig = {
"agent_name": agent_name,
"agent_version": agent_version if agent_version else None,
"project_name": project_name,
"conversation_id": conversation_id if conversation_id else None,
"foundry_resource_override": foundry_resource_override if foundry_resource_override else None,
"authentication_identity_client_id": agent_authentication_identity_client_id if agent_authentication_identity_client_id and foundry_resource_override else None,
}
conversation_id = os.environ.get("CONVERSATION_ID")
foundry_resource_override = os.environ.get("FOUNDRY_RESOURCE_OVERRIDE")
agent_authentication_identity_client_id = os.environ.get("AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID")
print("Environment variables:")
print(f"VOICELIVE_ENDPOINT: {endpoint}")
print(f"VOICE_NAME: {voice_name}")
print(f"AGENT_NAME: {agent_name}")
print(f"AGENT_VERSION: {agent_version}")
print(f"PROJECT_NAME: {project_name}")
print(f"CONVERSATION_ID: {conversation_id}")
print(f"FOUNDRY_RESOURCE_OVERRIDE: {foundry_resource_override}")
print(f"AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID: {agent_authentication_identity_client_id}")
if not endpoint or not agent_name or not project_name:
sys.exit("Set VOICELIVE_ENDPOINT, AGENT_NAME, and PROJECT_NAME in your .env file.")
# Create client with appropriate credential (Entra ID required for Agent mode)
credential = AzureCliCredential()
logger.info("Using Azure token credential")
# Create and start voice assistant
assistant = BasicVoiceAssistant(
endpoint=endpoint,
credential=credential,
voice=voice_name,
agent_name=agent_name,
agent_version=agent_version,
project_name=project_name,
conversation_id=conversation_id,
foundry_resource_override=foundry_resource_override,
agent_authentication_identity_client_id=agent_authentication_identity_client_id,
# Connect using AgentSessionConfig (new SDK pattern)
async with connect(
endpoint=self.endpoint,
credential=self.credential,
api_version="2026-01-01-preview",
agent_config=self.agent_config,
) as connection:
Эта конфигурация разрешается в main(), а затем применяется при создании помощника.
-
FOUNDRY_RESOURCE_OVERRIDEиAGENT_AUTHENTICATION_IDENTITY_CLIENT_IDсчитываются из переменных среды. - Оба значения передаются в
BasicVoiceAssistant(...). - В
BasicVoiceAssistant.__init__добавляются значенияself.agent_config, которые отправляются вconnect(..., agent_config=self.agent_config).
Важно
Для подключений между ресурсами требуются правильные назначения ролей. Убедитесь, что управляемое удостоверение ресурса Voice Live имеет роль Azure AI User в целевом ресурсе агента.
Добавление упреждающего сообщения при запуске сеанса
Отправьте упреждающее сообщение, чтобы инициировать беседы сразу после готовности сеанса. В этом примере проверяется однократный флаг в обработчике SESSION_UPDATED событий, отправляется запрос приветствия и запускается ответ.
self.greeting_sent = False
if event.type == ServerEventType.SESSION_UPDATED:
# <session_updated_metadata>
logger.info("Session ready: %s", event.session.id)
s, a, v = event.session, event.session.agent, event.session.voice
await write_conversation_log("\n".join([
f"SessionID: {s.id}", f"Agent Name: {a.name}",
f"Agent Description: {a.description}", f"Agent ID: {a.agent_id}",
f"Voice Name: {v['name']}", f"Voice Type: {v['type']}",
f"Voice Temperature: {v['temperature']}", ""
]))
# </session_updated_metadata>
self.session_ready = True
# <proactive_greeting>
# Invoke Proactive greeting
if not self.greeting_sent:
self.greeting_sent = True
logger.info("Sending proactive greeting request")
try:
await conn.conversation.item.create(
item=MessageItem(
role="system",
content=[
InputTextContentPart(
text="Say something to welcome the user in English."
)
]
)
)
await conn.response.create()
except Exception:
logger.exception("Failed to send proactive greeting request")
# </proactive_greeting>
# Start audio capture once session is ready
В этом примере проактивное информирование применяется в три этапа:
-
self.greeting_sent = Falseинициализирует единовременное состояние приветствия. - В ветви
SESSION_UPDATED,if not self.greeting_sent:ворота ограничивают упреждающее выполнение, чтобы оно выполнялось один раз за сеанс. -
conn.conversation.item.create(...)добавляет инструкцию приветствия в контекст беседы иconn.response.create()создает произнесенные выходные данные.
Улучшение времени ожидания вызова инструмента и задержки
Используйте функцию Voice Live interim_response для сокращения времени ожидания в процессе вызова инструмента или при создании ответов агента с высокой задержкой.
Voice Live предлагает два промежуточных режима отклика:
- Промежуточный ответ, сгенерированный с помощью LLM (
llm_interim_response): использует облегченный LLM для динамического создания текста, учитывающего контекст. Лучше всего подходит для адаптивных, естественных звуковых ответов. -
Статический промежуточный ответ (
static_interim_response): случайным образом выбирается из предопределенного списка предоставленных текстов. Лучше всего подходит для детерминированного или фирменного обмена сообщениями.
Дополнительные сведения см. в разделе "Улучшение вызова инструмента и времени ожидания задержки с промежуточными ответами".
Созданное с помощью voice-live-agents-quickstart.py краткое руководство показывает необходимые дополнения коду для настройки этой функции следующим образом:
from azure.ai.voicelive.models import (
InputAudioFormat,
Modality,
OutputAudioFormat,
RequestSession,
ServerEventType,
MessageItem,
InputTextContentPart,
LlmInterimResponseConfig,
InterimResponseTrigger,
AzureStandardVoice,
AudioNoiseReduction,
AudioEchoCancellation,
AzureSemanticVadMultilingual
)
async def _setup_session(self) -> None:
"""Configure the VoiceLive session for audio conversation."""
logger.info("Setting up voice conversation session...")
# Set up interim response configuration to bridge latency gaps during processing
interim_response_config = LlmInterimResponseConfig(
triggers=[InterimResponseTrigger.TOOL, InterimResponseTrigger.LATENCY],
latency_threshold_ms=100,
instructions="""Create friendly interim responses indicating wait time due to ongoing processing, if any. Do not include
in all responses! Do not say you don't have real-time access to information when calling tools!"""
)
# Create session configuration
session_config = RequestSession(
modalities=[Modality.TEXT, Modality.AUDIO],
input_audio_format=InputAudioFormat.PCM16,
output_audio_format=OutputAudioFormat.PCM16,
interim_response=interim_response_config,
# Uncomment the following, if not stored with agent configuration on the service side
# voice=AzureStandardVoice(name=self.voice),
# turn_detection=AzureSemanticVadMultilingual(),
# input_audio_echo_cancellation=AudioEchoCancellation(),
# input_audio_noise_reduction=AudioNoiseReduction(type="azure_deep_noise_suppression")
)
В этом примере настройка промежуточного ответа применяется внутри BasicVoiceAssistant._setup_session():
-
LlmInterimResponseConfig(...)определяет, когда активируются промежуточные ответы и какой стиль они используют. -
RequestSession(...)присоединяет конфигурациюinterim_responseчерез поле. -
conn.session.update(session=session_config)отправляет конфигурацию сеанса в Voice Live.
Используйте автоматическое сокращение для ответов, которые были прерваны
Когда пользователи прерывают звук агента, текст беседы может отклоняться от того, что они действительно слышали. Автоматическое усечение помогает поддерживать соответствие контекста сеанса доставленному звуку, что улучшает качество ответов после перебивания и делает логирование голосовых разговоров более точным.
В этом примере в настоящее время показана обработка прерываний с response.cancel() при запуске речи, но auto_truncate не настраивается в turn_detection.
Примечание
В службе агента Foundry сообщения потоков и потоки агента трассировки основаны на текстовом содержимом потоков. Без автоматического усечения эти записи могут отличаться от точной части звука, который пользователь фактически слышал до прерывания.
Сведения о настройке и поддерживаемых параметрах см. в разделе "Обработка прерываний голосовой связи в журнале чата (предварительная версия)".
Повторное подключение к прежнему разговору с агентом
Повторно подключитесь к предыдущей беседе, указав идентификатор беседы. Это сохраняет историю и контекст, позволяя пользователям продолжить с того места, где остановились.
Voice Live возвращает метаданные сеанса в событии SESSION_UPDATED, когда сеанс успешно подключается:
if event.type == ServerEventType.SESSION_UPDATED:
# <session_updated_metadata>
logger.info("Session ready: %s", event.session.id)
s, a, v = event.session, event.session.agent, event.session.voice
await write_conversation_log("\n".join([
f"SessionID: {s.id}", f"Agent Name: {a.name}",
f"Agent Description: {a.description}", f"Agent ID: {a.agent_id}",
f"Voice Name: {v['name']}", f"Voice Type: {v['type']}",
f"Voice Temperature: {v['temperature']}", ""
]))
В этом обработчике событий метаданные сеанса и агента регистрируются при готовности сеанса.
Пример кода автоматически записывает сведения о сеансе в файл журнала бесед в папке logs/ (например, logs/2026-02-19_14-30-00_conversation.log). Идентификатор сеанса можно получить из этого файла после запуска сеанса.
Чтобы повторно подключиться к этой беседе, передайте идентификатор беседы в качестве переменной CONVERSATION_ID среды (или параметром conversation_id ):
conversation_id: Optional[str] = None,
"conversation_id": conversation_id if conversation_id else None,
conversation_id = os.environ.get("CONVERSATION_ID")
В этом примере повторное подключение беседы применяется в трех местах:
- В
main()CONVERSATION_IDсчитывается из среды. - В вызове
BasicVoiceAssistant(...)conversation_idпередается конструктору класса. - В
BasicVoiceAssistant.__init__значение присваиваетсяself.agent_configкакconversation_id.
Если задано допустимое conversation_id , агент извлекает предыдущий контекст беседы и может ссылаться на предыдущие обмены в ответах.
Примечание
Идентификаторы бесед привязаны к агенту и проекту. Попытка использовать идентификатор беседы с другим агентом приводит к созданию новой беседы.
Логгировать метаданные сеанса для обеспечения непрерывности и диагностики
Записывайте ключевые метаданные сеанса, включая идентификатор сеанса, в файл журнала беседы с меткой времени под logs/. Это поможет вам:
- Определите сеанс для сценариев отладки и поддержки.
- Сопоставляйте поведение, сообщаемое пользователем, с метаданными сеанса.
- Отслеживайте выполнение с течением времени, сохраняя файлы журнала для каждого сеанса.
Данный код создает имя лог-файла и записывает метаданные сеанса при получении SESSION_UPDATED.
# Set up logging
## Add folder for logging
os.makedirs(os.path.join(_script_dir, 'logs'), exist_ok=True)
## Add timestamp for logfiles
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
s, a, v = event.session, event.session.agent, event.session.voice
await write_conversation_log("\n".join([
f"SessionID: {s.id}", f"Agent Name: {a.name}",
f"Agent Description: {a.description}", f"Agent ID: {a.agent_id}",
f"Voice Name: {v['name']}", f"Voice Type: {v['type']}",
f"Voice Temperature: {v['temperature']}", ""
]))
async def write_conversation_log(message: str) -> None:
"""Write a message to the conversation log."""
log_path = os.path.join(_script_dir, 'logs', logfilename)
await asyncio.to_thread(
lambda: open(log_path, 'a', encoding='utf-8').write(message + "\n")
)
В этом примере ведение журнала метаданных сеанса применяется в трех местах:
- Для каждого запуска создается файл журнала бесед с меткой времени.
- К
SESSION_UPDATEDдобавляются метаданные, включая идентификатор сеанса, имя агента и голосовая конфигурация. -
write_conversation_log(...)добавляет записи в один и тот же файл в течение всего жизненного цикла беседы.
Используйте метаданные зарегистрированного сеанса с CONVERSATION_ID, чтобы возобновить беседу с тем же агентом в последующем сеансе.
В этой статье вы узнаете, как использовать Voice Live с службой агента Microsoft Foundry с помощью VoiceLive SDK для C#. Эта статья дополняет Краткое руководство: Создание голосового агента с помощью службы агент Foundry и Voice Live дополнительными сведениями о функциях и вариантах интеграции.
Документация по справке | Пакет (NuGet) | Дополнительные примеры на GitHub
Создание и запуск приложений для использования Voice Live с агентами для бесед в режиме реального времени.
Агенты предоставляют несколько преимуществ:
- Используйте централизованную конфигурацию в самом агенте вместо кода сеанса.
- Обрабатывайте сложную логику и диалоговое поведение для облегчения обновлений.
- Автоматически подключитесь с помощью идентификатора агента.
- Поддержка нескольких вариантов без изменения клиентского кода.
Сведения об использовании Voice Live без агентов Foundry см. в кратком руководстве по API Voice Live.
Совет
Вам не нужно развертывать звуковую модель с Microsoft Foundry для использования Voice Live. Voice Live полностью управляется и автоматически развертывает модель для вас. Сведения о доступности модели см. в документации по Voice Live.
Необходимые условия
Примечание
Это руководство относится к порталу Microsoft Foundry (new) и последней версии службы агента Foundry.
- Подписка Azure. Создайте его бесплатно.
- набор инструментов разработки .NET 8.0 или более поздней версии.
- Необходимые языковые среды выполнения, глобальные инструменты и расширения Visual Studio Code. См. статью "Подготовка среды разработки".
- Ресурс Microsoft Foundry создан в поддерживаемом регионе. См. документацию Voice Live для получения сведений о доступности регионов.
- Развернутая модель в Microsoft Foundry. Если у вас нет одного, сначала выполните Quickstart: настройте ресурсы Microsoft Foundry.
- Роль
Azure AI User, назначенная учетной записи пользователя. Назначьте роли на портале Azure в разделе Access control (IAM)>Добавить назначение роли.
Подготовка среды и создание агента
Выполните Краткое руководство: Создание голосового агента с помощью службы агента Foundry и Voice Live, чтобы подготовить свою среду, настроить агента с параметрами Voice Live и провести первый тест.
Концепции интеграции агента
Эти понятия помогают понять, как служба агента Voice Live и Foundry работают вместе в примере C#.
Контракт конфигурации агента
Укажите AgentSessionConfig в настройках сеанса для идентификации целевого агента и проекта. Включите как минимум agentName и projectName. Добавьте AgentVersion, когда хотите закрепить поведение в определенной версии.
Проверка подлинности для режима агента
Используйте Microsoft Entra ID учетные данные для режима агента. Вызов агента не поддерживает проверку подлинности на основе ключей, поэтому настройте AzureCliCredential (или другие учетные данные токена Entra) для локальной разработки и развертывания.
Закрепление версий API
Используйте согласованную версию пакета SDK (Azure.AI.VoiceLive 1.1.0-beta.3) в файле проекта. Согласованное управление версиями позволяет прогнозировать поведение в предварительной версии обновлений и избегает смещения схемы.
Выравнивание бесед и трассировки
Рассматривайте поток агента и записи трассировки как историю текстовых сообщений, а не точную историю воспроизведения. Если ваше приложение допускает прерывание или усечение, включите обработку с учетом усечения. Это гарантирует, что хранимая история лучше соответствует тому, что пользователи действительно слышали.
Подключение к определенной версии агента
Голосовая трансляция позволяет подключаться к определенной версии агента. Это позволяет управляемым развертываниям, где в продуктивной среде используется стабильная версия, а в тестах разработки проверяются более новые итерации.
Чтобы подключиться к определенной версии агента, задайте AGENT_VERSION переменную среды или передайте agentVersion параметр при инициализации помощника:
// <agent_config>
public BasicVoiceAssistant(string endpoint, string agentName, string projectName,
string? agentVersion = null, string? conversationId = null,
string? foundryResourceOverride = null, string? authIdentityClientId = null)
{
_endpoint = endpoint;
// Build the agent session configuration
var config = new AgentSessionConfig(agentName, projectName);
if (!string.IsNullOrEmpty(agentVersion))
{
config.AgentVersion = agentVersion;
}
if (!string.IsNullOrEmpty(conversationId))
{
config.ConversationId = conversationId;
}
if (!string.IsNullOrEmpty(foundryResourceOverride))
{
config.FoundryResourceOverride = foundryResourceOverride;
if (!string.IsNullOrEmpty(authIdentityClientId))
{
config.AuthenticationIdentityClientId = authIdentityClientId;
}
}
_agentConfig = config;
}
// </agent_config>
// <main>
class Program
{
static async Task Main(string[] args)
{
var endpoint = Environment.GetEnvironmentVariable("VOICELIVE_ENDPOINT");
var agentName = Environment.GetEnvironmentVariable("AGENT_NAME");
var projectName = Environment.GetEnvironmentVariable("PROJECT_NAME");
var agentVersion = Environment.GetEnvironmentVariable("AGENT_VERSION");
var conversationId = Environment.GetEnvironmentVariable("CONVERSATION_ID");
var foundryResourceOverride = Environment.GetEnvironmentVariable("FOUNDRY_RESOURCE_OVERRIDE");
var authIdentityClientId = Environment.GetEnvironmentVariable("AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID");
Console.WriteLine("Environment variables:");
Console.WriteLine($"VOICELIVE_ENDPOINT: {endpoint}");
Console.WriteLine($"AGENT_NAME: {agentName}");
Console.WriteLine($"PROJECT_NAME: {projectName}");
Console.WriteLine($"AGENT_VERSION: {agentVersion}");
Console.WriteLine($"CONVERSATION_ID: {conversationId}");
Console.WriteLine($"FOUNDRY_RESOURCE_OVERRIDE: {foundryResourceOverride}");
if (string.IsNullOrEmpty(endpoint) || string.IsNullOrEmpty(agentName)
|| string.IsNullOrEmpty(projectName))
{
Console.Error.WriteLine("Set VOICELIVE_ENDPOINT, AGENT_NAME, and PROJECT_NAME environment variables.");
return;
}
// Verify audio devices
CheckAudioDevices();
Console.WriteLine("🎙️ Basic Foundry Voice Agent with Azure VoiceLive SDK (Agent Mode)");
Console.WriteLine(new string('=', 65));
using var assistant = new BasicVoiceAssistant(
endpoint, agentName, projectName,
agentVersion, conversationId,
foundryResourceOverride, authIdentityClientId);
// Handle graceful shutdown
using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (sender, e) =>
{
e.Cancel = true;
cts.Cancel();
};
try
{
await assistant.StartAsync(cts.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("\n👋 Voice assistant shut down. Goodbye!");
}
catch (Exception ex)
{
Console.Error.WriteLine($"Fatal Error: {ex.Message}");
}
Конфигурация версии применяется в трех местах:
- В
Main()считайтеAGENT_VERSIONиз переменной среды. - Передайте
agentVersionконструкторуBasicVoiceAssistant(...). - В конструкторе задайте значение
AgentSessionConfigчерезconfig.AgentVersion. Отправьте его в Voice Live черезStartSessionAsync(SessionTarget.FromAgent(agentConfig)).
Значение agentVersion соответствует строке версии, возвращаемой при создании или обновлении агента с помощью пакета SDK агента Foundry. Если это не указано, Voice Live подключается к последней версии агента.
Подключение к какому-либо агенту в другом ресурсе Foundry
Настройте голосовую трансляцию для подключения к агенту, размещенному в другом ресурсе Foundry, отличном от используемого для обработки звука.
Это полезно в следующих сценариях:
- Агент развертывается в регионе с разной доступностью функций.
- Вы хотите отделять разработку и промежуточное развертывание от рабочей среды.
- В организации используются различные ресурсы для разных рабочих нагрузок.
Чтобы подключиться к агенту в другом ресурсе, настройте две переменные среды:
-
FOUNDRY_RESOURCE_OVERRIDE: имя ресурса Foundry, в котором размещается проект агента (например,my-agent-resource). -
AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID: идентификатор клиента управляемой идентичности ресурса Voice Live, необходимый для проверки подлинности межресурсных взаимодействий.
// <agent_config>
public BasicVoiceAssistant(string endpoint, string agentName, string projectName,
string? agentVersion = null, string? conversationId = null,
string? foundryResourceOverride = null, string? authIdentityClientId = null)
{
_endpoint = endpoint;
// Build the agent session configuration
var config = new AgentSessionConfig(agentName, projectName);
if (!string.IsNullOrEmpty(agentVersion))
{
config.AgentVersion = agentVersion;
}
if (!string.IsNullOrEmpty(conversationId))
{
config.ConversationId = conversationId;
}
if (!string.IsNullOrEmpty(foundryResourceOverride))
{
config.FoundryResourceOverride = foundryResourceOverride;
if (!string.IsNullOrEmpty(authIdentityClientId))
{
config.AuthenticationIdentityClientId = authIdentityClientId;
}
}
_agentConfig = config;
}
// </agent_config>
// <main>
class Program
{
static async Task Main(string[] args)
{
var endpoint = Environment.GetEnvironmentVariable("VOICELIVE_ENDPOINT");
var agentName = Environment.GetEnvironmentVariable("AGENT_NAME");
var projectName = Environment.GetEnvironmentVariable("PROJECT_NAME");
var agentVersion = Environment.GetEnvironmentVariable("AGENT_VERSION");
var conversationId = Environment.GetEnvironmentVariable("CONVERSATION_ID");
var foundryResourceOverride = Environment.GetEnvironmentVariable("FOUNDRY_RESOURCE_OVERRIDE");
var authIdentityClientId = Environment.GetEnvironmentVariable("AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID");
Console.WriteLine("Environment variables:");
Console.WriteLine($"VOICELIVE_ENDPOINT: {endpoint}");
Console.WriteLine($"AGENT_NAME: {agentName}");
Console.WriteLine($"PROJECT_NAME: {projectName}");
Console.WriteLine($"AGENT_VERSION: {agentVersion}");
Console.WriteLine($"CONVERSATION_ID: {conversationId}");
Console.WriteLine($"FOUNDRY_RESOURCE_OVERRIDE: {foundryResourceOverride}");
if (string.IsNullOrEmpty(endpoint) || string.IsNullOrEmpty(agentName)
|| string.IsNullOrEmpty(projectName))
{
Console.Error.WriteLine("Set VOICELIVE_ENDPOINT, AGENT_NAME, and PROJECT_NAME environment variables.");
return;
}
// Verify audio devices
CheckAudioDevices();
Console.WriteLine("🎙️ Basic Foundry Voice Agent with Azure VoiceLive SDK (Agent Mode)");
Console.WriteLine(new string('=', 65));
using var assistant = new BasicVoiceAssistant(
endpoint, agentName, projectName,
agentVersion, conversationId,
foundryResourceOverride, authIdentityClientId);
// Handle graceful shutdown
using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (sender, e) =>
{
e.Cancel = true;
cts.Cancel();
};
try
{
await assistant.StartAsync(cts.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("\n👋 Voice assistant shut down. Goodbye!");
}
catch (Exception ex)
{
Console.Error.WriteLine($"Fatal Error: {ex.Message}");
}
Конфигурация определяется в Main() и применяется при создании помощника.
- Прочитайте
FOUNDRY_RESOURCE_OVERRIDEиAGENT_AUTHENTICATION_IDENTITY_CLIENT_IDиз переменных среды. - Передайте оба значения конструктору
BasicVoiceAssistant(...). - В конструкторе задайте оба значения на
AgentSessionConfigс помощьюconfig.FoundryResourceOverrideиconfig.AuthenticationIdentityClientId. Отправьте их вStartSessionAsync(SessionTarget.FromAgent(agentConfig)).
Важно
Для подключений между ресурсами требуются правильные назначения ролей. Убедитесь, что управляемое удостоверение ресурса Voice Live имеет роль Azure AI User в целевом ресурсе агента.
Добавление упреждающего сообщения при запуске сеанса
Отправьте упреждающее сообщение, чтобы инициировать беседы, когда сеанс готов. Помощник проверяет однократный флаг в обработчике SessionUpdateSessionUpdated событий, отправляет запрос приветствия и запускает ответ.
// <proactive_greeting>
private async Task SendProactiveGreetingAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Sending proactive greeting request");
try
{
// Create a system message to trigger greeting
await _session!.SendCommandAsync(
BinaryData.FromObjectAsJson(new
{
type = "conversation.item.create",
item = new
{
type = "message",
role = "system",
content = new[]
{
new { type = "input_text", text = "Say something to welcome the user in English." }
}
}
}), cancellationToken).ConfigureAwait(false);
// Request a response
await _session!.SendCommandAsync(
BinaryData.FromObjectAsJson(new { type = "response.create" }),
cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.Error.WriteLine($"Failed to send proactive greeting: {ex.Message}");
}
}
// </proactive_greeting>
Упреждающий обмен сообщениями осуществляется в три этапа:
-
_greetingSentпредставляет собойbool, инициализированный доfalseдля отслеживания состояния однократного приветствия. -
SessionUpdateSessionUpdatedВ ветви выполнениеif (!_greetingSent)контролируется, чтобы запускаться однократно для каждого сеанса. -
SendCommandAsync(...)с полезной нагрузкойconversation.item.createдобавляет приветствие в контекст беседы. Командаresponse.createсоздает голосовой вывод.
Улучшение времени ожидания вызова инструмента и задержки
Голосовая трансляция предлагает InterimResponse, чтобы сократить время ожидания при вызове инструмента или при создании ответов с высокой задержкой.
Voice Live предлагает два промежуточных режима отклика:
- Промежуточный ответ, сгенерированный с помощью LLM (
LlmInterimResponseConfig): использует облегченный LLM для динамического создания текста, учитывающего контекст. Лучше всего подходит для адаптивных, естественных звуковых ответов. -
Статический промежуточный ответ (
StaticInterimResponseConfig): случайным образом выбирается из предопределенного списка предоставленных текстов. Лучше всего подходит для детерминированного или фирменного обмена сообщениями.
Дополнительные сведения см. в разделе "Улучшение вызова инструмента и времени ожидания задержки с промежуточными ответами".
В голосовом помощнике для быстрого запуска показаны необходимые дополнения кода:
// <setup_session>
private async Task SetupSessionAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Setting up voice conversation session...");
// Create session configuration with interim response to bridge latency gaps
var interimConfig = new LlmInterimResponseConfig
{
Instructions = "Create friendly interim responses indicating wait time due to "
+ "ongoing processing, if any. Do not include in all responses! Do not "
+ "say you don't have real-time access to information when calling tools!",
};
interimConfig.Triggers.Add(InterimResponseTrigger.Tool);
interimConfig.Triggers.Add(InterimResponseTrigger.Latency);
interimConfig.LatencyThresholdMs = 100;
var options = new VoiceLiveSessionOptions
{
InputAudioFormat = InputAudioFormat.Pcm16,
OutputAudioFormat = OutputAudioFormat.Pcm16,
InterimResponse = BinaryData.FromObjectAsJson(interimConfig)
};
// Send session configuration
await _session!.ConfigureSessionAsync(options, cancellationToken).ConfigureAwait(false);
Console.WriteLine("Session configuration sent");
}
// </setup_session>
Временная настройка ответа применяется внутри SetupSessionAsync():
-
LlmInterimResponseConfigсоздается с пользовательскими инструкциями и триггерами для событийToolиLatency. - Конфигурация сериализуется с помощью
BinaryData.FromObjectAsJson()и назначаетсяVoiceLiveSessionOptions.InterimResponse. -
ConfigureSessionAsync(options)отправляет полную конфигурацию сеанса, включая промежуточный ответ, в Voice Live.
Используйте автоматическое сокращение для ответов, которые были прерваны
Когда пользователи прерывают звук агента, текст беседы может отклоняться от того, что они действительно слышали. Автоматическое усечение помогает поддерживать согласованность контекста сеанса с воспроизведенным аудио. Это улучшает последующие ответы после внедрения и делает журналирование разговоров более точным.
В настоящее время в примере показана обработка прерываний при CancelResponseAsync() запуске речи, но auto_truncate не настраивается в turn_detection.
Примечание
В службе агента Foundry потоковые сообщения и записи трассировки основаны на текстовом содержимом. Без автоматического усечения эти записи могут отличаться от точного фрагмента аудио, который пользователи слышали до прерывания.
Сведения о настройке и поддерживаемых параметрах см. в разделе "Обработка прерываний голосовой связи" в журнале чата (предварительная версия ).
Повторное подключение к прежнему разговору с агентом
Повторно подключитесь к предыдущей беседе, указав идентификатор беседы. Это сохраняет историю и контекст, позволяя пользователям продолжить с того места, где остановились.
Когда сеанс успешно подключается, Voice Live возвращает метаданные сеанса в событии SessionUpdateSessionUpdated . Извлеките идентификатор сеанса и зайдите в файл беседы:
// <handle_events>
private async Task HandleEventAsync(SessionUpdate serverEvent, CancellationToken cancellationToken)
{
switch (serverEvent)
{
case SessionUpdateSessionUpdated sessionUpdated:
Console.WriteLine("Session updated and ready");
var sessionId = sessionUpdated.Session?.Id;
WriteLog($"SessionID: {sessionId}\n");
// Send a proactive greeting
if (!_greetingSent)
{
_greetingSent = true;
await SendProactiveGreetingAsync(cancellationToken).ConfigureAwait(false);
}
// Start audio capture once session is ready
_audioProcessor?.StartCapture();
break;
В этом обработчике событий идентификатор сеанса извлекается из sessionUpdated.Session?.Id и записывается в журнал беседы.
Пример записывает сведения о сеансе в файл журнала бесед в папке logs/ (например, logs/conversation_20260219_143000.log).
Чтобы повторно подключиться, передайте идентификатор беседы в качестве переменной CONVERSATION_ID среды или conversationId параметра:
var conversationId = Environment.GetEnvironmentVariable("CONVERSATION_ID");
using var assistant = new BasicVoiceAssistant(
endpoint, agentName, projectName,
agentVersion, conversationId,
foundryResourceOverride, authIdentityClientId);
Повторное подключение сеанса связи применяется в трех местах.
- В
Main()считываетсяCONVERSATION_IDиз среды (строка 458). - Передайте значение конструктору
BasicVoiceAssistant(...)(строки 483-486). - В конструкторе задайте значение
AgentSessionConfigчерезconfig.ConversationId.
Если задано допустимое conversationId , агент извлекает предыдущий контекст беседы и может ссылаться на предыдущие обмены.
Примечание
Идентификаторы бесед привязаны к агенту и проекту. При использовании идентификатора разговора с другим агентом создается новый разговор.
Логгировать метаданные сеанса для обеспечения непрерывности и диагностики
В примере записываются ключевые метаданные сеанса, включая идентификатор сеанса, в файл logs/ журнала сеанса с отметкой времени. Это поможет вам:
- Определите сеанс для отладки и поддержки.
- Сопоставляйте поведение, сообщаемое пользователем, с метаданными сеанса.
- Отслеживайте выполнение с течением времени, сохраняя файлы журнала для каждого сеанса.
Следующий код создает имя файла журнала и записывает метаданные сеанса при SessionUpdateSessionUpdated срабатывании:
private static readonly string LogFilename = $"conversation_{DateTime.Now:yyyyMMdd_HHmmss}.log";
// <handle_events>
private async Task HandleEventAsync(SessionUpdate serverEvent, CancellationToken cancellationToken)
{
switch (serverEvent)
{
case SessionUpdateSessionUpdated sessionUpdated:
Console.WriteLine("Session updated and ready");
var sessionId = sessionUpdated.Session?.Id;
WriteLog($"SessionID: {sessionId}\n");
// Send a proactive greeting
if (!_greetingSent)
{
_greetingSent = true;
await SendProactiveGreetingAsync(cancellationToken).ConfigureAwait(false);
}
// Start audio capture once session is ready
_audioProcessor?.StartCapture();
break;
private static void WriteLog(string message)
{
try
{
var logDir = Path.Combine(Directory.GetCurrentDirectory(), "logs");
Directory.CreateDirectory(logDir);
File.AppendAllText(Path.Combine(logDir, LogFilename), message + Environment.NewLine);
}
catch (IOException ex)
{
Console.Error.WriteLine($"Failed to write conversation log: {ex.Message}");
}
}
Ведение журнала метаданных сеанса применяется в трех местах:
- Для каждого прогона создается файл журнала беседы с меткой времени (
conversation_YYYYMMDD_HHmmss.logстроки 188–189). - Обработчик
SessionUpdateSessionUpdatedизвлекает идентификатор сеанса и записывает его в журнал (строки 309–310). -
WriteLog(...)добавляет записи в течение жизненного цикла беседы (строки 427–439).
Используйте метаданные сеанса, записанные в журнале, с CONVERSATION_ID, чтобы возобновить беседу с тем же агентом позже. Используйте идентификатор сеанса вместе с идентификатором разговора для диагностики и сценариев повторного подключения.
Узнайте, как использовать Voice Live с службой агента Microsoft Foundry с помощью набора SDK VoiceLive для JavaScript. В этой статье мы расширяем краткое руководство по созданию агента голосовой связи с помощью службы агента Foundry и Voice Live, добавляя расширенные функции и параметры интеграции.
Справочная документация | Пакет (npm) | Дополнительные примеры на GitHub
Создание и запуск приложений для использования Voice Live с агентами для бесед в режиме реального времени.
Агенты предоставляют несколько преимуществ:
- Используйте централизованную конфигурацию в самом агенте вместо кода сеанса.
- Обрабатывайте сложную логику и диалоговое поведение для облегчения обновлений.
- Автоматически подключитесь с помощью идентификатора агента.
- Поддержка нескольких вариантов без изменения клиентского кода.
Сведения об использовании Voice Live без агентов Foundry см. в кратком руководстве по API Voice Live.
Совет
Вам не нужно развертывать звуковую модель с Microsoft Foundry для использования Voice Live. Voice Live полностью управляется и автоматически развертывает модель для вас. Сведения о доступности модели см. в документации по Voice Live.
Примечание
Пакет SDK для Голосовой трансляции JavaScript предназначен для приложений на основе браузера с встроенной поддержкой WebSocket и веб-аудио. В этом руководстве Node.js используется с node-record-lpcm16 и speaker для работы в консольной среде. Полный пользовательский интерфейс голосовой связи на основе браузера см. в примере универсального помощника voice Live.
Необходимые условия
Примечание
Этот документ ссылается на портал Microsoft Foundry (new) и последнюю версию службы агента Foundry.
- Подписка Azure. Создайте его бесплатно.
- Node.js версии 18 или более поздней.
-
SoX установлен в системе (требуется
node-record-lpcm16для захвата микрофона). - Необходимые языковые среды выполнения, глобальные инструменты и расширения Visual Studio Code, как описано в Подготовьте вашу среду разработки.
- Ресурс Microsoft Foundry создан в одном из поддерживаемых регионов. Для получения дополнительной информации о доступности регионов см. документацию Voice Live.
- Модель, развернутая в Microsoft Foundry. Если у вас нет модели, сначала выполните Quickstart: настройте ресурсы Microsoft Foundry.
- Назначьте роль
Azure AI Userучетной записи пользователя. Роли можно назначить на портале Azure в разделе Access control (IAM)>Add role assignment.
Подготовка среды и создание агента
Выполните Быстрый запуск: создание голосового агента с помощью службы Foundry Agent и Voice Live, чтобы настроить вашу среду, конфигурировать агента с настройками Voice Live и протестировать ваш первый разговор.
Концепции интеграции агента
Используйте эти понятия, чтобы понять, как служба агента Voice Live и Foundry работают вместе в примере JavaScript.
Контракт конфигурации агента
Задайте свойство с помощью объекта AgentSessionConfig в вызове agent, чтобы определить целевой агент и проект createSession(...). Как минимум, включите agentName и projectName. Добавьте agentVersion, когда хотите закрепить поведение в определенной версии.
Модель проверки подлинности для режима агента
Используйте Microsoft Entra ID учетные данные для режима агента. Вызов агента в этом потоке не поддерживает аутентификацию с использованием ключей, поэтому настройте DefaultAzureCredential (или другие учетные данные токена Entra) для локальной разработки и развертывания.
Закрепление версий API
Используйте согласованную версию пакета SDK (@azure/ai-voicelive@1.0.0-beta.3) в вашей package.json среде, чтобы обеспечить прогнозируемость поведения в предварительных версиях обновлений. Используйте одну и ту же версию последовательно в примерах быстрого старта и инструкциях, чтобы избежать дрейфа схемы.
Выравнивание бесед и трассировки
Рассматривайте поток агента и записи трассировки как историю текстовых сообщений, а не точную историю воспроизведения. Если ваше приложение допускает прерывание или усечение, включите обработку с учётом усечения, чтобы сохранённая история более точно соответствовала тому, что пользователь на самом деле слышал.
Подключение к определенной версии агента
Зафиксируйте агента на конкретной версии, чтобы обеспечить управляемые развертывания. Это позволяет рабочей среде использовать стабильные версии при тестировании новых итераций разработки.
AGENT_VERSION Задайте переменную среды или передайте agentVersion свойство при инициализации помощника:
constructor(opts) {
this.endpoint = opts.endpoint;
this.credential = opts.credential;
this.greetingText = opts.greetingText;
this.noAudio = opts.noAudio;
this.agentConfig = {
agentName: opts.agentName,
projectName: opts.projectName,
...(opts.agentVersion && { agentVersion: opts.agentVersion }),
...(opts.conversationId && { conversationId: opts.conversationId }),
...(opts.foundryResourceOverride && {
foundryResourceOverride: opts.foundryResourceOverride,
}),
...(opts.foundryResourceOverride &&
opts.authenticationIdentityClientId && {
authenticationIdentityClientId: opts.authenticationIdentityClientId,
}),
};
this._session = null;
this._audio = new AudioProcessor(!opts.noAudio, opts.audioInputDevice);
this._greetingSent = false;
this._activeResponse = false;
this._responseApiDone = false;
}
function parseArguments(argv) {
const parsed = {
endpoint: process.env.VOICELIVE_ENDPOINT ?? "",
agentName: process.env.AGENT_NAME ?? "",
projectName: process.env.PROJECT_NAME ?? "",
agentVersion: process.env.AGENT_VERSION,
conversationId: process.env.CONVERSATION_ID,
foundryResourceOverride: process.env.FOUNDRY_RESOURCE_OVERRIDE,
authenticationIdentityClientId:
process.env.AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID,
audioInputDevice: process.env.AUDIO_INPUT_DEVICE,
listAudioDevices: false,
greetingText: undefined,
noAudio: false,
help: false,
};
const assistant = new BasicVoiceAssistant({
endpoint: args.endpoint,
credential,
agentName: args.agentName,
projectName: args.projectName,
agentVersion: args.agentVersion,
conversationId: args.conversationId,
foundryResourceOverride: args.foundryResourceOverride,
authenticationIdentityClientId: args.authenticationIdentityClientId,
audioInputDevice: args.audioInputDevice,
greetingText: args.greetingText,
noAudio: args.noAudio,
});
В этом примере конфигурация версии применяется в трех местах:
- В
main(),AGENT_VERSIONсчитывается изprocess.env. - В конструкторе
BasicVoiceAssistantagentVersionраспространяется вagentConfigобъект. - Конфигурация передается
client.createSession({ agent: this.agentConfig }), который отправляет её на Voice Live.
Значение agentVersion соответствует строке версии, возвращаемой при создании или обновлении агента с помощью пакета SDK агента Foundry. Если это не указано, Voice Live подключается к последней версии агента.
Подключение к какому-либо агенту в другом ресурсе Foundry
Настройте Voice Live для подключения к агенту в другом ресурсе Foundry для обработки звука. Это полезно, когда:
- Агент развертывается в регионе с различной доступностью функций.
- Вы хотите разделить среды разработки и промежуточного хранения из рабочей среды
- В организации используются различные ресурсы для разных рабочих нагрузок
Чтобы подключиться к агенту в другом ресурсе, настройте две дополнительные переменные среды:
-
FOUNDRY_RESOURCE_OVERRIDE: имя ресурса Foundry, в котором размещается проект агента (например,my-agent-resource). -
AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID: идентификатор клиента управляемой идентичности ресурса Voice Live, необходимый для проверки подлинности межресурсных взаимодействий.
constructor(opts) {
this.endpoint = opts.endpoint;
this.credential = opts.credential;
this.greetingText = opts.greetingText;
this.noAudio = opts.noAudio;
this.agentConfig = {
agentName: opts.agentName,
projectName: opts.projectName,
...(opts.agentVersion && { agentVersion: opts.agentVersion }),
...(opts.conversationId && { conversationId: opts.conversationId }),
...(opts.foundryResourceOverride && {
foundryResourceOverride: opts.foundryResourceOverride,
}),
...(opts.foundryResourceOverride &&
opts.authenticationIdentityClientId && {
authenticationIdentityClientId: opts.authenticationIdentityClientId,
}),
};
this._session = null;
this._audio = new AudioProcessor(!opts.noAudio, opts.audioInputDevice);
this._greetingSent = false;
this._activeResponse = false;
this._responseApiDone = false;
}
function parseArguments(argv) {
const parsed = {
endpoint: process.env.VOICELIVE_ENDPOINT ?? "",
agentName: process.env.AGENT_NAME ?? "",
projectName: process.env.PROJECT_NAME ?? "",
agentVersion: process.env.AGENT_VERSION,
conversationId: process.env.CONVERSATION_ID,
foundryResourceOverride: process.env.FOUNDRY_RESOURCE_OVERRIDE,
authenticationIdentityClientId:
process.env.AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID,
audioInputDevice: process.env.AUDIO_INPUT_DEVICE,
listAudioDevices: false,
greetingText: undefined,
noAudio: false,
help: false,
};
const assistant = new BasicVoiceAssistant({
endpoint: args.endpoint,
credential,
agentName: args.agentName,
projectName: args.projectName,
agentVersion: args.agentVersion,
conversationId: args.conversationId,
foundryResourceOverride: args.foundryResourceOverride,
authenticationIdentityClientId: args.authenticationIdentityClientId,
audioInputDevice: args.audioInputDevice,
greetingText: args.greetingText,
noAudio: args.noAudio,
});
Эта конфигурация разрешается в main(), а затем применяется при создании помощника.
-
FOUNDRY_RESOURCE_OVERRIDEиAGENT_AUTHENTICATION_IDENTITY_CLIENT_IDсчитываются изprocess.env. - Оба значения распределяются по параметрам конструктора.
- В конструкторе значения задаются условно для
agentConfigобъекта, который отправляется вclient.createSession({ agent: this.agentConfig }).
Важно
Для подключений между ресурсами требуются правильные назначения ролей. Убедитесь, что управляемое удостоверение ресурса Voice Live имеет роль Azure AI User в целевом ресурсе агента.
Добавление упреждающего сообщения при запуске сеанса
Голосовая трансляция может инициировать беседу, отправив упреждающее сообщение, как только сеанс будет готов. В этом примере помощник проверяет однократный флаг в onSessionUpdated обработчике, отправляет запрос приветствия, а затем запускает ответ.
async _sendProactiveGreeting() {
const session = this._session;
if (this.greetingText) {
// Pre-generated assistant message (deterministic)
console.log("[session] Sending pre-generated greeting ...");
try {
await session.sendEvent({
type: "response.create",
response: {
preGeneratedAssistantMessage: {
content: [{ type: "text", text: this.greetingText }],
},
},
});
} catch (err) {
console.error("[session] Failed to send pre-generated greeting:", err.message);
}
} else {
// LLM-generated greeting (default)
console.log("[session] Sending proactive greeting ...");
try {
await session.addConversationItem({
type: "message",
role: "system",
content: [
{
type: "input_text",
text: "Say something to welcome the user in English.",
},
],
});
await session.sendEvent({ type: "response.create" });
} catch (err) {
console.error("[session] Failed to send greeting:", err.message);
}
}
}
В этом примере проактивное информирование применяется в три этапа:
-
_greetingSentпредставляет собойboolean, инициализированный доfalseдля отслеживания состояния однократного приветствия. - В обработчике
onSessionUpdatedif (!this._greetingSent)инициирует упреждающее выполнение, которое выполняется один раз за сеанс. -
session.addConversationItem(...)добавляет инструкцию приветствия в контекст беседы иsession.sendEvent({ type: "response.create" })создает произнесенные выходные данные.
Улучшение времени ожидания вызова инструмента и задержки
Voice Live предоставляет функцию interimResponse для сокращения времени ожидания, когда требуется вызов инструментов или возникает высокая задержка для получения ответа от агента.
Voice Live предлагает два промежуточных режима отклика:
- Промежуточный ответ, сгенерированный с помощью LLM (
llm_interim_response): использует облегченный LLM для динамического создания текста, учитывающего контекст. Лучше всего подходит для адаптивных, естественных звуковых ответов. -
Статический промежуточный ответ (
static_interim_response): случайным образом выбирается из предопределенного списка предоставленных текстов. Лучше всего подходит для детерминированного или фирменного обмена сообщениями.
Дополнительные сведения см. в разделе "Улучшение вызова инструмента и времени ожидания задержки с промежуточными ответами".
Голосовой помощник, созданный с помощью быстрого старта, показывает необходимые дополнения кода для настройки этой функции следующим образом:
async _setupSession() {
console.log("[session] Configuring session ...");
await this._session.updateSession({
modalities: ["text", "audio"],
inputAudioFormat: "pcm16",
outputAudioFormat: "pcm16",
interimResponse: {
type: "llm_interim_response",
triggers: ["tool", "latency"],
latencyThresholdInMs: 100,
instructions:
"Create friendly interim responses indicating wait time due to ongoing processing, if any. " +
"Do not include in all responses! Do not say you don't have real-time access to information when calling tools!",
},
});
console.log("[session] Session configuration sent");
}
В этом примере настройка промежуточного ответа применяется внутри _setupSession():
-
interimResponseопределяет, когда активируются промежуточные ответы и какой стиль они используют. -
session.updateSession(...)отправляет конфигурацию сеанса в Voice Live, включая промежуточные параметры ответа.
Используйте автоматическое сокращение для ответов, которые были прерваны
Когда пользователи прерывают звук агента, текст беседы может отклоняться от того, что они действительно слышали. Автоматическое усечение помогает поддерживать соответствие контекста сеанса доставленному звуку, что улучшает качество ответов после перебивания и делает логирование голосовых разговоров более точным.
В этом примере в настоящее время показана обработка прерываний с response.cancel при запуске речи, но auto_truncate не настраивается в turn_detection.
Примечание
В службе агента Foundry сообщения потоков и потоки агента трассировки основаны на текстовом содержимом потоков. Без автоматического усечения эти записи могут отличаться от точной части звука, который пользователь фактически слышал до прерывания.
Сведения о настройке и поддерживаемых параметрах см. в разделе "Обработка прерываний голосовой связи в журнале чата (предварительная версия)".
Повторное подключение к прежнему разговору с агентом
Голосовая трансляция позволяет повторно подключиться к предыдущей беседе, указав идентификатор беседы. Это сохраняет журнал беседы и контекст, позволяя пользователям продолжать работу, где они остались.
Когда сеанс подключается успешно, Voice Live возвращает метаданные сеанса в обработчике onSessionUpdated. Пример извлекает идентификатор сеанса из контекста и записывает его в файл беседы:
onSessionUpdated: async (event, context) => {
const s = event.session;
const agent = s?.agent;
const voice = s?.voice;
console.log(`[session] Session ready: ${context.sessionId}`);
writeConversationLog(
[
`SessionID: ${context.sessionId}`,
`Agent Name: ${agent?.name ?? ""}`,
`Agent Description: ${agent?.description ?? ""}`,
`Agent ID: ${agent?.agentId ?? ""}`,
`Voice Name: ${voice?.name ?? ""}`,
`Voice Type: ${voice?.type ?? ""}`,
"",
].join("\n"),
);
},
В этом обработчике событий идентификатор сеанса извлекается из context.sessionId и записывается в журнал беседы вместе с метаданными агента.
Пример кода записывает сведения о сеансе в файл журнала бесед в папке logs/ (например, logs/conversation_20260219_143000.log).
Чтобы повторно подключиться к этой беседе, передайте идентификатор беседы в качестве переменной CONVERSATION_ID среды (или свойством conversationId ):
conversationId: process.env.CONVERSATION_ID,
conversationId: args.conversationId,
В этом примере повторное подключение беседы применяется в трех местах:
- В
main(),CONVERSATION_IDсчитывается изprocess.env(строка 558). - Значение передается конструктору
BasicVoiceAssistant. - В конструкторе
conversationIdусловно распространяется наagentConfigобъект.
Если задано допустимое conversationId , агент извлекает предыдущий контекст беседы и может ссылаться на предыдущие обмены в ответах.
Примечание
Идентификаторы бесед привязаны к агенту и проекту. Попытка использовать идентификатор беседы с другим агентом приводит к созданию новой беседы.
Логгировать метаданные сеанса для обеспечения непрерывности и диагностики
В примере записываются ключевые метаданные сеанса, включая идентификатор сеанса, в файл logs/ журнала сеанса с отметкой времени. Это поможет вам:
- Определите сеанс для сценариев отладки и поддержки.
- Сопоставляйте поведение, сообщаемое пользователем, с метаданными сеанса.
- Отслеживайте выполнение с течением времени, сохраняя файлы журнала для каждого сеанса.
Данный код создает имя лог-файла и записывает метаданные сеанса при получении onSessionUpdated.
const logsDir = join(__dirname, "logs");
if (!existsSync(logsDir)) mkdirSync(logsDir, { recursive: true });
const timestamp = new Date()
.toISOString()
.replace(/[:.]/g, "-")
.replace("T", "_")
.slice(0, 19);
const conversationLogFile = join(logsDir, `conversation_${timestamp}.log`);
function writeConversationLog(message) {
appendFileSync(conversationLogFile, message + "\n", "utf-8");
}
onSessionUpdated: async (event, context) => {
const s = event.session;
const agent = s?.agent;
const voice = s?.voice;
console.log(`[session] Session ready: ${context.sessionId}`);
writeConversationLog(
[
`SessionID: ${context.sessionId}`,
`Agent Name: ${agent?.name ?? ""}`,
`Agent Description: ${agent?.description ?? ""}`,
`Agent ID: ${agent?.agentId ?? ""}`,
`Voice Name: ${voice?.name ?? ""}`,
`Voice Type: ${voice?.type ?? ""}`,
"",
].join("\n"),
);
},
В этом примере ведение журнала метаданных сеанса применяется в трех местах:
-
logs/Каталог создается, если он не существует, и файл журнала бесед с меткой времени (conversation_YYYYMMDD_HHmmss.log) создается для каждого запуска (строки 21–29). - Обработчик извлекает идентификатор сеанса из
context.sessionIdи записывает его вместе с метаданными агента в журнал (строки 306–321). -
writeConversationLog(...)добавляет записи в один и тот же файл журнала на протяжении всего жизненного цикла беседы (строки 31–33).
Используйте метаданные зарегистрированного сеанса с CONVERSATION_ID, чтобы возобновить беседу с тем же агентом в последующем сеансе.
Используйте значение идентификатора сеанса вместе с идентификатором разговора для диагностики и повторного подключения.
Узнайте, как использовать Voice Live с Службой агента Microsoft Foundry с помощью VoiceLive SDK для Java. В этой статье мы расширяем краткое руководство по созданию агента голосовой связи с помощью службы агента Foundry и Voice Live, добавляя расширенные функции и параметры интеграции.
Справочная документация | Пакет (Maven) | Дополнительные примеры на GitHub
Создание и запуск приложений для использования Voice Live с агентами для бесед в режиме реального времени.
Агенты предоставляют несколько преимуществ:
- Используйте централизованную конфигурацию в самом агенте вместо кода сеанса.
- Обрабатывайте сложную логику и диалоговое поведение для облегчения обновлений.
- Автоматически подключитесь с помощью идентификатора агента.
- Поддержка нескольких вариантов без изменения клиентского кода.
Сведения об использовании Voice Live без агентов Foundry см. в кратком руководстве по API Voice Live.
Совет
Вам не нужно развертывать звуковую модель с Microsoft Foundry для использования Voice Live. Voice Live полностью управляется и автоматически развертывает модель для вас. Сведения о доступности модели см. в документации по Voice Live.
Необходимые условия
Примечание
Этот документ ссылается на портал Microsoft Foundry (new) и последнюю версию службы агента Foundry.
- Подписка Azure. Создайте его бесплатно.
- Java комплект средств разработки (JDK) версии 11 или более поздней.
- Установлен Apache Maven.
- Необходимые языковые среды выполнения, глобальные инструменты и расширения Visual Studio Code, как описано в Подготовьте вашу среду разработки.
- Ресурс Microsoft Foundry создан в одном из поддерживаемых регионов. Для получения дополнительной информации о доступности регионов см. документацию Voice Live.
- Модель, развернутая в Microsoft Foundry. Если у вас нет модели, сначала выполните Quickstart: настройте ресурсы Microsoft Foundry.
- Назначьте роль
Azure AI Userучетной записи пользователя. Роли можно назначить на портале Azure в разделе Access control (IAM)>Add role assignment.
Подготовка среды и создание агента
Выполните Быстрый запуск: создание голосового агента с помощью службы Foundry Agent и Voice Live, чтобы настроить вашу среду, конфигурировать агента с настройками Voice Live и протестировать ваш первый разговор.
Концепции интеграции агента
Используйте эти понятия, чтобы понять, как служба агента Voice Live и Foundry работают вместе в примере Java.
Контракт конфигурации агента
Укажите AgentSessionConfig в настройках сеанса для идентификации целевого агента и проекта. Как минимум, включите agentName и projectName. Добавьте agentVersion, когда хотите закрепить поведение в определенной версии.
Модель проверки подлинности для режима агента
Используйте Microsoft Entra ID учетные данные для режима агента. Вызов агента в этом потоке не поддерживает аутентификацию с использованием ключей, поэтому настройте AzureCliCredential (или другие учетные данные токена Entra) для локальной разработки и развертывания.
Закрепление версий API
Используйте согласованную версию пакета SDK (azure-ai-voicelive:1.0.0-beta.5) в POM Maven, чтобы обеспечить прогнозируемость поведения в предварительных версиях обновлений. Используйте одну и ту же версию последовательно в примерах быстрого старта и инструкциях, чтобы избежать дрейфа схемы.
Выравнивание бесед и трассировки
Рассматривайте поток агента и записи трассировки как историю текстовых сообщений, а не точную историю воспроизведения. Если ваше приложение допускает прерывание или усечение, включите обработку с учётом усечения, чтобы сохранённая история более точно соответствовала тому, что пользователь на самом деле слышал.
Подключение к определенной версии агента
Зафиксируйте агента на конкретной версии, чтобы обеспечить управляемые развертывания. Это позволяет рабочей среде использовать стабильные версии при тестировании новых итераций разработки.
AGENT_VERSION Задайте переменную среды или передайте agentVersion параметр при инициализации помощника:
// <agent_config>
BasicVoiceAssistant(String endpoint, String agentName, String projectName,
String agentVersion, String conversationId,
String foundryResourceOverride, String authIdentityClientId) {
this.endpoint = endpoint;
// Build the agent session configuration
AgentSessionConfig config = new AgentSessionConfig(agentName, projectName);
if (agentVersion != null && !agentVersion.isEmpty()) {
config.setAgentVersion(agentVersion);
}
if (conversationId != null && !conversationId.isEmpty()) {
config.setConversationId(conversationId);
}
if (foundryResourceOverride != null && !foundryResourceOverride.isEmpty()) {
config.setFoundryResourceOverride(foundryResourceOverride);
if (authIdentityClientId != null && !authIdentityClientId.isEmpty()) {
config.setAuthenticationIdentityClientId(authIdentityClientId);
}
}
this.agentConfig = config;
}
// </agent_config>
// <main>
public static void main(String[] args) {
String endpoint = System.getenv("VOICELIVE_ENDPOINT");
String agentName = System.getenv("AGENT_NAME");
String projectName = System.getenv("PROJECT_NAME");
String agentVersion = System.getenv("AGENT_VERSION");
String conversationId = System.getenv("CONVERSATION_ID");
String foundryResourceOverride = System.getenv("FOUNDRY_RESOURCE_OVERRIDE");
String authIdentityClientId = System.getenv("AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID");
System.out.println("Environment variables:");
System.out.println("VOICELIVE_ENDPOINT: " + endpoint);
System.out.println("AGENT_NAME: " + agentName);
System.out.println("PROJECT_NAME: " + projectName);
System.out.println("AGENT_VERSION: " + agentVersion);
System.out.println("CONVERSATION_ID: " + conversationId);
System.out.println("FOUNDRY_RESOURCE_OVERRIDE: " + foundryResourceOverride);
if (endpoint == null || endpoint.isEmpty()
|| agentName == null || agentName.isEmpty()
|| projectName == null || projectName.isEmpty()) {
System.err.println("Set VOICELIVE_ENDPOINT, AGENT_NAME, and PROJECT_NAME environment variables.");
System.exit(1);
}
// Verify audio devices
checkAudioDevices();
System.out.println("🎙️ Basic Foundry Voice Agent with Azure VoiceLive SDK (Agent Mode)");
System.out.println("=".repeat(65));
BasicVoiceAssistant assistant = new BasicVoiceAssistant(
endpoint, agentName, projectName,
agentVersion, conversationId,
foundryResourceOverride, authIdentityClientId);
// Handle graceful shutdown
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("\n👋 Voice assistant shut down. Goodbye!");
}));
try {
assistant.start();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("\n👋 Voice assistant shut down. Goodbye!");
} catch (Exception e) {
System.err.println("Fatal Error: " + e.getMessage());
e.printStackTrace();
}
}
// </main>
В этом примере конфигурация версии применяется в трех местах:
- В
main()AGENT_VERSIONсчитывается из среды. - В конструктор
BasicVoiceAssistant(...)передаетсяagentVersion. - В конструкторе значение присваивается
AgentSessionConfigс помощьюconfig.setAgentVersion(agentVersion), а затем отправляется в Voice Live черезclient.startSession(agentConfig).
Значение agentVersion соответствует строке версии, возвращаемой при создании или обновлении агента с помощью пакета SDK агента Foundry. Если это не указано, Voice Live подключается к последней версии агента.
Подключение к какому-либо агенту в другом ресурсе Foundry
Настройте Voice Live для подключения к агенту в другом ресурсе Foundry для обработки звука. Это полезно, когда:
- Агент развертывается в регионе с различной доступностью функций.
- Вы хотите разделить среды разработки и промежуточного хранения из рабочей среды
- В организации используются различные ресурсы для разных рабочих нагрузок
Чтобы подключиться к агенту в другом ресурсе, настройте две дополнительные переменные среды:
-
FOUNDRY_RESOURCE_OVERRIDE: имя ресурса Foundry, в котором размещается проект агента (например,my-agent-resource). -
AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID: идентификатор клиента управляемой идентичности ресурса Voice Live, необходимый для проверки подлинности межресурсных взаимодействий.
// <agent_config>
BasicVoiceAssistant(String endpoint, String agentName, String projectName,
String agentVersion, String conversationId,
String foundryResourceOverride, String authIdentityClientId) {
this.endpoint = endpoint;
// Build the agent session configuration
AgentSessionConfig config = new AgentSessionConfig(agentName, projectName);
if (agentVersion != null && !agentVersion.isEmpty()) {
config.setAgentVersion(agentVersion);
}
if (conversationId != null && !conversationId.isEmpty()) {
config.setConversationId(conversationId);
}
if (foundryResourceOverride != null && !foundryResourceOverride.isEmpty()) {
config.setFoundryResourceOverride(foundryResourceOverride);
if (authIdentityClientId != null && !authIdentityClientId.isEmpty()) {
config.setAuthenticationIdentityClientId(authIdentityClientId);
}
}
this.agentConfig = config;
}
// </agent_config>
// <main>
public static void main(String[] args) {
String endpoint = System.getenv("VOICELIVE_ENDPOINT");
String agentName = System.getenv("AGENT_NAME");
String projectName = System.getenv("PROJECT_NAME");
String agentVersion = System.getenv("AGENT_VERSION");
String conversationId = System.getenv("CONVERSATION_ID");
String foundryResourceOverride = System.getenv("FOUNDRY_RESOURCE_OVERRIDE");
String authIdentityClientId = System.getenv("AGENT_AUTHENTICATION_IDENTITY_CLIENT_ID");
System.out.println("Environment variables:");
System.out.println("VOICELIVE_ENDPOINT: " + endpoint);
System.out.println("AGENT_NAME: " + agentName);
System.out.println("PROJECT_NAME: " + projectName);
System.out.println("AGENT_VERSION: " + agentVersion);
System.out.println("CONVERSATION_ID: " + conversationId);
System.out.println("FOUNDRY_RESOURCE_OVERRIDE: " + foundryResourceOverride);
if (endpoint == null || endpoint.isEmpty()
|| agentName == null || agentName.isEmpty()
|| projectName == null || projectName.isEmpty()) {
System.err.println("Set VOICELIVE_ENDPOINT, AGENT_NAME, and PROJECT_NAME environment variables.");
System.exit(1);
}
// Verify audio devices
checkAudioDevices();
System.out.println("🎙️ Basic Foundry Voice Agent with Azure VoiceLive SDK (Agent Mode)");
System.out.println("=".repeat(65));
BasicVoiceAssistant assistant = new BasicVoiceAssistant(
endpoint, agentName, projectName,
agentVersion, conversationId,
foundryResourceOverride, authIdentityClientId);
// Handle graceful shutdown
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("\n👋 Voice assistant shut down. Goodbye!");
}));
try {
assistant.start();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("\n👋 Voice assistant shut down. Goodbye!");
} catch (Exception e) {
System.err.println("Fatal Error: " + e.getMessage());
e.printStackTrace();
}
}
// </main>
Эта конфигурация разрешается в main(), а затем применяется при создании помощника.
-
FOUNDRY_RESOURCE_OVERRIDEиAGENT_AUTHENTICATION_IDENTITY_CLIENT_IDсчитываются из переменных среды. - Оба значения передаются конструктору
BasicVoiceAssistant(...). - В конструкторе значения задаются на
AgentSessionConfigчерезconfig.setFoundryResourceOverride(...)иconfig.setAuthenticationIdentityClientId(...), которые отправляются вclient.startSession(agentConfig).
Важно
Для подключений между ресурсами требуются правильные назначения ролей. Убедитесь, что управляемое удостоверение ресурса Voice Live имеет роль Azure AI User в целевом ресурсе агента.
Добавление упреждающего сообщения при запуске сеанса
Отправьте упреждающее сообщение, чтобы инициировать беседы сразу после готовности сеанса. В этом примере проверяется однократный флаг в обработчике SESSION_UPDATED событий, отправляется запрос приветствия и запускается ответ.
// <proactive_greeting>
private void sendProactiveGreeting() {
logger.info("Sending proactive greeting request");
try {
// Create a system message to trigger greeting
SystemMessageItem greetingMessage = new SystemMessageItem(
Arrays.asList(new InputTextContentPart("Say something to welcome the user in English.")));
ClientEventConversationItemCreate createEvent = new ClientEventConversationItemCreate()
.setItem(greetingMessage);
session.sendEvent(createEvent).block();
// Request a response
session.sendEvent(new ClientEventResponseCreate()).block();
} catch (Exception e) {
logger.log(Level.WARNING, "Failed to send proactive greeting", e);
}
}
// </proactive_greeting>
В этом примере проактивное информирование применяется в три этапа:
-
greetingSentпредставляет собойboolean, инициализированный доfalseдля отслеживания состояния однократного приветствия. - В ветви
SESSION_UPDATED,if (!greetingSent)ворота ограничивают упреждающее выполнение, чтобы оно выполнялось один раз за сеанс. -
sendEvent(new ClientEventConversationItemCreate()...)добавляет инструкцию приветствия в контекст беседы иsendEvent(new ClientEventResponseCreate())создает произнесенные выходные данные.
Улучшение времени ожидания вызова инструмента и задержки
Используйте функцию Voice Live interimResponse для сокращения времени ожидания в процессе вызова инструмента или при создании ответов агента с высокой задержкой.
Voice Live предлагает два промежуточных режима отклика:
- Промежуточный ответ, сгенерированный с помощью LLM (
LlmInterimResponseConfig): использует облегченный LLM для динамического создания текста, учитывающего контекст. Лучше всего подходит для адаптивных, естественных звуковых ответов. -
Статический промежуточный ответ (
StaticInterimResponseConfig): случайным образом выбирается из предопределенного списка предоставленных текстов. Лучше всего подходит для детерминированного или фирменного обмена сообщениями.
Дополнительные сведения см. в разделе "Улучшение вызова инструмента и времени ожидания задержки с промежуточными ответами".
Голосовой помощник, созданный с помощью быстрого старта, показывает необходимые дополнения кода для настройки этой функции следующим образом:
// <setup_session>
private void setupSession() {
logger.info("Setting up voice conversation session...");
// Configure interim responses to bridge latency gaps during processing
LlmInterimResponseConfig interimResponseConfig = new LlmInterimResponseConfig()
.setTriggers(Arrays.asList(
InterimResponseTrigger.TOOL,
InterimResponseTrigger.LATENCY))
.setLatencyThresholdMs(100)
.setInstructions("Create friendly interim responses indicating wait time due to "
+ "ongoing processing, if any. Do not include in all responses! Do not "
+ "say you don't have real-time access to information when calling tools!");
// Create session configuration
VoiceLiveSessionOptions sessionOptions = new VoiceLiveSessionOptions()
.setModalities(Arrays.asList(InteractionModality.TEXT, InteractionModality.AUDIO))
.setInputAudioFormat(InputAudioFormat.PCM16)
.setOutputAudioFormat(OutputAudioFormat.PCM16)
.setInterimResponse(BinaryData.fromObject(interimResponseConfig));
// Send session update
session.sendEvent(new ClientEventSessionUpdate(sessionOptions)).block();
logger.info("Session configuration sent");
}
// </setup_session>
В этом примере настройка промежуточного ответа применяется внутри BasicVoiceAssistant.setupSession():
-
LlmInterimResponseConfigопределяет, когда активируются промежуточные ответы и какой стиль они используют. -
VoiceLiveSessionOptionsподключает эту конфигурацию через полеinterimResponse(сериализованное черезBinaryData.fromObject(...)). -
session.sendEvent(new ClientEventSessionUpdate(sessionOptions))отправляет конфигурацию сеанса в Voice Live.
Используйте автоматическое сокращение для ответов, которые были прерваны
Когда пользователи прерывают звук агента, текст беседы может отклоняться от того, что они действительно слышали. Автоматическое усечение помогает поддерживать соответствие контекста сеанса доставленному звуку, что улучшает качество ответов после перебивания и делает логирование голосовых разговоров более точным.
В этом примере в настоящее время показана обработка прерываний с ClientEventResponseCancel при запуске речи, но auto_truncate не настраивается в turn_detection.
Примечание
В службе агента Foundry сообщения потоков и потоки агента трассировки основаны на текстовом содержимом потоков. Без автоматического усечения эти записи могут отличаться от точной части звука, который пользователь фактически слышал до прерывания.
Сведения о настройке и поддерживаемых параметрах см. в разделе "Обработка прерываний голосовой связи в журнале чата (предварительная версия)".
Повторное подключение к прежнему разговору с агентом
Повторно подключитесь к предыдущей беседе, указав идентификатор беседы. Это сохраняет историю и контекст, позволяя пользователям продолжить с того места, где остановились.
Когда сеанс успешно подключается, Voice Live возвращает метаданные сеанса в событии SESSION_UPDATED . Пример извлекает идентификатор сеанса и записывает его в файл беседы:
if (type == ServerEventType.SESSION_UPDATED) {
logger.info("Session updated and ready");
sessionReady = true;
String sessionId = extractField(event, "id");
writeLog(String.format("SessionID: %s\n", sessionId));
// Send a proactive greeting
if (!greetingSent) {
greetingSent = true;
sendProactiveGreeting();
}
// Start audio capture once session is ready
try {
audioProcessor.startCapture();
} catch (LineUnavailableException e) {
logger.log(Level.SEVERE, "Failed to start audio capture", e);
}
В этом обработчике событий идентификатор сеанса извлекается из JSON события с помощью extractField(event, "id") и записывается в журнал беседы.
Пример кода записывает сведения о сеансе в файл журнала бесед в папке logs/ (например, logs/conversation_20260219_143000.log).
Чтобы повторно подключиться к этой беседе, передайте идентификатор беседы в качестве переменной CONVERSATION_ID среды (или параметром conversationId ):
String conversationId = System.getenv("CONVERSATION_ID");
BasicVoiceAssistant assistant = new BasicVoiceAssistant(
endpoint, agentName, projectName,
agentVersion, conversationId,
foundryResourceOverride, authIdentityClientId);
В этом примере повторное подключение беседы применяется в трех местах:
- В
main(),CONVERSATION_IDсчитывается из окружения (строка 512). - Значение передается конструктору
BasicVoiceAssistant(...)(строки 537-540). - В конструкторе значение устанавливается на
AgentSessionConfigс помощьюconfig.setConversationId(conversationId).
Если задано допустимое conversationId , агент извлекает предыдущий контекст беседы и может ссылаться на предыдущие обмены в ответах.
Примечание
Идентификаторы бесед привязаны к агенту и проекту. Попытка использовать идентификатор беседы с другим агентом приводит к созданию новой беседы.
Логгировать метаданные сеанса для обеспечения непрерывности и диагностики
Записывайте ключевые метаданные сеанса, включая идентификатор сеанса, в файл журнала беседы с меткой времени под logs/. Это поможет вам:
- Определите сеанс для сценариев отладки и поддержки.
- Сопоставляйте поведение, сообщаемое пользователем, с метаданными сеанса.
- Отслеживайте выполнение с течением времени, сохраняя файлы журнала для каждого сеанса.
Данный код создает имя лог-файла и записывает метаданные сеанса при получении SESSION_UPDATED.
// Conversation log
private static final String LOG_FILENAME = "conversation_"
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")) + ".log";
if (type == ServerEventType.SESSION_UPDATED) {
logger.info("Session updated and ready");
sessionReady = true;
String sessionId = extractField(event, "id");
writeLog(String.format("SessionID: %s\n", sessionId));
// Send a proactive greeting
if (!greetingSent) {
greetingSent = true;
sendProactiveGreeting();
}
// Start audio capture once session is ready
try {
audioProcessor.startCapture();
} catch (LineUnavailableException e) {
logger.log(Level.SEVERE, "Failed to start audio capture", e);
}
private void writeLog(String message) {
try {
Path logDir = Paths.get("logs");
Files.createDirectories(logDir);
try (PrintWriter writer = new PrintWriter(
new FileWriter(logDir.resolve(LOG_FILENAME).toString(), true))) {
writer.println(message);
}
} catch (IOException e) {
logger.warning("Failed to write conversation log: " + e.getMessage());
}
}
В этом примере ведение журнала метаданных сеанса применяется в трех местах:
- Для каждого запуска создается файл журнала разговора с меткой времени (
conversation_YYYYMMDD_HHmmss.logстроки 92–95). - Обработчик
SESSION_UPDATEDизвлекает идентификатор сеанса из JSON события и записывает его в журнал (строки 365–366). -
writeLog(...)добавляет записи в один и тот же файл журнала на протяжении всего жизненного цикла беседы (строки 471–482).
Используйте метаданные зарегистрированного сеанса с CONVERSATION_ID, чтобы возобновить беседу с тем же агентом в последующем сеансе.
Используйте значение идентификатора сеанса вместе с идентификатором разговора для диагностики и повторного подключения.
Миграция из службы агента (классическая модель)
Если вы используете Voice Live со службой агентского обслуживания (classic), мы рекомендуем перейти на новую службу агентского обслуживания Foundry. Общие действия по миграции службы агента см. в разделе "Миграция из службы агента (классической) в службу агента Foundry.
Изменения пакета SDK для голосовой трансляции
Пакет SDK voice Live содержит типизированные классы конфигурации, заменяющие необработанные параметры запроса, используемые в классической интеграции:
| Классический (версия 1) | Новый (v2) |
|---|---|
agent-id Параметр запроса |
agent_name в AgentConfig / AgentSessionConfig |
agent-project-name Параметр запроса |
Конечная точка проекта в конструкторе клиента |
agent-access-token Параметр запроса |
Автоматически обрабатывается пакетом SDK |
Вручную connect() с диктовкой запроса |
Строго типизированные параметры, переданные в параметры сеанса AgentSessionConfig |
Минимальные версии пакета SDK
| Язык | Пакет | Минимальная версия |
|---|---|---|
| Python | azure-ai-voicelive |
1.0.0b5 |
| C# | Azure.AI.VoiceLive |
1.1.0-beta.2 |
| Java | azure-ai-voicelive |
1.0.0-beta.5 |
| Javascript | @azure/ai-voicelive |
1.0.0-beta.3 |
До и после: настройка подключения Python
Классический (v1) — необработанные параметры запроса в connect():
async with connect(
endpoint=self.endpoint,
credential=self.credential,
query={
"agent-id": self.agent_id,
"agent-project-name": self.foundry_project_name,
"agent-access-token": agent_access_token
},
) as connection:
New (v2) — строго типизированный AgentSessionConfig:
from azure.ai.voicelive import AgentConfig, AgentSessionConfig
agent_config = AgentConfig(agent_name=agent_name)
agent_session_config = AgentSessionConfig(agent_config=agent_config)
session_options = VoiceLiveSessionOptions(
agent_session_config=agent_session_config,
# ... other options
)
Полные примеры кода см. в кратком руководстве по новому агенту. Классическое краткое руководство все еще доступно.
Связанное содержимое
- Узнайте , как добавлять упреждающие сообщения
- Узнайте , как улучшить вызовы инструментов и задержки во времени ожидания
- Дополнительные сведения об использовании API голосовой трансляции
- См. справочник по API голосовой трансляции