Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

DynamicEndpointing: one long silence between user utterances inflates min_delay for the rest of the session

オープン
#7,744 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@NabiBukhsh-AI がすでに取り組んでいます。

2026年10月11日 から。

  • #7750 @NabiBukhsh-AI による — オープン

評価

難易度
3/5
見積もり時間
半日
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
停滞
技術スタック
python

調査の方向性

Start with voice/endpointing.py and inspect DynamicEndpointing.on_end_of_speech, especially the between-utterance pause update. Add coverage for a pause longer than max_delay and confirm it does not raise the learned min_delay; retain the existing behavior for shorter pauses. An open pull request (#7750) is already linked.

索引モデルが issue の本文から書いたものです。

説明

Environment

  • livekit-agents 1.8.5 (voice/endpointing.py is identical in 1.8.6 and on main)
  • turn_handling={"endpointing": {"mode": "dynamic", "min_delay": 0.3, "max_delay": 2.5}} (alpha 0.9)

What happens

DynamicEndpointing learns min_delay from the pause between two user utterances with no agent speech in between. That pause goes into ExpFilter.apply() unbounded, and only the filtered result is clamped to max_delay. One long silence, such as a user waiting for a reply that never came because STT dropped a short "yes", lifts the learned floor far above anything a mid-turn pause would justify. Every later turn of the session then waits that long before committing.

Repro

from livekit.agents.voice.endpointing import DynamicEndpointing

ep = DynamicEndpointing(min_delay=0.3, max_delay=2.5, alpha=0.9)
ep.on_start_of_speech(0.0)
ep.on_end_of_speech(0.3)     # a short "yes" that STT drops: no reply follows
ep.on_start_of_speech(15.5)  # the user speaks again after 15.2 s of silence
ep.on_end_of_speech(16.7)

assert ep.min_delay <= 1.0, ep.min_delay  # AssertionError: 1.79 (0.9*0.3 + 0.1*15.2)

On a real phone call this produced exactly that: end_of_utterance_delay went from 0.52 s to 1.79 s and stayed between 1.67 s and 2.13 s for the rest of the call (18 turns). Replaying the user/agent state events of 84 recorded sessions through DynamicEndpointing gave 51 of 624 user turns committed on a floor above 1 s, across 6 sessions, all of them phone calls.

Proposed fix

min_delay exists to cover pauses inside a user's turn. A pause longer than max_delay can never be covered, because the floor is clamped to max_delay. Learning from such a pause only adds latency. In the "pause between utterances" branch of on_end_of_speech, skip the update when pause > self.max_delay:

if (
    (pause := self.between_utterance_delay) > 0
    and pause <= self.max_delay
    and self._agent_speech_ended_at is None
    and self._agent_speech_started_at is None
):

Clamping the sample to max_delay instead still moves the floor by (1 - alpha) * max_delay (0.22 s) per long silence. Over the same 84 sessions the highest floor was 0.94 s with clamping and 0.62 s with the skip.

We currently ship this as a subclass injected through agent_activity.create_endpointing. We would be glad to drop it once this is fixed upstream, and can open a PR if that helps.

主要言語
Python
スター
14.6k
フォーク
3.9k
平均マージ
2日 23時間
マージ済み PR(30日)
177

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

livekit/agents のほかの issue

livekit/agents の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。