EmbedChain项目实战:基于LiveKit构建具备记忆功能的语音助手
引言
在现代人工智能应用中,结合语音交互和长期记忆能力的智能助手正变得越来越重要。本文将详细介绍如何利用EmbedChain项目中的技术栈,结合LiveKit实时通信平台,构建一个具备记忆功能的旅行规划语音助手。
技术栈概述
本项目主要整合了以下核心技术组件:
- LiveKit:提供实时音视频通信能力
- Deepgram:高质量的语音转文本服务
- OpenAI:强大的语言模型处理能力
- Mem0:长期记忆存储和检索系统
- EmbedChain:作为基础框架整合各组件
环境准备
在开始开发前,需要完成以下准备工作:
1. 安装核心依赖
pip install livekit livekit-agents livekit-plugins-silero livekit-plugins-deepgram livekit-plugins-openai
2. 安装记忆组件
pip install mem0ai
3. 配置API密钥
创建.env
文件并配置以下环境变量:
LIVEKIT_URL=你的LiveKit服务地址
LIVEKIT_API_KEY=你的LiveKit API密钥
LIVEKIT_API_SECRET=你的LiveKit API密钥
DEEPGRAM_API_KEY=你的Deepgram API密钥
MEM0_API_KEY=你的Mem0 API密钥
OPENAI_API_KEY=你的OpenAI API密钥
核心架构解析
1. 初始化模块
import asyncio
import logging
import os
from typing import List, Dict, Any, Annotated
import aiohttp
from dotenv import load_dotenv
from livekit.agents import (
AutoSubscribe,
JobContext,
JobProcess,
WorkerOptions,
cli,
llm,
metrics,
)
from livekit import rtc, api
from livekit.agents.pipeline import VoicePipelineAgent
from livekit.plugins import deepgram, openai, silero
from mem0 import AsyncMemoryClient
# 加载环境变量
load_dotenv()
# 配置日志记录
logger = logging.getLogger("memory-assistant")
logger.setLevel(logging.INFO)
# 定义全局用户ID
USER_ID = "voice_user"
# 初始化Mem0客户端
mem0 = AsyncMemoryClient()
这部分代码负责:
- 导入必要的Python模块
- 加载环境配置
- 设置日志记录系统
- 初始化记忆存储客户端
2. 记忆增强功能
async def _enrich_with_memory(agent: VoicePipelineAgent, chat_ctx: llm.ChatContext):
"""利用记忆增强对话上下文"""
if not chat_ctx.messages:
return
# 存储用户消息到记忆系统
user_msg = chat_ctx.messages[-1]
await mem0.add(
[{"role": "user", "content": user_msg.content}],
user_id=USER_ID
)
# 语义搜索相关记忆
results = await mem0.search(
user_msg.content,
user_id=USER_ID,
)
# 用检索到的记忆增强上下文
if results:
memories = ' '.join([result["memory"] for result in results])
logger.info(f"使用记忆增强: {memories}")
rag_msg = llm.ChatMessage.create(
text=f"相关记忆: {memories}\n",
role="assistant",
)
# 修改聊天上下文
chat_ctx.messages[-1] = rag_msg
chat_ctx.messages.append(user_msg)
该功能模块实现了:
- 对话历史的持久化存储
- 基于语义的相关记忆检索
- 上下文增强机制
3. 主程序入口
def prewarm_process(proc: JobProcess):
# 预加载语音活动检测模型
proc.userdata["vad"] = silero.VAD.load()
async def entrypoint(ctx: JobContext):
# 连接LiveKit房间
await ctx.connect(auto_subscribe=AutoSubscribe.AUDIO_ONLY)
# 等待参与者加入
participant = await ctx.wait_for_participant()
# 定义初始系统上下文
initial_ctx = llm.ChatContext().append(
role="system",
text=(
"""
你是一个乐于助人的语音助手。
你是一位名叫George的旅行向导,将帮助用户规划他们梦想中的旅行。
你应该帮助用户规划各种冒险活动,如工作度假、家庭旅行或独自背包旅行。
你应该注意不要建议任何危险、非法或不适当的内容。
你可以记住过去的互动,并用它们来指导你的回答。
使用语义记忆检索来提供上下文相关的响应。
"""
),
)
# 创建具备记忆功能的语音管道代理
agent = VoicePipelineAgent(
chat_ctx=initial_ctx,
vad=silero.VAD.load(),
stt=deepgram.STT(),
llm=openai.LLM(model="gpt-4o-mini"),
tts=openai.TTS(),
before_llm_cb=_enrich_with_memory,
)
# 启动代理并发送初始问候
agent.start(ctx.room, participant)
await agent.say(
"你好!我是George。我能帮你规划即将到来的旅行吗?",
allow_interruptions=True
)
# 运行应用
if __name__ == "__main__":
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint, prewarm_fnc=prewarm_process))
主程序实现了:
- 实时通信连接管理
- 语音代理初始化
- 对话流程控制
- 异常处理机制
完整实现代码
以下是整合了所有功能的完整实现:
import asyncio
import logging
import os
from typing import List, Dict, Any, Annotated
import aiohttp
from dotenv import load_dotenv
from livekit.agents import (
AutoSubscribe,
JobContext,
JobProcess,
WorkerOptions,
cli,
llm,
metrics,
)
from livekit import rtc, api
from livekit.agents.pipeline import VoicePipelineAgent
from livekit.plugins import deepgram, openai, silero
from mem0 import AsyncMemoryClient
# 加载环境变量
load_dotenv()
# 配置日志记录
logger = logging.getLogger("memory-assistant")
logger.setLevel(logging.INFO)
# 定义全局用户ID
USER_ID = "voice_user"
# 初始化Mem0记忆客户端
mem0 = AsyncMemoryClient()
def prewarm_process(proc: JobProcess):
# 预加载语音活动检测模型
proc.userdata["vad"] = silero.VAD.load()
async def entrypoint(ctx: JobContext):
# 连接LiveKit房间
await ctx.connect(auto_subscribe=AutoSubscribe.AUDIO_ONLY)
# 等待参与者加入
participant = await ctx.wait_for_participant()
async def _enrich_with_memory(agent: VoicePipelineAgent, chat_ctx: llm.ChatContext):
"""利用记忆增强对话上下文"""
if not chat_ctx.messages:
return
# 存储用户消息到记忆系统
user_msg = chat_ctx.messages[-1]
await mem0.add(
[{"role": "user", "content": user_msg.content}],
user_id=USER_ID
)
# 语义搜索相关记忆
results = await mem0.search(
user_msg.content,
user_id=USER_ID,
)
# 用检索到的记忆增强上下文
if results:
memories = ' '.join([result["memory"] for result in results])
logger.info(f"使用记忆增强: {memories}")
rag_msg = llm.ChatMessage.create(
text=f"相关记忆: {memories}\n",
role="assistant",
)
# 修改聊天上下文
chat_ctx.messages[-1] = rag_msg
chat_ctx.messages.append(user_msg)
# 定义初始系统上下文
initial_ctx = llm.ChatContext().append(
role="system",
text=(
"""
你是一个乐于助人的语音助手。
你是一位名叫George的旅行向导,将帮助用户规划他们梦想中的旅行。
你应该帮助用户规划各种冒险活动,如工作度假、家庭旅行或独自背包旅行。
你应该注意不要建议任何危险、非法或不适当的内容。
你可以记住过去的互动,并用它们来指导你的回答。
使用语义记忆检索来提供上下文相关的响应。
"""
),
)
# 创建具备记忆功能的语音管道代理
agent = VoicePipelineAgent(
chat_ctx=initial_ctx,
vad=silero.VAD.load(),
stt=deepgram.STT(),
llm=openai.LLM(model="gpt-4o-mini"),
tts=openai.TTS(),
before_llm_cb=_enrich_with_memory,
)
# 启动代理并发送初始问候
agent.start(ctx.room, participant)
await agent.say(
"你好!我是George。我能帮你规划即将到来的旅行吗?",
allow_interruptions=True
)
# 运行应用
if __name__ == "__main__":
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint, prewarm_fnc=prewarm_process))
关键特性解析
- 上下文感知对话:系统能够记住过去的对话内容,并在适当的时候引用
- 实时语音处理:低延迟的语音识别和合成能力
- 语义记忆检索:基于内容而非关键词的记忆检索机制
- 领域专业化:专注于旅行规划场景的对话优化
运行与测试
要运行这个语音助手,请执行以下步骤:
- 确保所有依赖已正确安装
- 配置好
.env
文件中的API密钥 - 检查音频设备是否正常工作
- 运行主程序:
python mem0-livekit-voice-agent.py start
- 使用LiveKit客户端连接并与助手交互
开发最佳实践
-
记忆管理策略:
- 定期清理过时记忆
- 对敏感信息进行脱敏处理
- 实现记忆的版本控制
-
性能优化:
- 使用异步I/O提高并发能力
- 实现记忆缓存机制
- 优化语音处理流水线
-
用户体验优化:
- 设计自然的对话流程
- 实现优雅的错误恢复机制
- 提供明确的对话边界指示
调试技巧
- 日志记录配置:
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
- 开发模式运行:
python mem0-livekit-voice-agent.py dev
- 关键检查点:
- 语音活动检测准确性
- 记忆存储和检索的正确性
- 上下文管理的连贯性
总结
本文详细介绍了如何使用EmbedChain项目结合LiveKit等组件构建具备记忆功能的语音助手。这种架构不仅适用于旅行规划场景,经过适当调整后,也可应用于客服、教育、医疗等多个领域。关键在于理解记忆增强机制和实时语音处理的整合方式,这将为构建更智能的人机交互系统奠定基础。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考