拒绝套壳:从零打造全能型万象AI助手(WanXiangAI)的架构与实战复盘
文章目录
一、 前言:为什么要做 WanXiangAI?
在“百模大战”的今天,各家大模型 API 层出不穷。作为一名开发者,与其每天在不同的网页端来回切换,不如亲手打造一个属于自己的全能 AI 终端。这正是 WanXiangAI(万象 AI 助手) 诞生的初衷。
在这个项目中,我没有使用过于沉重的 LangChain 或 LlamaIndex 框架,而是选择用纯 Python 结合现代化的 UI 框架,从底层构建核心逻辑。通过这个项目,我不仅串联了多家大模型的 API,还深入落地了文档解析、RAG(检索增强生成)以及多模态语音交互技术。这篇文章将对 WanXiangAI 的核心技术实现进行一次全面的复盘。
二、 架构概览:不仅仅是一个聊天框
WanXiangAI 的后端架构高度模块化,主要由以下几个核心部分驱动:
引擎层 (Models):统一封装了 Doubao(豆包)、DeepSeek、Kimi、Qwen(通义千问)和 Spark(星火)等主流大模型的 API。
核心逻辑层 (Modules):包含文件处理与检索 (file_utils.py)、对话状态调度 (chat.py)、系统提示词管理 (prompt.py) 以及工具链 (tools.py)。
表现层 (UI):基于 Gradio 框架,深度定制 CSS 以实现响应式、沉浸式的交互界面。
三、 核心技术点一:多模型统一调度与“随时中断”机制
在接入多个大模型时,我利用 Python 的多态特性和单例模式,优雅地解决了频繁实例化带来的性能开销,并实现了一个非常关键的 UX 功能:随时停止生成。
在 modules/chat.py 中,我维护了一个全局的 model_instances 字典来管理模型实例,确保每个模型只被初始化一次。为了实现停止功能,我在每个 LLM 引擎内部(例如 DeepSeekLlmEngine)都增加了一个 stop_flag 标志位。
核心调度与打断代码:
# models/deepseek.py (模型内部处理流式输出与打断)
for chunk in response:
# 检测停止标志位,中断流式输出
if self.stop_flag:
print("\n生成已停止")
break
if chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
history[-1]['content'] += content
yield history
# modules/chat.py (全局触发打断)
def stop_generation(model_name):
"""停止生成的逻辑:设置标志位"""
model = model_instances.get(model_name)
if model:
# 动态给对象设置属性,即使原类中没有定义 stop_flag 也能生效
model.stop_flag = True
print(f"🛑 {model_name} 接收到停止指令")
这种设计不仅解耦了前端按钮与后端网络请求,还有效避免了长文本生成时对服务器资源和 Token 的浪费。
四、 核心技术点二:手搓纯本地 RAG(检索增强生成)系统
为了让 WanXiangAI 能“读懂”本地文件,我用 Python 基础库手写了一套轻量级的 RAG 系统。
在 modules/file_utils.py 中,我集成了 PyPDF2 (处理 PDF)、python-docx (处理 Word)、openpyxl (处理 Excel) 甚至 pytesseract (通过 OCR 提取图片文字)。
当提取完长文本后,系统会进行分片(Chunking),并通过自研的关键词匹配算法,提取与用户当前问题最相关的片段。随后,在对话主循环中,将检索到的片段通过 Prompt 强制注入给大模型:
防幻觉的 Prompt 注入逻辑:
# modules/chat.py
if relevant_context and relevant_context.strip():
doc_prompt = f"""
以下是和用户问题相关的文档内容(仅基于此内容回答,不要编造):
{relevant_context}
【回答规则】:
1. 优先使用上述文档内容回答用户问题;
2. 如果文档中没有相关信息,明确告知"文档中未提及相关内容";
3. 回答需基于文档,不要添加无关信息;
4. 保留文档中的关键信息(如数字、术语、逻辑)。
"""
# 拼接并覆盖原有 prompt
prompt = (prompt or "") + doc_prompt
通过这种极其严格的指令约束,WanXiangAI 在处理长文档问答时,极大地降低了“一本正经胡说八道”的幻觉概率。
五、 核心技术点三:赋予 AI 听觉——语音交互模块
为了丰富交互维度,WanXiangAI 接入了强大的开源音频处理库。
在语音转文本(STT)方面,系统在本地加载了 OpenAI 的 Whisper 模型。为了解决模型偶尔将环境杂音误识别为外语的痛点,我在调用时做了两个硬性约束:
# modules/tools.py
result = stt_model.transcribe(
audio_path, # 临时录音文件
language="zh", # 1. 强制指定为中文
initial_prompt="你好,这是一段清晰的普通话对话。" # 2. 给予语境暗示
)
而在文本转语音(TTS)方面,则采用了微软的 Edge-TTS 服务,实现了低延迟、拟真度极高的语音播报。
六、 UI 与交互:高仿 Gemini 的沉浸式体验
除了硬核的后端逻辑,我在前端体验上也下了很大功夫。原生的 Gradio 界面偏向学术风,为了达到工业级产品的质感,我在 app.py 中注入了大量的定制 CSS 以及 JavaScript。
例如,我重写了聊天气泡的样式,采用了非对称圆角;同时,彻底改造了输入框的布局,去掉了冗余边框,使用悬浮感设计,辅以正圆形的“➤”发送按钮,打造出了一体化、类似 Gemini 的现代搜索栏质感。
七、 总结与展望
从零堆砌 WanXiangAI 的过程,对我而言是一次技术思维的刷新。
在大模型 API 抹平了算法门槛的今天,如何通过优秀的架构设计(如单例模式调度引擎)、扎实的工程实现(如手搓 RAG 分片与评分)以及极致的用户体验打磨(定制 CSS 与多模态 I/O),才是开发者真正的护城河。
目前 WanXiangAI 的 RAG 检索仍基于关键词的频率与权重计算。下一步,我计划引入轻量级的向量数据库(如 ChromaDB 或 FAISS)以及 Embedding 模型,将其升级为真正的语义检索架构。
保持动手,保持热爱。期待 WanXiangAI 的下一次蜕变!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)