RealChar 实时 AI 角色系统部署实战指南:从环境配置、Python/Docker 安装到 Web 与终端多端对话
RealChar 实时 AI 角色系统部署实战指南:从环境配置、Python/Docker 安装到 Web 与终端多端对话
RealChar 是一个开源的实时 AI 角色(AI Companion)对话系统,允许你零代码创建、定制并实时与 AI 角色对话。本文以仓库根目录的 README.md 为主干,结合 .env.example、cli.py、main.py 与 websocket_routes.py 等源码,完整讲解 API Key 准备、Python 安装、Docker 部署、多端客户端使用,以及底层 LLM/语音模块的替换机制,帮助你从零搭建一套属于自己的实时 AI 角色对话服务。
项目简介与核心特性
RealChar 的口号是 "Create, customize and talk to your AI Character/Companion in realtime"。它把 LLM(大语言模型)、语音识别(Speech-to-Text)、语音合成(Text-to-Speech)、向量数据库与角色扮演提示词编排进一个代码仓库,让开发者或普通用户都能快速拥有一个“随时可聊”的 AI 角色。官方演示场景包括与 AI 版 Elon Musk 聊笼中格斗、与 AI 版 Raiden 讨论 AI 与"真实记忆"等,演示配置为:Web 端、GPT-4、ElevenLabs 语音克隆、Chroma 向量库、Google Speech-to-Text。
其核心特性可归纳为:
- 易用:无需编码即可创建自己的 AI 角色;
- 可定制:可自定义角色的性格、背景甚至声音;
- 实时:通过 WebSocket 实时对话,支持打断式语音交互;
- 多平台:支持 Web、终端(Terminal)与移动端(iOS 源码开源);
- 前沿 AI 技术栈:集成 OpenAI、Anthropic Claude 2、Chroma、Whisper、ElevenLabs 等;
- 模块化:LLM、语音模块均可替换,框架低耦合,适合作为 AI 工程入门项目。
技术栈概览
README 中给出的技术栈如下:
- Web:React JS、Vanilla JS、WebSockets(对应仓库中的 client/web 与 client/next-web 两个前端实现)
- Mobile:Swift、WebSockets(client/mobile/ios)
- Backend:FastAPI、SQLite、Docker
- Data Ingestion:LlamaIndex、Chroma(见 catalog_manager.py 使用
SimpleDirectoryReader加载角色背景数据并切分入库) - LLM Orchestration:LangChain、Chroma
- LLM:OpenAI GPT-3.5/4、Anthropic Claude 2,另可通过 Anyscale 使用 Llama-2 系列
- Speech to Text:本地 Whisper、OpenAI Whisper API、Google Speech-to-Text
- Text to Speech:ElevenLabs
- Voice Clone:ElevenLabs Voice Lab
前置准备:各类 API Key 与凭据
1. OpenAI API Token(必需)
应用通过 OpenAI API 获得语言模型能力,需要先取得 API Token:
- 在 OpenAI 官网注册账号;
- 登录后进入 API Keys 页面;
- 点击 "Create API Key" 生成新密钥;
- 复制并妥善保存;
- 写入环境变量,例如
export OPENAI_API_KEY=<your API key>。
如需改用 Azure OpenAI API,还需配置:
export OPENAI_API_TYPE=azure
# 如需使用早期版本 2023-03-15-preview
export OPENAI_API_VERSION=2023-03-15-preview
export OPENAI_API_BASE=https://your-base-url.openai.azure.com
export OPENAI_API_MODEL_DEPLOYMENT_NAME=gpt-35-turbo-16k
export OPENAI_API_EMBEDDING_DEPLOYMENT_NAME=text-embedding-ada-002
这些配置与 .env.example 中 Azure OpenAI 一节一一对应。
2. Anthropic Claude 2 API Token(可选)
如需使用 Claude 2:
- 在 Anthropic 官网注册并获取 API Keys;
- 点击 "Create Key" 生成密钥并妥善保存;
- 设置环境变量
export ANTHROPIC_API_KEY=<your API key>。
3. Google Cloud Speech-to-Text(可选)
若希望用 Google 语音识别替代本地 Whisper:
- 注册 GCP 账号并创建项目、启用 Speech-to-Text API;
- 将
google_credentials.json放到项目根目录; - 在
.env中将SPEECH_TO_TEXT_USE改为GOOGLE。
对应源码实现见 speech_to_text/init.py:get_speech_to_text() 依据 SPEECH_TO_TEXT_USE 环境变量(默认 LOCAL_WHISPER)在 GOOGLE、LOCAL_WHISPER、OPENAI_WHISPER 三个引擎间分发。
4. ElevenLabs API Key(文本转语音)
- 访问 ElevenLabs 官网注册账号,用于文字转语音与语音克隆;
- 在 Profile Setting 中获取 API Key 并妥善保存;
- 在
.env中配置:
ELEVEN_LABS_API_KEY=<api key>
同样地,text_to_speech/init.py 中的 get_text_to_speech() 根据 TEXT_TO_SPEECH_USE(默认 ELEVEN_LABS)在 ELEVEN_LABS、GOOGLE_TTS、UNREAL_SPEECH、EDGE_TTS 间分发。
安装与部署:Python 方式(完整步骤)
按 README 的 8 步流程操作:
Step 1. 克隆仓库
git clone https://github.com/Shaunwei/RealChar.git && cd RealChar
Step 2. 安装依赖:音频功能需要 portaudio 与 ffmpeg。
macOS:
brew install portaudio
brew install ffmpeg
Ubuntu:
sudo apt update
sudo apt install portaudio19-dev
sudo apt install ffmpeg
然后安装 Python 依赖:
pip install -r requirements.txt
注意:Python 版本需高于 3.10,否则 cli.py 会直接断言失败。
Step 3. 创建 SQLite 数据库(首次使用):
sqlite3 test.db "VACUUM;"
Step 4. 执行数据库迁移:
alembic upgrade head
这条命令会确保数据库 schema 与当前代码一致,README 明确建议每次拉取 main 分支后都执行一次。仓库 alembic/versions 下保存了从建表到添加 llm_settings、session_id、tools、language、feedback、memory 等全部迁移脚本。
Step 5. 配置 .env:
cp .env.example .env
然后按需填写 API Key 与模块选择项(详见下文“环境变量配置”一节)。
Step 6. 启动后端服务:
# 先构建 Web 前端(供 FastAPI 托管)
python cli.py web-build
python cli.py run-uvicorn
# 或直接使用 uvicorn
uvicorn realtime_ai_character.main:app
其中 python cli.py run-uvicorn 等价于以 --ws-ping-interval 60 --ws-ping-timeout 60 --timeout-keep-alive 60 参数启动 uvicorn(见 cli.py),这些参数对维持长时间 WebSocket 语音连接很关键。
Step 7. 启动客户端:
-
建议使用 GPT-4 获得更好的对话质量,并佩戴耳机以获得最佳音频体验(避免回声)。
-
方式一(默认):浏览器访问 http://localhost:8000(注意是 8000 而非 0.0.0.0:8000),且必须先执行
python cli.py web-build。从 main.py 可以看到,服务只有在检测到client/web/build目录存在时才会托管构建好的前端;否则会返回 static/404.html 提示用户构建。 -
方式二(React 开发模式):
cd client/web npm install npm start启动后浏览器自动打开 http://localhost:3000。
-
方式三(实验性 Next.js):
cd client/next-web npm install npm run dev同样默认运行在 http://localhost:3000。
-
终端客户端(可选):
python client/cli.py -
移动端(可选):用 Xcode 打开
client/mobile/ios/rac/rac.xcodeproj/project.pbxproj运行 iOS App。
Step 8. 选择一个角色开始对话。
提示:如果希望远程连接 RealChar 服务器,必须配置 SSL 才能建立音频连接。
可选方案:Docker 部署
Docker 方式适合快速上手(非 Apple M1/M2 芯片):
-
拉取官方镜像(或自行构建):
docker pull shaunly/real_char:latest docker tag shaunly/real_char:latest realtime-ai-character自行构建:
python cli.py docker-build该命令默认构建名为
realtime-ai-character的镜像,可用--name改名、--rebuild强制重建(见 cli.py)。 -
使用
.env运行容器:python cli.py docker-run底层执行
docker run --env-file .env --name realtime-ai-character -p 8000:8000 realtime-ai-character,也支持--db-file参数将宿主机数据库文件挂载进容器(见 cli.py)。若缺少.env文件,命令会给出黄色警告但继续运行。 -
访问 http://localhost:8000 开始对话,或在终端运行
python client/cli.py。
环境变量配置详解(.env.example 全解析)
.env.example 是配置系统的权威参考,逐段说明如下:
数据库
DATABASE_URL=sqlite:///./test.db
LLM 模型选择
LLM_MODEL_USE=gpt-3.5-turbo-16k
可选值包括:
gpt-4或gpt-3.5-turbo-16k(OpenAI)claude-instant-1或claude-2(Anthropic)meta-llama/Llama-2-7b-chat-hf/-13b-/-70b-(Anyscale 托管的 Llama-2)- 本地模型:设置
LOCAL_LLM_URL(如http://localhost:8001/v1)后,把模型名改为该 URL,即走 OpenAI 兼容的本地接口
llm/init.py 中的 get_llm() 按模型名前缀分发:gpt 开头用 OpenAI、claude 开头用 Anthropic、包含 localhost 用本地、包含 llama 用 Anyscale,其余抛 ValueError。README 建议 gpt-4 角色控制更佳、gpt-3.5-turbo-16k 速度更快。
Azure OpenAI(可选)
#OPENAI_API_TYPE=azure
#OPENAI_API_VERSION=2023-03-15-preview
#OPENAI_API_BASE=https://your-base-url.openai.azure.com
#OPENAI_API_MODEL_DEPLOYMENT_NAME=gpt-35-turbo
#OPENAI_API_EMBEDDING_DEPLOYMENT_NAME=text-embedding-ada-002
各类密钥
OPENAI_API_KEY=YOUR_API_KEY
ANTHROPIC_API_KEY=YOUR_API_KEY
ANYSCALE_ENDPOINT_API_KEY=
LOCAL_LLM_URL=
语音识别(Speech-to-Text)
# "LOCAL_WHISPER" 或 "OPENAI_WHISPER"(可选) 或 "GOOGLE"(可选)
SPEECH_TO_TEXT_USE=LOCAL_WHISPER
LOCAL_WHISPER_MODEL=base
GOOGLE_APPLICATION_CREDENTIALS=google_credentials.json
OPEN_AI_WHISPER_API_KEY=YOUR_API_KEY
LOCAL_WHISPER_MODEL 默认 base,可在 whisper.py 中调整为更小(更快)或更大(更准)的 Whisper 模型。
语音合成(Text-to-Speech)
# "ELEVEN_LABS" 或 "GOOGLE_TTS" 或 "UNREAL_SPEECH"
TEXT_TO_SPEECH_USE=ELEVEN_LABS
ELEVEN_LABS_API_KEY=YOUR_API_KEY
ELEVEN_LABS_USE_V2= # 有 V2 模型访问权限时改为 true
# 各角色的克隆声音 ID,留空则使用默认声音
ELON_MUSK_VOICE_ID=
LOKI_VOICE_ID=
RAIDEN_SHOGUN_AND_EI_VOICE_ID=
SAM_ALTMAN_VOICE_ID=
BRUCE_WAYNE_VOICE_ID=
STEVE_JOBS_VOICE_ID=
这里每个角色的 VOICE_ID 会覆盖角色配置文件中的默认 voice_id。例如 elon_musk/config.yaml 默认使用 ElevenLabs 男声 ErXwobaYiN019PkySvjV,女声默认 EXAVITQu4vr4xnSDxMaL;catalog_manager.py 在加载角色时检查 ELON_MUSK_VOICE_ID 这类环境变量并优先采用。
认证与对象存储(可选)
# 启用基础认证,留空则禁用
USE_AUTH=
FIREBASE_CONFIG_PATH=
GCP_STORAGE_BUCKET_NAME=
从 restful_routes.py 可见,设置 USE_AUTH 后服务会初始化 Firebase Admin,并以 Bearer Token 校验用户身份;头像上传、语音克隆音频等会写入 GCP_STORAGE_BUCKET_NAME 指定的 GCS 桶。
实验功能
# 留空禁用;开启后允许测试“说一半就被打断”的语句级对话
EXPERIMENT_CONVERSATION_UTTERANCE=
该开关对应 websocket_routes.py 中 [&] 中间转写消息的 utterance 级 LLM 响应逻辑。
LLM 链路追踪(LangSmith)
LANGCHAIN_TRACING_V2=false # 默认关闭
LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
LANGCHAIN_API_KEY=YOUR_LANGCHAIN_API_KEY
LANGCHAIN_PROJECT=YOUR_LANGCHAIN_PROJECT
网络搜索(可选)
# 优先级:SERPER_API_KEY > SERPAPI_API_KEY > GOOGLE_API_KEY
SERPER_API_KEY=
SERPAPI_API_KEY=
GOOGLE_API_KEY=
GOOGLE_CSE_ID=
其他
# 跳过 Chroma 数据重建;首次启动时会将角色背景文档写入向量库
OVERWRITE_CHROMA=true
在 main.py 中,OVERWRITE_CHROMA(默认 True)直接决定 CatalogManager.initialize(overwrite=...) 是否清空并重建 Chroma 集合。
深入理解:实时对话链路与模块化机制
WebSocket 实时对话流程
实时对话的核心是 websocket_routes.py 中的 /ws/{session_id} 端点,其链路大致如下:
- 客户端通过 URL 参数携带
llm_model、language、character_id、platform、token(可选)、use_search、use_quivr、use_multion建立连接; - 若启用
USE_AUTH,服务端校验 Firebase Token 并执行check_session_auth会话归属检查(websocket_routes.py); - 服务端按所选角色初始化 LLM 与 TTS,发送多语言问候语(内置 en-US、zh-CN、ja-JP 等 11 种语言问候文案,见 websocket_routes.py);
- 循环接收客户端消息:
- 文本消息:直接送入 LLM,token 通过回调实时推回前端,同时以
[end=<message_id>]标记结束; - 二进制音频:先由 STT 转写(
[&Speech]标记进入中间转写模式,[SpeechFinished]提交完整语句),再送入 LLM 生成回复,TTS 流式合成并推回音频;
- 文本消息:直接送入 LLM,token 通过回调实时推回前端,同时以
- 每轮对话写入
Interaction表(含session_id、角色、语言、平台、使用的工具如 search/quivr/multion、llm_config等字段),支持断线后通过ConversationHistory.load_from_db恢复历史(utils.py)。
角色系统与 Chroma 记忆
角色定义存放于 character_catalog 目录,每个角色一个子目录,包含 config.yaml 与 data/ 背景资料。以 elon_musk/config.yaml 为例,结构为:
character_id/character_name:角色标识与显示名;system:系统提示词,定义角色人设、语气与回复前缀(如Elon>),并声明“绝不承认自己是 AI”;user:用户提示词模板,内含{context}(向量检索出的背景知识)与{query}两个占位符;text_to_speech_use:该角色使用的 TTS 引擎;voice_id:默认声音 ID;visibility:可见性。
启动时 catalog_manager.py 会扫描角色目录,把 data/ 下的背景文档用 LlamaIndex SimpleDirectoryReader 读取,经 500 字符/100 重叠的 CharacterTextSplitter 切分后写入 Chroma(catalog_manager.py),在对话时作为上下文注入提示词。同时它每 30 秒从 SQLite 增量加载用户在 Web UI 创建的角色(load_sql_db_loop,catalog_manager.py)。
此外仓库还提供了 REST API 支持角色创建/编辑/删除、记忆查询/编辑、反馈提交、语音克隆与系统提示词生成等能力(restful_routes.py),是 Web UI 的完整后端支撑。
角色创建的社区生态
除内置角色外,character_catalog/community 目录收录了社区角色(如 Arnold Schwarzenegger、Keanu Reeves、Ion Stoica、The Cat 等),每个同样以 config.yaml + data/talk.csv 组织,可参考 character_catalog/README.md 了解如何自行制作角色。
Anyscale 与 LangSmith 集成
Anyscale(Llama-2)
在 .env.example 设置:
ANYSCALE_ENDPOINT_API_KEY=<your API Key>
即可在 Web UI 中默认使用 Anyscale Endpoint 托管的最大 Llama-2 模型 meta-llama/Llama-2-70b-chat-hf,也可在模型中改选 13b、7b 版本。
LangSmith(LLM 追踪)
编辑环境变量开启:
LANGCHAIN_TRACING_V2=false # 默认关闭
LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
LANGCHAIN_API_KEY=YOUR_LANGCHAIN_API_KEY
LANGCHAIN_PROJECT=YOUR_LANGCHAIN_PROJECT
配置后即可开箱即用地在 LangSmith 中观测对话链路。
常见问题与使用建议
- 音频回声:使用耳机对话以获得最佳音频效果;
- 前端 404:若访问 http://localhost:8000 看到 404 页面,说明未先执行
python cli.py web-build(参见 main.py 的降级逻辑); - 远程部署:音频连接依赖 WebSocket,远程访问必须配置 SSL;
- 角色无声音:检查
TEXT_TO_SPEECH_USE与对应角色的VOICE_ID环境变量是否配置正确; - 数据库变更:每次拉取最新代码后建议重新执行
alembic upgrade head。
结语
RealChar 把“LLM + 语音 + 向量记忆 + 角色扮演”完整串成了一条实时对话链路,既有 Web/终端/移动端多端接入,也有清晰的模块替换接口。按本文步骤完成环境配置与部署后,你可以:用 .env 一键切换 GPT-4/Claude-2/Llama-2 与 Whisper/ElevenLabs 等引擎;在 character_catalog 中通过 YAML 定义新角色;再借助 Chroma 注入背景知识实现更真实的角色扮演。深入阅读 contribute.md 与仓库源码,即可在此基础上继续扩展属于自己的 AI 角色应用。