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

Đang mở
#7,744 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@NabiBukhsh-AI đang làm issue này rồi.

Từ ngày 11/10/2026.

  • #7750 của @NabiBukhsh-AI — đang mở

Đánh giá

Độ khó
3/5
Thời gian dự kiến
Nửa ngày
Mức phù hợp với người mới
35/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
python
Lĩnh vực
audio-video-rtc, backend

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
Python
Star
14.6k
Fork
3.9k
Merge trung bình
3 ngày
Pull request đã merge (30 ngày)
262

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của livekit/agents

Tất cả issue của livekit/agents

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.