Qwen3-4B-Thinking-GPT-5-Codex-Distill教程:Chainlit前端支持语音输入输出
想不想让一个能理解代码、擅长推理的AI助手,不仅能看懂你写的文字,还能听懂你说的话,并用语音回答你?今天,我们就来搭建这样一个智能对话系统。它基于一个经过GPT-5-Codex数据微调的强大模型,并配上一个支持语音交互的现代化前端界面。整个过程清晰明了,即使你之前没怎么接触过AI部署,也能跟着一步步实现。
1. 项目核心:认识我们的AI大脑
在开始动手之前,我们先来了解一下这个系统的核心——AI模型。它决定了整个系统的“智商”和“能力”。
1.1 模型简介:Qwen3-4B-Thinking-GPT-5-Codex-Distill
我们使用的模型是 Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF。这个名字有点长,我们来拆解一下它的“身世”:
- 基础模型:它源自 Qwen3-4B-Thinking-2507,这是一个拥有40亿参数、专门为复杂推理和思考链任务设计的模型。你可以把它想象成一个天生逻辑能力很强的“大脑”。
- 能力强化:这个“大脑”又在 GPT-5-Codex 的1000个高质量示例上进行了微调。GPT-5-Codex 以其卓越的代码理解和生成能力闻名。这就好比给这个逻辑大脑进行了一次“代码特训”,让它不仅会推理,还精通编程逻辑,能更好地理解代码问题、生成代码片段、解释技术概念。
- 部署格式:模型以 GGUF 格式提供。这是一种高效、跨平台的模型文件格式,特别适合在各种硬件上(包括CPU)进行推理,部署起来非常方便。
简单来说,我们得到的是一位 “逻辑推理专家” 和 “代码编程高手” 的结合体。它非常适合用来解答技术问题、协助编程、进行代码审查或者学习新的技术概念。
1.2 技术栈:vLLM与Chainlit
为了让这个“大脑”活起来并和我们愉快地交流,我们需要两样工具:
整个流程就是:你在Chainlit的网页界面上用语音或文字提问 -> Chainlit将问题发送给vLLM服务 -> vLLM驱动模型思考并生成答案 -> 答案返回给Chainlit,以文字和语音两种形式呈现给你。
2. 环境准备与快速验证
假设你的模型已经通过vLLM部署好了(通常服务会运行在 http://localhost:8000 这样的地址)。我们首先需要确认服务是正常的,然后才能让Chainlit去连接它。
2.1 验证模型服务状态
打开终端,运行以下命令来检查vLLM服务的日志,确认模型是否加载成功:
# 查看服务日志,通常日志会输出到指定文件
cat /root/workspace/llm.log
如果服务部署成功且模型加载完毕,你会在日志中看到类似下面的关键信息:
- Uvicorn running on http://0.0.0.0:8000 (服务启动)
- Model loaded successfully 或相关模型名称 (模型加载成功)
- 没有持续的报错信息。
看到这些,就说明你的AI“大脑”已经在线并准备就绪了。
2.2 使用Chainlit进行基础测试
在配置语音功能前,我们先确保最基本的文字对话是通的。创建一个Python脚本,比如叫 app.py。
# app.py
import chainlit as cl
from openai import OpenAI
# 配置连接到本地的vLLM服务
# 注意:vLLm的OpenAI API兼容端点通常是 /v1
client = OpenAI(
base_url="http://localhost:8000/v1", # 你的vLLM服务地址
api_key="token-abc123" # vLLM服务如果没设置API密钥,可以随意填写一个非空字符串
)
@cl.on_message
async def main(message: cl.Message):
"""
处理用户消息的核心函数。
"""
# 创建一个消息对象,显示“思考中…”提示给用户
msg = cl.Message(content="")
await msg.send()
# 调用vLLM服务(兼容OpenAI API)
response = client.chat.completions.create(
model="Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF", # 你的模型名称
messages=[
{"role": "system", "content": "你是一个乐于助人且精通编程和逻辑推理的AI助手。"},
{"role": "user", "content": message.content}
],
stream=True, # 启用流式输出,实现打字机效果
)
# 流式处理回复内容
for chunk in response:
if chunk.choices[0].delta.content is not None:
token = chunk.choices[0].delta.content
await msg.stream_token(token)
# 消息流结束,更新消息状态
await msg.update()
if __name__ == "__main__":
# 启动Chainlit应用
cl.run(app, host="0.0.0.0", port=7860)
在终端运行这个应用:
chainlit run app.py
然后在浏览器中打开 http://localhost:7860,你应该能看到Chainlit的聊天界面。尝试输入一个问题,比如“用Python写一个快速排序函数”,如果能看到模型流畅地生成代码和解释,那么基础通信就成功了。
3. 实现语音输入与输出功能
Chainlit最酷的功能之一就是开箱即用的语音支持。启用它非常简单,几乎不需要额外代码。
3.1 启用前端语音功能
Chainlit的语音功能主要通过前端配置开启。我们只需要在项目根目录下创建一个 chainlit.md 文件,这个文件是应用的用户须知,但同时也承载配置。
在 chainlit.md 文件中,我们可以在开头添加特定的元数据来启用语音:
# Welcome to My AI Assistant! 🎙️
这个助手基于强大的Qwen3-4B-Thinking模型,并经过GPT-5-Codex数据微调,擅长代码和推理任务。
<!– 启用语音输入和输出 –>
<font size=2>features: [“audio”]</font>
你可以:
1. 点击输入框旁的**麦克风图标**进行语音提问。
2. 助手回复后,可以点击回复气泡旁的**扬声器图标**收听语音回答。
开始对话吧!
关键就是那一行 features: [“audio”],它告诉Chainlit前端加载音频模块。
3.2 完善应用代码以支持语音
我们的 app.py 代码几乎不需要为语音做特殊改动,因为Chainlit会自动处理音频的录制、转文本(语音识别)、文本转语音(语音合成)等流程。但是,为了让体验更好,我们可以稍作优化:
# app.py (优化版)
import chainlit as cl
from openai import OpenAI
import asyncio
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="token-abc123"
)
@cl.on_message
async def main(message: cl.Message):
"""
处理用户消息,同时支持文本和语音输入。
Chainlit会自动将用户语音转换为文字传入 message.content。
"""
# 检查是否是语音输入(Chainlit可能会在消息中附加音频信息,但内容已是文本)
# 这里我们主要关注消息文本内容本身
user_input = message.content
if not user_input.strip():
await cl.Message(content="似乎没有接收到有效的输入,请重试。").send()
return
# 发送一个初始响应,告知用户已开始处理
msg = cl.Message(content=f“我正在思考你的问题:'{user_input[:50]}…'”)
await msg.send()
try:
# 准备系统提示词,让模型知道它可以被语音调用
system_prompt = “”"
你是一个支持语音交互的AI助手。你的回答将被转换为语音播报给用户。
因此,请尽量使用口语化、清晰、断句合理的语言进行回复。
你精通编程和逻辑推理,请用你的专业知识帮助用户。
“”"
# 调用模型
response = client.chat.completions.create(
model="Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_input}
],
stream=True,
max_tokens=1024, # 控制回复长度
)
full_response = ""
async for chunk in response:
if hasattr(chunk.choices[0].delta, 'content') and chunk.choices[0].delta.content:
token = chunk.choices[0].delta.content
full_response += token
await msg.stream_token(token)
await msg.update()
# 重要:Chainlit会自动将 msg 的最终文本内容用于语音合成。
# 用户在前端点击扬声器图标即可听到。
except Exception as e:
error_msg = f“抱歉,处理你的请求时出现了错误:{str(e)}”
await cl.Message(content=error_msg).send()
@cl.on_chat_start
async def start():
"""
聊天开始时发送欢迎信息,并提示语音功能。
"""
welcome_msg = “”"
👋 你好!我是你的AI助手。
🎙️ **我支持语音功能**:
– 点击输入框旁的**麦克风**图标,可以直接对我说话提问。
– 我的回答会以文字显示,点击回答旁的**扬声器**图标可以听到语音播报。
试试问我一个技术问题吧!
“”"
await cl.Message(content=welcome_msg, author="助手").send()
if __name__ == "__main__":
cl.run(app, host="0.0.0.0", port=7860)
3.3 启动与体验
现在,确保你的vLLM模型服务在运行,然后启动Chainlit应用:
chainlit run app.py -w
-w 参数会自动打开浏览器。进入界面后,你会看到:
一个完整的语音对话流程就实现了! 你可以尝试问:“嘿,帮我解释一下Python中的装饰器是什么?”然后听它用语音回答你。
4. 进阶配置与问题排查
4.1 调整语音合成效果
Chainlit默认使用浏览器的Web Speech API进行语音合成(TTS)。如果你对声音不满意,可以在 chainlit.md 中尝试指定不同的语音:
<font size=2>features: [“audio”]
voice: “Google US English”</font>
可用的语音取决于你的操作系统和浏览器。你也可以在前端播放语音时,在浏览器的语音设置中选择不同的发音人。
4.2 常见问题与解决
- 麦克风无法使用:检查浏览器权限,确保允许网页访问麦克风。尝试在浏览器设置中重置权限。
- 没有语音播报图标:
- 确认 chainlit.md 文件中正确配置了 features: [“audio”]。
- 确认你的 app.py 中通过 cl.Message 返回了文本内容。
- 硬刷新浏览器页面(Ctrl+F5)。
- 语音播报没有声音:
- 检查电脑或浏览器的音量是否打开。
- 检查浏览器是否禁用了自动播放音频。通常首次点击扬声器图标需要用户交互,这是浏览器的安全策略。
- 尝试更换 chainlit.md 中的 voice 配置。
- 模型响应慢:vLLM服务首次推理或处理长文本时可能较慢。确保服务器资源(CPU/内存)充足。可以在调用时设置 max_tokens 限制回复长度。
4.3 提升对话体验的小技巧
为了让这个语音助手更好用,你可以:
5. 总结
通过本教程,我们完成了一个支持语音交互的智能助手搭建:
这个组合的优势在于:
- 部署简单:vLLM + GGUF模型使得服务部署非常便捷。
- 开发高效:Chainlit极大简化了前端开发,让开发者能专注于核心逻辑。
- 体验友好:语音功能让交互更自然,尤其适合在不想打字的场景下使用,比如学习、头脑风暴或者演示。
你现在拥有了一个私人的、支持语音的编程和推理助手。接下来,你可以尝试用它来解答技术难题、学习新概念、或者仅仅是进行一场有趣的对话。动手试试吧,感受语音与AI结合带来的便利!
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。





