operating-livekit-agents について
LiveKit エージェントの運用担当者向けスキルです。LiveKit Cloud へのデプロイ、本番動作、アップグレード、障害対応を扱い、ワーカープロセス、性能、可観測性についても説明します。
主な機能
- 01エージェントのバージョンをデプロイ・ロールバック
- 02シークレットと環境変数の管理
- 03ワーカーとリソースの事前ロードを理解
- 04プロバイダー障害と遅延の診断
- 05ログ、メトリクス、セッションの監視
活用シーン
- 01LiveKit Cloud へのエージェントのリリース
- 02本番のタイムアウトや無応答の調査
- 03セッション遅延とリソース読み込みの改善
- 04稼働中エージェントの更新と検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ livekit/ agent-skills --skill operating-livekit-agentsインストール後、Claude Code で/operating-livekit-agentsを入力して読み込まれたか確認します。
詳細
LiveKit エージェントの運用
エージェントの動作後に必要になるすべてのこと、つまり LiveKit Cloud へのバージョンのデプロイ、実際の負荷のもとで高速かつ安定して稼働させること、そして稼働中のものを壊さずに変更する方法について説明します。コマンドは lk agent の下にあります。フラグについては、このガイドを当てにするのではなく、lk agent --help と各サブコマンドのヘルプを確認してください。意図的にフラグの説明は繰り返していません。デプロイとオブザーバビリティのドキュメントは reading-livekit-docs にあります。
LiveKit Cloud へのデプロイ
フラグが変わっても、基本的な流れは変わりません。
- プロジェクトディレクトリは、CLI が書き出す設定ファイル(
livekit.toml)によってエージェントにひも付けられます。 そのディレクトリから実行するコマンドでは、ID を指定しなくてもエージェントが特定されます。 - エージェントはコンテナとしてデプロイされます。 CLI でプロジェクト用の Dockerfile を生成することも、事前にビルドしたイメージを用意することもできます。初回のデプロイ前に、コンテナの起動コマンドをローカルで実行してください(
lk agent start)。これは本番モードであり、本番用のログ出力とシャットダウン時のドレイン処理が行われます。devモードとは異なります。 - デプロイごとにバージョンが作成され、ロールアウトされます。
status、versions、logsを使って、現在稼働中のバージョンとロールアウトに失敗した理由を確認できます(ビルドログとデプロイログは別々です)。 - シークレットは環境変数として注入され、コードとは別に管理されます。 イメージに焼き込んだり、コミットしたりしないでください。シークレットを変更すると、エージェントが再起動します。
- ロールバックすると、以前のバージョンに戻ります。 即時に戻せるかどうかはプランによります。詳しくはドキュメントを確認してください。必要になる前に、ロールバックコマンドを把握しておきましょう。
デプロイ後は、見知らぬエージェントに使うのと同じツールで確認してください。ロールアウトには status、最初の数分間の動作には logs、そして実際の会話で検証します。running-livekit-simulations を使うと、ファイルに記述したシナリオをデプロイ済みエージェントの名前で指定して実行できます。これは、トラフィックを処理しているものが、意図したとおりにデプロイしたものかを確認する、最も手軽なエンドツーエンドテストです。
ワーカープロセスモデル
どちらの SDK も、親プロセスから起動されたワーカープロセス内でセッションを実行します。この仕組みを理解していないことが、本番環境でしか起きない不具合の最も一般的な原因です。
親プロセスで事前ウォームアップし、子プロセスがそれを継承します。 VAD やターン検出モデル、永続的なクライアントなど、読み取り専用で高コストなリソースは、SDK の事前ウォームアップ用フックを使って親プロセスで一度だけ読み込みます。各セッションはそれを再読み込みせずに継承します。この方法で共有するものはすべて、読み取り専用か、並行処理に安全である必要があります。子プロセスから親プロセスの状態を変更した場合の動作は未定義です。セッション固有の状態は事前ウォームアップせず、節約できるメモリよりも多くのメモリを消費するものも事前ウォームアップしないでください。親プロセスのメモリは、すべての子プロセスのメモリ使用量に含まれます。その後、子プロセスが事前ウォームアップ済みのインスタンスを実際に使っていることを確認してください。 よくある間違いは、モデルを事前ウォームアップしたのに、セッションのコードで新しいモデルを読み込んでしまうことです。その場合、事前ウォームアップは何の効果もなく、起動は遅いままです。
イベントループはフレームワークが管理します。 ワーカー内に新しい非同期ランタイムを作成してはいけません。また、結果を得るために、同期コンストラクターから非同期呼び出しをブロックしてはいけません。初期化に非同期処理が必要な場合は、すでに非同期のメソッドから初回使用時に遅延読み込みするか、オブジェクトの生成と、initialize を待機する手順を分けてください。イベントが別のループにバインドされている、ループがすでに実行中である、タスクが保留中に破棄された、再利用できない閉じたループに関するエラーが発生した場合、原因はほぼ間違いなくこのどちらかです。ランタイムを作成した箇所や、同期処理経路で何かを待機した箇所をたどってください。
プロバイダー
STT、TTS、LLM、VADなど、あらゆるバックエンドは本番環境で障害を起こします。レート制限、タイムアウト、過負荷、停止などが原因です。タイムアウトを設定してください。ハングする呼び出しは、すぐに失敗する呼び出しよりも深刻です。再試行する価値のある一時的な障害と、フォールバックやエスカレーションが必要な恒常的な障害を区別してください。無音ではなく、意味のある音声応答に切り替えてください。プロバイダーの応答時間を記録してください。レイテンシーの上昇は、通常、障害の最初の兆候です。
既存のエージェントにプロバイダーを追加する場合は、実装する前にSDKにプラグインが用意されていないか確認してください。ほかのプロバイダーを初期化、設定し、エラーを処理する際のコードベースの既存の方法に従ってください。同じパイプラインで設定を処理し、正常系の応答だけでなく、現実的なレイテンシーのもとでテストしてください。
パフォーマンス:変更する前に測定する
ユーザーが体感する指標は、最初の音声が出るまでの時間です。発話者が話し終えてから、エージェントが話し始めるまでの時間を指します。最適化する前に、接続、プロバイダーの初期化、初回推論、ツールの実行に分けて分析してください。長い通話ではコンテキストの増大に注意してください。履歴に上限がないと、ターンを重ねるごとに処理が遅くなります。
grepで見つけておきたいアンチパターン:
- 非同期コンテキストでの同期I/O。 ブロッキングするHTTP呼び出しやファイル読み込みが1つあるだけで、そのプロセス内のすべての並行処理で音声が止まります。
- 通話中の読み込み — セッション内で初回使用時にモデルを読み込んだり接続を確立したりすると、そのレイテンシーが発話者に聞こえてしまいます。事前ウォームアップまたはセッションのセットアップに移してください。
- 要約されない無制限のコンテキスト。
- 会話の段階に関係なくすべてのツールをグローバルに登録すること。 各定義が、すべてのLLM呼び出しでコストになります。
エンドポイント検出とターン検出は調整が必要なパラメーターであり、デフォルトのまま受け入れるものではありません。積極的すぎると、考えるために間を置いた人にエージェントがかぶせて話してしまいます。慎重すぎると、すべての返答が遅く感じられます。適切な設定はユースケースによって異なります。複雑な質問に対応するサポートエージェントには余裕が必要ですが、すぐに答えるアシスタントには速度が求められます。感覚ではなく、音声シミュレーションで測定してください(running-livekit-simulationsはターンテイキングと体感レイテンシーを採点します)。
シャットダウンとアップグレード
本番モードでは、サーバーは終了シグナルを受け取ると処理をドレインします。新しいジョブの受け付けを停止し、ドレインタイムアウトまでは進行中のジョブを完了させてから終了します。これを妨げる要因が2つあります。オーケストレーターの猶予期間がドレインタイムアウトより短いと、通話の途中で強制終了されます。両者の値を合わせてください。また、ジョブのライフサイクルに結び付いていない通話後の処理(状態の書き込み、イベントの公開、録音の確定処理)は中断されます。ドレイン中に完了するようにしてください。開発モードではドレインが行われないため、シャットダウンの動作はスタートモードでテストする必要があります。
SDKは頻繁に更新され、バージョン間で互換性が失われることもあります。バージョンを固定してください。アップグレード前にreading-livekit-docsで変更履歴を確認してください。ブランチ上でアップグレードしてテストスイートを実行し、実際に会話をしてからシミュレーションスイートを実行してください。実際の対話でしか現れないリグレッションもあります。デプロイ後の最初の数時間は、レイテンシーとエラー率を監視してください。
可観測性
本番環境のインシデントを謎ではなく、対処可能なものにするには、次の3点が重要です。
- すべてのログ行にセッションIDを含めることで、1回の通話を最初から最後まで追跡できます。
- 各フェーズの境界で時間を計測する — 接続、最初のユーザー発話、最初のエージェント応答などを計測することで、レイテンシーが発生したという事実だけでなく、どこで発生したのかを把握できます。
- プロバイダーのメトリクスをアプリケーションログとは別に追跡することで、調査を掘り下げなくてもプロバイダーの劣化を把握できます。
LiveKit Cloudでは、エージェントのログ、セッションの分析情報、トレーシングを利用できます。これらは独自の可観測性プロバイダーにエクスポートでき、利用可能な情報と接続方法はドキュメントで説明されています。
本番環境での障害のデバッグ
まず分類してから、再現します。
- ループとタスクのエラー — 前述のワーカープロセスモデルを確認します。ランタイムが作成された箇所や、同期パスが待機した箇所を特定します。
- プロバイダーのタイムアウトと劣化 — 単発のタイムアウトは一時的なものですが、レイテンシーの上昇傾向はシステム全体の問題です。プロバイダーの応答時間ログで原因を特定できます。
- ツールのサイレントな失敗 — ツールで発生したエラーがフレームワークに捕捉され、ユーザーには曖昧な返答が届くか、何も返っていません。モデルがユーザーに伝えられる内容を返すよう、ツールに明示的なエラー処理を追加する必要があります。
- 接続の不安定性 — SDK に組み込まれた再接続の仕組みを把握してから、さらにリトライを追加します。接続状態の変化をログに記録します。
次に、ローカル環境で再現します。debugging-livekit-agents を使って会話を再現し、testing-livekit-agents で原因をテストとして固定します。会話全体に関わる障害だった場合は、再発に気づかないまま見過ごさないよう、シナリオを追加します。
すでに稼働中のコードベースの変更
まず、プロジェクト独自のドキュメントと規約を確認します。一般的なガイドラインよりも、プロジェクト独自のものを優先してください。追加しようとしているものと似たモジュールを2つか3つ読み、記述を始める前に、それらがどのように初期化、設定、テストされ、設定パイプラインに組み込まれているかを確認します。既存のテスト用フィクスチャとモックのパターンを使い、並行する仕組みは作らないでください。同じことをする方法が2つあると、今後のすべてのコントリビューターを混乱させます。モックは境界(プロバイダーの呼び出しやデータベース)に配置し、モジュールの実際のロジックを実行してテストします。
関連スキル
- エージェントを最初から設計する:
building-livekit-agents - 問題のある会話をローカルで再現する:
debugging-livekit-agents - 本番環境のバグをテストとして固定する:
testing-livekit-agents - デプロイ済みエージェントに対するエンドツーエンドのチェック:
running-livekit-simulations - デプロイと可観測性のドキュメント、変更履歴:
reading-livekit-docs