当前位置: 首页 > news >正文

[数智金融][14]金融桌面助手的设计和实现

🎈金融桌面助手 —— 你的桌面 AI 陪伴

🌈 为什么需要桌面助手?

想象一下,有一个 助理:

  • 🎈随时可见—— 一个小巧的悬浮球,安静地待在你的桌面角落
  • 💬随时可聊—— 点一下就能对话,不需要打开任何网页或 App
  • 👀能看懂你的屏幕—— 遇到报错?让它帮你分析,不用复制粘贴
  • 🤗主动关心你—— 发现你长时间工作,会提醒你休息

这不只是一个工具,而是一个虚拟助理


悬浮球的独特之处

特点传统 AI 聊天桌面悬浮球
存在感需要打开网页/App始终在桌面陪伴你
交互方式主动去找它它就在那里,点一下即可
屏幕理解需要复制粘贴直接"看懂"你的屏幕
主动性只会被动回答会主动关心你的状态
情感连接冷冰冰的工具陪伴感

✨ 核心功能

💬 随时对话

点击悬浮球,打开对话窗口,和你的 AI 伙伴聊天。

你:今天有点累... AI:我注意到你已经连续工作了 3 个小时了呢,要不要站起来活动一下? 我可以帮你设置一个 10 分钟后的提醒 ☕

沉浸式对话体验

  • 📝 完整 Markdown 渲染(代码高亮、公式、表格)
  • 🖼️ 图片/文件拖拽发送

👀 屏幕感知

AI 能"看到"你屏幕上的内容,帮你分析问题。

(你遇到一个代码报错) 你:帮我看看这个报错 AI:我看到了,这是一个 NullPointerException。 问题出在第 42 行,userService 没有被正确初始化。 你可以在调用前加上空值检查,或者检查依赖注入配置...

🤗 主动交互

AI 会根据屏幕内容,在合适的时机主动给你建议。

(你在浏览技术文章) AI:这篇关于 Rust 异步编程的文章不错! 需要我帮你总结一下关键点吗? (你长时间盯着代码发呆) AI:看起来遇到了难题?要不要说说你的思路, 我帮你梳理一下?

架构设计

系统概述

Desktop Assistant 是一个基于 PySide6 的跨平台桌面客户端,采用悬浮球 + 对话窗口的交互模式,与 AstrBot 服务端通过 WebSocket 进行实时通信。

技术栈

层次技术选型
GUI 框架PySide6 (Qt6)
异步框架asyncio + qasync
HTTP 客户端httpx
配置管理Pydantic
屏幕截图mss + Pillow
Markdownmarkdown + pygments

设计原则

  1. 模块化:各模块职责单一,便于测试和维护
  2. 响应式:采用 Qt 信号槽机制实现组件间通信
  3. 异步优先:使用 asyncio 处理 I/O 操作

架构图

整体架构

┌─────────────────────────────────────────────────────────────────┐ │ Desktop Client │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ Presentation Layer │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │ │ │ │ │ FloatingBall│ │ ChatWidgets│ │ SettingsWindow │ │ │ │ │ └────────────┘ └────────────┘ └────────────────────┘ │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │ │ │ │ │ SystemTray │ │ Themes │ │ ScreenshotSelector │ │ │ │ │ └────────────┘ └────────────┘ └────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ Application Layer │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │ │ │ │ │ App │ │ Controllers│ │ Handlers │ │ │ │ │ │ │ │ (Settings) │ │ (Msg/Screenshot/ │ │ │ │ │ │ │ │ │ │ Proactive/Media) │ │ │ │ │ └────────────┘ └────────────┘ └────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ Domain Layer │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │ │ │ │ │ Bridge │ │ Services │ │ Platforms │ │ │ │ │ │ (Message) │ │ (Monitor/ │ │ │ │ │ │ │ │ │ │ Capture) │ │ │ │ │ │ │ └────────────┘ └────────────┘ └────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ Infrastructure Layer │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │ │ │ │ │ API Client │ │ Config │ │ Storage │ │ │ │ │ │ (HTTP/WS) │ │ (Pydantic) │ │ (ChatHistory) │ │ │ │ │ └────────────┘ └────────────┘ └────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ WebSocket / HTTP ▼ ┌─────────────────────────────────────────────────────────────────┐ │ AstrBot Server │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ astrbot_plugin_desktop_assistant │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ │ │ WSHandler │ │DesktopMonitor│ │ProactiveDialog │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │ │ └────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘

模块依赖图

┌─────────────────┐ │ App │ │ (DesktopClient │ │ App) │ └────────┬────────┘ │ ┌─────────────────┼─────────────────┐ │ │ │ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ GUI │ │ Handlers │ │ Controllers │ │ Components │ │ │ │ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │ │ │ ┌────────────┴────────────┐ │ │ │ │ │ ▼ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ Bridge │◄───────────────│ Services │ │ (Message) │ │ │ └──────┬───────┘ └──────┬───────┘ │ │ ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ API Client │ │ Platforms │ │ (HTTP/WS) │ │ (Adapters) │ └──────┬───────┘ └──────────────┘ │ ▼ ┌──────────────┐ │ Config │ └──────────────┘

核心模块

1. GUI 模块 (gui/)

负责用户界面展示和交互。

1.1 悬浮球 (floating_ball.py)
classFloatingBallWindow(QWidget):""" 悬浮球主窗口 功能: - 拖拽移动与边缘吸附 - 单击切换输入框 - 双击触发主动对话 - 右键菜单 - 消息气泡显示 - 呼吸灯状态提示 信号: - clicked: 单击事件 - double_clicked: 双击事件 - message_sent: 消息发送 - image_sent: 图片发送 - screenshot_requested: 截图请求 - settings_requested: 设置请求 - quit_requested: 退出请求 """
1.2 聊天组件 (chat_widgets.py)
classChatWidget(QWidget):""" 聊天界面组件 功能: - Markdown 渲染(代码高亮、表格、公式) - 消息气泡展示 - 图片预览与缩放 - 消息输入与发送 """
1.3 主题系统 (themes.py)
classThemeManager:""" 主题管理器(单例) 功能: - 亮色/暗色主题切换 - 自定义颜色配置 - 系统主题跟随 使用: >>> from gui.themes import theme_manager >>> theme_manager.set_theme("dark") >>> colors = theme_manager.get_colors() """

2. Handler 模块 (handlers/)

处理各类事件和消息。

2.1 消息处理器 (message_handler.py)
classMessageHandler(QObject):""" 消息处理器 职责: - 解析服务端响应消息 - 处理文本、图片、语音等消息类型 - 更新聊天历史 - 触发 UI 更新 信号: - message_processed: 消息处理完成 """
2.2 截图处理器 (screenshot_handler.py)
classScreenshotHandler(QObject):""" 截图处理器 职责: - 全屏截图 - 区域截图 - 主动对话截图 - 截图编码与发送 信号: - screenshot_completed: 截图完成 - proactive_screenshot_completed: 主动截图完成 """
2.3 主动对话处理器 (proactive_handler.py)
classProactiveHandler(QObject):""" 主动对话处理器 职责: - 处理主动对话触发事件 - 组装桌面状态信息 - 发送至服务端进行分析 """
2.4 媒体处理器 (media_handler.py)
classMediaHandler(QObject):""" 媒体文件处理器 职责: - 下载图片/语音文件 - 文件存储管理 """

3. Service 模块 (services/)

封装核心业务逻辑。

3.1 桌面监控服务 (desktop_monitor.py)
classDesktopMonitorService:""" 桌面状态监控服务 功能: - 定时捕获桌面状态 - 窗口变化检测 - 截图采集 - 状态上报 使用: >>> monitor = DesktopMonitorService( ... screen_capture_service=screen_capture, ... report_interval=60 ... ) >>> await monitor.start() """
3.2 屏幕捕获服务 (screen_capture.py)
classScreenCaptureService:""" 屏幕捕获服务 功能: - 全屏截图 - 区域截图 - 图片压缩 - Base64 编码 """
3.3 主动对话服务 (proactive_dialog.py)
classProactiveDialogService(QObject):""" 主动对话服务 功能: - 定时检查触发条件 - 概率触发主动对话 - 收集上下文信息 信号: - dialog_triggered: 对话触发 """

4. Bridge 模块 (bridge.py)

消息桥接层,统一管理消息收发。

classMessageBridge(QObject):""" 消息桥接层 职责: - 封装 API Client - 统一消息格式 - 管理连接状态 - 信号分发 信号: - message_received: 收到消息 - connection_state_changed: 连接状态变化 使用: >>> bridge = MessageBridge(config) >>> await bridge.connect_server() >>> await bridge.send_input(InputMessage(...)) """

5. API Client 模块 (api_client.py)

底层通信客户端。

classDesktopAPIClient:""" API 客户端 功能: - HTTP 请求(登录、文件上传) - WebSocket 长连接 - SSE 流式响应 - 自动重连 支持的消息类型: - text: 文本消息 - image: 图片消息 - voice: 语音消息 - desktop_state: 桌面状态 """

设计模式

1. Handler 链模式 (Chain of Responsibility)

消息处理的职责链。

消息进入 ──► MessageHandler ──► MediaHandler ──► ProactiveHandler │ │ │ ▼ ▼ ▼ 处理文本 处理媒体 处理主动对话

特点

3. 观察者模式 (Observer Pattern)

基于 Qt 信号槽实现组件间通信。

# 定义信号classMessageBridge(QObject):message_received=Signal(OutputMessage)connection_state_changed=Signal(ConnectionState)# 连接信号到槽bridge.message_received.connect(message_handler.handle_output_message)bridge.connection_state_changed.connect(app.on_connection_state_changed)

4. 单例模式 (Singleton Pattern)

用于全局唯一的管理器。

# themes.pyclassThemeManager:_instance=Nonedef__new__(cls):ifcls._instanceisNone:cls._instance=super().__new__(cls)returncls._instance# 全局访问theme_manager=ThemeManager()

5. MVC 变体模式

分离关注点。

┌─────────────────────────────────────────────────────────┐ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │ │ View │◄───│ Controller │───►│ Model │ │ │ │ (GUI) │ │ (Handlers/ │ │ (Config/ │ │ │ │ │ │ Controllers)│ │ Bridge) │ │ │ └──────────────┘ └──────────────┘ └──────────┘ │ │ │ │ │ │ │ └───────────────────┴──────────────────┘ │ │ Qt Signals │ └─────────────────────────────────────────────────────────┘

数据流

1. 用户消息发送流程

用户输入 │ ▼ ┌──────────────┐ │ FloatingBall │ message_sent 信号 └──────┬───────┘ │ ▼ ┌──────────────┐ │ App │ _on_message_sent() └──────┬───────┘ │ ▼ ┌──────────────┐ │ Bridge │ send_input(InputMessage) └──────┬───────┘ │ ▼ ┌──────────────┐ │ API Client │ WebSocket 发送 └──────┬───────┘ │ ▼ AstrBot Server

2. 服务端消息接收流程

AstrBot Server │ ▼ ┌──────────────┐ │ API Client │ WebSocket 接收 └──────┬───────┘ │ ▼ ┌──────────────┐ │ Bridge │ message_received 信号 └──────┬───────┘ │ ▼ ┌──────────────┐ │MessageHandler│ handle_output_message() └──────┬───────┘ │ ├─── 文本消息 ──► 更新聊天界面 │ ├─── 图片消息 ──► MediaHandler 下载 ──► 显示图片 │ └─── 语音消息 ──► MediaHandler 下载 ──► 自动播放

3. 主动对话触发流程

┌────────────────────┐ │ProactiveDialogSvc │ 定时检查 └─────────┬──────────┘ │ ▼ 触发条件满足? │ ▼ Yes ┌────────────────────┐ │ ScreenshotHandler │ 捕获截图 └─────────┬──────────┘ │ ▼ ┌────────────────────┐ │ProactiveHandler │ 组装状态 └─────────┬──────────┘ │ ▼ ┌────────────────────┐ │ Bridge │ 发送 desktop_state └─────────┬──────────┘ │ ▼ AstrBot Server │ ▼ AI 分析并响应

通信协议

WebSocket 消息格式

1. 客户端 → 服务端

文本消息

{"type":"text","content":"你好","session_id":"user_12345"}

图片消息

{"type":"image","content":"/path/to/image.png","session_id":"user_12345","metadata":{"text":"这是什么?"}}

桌面状态

{"type":"desktop_state","data":{"timestamp":"2024-01-01T12:00:00","active_window_title":"Visual Studio Code","active_window_process":"Code.exe","active_window_pid":12345,"screenshot_base64":"iVBORw0KGgo...","screenshot_width":800,"screenshot_height":600,"running_apps":[{"pid":12345,"name":"Code.exe"},{"pid":67890,"name":"chrome.exe"}],"window_changed":true,"previous_window_title":"Chrome"}}
2. 服务端 → 客户端

文本响应

{"type":"text","content":"你好!有什么可以帮助你的吗?"}

图片响应

{"type":"image","url":"https://server/images/response.png"}
http://www.jsqmd.com/news/1050988/

相关文章:

  • WSL2下Ollama与vLLM混合部署实战:本地大模型推理最优解
  • 孩子中考没达到普高线应该上什么学校?推荐上合肥理工学校! - 教育为先
  • QKeyMapper:终极游戏手柄按键映射工具,让所有设备都能畅玩PC游戏
  • 长沙全屋定制工艺大对比,专业视角带你一探究竟! - 资讯速览
  • ComfyUI-Impact-Pack Switch节点兼容性问题:从故障诊断到高效修复指南
  • 2026年东莞工业胶粘制品选购指南:EVA泡棉、硅胶垫、保护膜、双面胶、绒布垫配套厂商优选指南 - 海棠依旧大
  • 2026 电机平键口碑实力推荐|贴片螺母・贴片汇流条・组合螺钉口碑榜 | 高精度紧固件哪家好?二十年匠心赛道,国家级高新技术企业盘点 -- 深圳劲力加五金精密科技有限公司 - 资讯速览
  • 2026年洛阳市CPPM考试最新全攻略:科目题型、通过率、备考重点及官方双认证报考机构推荐 - 众智商学院课程中心
  • 概率策略语言中的冲突检测与Voronoi归一化解决方案
  • Simulink Agentic Toolkit:用强化学习智能体驱动仿真优化与自主决策
  • 2026年江苏GEO优化服务商实力榜单|本地企业生成式搜索优化首选指南 - 936品牌测评网
  • Windows HEIC缩略图插件:5分钟快速解决iPhone照片预览难题的终极方案
  • 2026年6月市场优质的淋漠挤出复合机实力厂家哪个好,纸塑淋膜机/PLA淋膜机,淋漠挤出复合机公司怎么选择 - 品牌推荐师
  • 多场景低压配电母线槽应用方案,适配高安全标准电气工程
  • 安能物流电瓶车托运2026全测评:服务、费用与避坑指南 - 快递物流资讯
  • 抖店新手怎么选拍单工具?筛选标准 + 避坑全指南 - 抖掌柜
  • 想做专业长沙全屋定制?这些优质之选不容错过! - 资讯速览
  • Apifox实战:从优惠券创建到秒杀压测的完整接口测试流程
  • 2026寄大件哪家快递最便宜?全网渠道对比+省钱技巧 - 快递物流资讯
  • 10分钟打造专属AI歌手:Retrieval-based Voice Conversion完全指南
  • 黄山学院的整体就业率怎么样?王牌专业的就业率能达到多少? - 寻茫精选
  • 嵌入式实时系统事件驱动任务调度:从OSEK OS原理到汽车ECU周期任务实战
  • 开发K8s准入控制器前的准备工作:集群检查与项目搭建指南
  • 如何高效使用开源网盘直链下载助手:专业用户的实战指南
  • 合肥理工学校 2026 招生什么条件?2026年6月21号最新公布! - 教育为先
  • 终极指南:5步免费绕过iOS 15-16激活锁,解锁你的iPhone/iPad设备
  • 鸿蒙应用开发中的单位详解:px、vp、fp、lpx
  • 做税务体检怕踩坑?广州中小企业服务筛选全攻略 - 资讯速览
  • 2026年南阳市PMP培训机构哪家好?官方授权R.E.P.报考指南 - 众智商学院课程中心
  • 终极免费解决方案:如何用novideo_srgb轻松校准NVIDIA显卡广色域显示器色彩