本文是 DeepSeekPulse 的Design Docs第一篇,讲产品定位与边界。 架构见《系统架构与数据流》,关键实现见《三个关键技术决定》。
一、要解决的问题
同时用 DeepSeek 和 GLM Coding Plan 的人有一个共同的日常动作:打开两个Admin,各看一眼还剩多少。
- DeepSeek 是按量付费,关心的是"余额还能撑多久"
- GLM 是订阅套餐,关心的是"这个 5 小时窗口还剩几成,别用超了等刷新"
两件事性质不同,但动作同构——都是一次没有产出的查看。按每天两次、每次 15 秒算,一个月是十几分钟。这个工具的全部价值就是把这十几分钟省掉。
顺带解决一个次要问题:Windows 上常年累积的僵尸进程。那些父进程早已Sign out、却还占着几百 MB 的 node.exe,任务管理器里看得见但很难判断该不该杀。
二、明确不做什么
边界定得清楚,后面所有设计决定才有依据。
不做账号体系。 不引入任何注册登录,凭证就是用户自己的 API Key,存在本地 config.json。
不做云端同步。 没有服务端,没有账号,数据不出本机。代价是换机器要重新配置,但这符合工具的定位。
不做历史曲线。 只用本地状态文件记录"今天已经花了多少",不存长期时序。做历史就要考虑存储、聚合、图表缩放,会把这个 40 MB 的小工具撑成另一个产品。
不做跨平台。 WinForms + WebView2,只服务 Windows。跨平台意味着重写托盘和弹窗那一层,收益不足以justify。
不自动杀进程。 清理功能只做「扫描 + 建议 + 人工确认」,不做「一键优化」。理由在《三个关键技术决定》里详细展开了——判定逻辑有天花板,最后一公里必须留给人。
三、信息架构
四个界面,按"看一眼 → 想知道更多 → 要改配置 → 要维护"的深度递进:
托盘图标 —— 一眼:余额或今日消耗
└─ 悬停 tooltip —— 扫一眼:两家账摘要 + 峰谷
└─ 浮窗 —— 细看:双页签完整面板
├─ DeepSeek 页:余额、消耗、指标、峰谷轴
└─ GLM 页:套餐等级、三档额度、刷新时间
└─ 设置窗口 —— 配置:Key、刷新间隔、显示模式、日志
清理窗口是独立入口,从托盘右键直接打开,不嵌在浮窗里——它不是日常动作,不该占用高频界面。
四、两个页签而不是一个统一面板
最开始的设想是"把两家余额并成一个总览",做到一半发现行不通。
| DeepSeek | GLM | |
|---|---|---|
| 核心数字 | 金额(元) | 百分比 |
| 能换算吗 | 是 | 否 |
| 用完的后果 | 服务中断 | 等窗口刷新 |
GLM 的额度不能折算成金额。它不是"你还有 37 块钱额度",而是"这个 5 小时窗口还能用 62%"。同样是 62%,Lite 和 Max 套餐背后是完全不同的算力。
强行抽象成一个"总剩余量"会造出一个没有意义的数字。所以放弃统一,改成两个页签——承认它们语义不同,比造一个假统一更诚实。
五、交互原则
托盘要能"不说话"。 图标的职责是让你瞥一眼就知道状态,不需要点开。所以金额压到 2–3 个字符(233 / 1.3k),去掉货币符号,读不出来时显示 !,欠费显示 欠费。
tooltip 只做摘要。 NotifyIcon.Text 有 63 字符硬上限。定位是"扫一眼知道要不要点开",不是"完整信息"。完整信息留给浮窗。
浮窗失焦即收。 它是"看一眼就走"的东西,不该需要额外动作关闭。Esc 也能关。
危险操作加摩擦。 清理进程是唯一不可逆的动作,所以做成"扫描 → 列表 → 勾选 → 二次确认"四步。多两次点击换一次安心,值。
六、两个数据源的独立原则
设计上有一条硬约束:任一方失败不能影响另一方。
- DeepSeek 挂了,GLM 部分照常显示
- GLM 没配 Key,DeepSeek 部分完全不受影响
- 两个都挂,界面显示错误但托盘图标保持可读(显示
!)
这条约束决定了数据模型里 GlmSnapshot 是 PulseSnapshot 的可选字段,而不是必填。也决定了拉取逻辑里两段 try/catch 是独立的,不共用错误状态。
七、可维护性的取舍
日志默认开启。 这类小工具最常见的死法是"某个接口悄悄改版,用户只看到数字不对,也不知道为什么"。所以内置分级日志(DEBUG/INFO/WARN/ERROR + 模块名),设置窗口里能直接看最近 200 行,托盘右键一键打开。
原始响应落盘。 接口改版时最有用的东西是"上一次成功时返回了什么"。所以 sample-amount.json / sample-cost.json / sample-glm.json 会保留最近一次原始响应。
页面脚本错误要上报。 WebView2 里的 JS 异常默认是静默的,白屏了也查不到。所以挂了 window.onerror,把错误回传给宿主写进日志——这一条在开发阶段就救过我一次。
八、已知的能力边界
诚实地列出来,因为这些不是"以后优化"的问题,而是设计方案本身的限制:
- DeepSeek 精确用量依赖内部接口。 网页登录态随时可能失效,所以双轨降级不是可选项,是必需品。
- GLM 额度不含套餐到期日。 接口只给额度窗口,不给订阅周期。
- 峰谷的法定节假日无法自动判断。 官方规则说节假日全天低谷,但没有公开日历接口,只能手动在配置里加日期。
- 桌面应用没有 Web 地址。 这导致它无法按"作品必须有线上地址"的规则发到某些平台——工具本身的形态和平台模型存在错位。
- 进程残留判定有天花板。 纯Admin、无窗口、父进程又Sign out的服务型进程,会被判成孤儿。没有可靠的通用信号区分"安静地服务"和"安静地僵死"。