LiveKit 语音 Agent 开场问候的设计与实现:从 greeting 提示词看 homepage 示例的提示词工程
2026/9/14 19:44:32 网站建设 项目流程

LiveKit 语音 Agent 开场问候的设计与实现:从 greeting 提示词看 homepage 示例的提示词工程

【免费下载链接】agentsA framework for building realtime voice AI agents 🤖🎙️📹项目地址: https://gitcode.com/GitHub_Trending/agen/agents

导读

本文以 examples/homepage/prompts/greeting.md 这份开场问候提示词为线索,完整讲解 LiveKit Agents 语音 Agent 中"开场白"的设计与落地:它如何被当作 Markdown 模板加载、在何时由谁触发、如何与系统指令(instructions)协作,以及如何用单元测试和 LLM 评估保证问候行为稳定可靠。读完本文,你将掌握在 LiveKit Agents 框架中管理提示词模板、编排on_enter开场流程、并为语音场景约束模型输出的完整实战方案。

greeting.md 到底在说什么

greeting.md全文是一句面向 LLM 的行为指令,它定义了语音 Agent 接通用户后的第一反应:

Greet the user warmly. Introduce yourself as an assistant who can help with LiveKit Agents and other LiveKit products. Ask them how familiar they are with LiveKit so you can tailor your answers.

拆解这句话,它同时完成了三件事:

  1. 情绪基调(warmly):开场要热情,对应语音客服场景对亲和力的要求;
  2. 身份介绍(who you are):自我介绍为"能够帮助 LiveKit Agents 及其他 LiveKit 产品"的助手;
  3. 信息收集(tailor your answers):主动询问用户对 LiveKit 的熟悉程度,从而动态调整后续回答的深度——这一点与 agents_sdks.md 中 "start simple, ask the user what they want to know, and only dive deep when they ask for it" 的分层讲解策略一脉相承。

值得注意的是,greeting.md不是系统指令(system prompt)的一部分,而是被单独加载、单独注入的一次性开场指令。理解这一点,是理解整个 homepage 示例提示词架构的关键。

提示词即模板:prompts 目录与加载机制

在 homepage 示例中,所有作者编写的"Agent 语言"都存放在 examples/homepage/prompts/ 目录下,以 Markdown 模板形式管理:

  • greeting.md——开场问候指令;
  • agents_sdks.md——系统指令(system prompt),内含角色设定、知识库与 FAQ;
  • user_away.md——用户长时间沉默后的"回访"指令。

加载机制实现在 examples/homepage/prompts/init.py,它用importlib.resources.files按模板名读取同包下的.md文件,并通过functools.cache缓存结果:

@cache def prompt(name: str) -> str: resource = files(__package__).joinpath(f"{name}.md") if not resource.is_file(): raise FileNotFoundError(f"no prompt named {name!r}") return resource.read_text(encoding="utf-8")

这段实现有几个值得借鉴的设计点:

  • 模板与代码分离:提示词是可朗读、可评审、可单独修改的 Markdown 文件,不需要改动 Python 代码;
  • 缓存加载@cache保证同名模板进程内只读一次文件,避免每个会话重复 I/O;
  • 显式失败:模板名不存在时抛出FileNotFoundError,让拼写错误在启动期即暴露,而不是静默传入空指令。

在 examples/homepage/agent.py 中,greetingagents_sdks两个模板在模块加载时即被读取:

INSTRUCTIONS = prompt("agents_sdks") GREETING = prompt("greeting")

这种"启动时加载、运行时复用"的模式,让提示词内容对 Agent 逻辑完全透明。

开场白在哪里触发:on_enter 与 generate_reply

greeting.md 的实际消费点在Assistant.on_enter。在 examples/homepage/agent.py 中:

async def on_enter(self): await self.session.generate_reply( instructions=GREETING, allow_interruptions=True, )

on_enter是 LiveKit Agents 中 Agent 每次进入会话时的生命周期钩子,在这里主动调用session.generate_reply生成第一轮回复。两个参数值得展开:

  • instructions=GREETING:本次生成临时注入的指令。它只作用于这次开场回复,不会污染系统指令INSTRUCTIONS。这意味着你可以为每一轮生成单独定制上下文,而系统指令保持稳定的"角色底座";
  • allow_interruptions=True:允许用户在开场白尚未说完时打断。对语音场景这是关键体验设计——若用户一接通就直接提问,Agent 不应机械地把整段问候念完,而应立刻响应。

由此形成的完整调用链是:prompt("greeting")加载模板 →GREETING常量 →on_enter中作为临时指令注入 →generate_reply产出首轮语音回复。greeting.md 的"温暖开场 + 自我介绍 + 询问熟悉度"正是在这一链路中被执行的。

语音场景的提示词约束:为什么问候必须"简短口语化"

问候提示词的设计不能脱离语音输出媒介。在 homepage 示例中,TTS 使用了 Fish Audio S2.1 Pro 的 expressive 模式(见 agent.py 的tts_model/tts_voice配置),并通过tts_text_transforms挂载了 Markdown/emoji 过滤与 LiveKit 发音过滤器(agent.py)。这些技术手段能修正"怎么说",但"说什么"仍需提示词层面约束。

系统指令 agents_sdks.md 为此立下了两条硬性规矩:

  1. 长度克制:除非用户追问细节,否则每次回复不超过两句话,"DON'T WANT TO HOG THE CONVERSATION"(不要霸占对话);
  2. 零符号输出:不使用复杂排版、标点、emoji、星号等符号,全部使用缩略形式(you're、it's、don't)以贴近自然口语。

greeting.md 与之一致:问候只包含"热情招呼 + 身份 + 一个问题"三个要素,没有冗余铺垫。这印证了语音提示词工程的核心原则——在提示词层面就把"可朗读性"写进去,而不是依赖后处理补救

开场问候在会话编排中的位置:与其他提示词的协作

homepage 示例展示了"一份模板各司其职"的编排思想,三种提示词覆盖了会话的三个阶段:

提示词模板注入时机作用
greetingon_enter(首轮)温暖开场、自我介绍、询问熟悉度以分层作答
agents_sdks系统指令(全程常驻)角色设定、LiveKit 知识库、语音输出约束
user_away用户静默超时事件回访确认用户是否还在

其中user_away的注入路径与 greeting 完全相同:在 examples/homepage/behaviors/user_away.py 中监听user_state_changed事件,当用户状态变为away(默认静默 15 秒,AgentSession选项user_away_timeout)时,同样以generate_reply(instructions=CHECK_IN_INSTRUCTIONS, allow_interruptions=True)的方式注入 user_away.md 的指令。

这说明generate_reply(instructions=...)是 homepage 示例中"临时指令注入"的统一入口:开场用、回访也用。greeting.md 不是孤立的一句话,而是这套"常驻系统指令 + 按需临时指令"提示词架构的一个实例。

如何验证问候行为:单元测试与 LLM 评估

提示词是行为契约,必须有测试兜底。homepage 示例提供了两层保障:

单元测试层(tests/unit/test_prompts.py)验证模板加载机制本身:对agents_sdksgreetinguser_away三个模板逐一断言prompt(name)能返回非空内容;对不存在的模板名断言抛出FileNotFoundError。这保证了任何一次提示词改动都不会引入"空指令"或"加载失败"。

评估测试层(tests/evals/test_agent_behavior.py)用真实的 LLM(如openai/gpt-4.1-mini作为 judge)验证行为效果。其中test_offers_assistance与 greeting.md 直接对应:向 Agent 输入 "Hello",然后用 judge LLM 按意图清单(友好问候、介绍自己是可协助 LiveKit 的助手、允许适度寒暄但不过度打扰)评估首轮回复,并要求事件流中除助手消息外没有多余事件。

result = await session.run(user_input="Hello") await ( result.expect.next_event() .is_message(role="assistant") .judge( judge_llm, intent=textwrap.dedent("""\ Greets the user in a friendly manner. ... """), ) )

该文件还覆盖了与问候协作相关的行为:Agent SDK 问题直接内联回答(无需工具)、其他产品问题触发lookup_product工具调用、未知个人信息拒绝回答、有害请求礼貌拒绝。这些评估与 greeting.md 共同定义了"一个合格开场 Agent"的完整行为边界。

本地运行与自定义实践

在仓库根目录安装工作区依赖后,可以按 examples/homepage/README.md 的方式本地体验:

uv sync --all-extras --dev # 从仓库根目录执行 uv run agent.py console # 本地控制台会话

连接 LiveKit Cloud 以便接入前端或电话会话则使用uv run agent.py dev。开发依赖安装完成后,可用python -m pytest跑快速单元测试,用python -m pytest -m evals跑依赖LIVEKIT_API_KEYLIVEKIT_API_SECRET的在线评估套件。

如果想自定义开场白,只需修改 examples/homepage/prompts/greeting.md 的内容——比如调整自我介绍口径、增加品牌话术或改变询问方式——无需改动任何 Python 代码。修改后跑一遍test_prompts.py确认模板可加载,再用 evals 套件验证新的问候仍符合友好、克制的行为契约。如果需要新增一个"开场即介绍特定产品"的场景,也可以仿照该文件新建模板,并在on_enter中通过prompt("新模板名")注入,这正是提示词即模板设计带来的扩展性。

小结

从一句看似简单的 greeting.md 出发,可以看清 homepage 示例完整的提示词工程链路:Markdown 模板管理加载(prompts/init.py)→ 启动期读取(agent.py)→on_enter生命周期钩子注入(agent.py)→ 语音输出约束(agents_sdks.md)→ 单元测试与 LLM 评估闭环(test_prompts.py、test_agent_behavior.py)。这一模式不仅适用于开场白,也被 user_away.py 复用于用户回访场景,是构建可维护、可评估的语音 Agent 提示词体系的可直接复用的范本。

【免费下载链接】agentsA framework for building realtime voice AI agents 🤖🎙️📹项目地址: https://gitcode.com/GitHub_Trending/agen/agents

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询