乐于分享
好东西不私藏

AIAsker:一款 Windows 桌面悬浮球 AI 助手,支持截图提问、语音输入与公式渲染

AIAsker:一款 Windows 桌面悬浮球 AI 助手,支持截图提问、语音输入与公式渲染

在日常教学中,我们经常会碰到如下场景:正在用PPT讲课,然后需要演示一下AI对当前问题的回答,启发学生思维,因此我们不得不退出PPT——打开浏览器——登录豆包或deepseek——提问等待回答——回答完毕切换到PPT播放上,如果需要对屏幕上的内容提问,还得先截图保存、再手动上传。整个流程琐碎且割裂,如果再遇到电脑卡顿,常常会打乱整个讲课节奏。而且通用AI经常无法将回答限制在课堂内容上,导致回答偏离课堂主线。 

为解决这一问题,我开发了AIAsker软件, 这是一款面向 Windows 平台的桌面 AI 助手,它将这些步骤压缩到「点击—提问—获得回答」三个动作以内,将 AI 交互融入操作系统层面,大幅减少使用步骤的同时,提供简单易用的上下文设置功能,让AI真正赋能课堂而不是扰乱课堂。

📥 软件获取

渠道
说明
🌐 Gitee Releases
前往 [项目主页] 的 Releases 页面,下载最新版 AIAsker_Setup_v1.0.exe 安装包
📦 便携版压缩包
由于gitee上传文件超限,可前往夸克网盘下载 AIAsker_portable.zip,解压即用,无需安装
🔧 源码构建
git clone
 仓库后按本文第二部分「开发环境搭建」步骤自行构建
# 项目主页:https://gitee.com/devount/aiasker# 夸克网盘:https://pan.quark.cn/s/e38799feb0b6?pwd=8Gk5

⚠️ 目前仅提供 Windows 64 位版本,支持 Windows 7 / 10 / 11。


📦 Part 1 —— 普通用户使用指南

⚡ 安装(两种方式任选)

方式一:一键安装(推荐)

1. 下载 AIAsker_Setup_v1.0.exe2. 双击运行,如弹出 UAC 提示点击「是」3. 等待安装完成,安装程序会询问是否立即启动,按 Y 启动

安装程序会自动完成以下操作:

  • 📁 将程序文件拷贝至 C:\Program Files\AIAsker\
  • 📌 在开始菜单创建「AIAsker」程序组(含启动快捷方式和卸载入口)
  • 🖥️ 在桌面创建快捷方式

方式二:便携模式

如果不想安装,直接运行压缩包内的 AIAsker.exe 即可,注意运行路径不要有中文。不写注册表、不留系统痕迹,适合放在 U 盘里随身携带。

🔵 初次见面:一个悬浮在桌面上的球

安装完成后,屏幕右下角会出现一个带有径向渐变效果的蓝色悬浮球,中央显示「AI」标识,并伴有呼吸灯动画。该控件始终置顶于所有窗口之上,可自由拖拽至任意位置,不干预正常办公。

操作
功能
🖱️ 左键单击
呼出/隐藏聊天窗口
🖱️ 左键拖拽
移动悬浮球位置
🖱️ 右键菜单
打开设置 / 退出程序

🔑 首次配置

初次使用需要填入大模型 API Key:

  1. 右键悬浮球 →「设置...」

  2. 在「基础设置」页签中选择模型预设(如"阿里千问 3.7"),API 地址和模型名称会自动填充

  3. 填入你的 API Key 

  4. (可选)切换到「知识配置」页签,设置系统提示词或粘贴知识库文本 

  5. 点击「保存」

阿里云百炼 API Key 可在阿里云百炼注册账号并免费申请。其他服务商(DeepSeek、智谱、豆包)同理,填入对应 Key 即可。

#阿里云百炼地址:https://bailian.console.aliyun.com/cn-beijing#/home

💬 聊天窗口:极简但不简陋

点击悬浮球后,会弹出一个圆角白色面板的聊天窗口。设计上遵循「最小干扰」原则:无标题栏按钮(仅保留一个关闭图标)、无多余装饰。输入区域位于底部,支持多行文本,Ctrl + Enter 发送。 

📸 截图提问 —— 核心功能

这是 AIAsker 最具实用价值的能力。操作流程如下:

  1. 点击输入框左侧的 相机图标 
  2. 窗口自动隐藏,200ms 延迟后全屏截图(给你时间将目标内容展示在屏幕上)
  3. 截图以缩略图形式呈现在输入区域上方
  4. 点击缩略图可进入 ✂️ 裁剪编辑器:用鼠标拖拽创建裁剪框,支持 8 锚点自由调整(四角 + 四边中点),精确选取需要 AI 关注的区域
  5. 在输入框中键入问题,点击「发送」

发送后,截图(自动压缩为 JPEG、分辨率 ≤ 1920px)与文字问题一同传递给大模型,视觉模型可理解图片内容并基于上下文作答。

对话支持多轮上下文记忆,可连续追问,AI 会关联历史消息作答。

🎤 语音输入 —— 边说边出字

点击输入框左侧的 🎙️ 麦克风图标

开始录音,再次点击结束。

底层基于 阿里云 Qwen3-ASR-Flash-Realtime 实时语音识别引擎,通过 WebSocket 流式传输音频数据。支持以下特性:

  • 实时中间结果
    边说边在输入框中显示识别进度
  • VAD 断句
    语音活动检测自动分段,长段语音会被切分为多个句子逐段追加
  • 追加模式
    多次录音结果以空格拼接,不会覆盖已有文本
  • 最长 15 秒单次录音
    超时自动停止

实测在普通办公和教学环境下,标准普通话识别准确率非常高。

✨ AI 回复的渲染效果

AI 回复气泡具备完整的富文本渲染能力:

  • 📝 Markdown 完整支持:标题、列表、粗体、斜体、链接等
  • 💻 代码语法高亮:基于 Pygments 的 friendly 浅色主题,适配白色聊天背景
  • 📊 表格渲染:自适应列宽,横向溢出时可滚动
  • 🧮 LaTeX 数学公式:基于 MathJax 3 引擎,行内公式 $...$ 和块级公式 $$...$$ 均以矢量 SVG 呈现,支持 ams 宏包
  • 🔄 流式输出:逐 token 渲染,呈现「打字机」效果,避免长时间空白等待

⚙️ 设置详解

右键悬浮球 →「设置...」,打开两页配置对话框。

📋 标签页一:基础设置

配置项
说明
🎯 模型预设
内置 5 套主流服务商预设,一键切换
🌐 API 地址
OpenAI 兼容端点 URL,支持自动补全 /chat/completions 后缀
🔑 API Key
密码输入框,保存后以掩码显示
🏷️ 模型名称
如 qwen3.7-plus、deepseek-chat 等
🎤 语音识别引擎
当前支持阿里云 Qwen-ASR

内置模型预设清单:

预设名称
服务商
阿里千问 3.7
dashscope.aliyuncs.com
阿里千问 VL Max
dashscope.aliyuncs.com(视觉模型)
DeepSeek
api.deepseek.com
智谱 GLM-4-Flash
open.bigmodel.cn
字节豆包 Lite
ark.cn-beijing.volces.com

选择预设后,API 地址和模型名称自动填充。填入 API Key 即可使用。注意:非视觉模型不能识别图片,如deepseek-v4-pro等,请选择可以识别视觉图片的模型,如qwen3.7-plus

📚 标签页二:知识配置

  • 🧠 系统提示词
    定义 AI 的身份与行为边界。例如:「你是一位有多年教学经验的语文教师,擅长知人论世、诗词赏析。」
  • 📖 知识库
    粘贴参考文本,如本节课的文章内容等,AI在回答时将优先基于这些内容。支持从 .txt / .md 文件导入,内容会追加到已有知识库之后。

两项均为可选。留空则使用模型的默认行为。

🩺 诊断功能

设置对话框中设有「🔍 诊断」按钮,点击后启动一套 10 步全链路自动检查:

步骤
检查内容
1️⃣
配置文件存在性与 JSON 合法性
2️⃣
各配置项完整性(含 API Key 掩码显示)
3️⃣
API URL 格式校验(scheme / host)
4️⃣
dashscope SDK 安装状态与版本
5️⃣
PyAudio / speech_recognition 依赖检测
6️⃣
LLM 端点 HTTP 连通性(GET /models)
7️⃣
模型名称是否在 API 返回列表中
8️⃣
系统信息(DPI 缩放、Python 版本、OS)
9️⃣
图片理解实测
自动生成测试图像 → 发送给 LLM → 流式输出识别结果
🔟
语音识别实测
WebSocket 连接 → 录音 5 秒 → 返回识别文本

每一步都有 [PASS] / [FAIL] / [WARN] 标记,出现问题时可快速定位故障环节。

🗑️ 卸载

  • 打开开始菜单 → AIAsker → Uninstall AIAsker
  • 或手动删除 C:\Program Files\AIAsker 目录

便携版直接删除解压文件夹即可,不在系统中留任何痕迹。


🔧 Part 2 —— 开发者继续开发指南

以下内容面向具备 Python 基础的开发者,介绍项目架构、关键技术细节与二次开发切入点。

📥 源码获取

git clonegit clone https://gitee.com/devount/aiasker.gitcd AIAsker

💻 开发环境搭建

# 1. 创建虚拟环境(Python 3.8+)python -m venv venvvenv\Scripts\activate  # Windows# source venv/bin/activate  # macOS/Linux# 2. 安装依赖pip install -r requirements.txt# 3. 创建配置文件(参考 core/config.py 中的 DEFAULT_CONFIG)echo {} > config.json# 4. 直接运行python main.py# 5. 打包为 exepip install pyinstallerpyinstaller AIAsker.spec

注意事项:

  • ⚠️ PyAudio 在 Windows 上可能需要从 .whl 文件安装,可访问 Python Extension Packages 获取对应 Python 版本的预编译包
  • ⚠️ 语音功能依赖物理麦克风,纯文本对话开发可跳过
  • ⚠️ 打包时如果新增了动态 import 的模块,需在 AIAsker.spec 的 hiddenimports 列表中添加
  • ⚠️ QtWebEngine 模块体积较大(约 100MB),打包后的 exe 包含完整的 Chromium 内核

📐 技术栈总览

层次
技术选型
🖼️ UI 框架
PyQt5 + QtWebEngine(WebView 气泡)
🌊 AI 对话
httpx 同步流式请求,兼容 OpenAI Chat Completions API
🎤 语音识别
dashscope SDK,Qwen3-ASR 通过 WebSocket 实时流式传输
📸 截图
Pillow(PIL.ImageGrab 全屏抓取 + JPEG 压缩 + Base64 编码)
📝 Markdown
Python-Markdown + Pygments 代码高亮
🧮 数学公式
MathJax 3 CDN(tex-svg.js),在 QWebEngineView 中原生渲染
📦 打包
PyInstaller,单 exe 输出

🗂️ 项目文件结构

AIAsker/├── main.py                  # 🚀 应用入口,App 主控类├── core/│   ├── ai_client.py         # AI 客户端(OpenAI 兼容流式调用)│   ├── config.py            # 配置读写(config.json,默认值定义)│   ├── screenshot.py        # 截图管理(抓取/缩略图/Base64/裁剪替换)│   ├── voice_input.py       # 语音识别(Qwen-ASR WebSocket 实时流)│   ├── markdown.py          # Markdown → HTML(代码高亮、表格样式注入)│   ├── latex.py             # LaTeX 公式 → MathJax 标记处理│   ├── math_page.py         # 生成嵌入 MathJax 的完整 HTML 模板│   ├── diagnostics.py       # 🔍 诊断引擎(10 步全链路检查)│   └── scale.py             # DPI 缩放适配工具├── ui/│   ├── floating_ball.py     # 🔵 悬浮球控件(置顶/拖拽/呼吸灯/右键菜单)│   ├── chat_dialog.py       # 💬 聊天窗口(消息气泡/流式渲染/语音/截图)│   ├── image_editor.py      # ✂️ 截图裁剪覆盖层(8 锚点自由调整)│   ├── image_editor_dialog.py  # 截图编辑对话框容器│   ├── settings_dialog.py   # ⚙️ 设置对话框(模型预设/知识配置)│   ├── config_test_dialog.py   # 🩺 诊断结果显示对话框│   ├── icons.py             # 🎨 图标绘制(SVG 手绘按钮图标)│   └── styles.py            # 🎨 全局 QSS 样式表├── assets/                  # 静态资源(logo、SVG 图标)├── config.json              # 用户配置文件├── requirements.txt         # Python 依赖清单├── AIAsker.spec             # PyInstaller 打包配置├── Install_AIAsker.bat      # 一键安装批处理├── AIAsker_Install.ps1      # PowerShell 安装脚本└── AIAsker_Setup.iss        # Inno Setup 安装包脚本

🧩 核心架构解析

应用主控(main.py)

App 类是全局调度中心,持有 FloatingBall(悬浮球)和 ChatDialog(聊天窗口)两个核心实例。关键交互逻辑:

悬浮球左键单击 → App._toggle_dialog() → 在悬浮球左上方定位并显示/隐藏聊天窗口悬浮球右键设置 → App._show_settings() → 打开模态设置对话框

悬浮球的「点击」判断采用位移阈值法:在 mouseReleaseEvent 中,只有当拖拽位移 ≤ 3px 时才视为点击,否则视为拖拽移动。这有效避免了拖拽操作误触发对话框。

AI 流式对话(core/ai_client.py + ui/chat_dialog.py)

对话流程采用 QThread 后台线程 + Qt 信号回调 的经典模式:

用户发送消息  → _AIThread(QThread) 启动    → AIClient.chat_stream_sync() 同步阻塞流式调用      → 每收到 token → token.emit(token) 信号跨线程发射到主线程  → 主线程 _on_ai_token():    → markdown_to_html() 转换为 HTML    → render_math_in_html() 处理 LaTeX 标记    → QWebEngineView.set_content_html() 更新气泡内容      → JS: document.getElementById("bubble").innerHTML = ...      → JS: MathJax.typesetPromise() 重新渲染公式

系统提示词与知识库在 _AIThread.run() 中注入:如果用户配置了 system_prompt 或 knowledge_base,会在消息列表头部插入一条 role: "system" 消息。

AI 回复气泡:QWebEngineView + MathJax

选择 QWebEngineView 而非 QLabel 或 QTextBrowser 的核心原因是 MathJax 需要完整的 JavaScript 运行环境来将 LaTeX 公式渲染为 SVG。

气泡组件 _AIBubble 封装了以下关键机制:

  • 首次加载
    注入完整的 MathJax HTML 页面模板(make_math_page())
  • 后续更新
    通过 page().runJavaScript() 热替换 #bubble 元素内容,触发 MathJax 增量重排
  • 滚轮转发
    WebView 中注入 JS 拦截 wheel 事件,将 deltaY 写入 document.title,Qt 端通过 titleChanged 信号解析 "scroll:xxx" 前缀,再驱动外层 QScrollArea 滚动——解决了 WebView 吞掉滚轮事件的问题
  • 高度自适应
    每次内容更新后 JS 将 document.body.scrollHeight 通过 document.title 传回 Qt,动态调整 WebView 高度

语音识别(core/voice_input.py)

基于阿里云 dashscope SDK 的 OmniRealtimeConversation:

_VoiceThread(QThread)  → VoiceInput.recognize()    → OmniRealtimeConversation.connect() 建立 WebSocket    → 等待 session.created 事件(超时 10 秒)    → update_session() 配置中文识别参数(16kHz PCM)    → PyAudio 麦克风循环读取 → base64 编码 → append_audio()    → VAD 断句回调:      - input_audio_transcription.text → interim 信号(中间结果)      - input_audio_transcription.completed → result 信号(最终段落)    → end_session() + close()

识别结果采用追加模式:on_result 回调将每段确认文本追加到 voice_accumulated,on_interim 回调将中间结果拼接在已确认文本之后显示。这样多次说话之间不会互相覆盖。

截图编辑器(ui/image_editor.py)

_CropOverlay 是一个自定义 QLabel,实现了完整的截图裁剪交互:

  • 在图片区域内拖拽绘制裁剪框
  • 已有裁剪框时,8 个锚点(四角 + 四边中点)可独立拖拽调整
  • 裁剪框内部可拖拽平移
  • 所有操作约束在图片显示区域内,最小尺寸 20px
  • 通过 get_crop_rect_pil() 方法将控件坐标逆映射回 PIL Image 坐标

🛠️ 二次开发切入点

1. 接入新的 AI 服务商

只要目标 API 兼容 OpenAI Chat Completions 格式,只需在 ui/settings_dialog.py 的 _MODEL_PRESETS 字典中添加一行:

"你的服务商名称": ("https://your-api.example.com/v1/chat/completions","your-model-name",),

如果需要非标准的请求头或 payload 结构,修改 core/ai_client.py 中的 chat_stream_sync() 方法。

2. 添加新的聊天功能按钮

在 ui/chat_dialog.py 的 _init_ui 方法中,参考相机按钮的模式:

btn_new = IconButton(IconType.XXX, tooltip="功能描述")btn_new.setFixedSize(dp(_BTN_ICON), dp(_BTN_ICON))btn_new.clicked.connect(self._your_handler)il.addWidget(btn_new)

图标类型枚举定义在 ui/icons.py 中,如有需要可扩展 IconType 并实现对应的 draw_xxx_icon() 函数。

3. 修改悬浮球外观

ui/floating_ball.py 的 paintEvent() 方法控制悬浮球的完整绘制:阴影椭圆 → 径向渐变主体 → AI 图标文字。修改形状、颜色、呼吸灯速度(_breath_dir)、透明度等均在此处。

4. 本地化 MathJax

当前 MathJax 通过 jsdelivr CDN 加载。内网环境可下载 tex-svg.js 及相关资源放置于项目中,修改 core/math_page.py 中 <script src> 为本地路径。


📌 结语

AIAsker 是一个为优化课堂教学中AI使用流程的工具型桌面软件:只做「最快把屏幕上的东西丢给 AI 并获得回答」这一件事。悬浮球 + 截图 + 流式回答的组合,让 AI 以最便捷的方式融入了课堂之中。

从开发者角度看,它是一个麻雀虽小五脏俱全的 PyQt5 参考案例——多线程通信、WebView 双向通信(JS ↔ Qt)、WebSocket 音频流处理、Markdown/LaTeX 渲染管道、跨线程信号安全——每一块都写得清晰克制,适合作为桌面 AI 应用开发的起步模板。

项目代码量适中(核心约 2500 行),结构干净,注释充分。欢迎 clone、fork、提 PR。


👇 关注公众号,获取更多效率工具分享

Edtshare

教育技术分享平台

分享|合作|进步|提高

相关学习资料