Skip to content

用于 ADK 的 LiveKit 运行器

Supported in ADKPython v2.9.0Experimental

ADK 提供了 LiveKitRunner 类,让你可以通过 LiveKit(一个用于 WebRTC 和 SIP 电话的开源平台)来运行实时智能体。此 集成充当传输适配器,负责处理音频和视频的捕获、播放、 打断、字幕和呼叫控制,因此你的 ADK 智能体无需任何改动即可从浏览器、 电话或游戏客户端访问。

使用场景

你可以在多种场景中使用 LiveKit,包括浏览器应用、移动应用、SIP 电话呼叫、游戏和沉浸式客户端。

浏览器和移动应用

智能体作为普通参与者加入房间,因此任何 LiveKit 客户端 SDK 都可以与之通信。 该连接器在 LiveKit 自身组件绑定的频道上发布字幕和说话状态, 因此这些组件无需额外配置即可与 ADK 智能体配合使用:

LiveKit 资源 ADK 智能体获得的能力
Client SDKs 浏览器、Swift、Android、Flutter、React Native、Unity、C++、Rust 和 ESP32
UI components 预构建的语音助手小组件,支持 React、SwiftUI、Compose 和 Flutter
Starter apps 各平台可运行的应用,以及 Agents Playground,无需前端即可与智能体对话

电话呼叫

SIP 呼叫方是普通的 LiveKit 参与者,因此一旦配置了 呼入中继和 分发规则指向你的 worker, 电话呼叫就能到达智能体。

呼叫方的身份在对方开口说话之前就已存入 ADK 会话状态,因此函数工具可以像读取其他状态值一样读取它:

from google.adk.tools.tool_context import ToolContext

async def greet_by_account(tool_context: ToolContext) -> str:
  """在问候之前查找呼叫方信息。"""
  number = tool_context.state.get("livekit_caller_phone_number")  # '+15105550100'
  if not number:
    return "I could not see the number you are calling from."
  return await crm.lookup(number)  # 你自己的客户查询逻辑

连接器将键盘输入缓冲为单个轮次,因此六位数的账号会作为一次输入到达,而不是被打断六次。

游戏和沉浸式客户端

LiveKit 的 Unity SDK 为 Unity 应用添加了实时音频、 视频和数据通道,由 LiveKit Cloud 或你自建的服务器提供支持。将 ADK 智能体放入房间,玩家就可以与一个同时作用于 游戏世界的角色进行对话,例如语音驱动的 NPC 或游戏内助手:

from google.adk.integrations.livekit import current_call
from google.adk.tools.tool_context import ToolContext

async def open_the_door(door_id: str, tool_context: ToolContext) -> str:
  """在游戏世界中打开一扇门。"""
  call = current_call(tool_context)
  return await call.perform_rpc(method="open_door", payload=door_id)

客户端返回的任何内容都会成为模型叙述的工具结果,因此智能体会描述实际发生了什么。在 Unity 客户端上,注册一个 RPC 方法即可;ADK 负责管理 对话、工具调用和会话。

快速开始

  • ADK >= 2.9.0,需要安装 livekit 额外依赖。
  • 实时模型的凭据。
  • LiveKit 服务器,自建或使用 LiveKit Cloud。两者暴露相同的 API,因此 同一份 worker 代码可以同时适用于两者。本地开发时,运行 livekit-server --dev。
  • 在环境中设置 LIVEKIT_URL、LIVEKIT_API_KEY 和 LIVEKIT_API_SECRET。
pip install "google-adk[livekit]" "livekit-agents>=1.4"

从你已有的智能体开始。添加 LiveKitToolset() 可为其提供呼叫控制功能,如 挂断或转接呼叫方。该工具集仅在有呼叫时激活,因此 adk web 仍然可以不变地运行智能体:

from google.adk.agents import Agent
from google.adk.integrations.livekit import LiveKitToolset
from google.adk.runners import InMemoryRunner

root_agent = Agent(
    model="gemini-live-2.5-flash-native-audio",
    name="support_agent",
    instruction="You help customers troubleshoot their home internet.",
    tools=[check_line_status, LiveKitToolset()],  # check_line_status 是你自己的工具
)
runner = InMemoryRunner(agent=root_agent, app_name="support")

要连接智能体,请将一个已连接的房间传递给 runner。在生产环境中,你运行一个 worker,LiveKit 每次呼叫时分发一次,同一份代码同时服务于浏览器和 电话。

from google.adk.integrations.livekit import LiveKitRunner
from livekit.agents import AgentServer
from livekit.agents import cli
from livekit.agents import JobContext

server = AgentServer()


@server.rtc_session(agent_name="support")
async def entrypoint(ctx: JobContext) -> None:
  """将一次分发的呼叫桥接到 ADK 智能体。"""
  await ctx.connect()
  # LiveKit 没有 ADK 用户或会话 ID。示例从任务元数据中读取它们。
  await LiveKitRunner(
      runner=runner, room=ctx.room, user_id="live-user", session_id=ctx.room.name
  ).start()


if __name__ == "__main__":
  cli.run_app(server)

部署 worker

worker 主动连接到 LiveKit 服务器,并通过同一连接接收分发的任务,因此它需要出站网络访问,不需要公网地址,也不需要负载均衡器。 除此之外,它是一个普通的 ADK 容器,部署方式与任何 ADK 智能体相同。将 入口点指向你的 worker 模块:

CMD ["python", "-m", "support_agent.livekit_worker", "start"]

Agents CLI 根据你 pyproject.toml 中的 deployment_target 将该容器部署到 Agent Runtime、Cloud Run 或 GKE。参见 使用 Agents CLI 部署,或手动部署到 Cloud Run 或 GKE。

Cloud Run 探测 $PORT,而 worker 在固定端口上提供健康检查端点,因此 请确保两者匹配。在创建服务器时从环境变量读取端口:

import os

server = AgentServer(port=int(os.environ["PORT"]))

使用 --port=8081 部署也能达到相同效果,因为这是 worker 在 生产环境中使用的端口。worker 在呼叫之间也会闲置,因此请使用 --no-cpu-throttling 和 --min-instances=1 以保持它持续接受分发任务。

每个分发的任务都在独立的进程中运行,因此请使用持久化的 会话服务。InMemoryRunner 类在呼叫之间不持久化任何数据。

相关资源