OpenSource-Hub

agents

프레임워크

livekit/agents

실시간 음성 AI 에이전트를 구축하기 위한 프레임워크.

개요

LiveKit은 실시간 대화형 에이전트를 만들기 위한 오픈 소스 Python 프레임워크입니다. STT, LLM, TTS 통합, 작업 스케줄링, WebRTC 클라이언트, 전화 통합, RPC 데이터 교환 및 시맨틱 턴 감지를 지원합니다. 멀티 에이전트 핸드오프와 내장 테스트 프레임워크를 제공합니다.

README 미리보기

\n\n\n  \n  \n  \n\n\n\n\n\n\n[](https://pepy.tech/projects/livekit-agents)\n[](https://livekit.io/join-slack)\n[](https://twitter.com/livekit)\n[](https://deepwiki.com/livekit/agents)\n[](https://github.com/livekit/livekit/blob/master/LICENSE)\n\n\n\nLooking for the JS/TS library? Check out [AgentsJS](https://github.com/livekit/agents-js)\n\n## What is Agents?\n\n\n\nThe Agent Framework is designed for building realtime, programmable participants\nthat run on servers. Use it to create conversational, multi-modal voice\nagents that can see, hear, and understand.\n\n\n\n## Features\n\n- **Flexible integrations**: A comprehensive ecosystem to mix and match the right STT, LLM, TTS, and Realtime API to suit your use case.\n- **Integrated job scheduling**: Built-in task scheduling and distribution with [dispatch APIs](https://docs.livekit.io/agents/build/dispatch/) to connect end users to agents.\n- **Extensive WebRTC clients**: Build client applications using LiveKit's open-source SDK ecosystem, supporting all major platforms.\n- **Telephony integration**: Works seamlessly with LiveKit's [telephony stack](https://docs.livekit.io/sip/), allowing your agent to make calls to or receive calls from phones.\n- **Exchange data with clients**: Use [RPCs](https://docs.livekit.io/home/client/data/rpc/) and other [Data APIs](https://docs.livekit.io/home/client/data/) to seamlessly exchange data with clients.\n- **Semantic turn detection**: Uses a transformer model to detect when a user is done with their turn, helps to reduce interruptions.\n- **MCP support**: Native support for MCP. Integrate tools provided by MCP servers with one line of code.\n- **Builtin test framework**: Write tests and use judges to ensure your agent is performing as expected.\n- **Open-source**: Fully open-source, allowing you to run the entire stack on your own servers, including [LiveKit server](https://github.com/livekit/livekit), one of the most widely used WebRTC media servers.\n\n## Installation\n\nTo

FAQ (5)

문제 해결
worker 메모리 사용량을 줄이기 위해 LiveKit Agents EOT weight preloading을 어떻게 비활성화하나요?

PR #7580이 포함된 LiveKit Agents 릴리스로 업그레이드한 다음 LIVEKIT_AGENTS_PRELOAD_EOT=0을 설정하여 워커를 시작하세요. 허용되는 비활성화 값은 0, false, no, off입니다.

임시 셸 시작:

export LIVEKIT_AGENTS_PRELOAD_EOT=0
python your_worker.py

systemd 워커의 경우 다음을 추가하세요:

[Service]
Environment=LIVEKIT_AGENTS_PRELOAD_EOT=0

이렇게 하면 경량 VAD 프리로드는 유지하면서 ~240MB end-of-turn 모델 프리로드를 건너뜁니다. 로컬 TurnDetector가 나중에 실제로 사용되면 해당 가중치는 첫 사용 시 지연 로드됩니다. Linux forkserver에서는 EOT 프리로딩이 기본적으로 계속 활성화됩니다. 여러 워커가 한 호스트에서 실행되는 경우, 더 큰 num_idle_processes 값으로 하나의 AgentServer를 사용하면 워커마다 개별적으로 로드하는 대신 단일 복사본을 공유할 수도 있습니다.

원본 Issue #7579
문제 해결
LiveKit Agents THREAD executor가 셧다운 시 'job did not ack shutdown in time' 오류와 함께 멈추는 문제를 어떻게 해결하나요?

livekit-agents를 **1.8.3 이상**으로 업그레이드하세요. 이 종료 레이스 컨디션은 PR #7225에서 수정되었으며, 1.8.1을 포함한 버전에서는 유휴 상태의 사전 예열된 THREAD 러너가 종료 확인이 읽히기 전에 종료될 경우 멈출 수 있습니다.

pip install --upgrade 'livekit-agents>=1.8.3'

uv를 사용하는 경우:

uv add 'livekit-agents>=1.8.3'

그런 다음 워커를 재시작하고 유휴 러너가 초기화된 후 SIGTERM/Ctrl+C를 보내세요. 워커는 반복되는 job did not ack shutdown in time 오류 없이 즉시 종료되어야 합니다.

즉시 업그레이드할 수 없는 경우에는 이 멈춤 현상이 발생하지 않는 JobExecutorType.PROCESS를 사용하세요. 두 번째 신호를 보내는 것은 프로세스를 강제 종료시킬 뿐이며, graceful한 해결 방법이 아닙니다.

원본 Issue #7226
문제 해결
JobExecutorType.THREAD와 함께 LiveKit Agents를 사용할 때 "ResourceWarning: unclosed event loop"를 수정하는 방법

이 문제는 livekit-agents==1.8.4와 같은 영향을 받는 버전에서 발생합니다: _ProcClient.run()은 asyncio 이벤트 루프를 생성하지만 보류 중인 작업을 취소하거나, 비동기 제너레이터를 종료하거나, 스레드 루프를 재설정하거나, 루프를 닫지 않습니다.

**권장 해결 방법:** fix(ipc): close the job loop when the runner exits PR이 포함된 릴리스로 livekit-agents를 업그레이드하세요 (이슈 #7629 수정).

즉시 업그레이드할 수 없는 경우, _ProcClient.run()의 finally 블록을 패치하여 asyncio.run()과 동일한 종료 시퀀스를 수행하세요:

finally:
    loop_monitor.stop_monitoring(loop)
    try:
        pending = [t for t in asyncio.all_tasks(loop) if not t.done()]
        for task in pending:
            task.cancel()
        if pending:
            loop.run_until_complete(
                asyncio.gather(*pending, return_exceptions=True)
            )
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.run_until_complete(loop.shutdown_default_executor())
    finally:
        asyncio.set_event_loop(None)
        loop.close()

임시 해결 방법으로, 스레드 대신 프로세스 격리를 사용하세요:

server = AgentServer(job_executor_type=JobExecutorType.PROCESS)

수정 후에는 완료된 작업 루프가 is_closed() == True를 반환해야 하며, Python이 더 이상 ResourceWarning: unclosed event loop를 발생시키지 않아야 합니다.

원본 Issue #7629
문제 해결
LiveKit Agents에서 Muse STT 전사와 end-of-turn 이벤트가 지연되는 이유는 무엇이며, 오디오 지연은 어떻게 해결하나요?

근본 원인: SpeechStream._send_audio(livekit-plugins-meta)에서 페이싱 클럭(pacing_origin)은 스트림이 시작될 때가 아니라 첫 번째 패킷이 전송될 때 시작됩니다. _run이 먼저 _connect_ws()를 await하기 때문에, Muse websocket이 연결되는 동안 큐에 쌓인 오디오 프레임은 영구적인 오프셋을 발생시킵니다. 페이싱은 실제 시간보다 빠르게 전송하지 않고 백로그가 따라잡히지 않기 때문에, 스트림이 끝날 때까지 모든 패킷이 연결 시간만큼 늦게 전송됩니다(예: 연결 시간 300 ms ≈ 221 ms의 고정 지연). 이로 인해 트랜스크립트와 end-of-turn 이벤트가 동일한 시간만큼 지연됩니다.

수정 (PR #7890): 첫 번째 전송 시점 대신 스트림이 실행을 시작할 때 페이싱 클럭을 시작하도록 변경했습니다. 소켓이 준비되면 버퍼링된 백로그가 즉시 플러시되고, 이후 패킷은 이전과 같이 실제 시간에 맞춰 페이싱됩니다.

패치된 릴리스 전까지의 우회 방법: _input_ch에 아직 큐잉된 프레임이 남아 있는 동안에는 페이싱 슬립을 건너뛰도록 _send_audio를 monkey-patch합니다(버퍼가 모두 비워진 후에만 슬립).

영향이 확인된 버전: livekit-agents==1.8.6, livekit-plugins-meta==1.8.6, muse-voice-transcribe-1.0 사용 시.

원본 Issue #7876
문제 해결
최종 트랜스크립트에 아랍어, CJK, 데바나가리 또는 우르두어 구두점만 추가되는 경우 LiveKit Agents가 preemptive generation을 무효화하는 이유는 무엇인가요?

영향을 받는 버전: livekit-agents 1.8.3 및 main @ 57b3227. _transcripts_equivalent()는 split_words(..., ignore_punctuation=True)를 호출하지만, livekit/agents/tokenize/_basic_word.py의 문장 부호 제거 목록은 ASCII만 포함합니다. 따라서 아랍어 ، ؛ ؟, 우르두어 ۔, 데바나가리 ।, 전각 CJK ,。가 단어에 붙은 채로 남아 있어 최종 전사문이 달라진 것처럼 보이게 되고, preemptive generation invalidated ... because the transcript ... changed가 발생합니다.

기존 ASCII 문장 부호에 더해 모든 유니코드 문장 부호 범주(P*)를 제거하도록 토크나이저를 수정하세요:

import unicodedata

def _is_punctuation(char: str) -> bool:
    return (
        char in tokenize.tokenizer.PUNCTUATIONS
        or unicodedata.category(char).startswith("P")
    )

ignore_punctuation=True가 문자를 필터링하는 _basic_word.py의 모든 위치에서 이 검사를 사용하세요. 이렇게 하면 범주가 S인 $ 및 +와 같은 기호와 범주가 Mn인 아랍어 발음 구별 부호가 보존됩니다.

다음으로 확인하세요:

from livekit.agents.voice.agent_activity import _transcripts_equivalent

assert _transcripts_equivalent("مرحبا كيف حالك", "مرحبا، كيف حالك؟")
assert _transcripts_equivalent("你好 我很好", "你好,我很好。")
assert _transcripts_equivalent("आप कैसे हैं", "आप कैसे हैं।")

패치된 패키지를 다시 빌드하거나 재설치하세요. 업스트림 수정이 릴리스되면 pip install -U livekit-agents로 업그레이드하세요.

원본 Issue #7506