如果你是一名 macOS 开发者,或者深度依赖 Claude Code 或 Codex 这类 AI 编程助手,那么下面这个场景你一定不陌生:
你正全神贯注地编写代码,AI 助手在侧边栏或独立的聊天窗口中与你协作。突然,一个想法闪过,你想快速确认一下今天还剩下多少 AI 使用额度,或者当前模型的状态。于是,你不得不:
- 切换到浏览器,找到 Claude 或 Codex 的官网。
- 登录账户,在层层菜单中找到“用量”或“账单”页面。
- 或者,在 IDE 里打开 AI 助手的设置面板,寻找相关的状态信息。
这个过程打断了你的“心流”,浪费了宝贵的专注时间。更糟糕的是,如果你使用的是按 token 计费的服务,或者有严格的月度限额,这种“盲用”状态可能会带来意外的成本或服务中断。
这正是开源项目AI Usage要解决的核心痛点。它不是一个功能繁杂的 AI 工具,而是一个极其专注的“状态显示器”。它的全部使命,就是将一个开发者最关心的信息——Claude Code 和 Codex 的实时使用额度与限额——直接、永久地显示在你的 macOS 菜单栏上。
想象一下,就像你随时可以瞥一眼菜单栏右上角,看到 Wi-Fi 信号、电池电量或时间一样,现在你也能一眼看到:“Claude Code: 已用 120/500 请求”、“Codex: 剩余 $4.32”。这种“零认知负担”的信息获取方式,才是真正提升效率的细节。
本文将带你深入了解 AI Usage 这个工具。我们不止步于“它是什么”,而是要深入探讨:
- 为什么这样一个看似简单的工具,对现代 AI 辅助编程工作流如此重要?
- 它如何通过 SwiftUI 和原生 macOS 菜单栏集成,实现优雅且高效的状态监控?
- 作为开发者,如何从零开始配置、使用它,并理解其背后的技术实现与安全考量?
- 在实际使用中,可能会遇到哪些常见问题,又该如何解决?
无论你是想直接使用这个工具来优化自己的工作流,还是对如何开发一个类似的 macOS 原生状态栏应用感兴趣,这篇文章都将提供从理论到实践的完整指南。
1. 核心价值:告别“盲用”,实现 AI 资源精细化管理
在深入代码之前,我们必须先理解 AI Usage 项目诞生的背景和它要解决的深层问题。这不仅仅是“多了一个显示数字的小工具”,而是反映了 AI 工具深度融入开发生命周期后,所催生的新需求。
1.1 从“黑盒”到“透明化”:AI 辅助编程的成本意识
传统的代码补全工具(如早期的 IntelliSense)或本地 LSP 服务器,其成本往往是隐性的,一次性支付软件许可或消耗本地算力。但 Claude Code、GitHub Copilot、Codex 等基于云的大型语言模型(LLM)服务,其计费模式发生了根本性变化:
- 按量计费(Pay-as-you-go): 你的每一行建议代码、每一次代码解释,都在消耗 token,直接关联到你的钱包。
- 额度限制(Usage Limits): 许多服务为免费用户或特定套餐设置了每日/每月的请求次数、token 数量或金额上限。
- 模型选择影响成本: 使用更强大的模型(如 Claude 3.5 Sonnet vs. Haiku)成本差异巨大。
在这种模式下,“不知道自己用了多少”就成了一种实实在在的风险。你可能在调试一个复杂函数时,无意中让 AI 生成了大量冗余代码,消耗了远超预期的额度。或者,在月度末尾,因为额度用尽,关键的代码生成功能突然失效,打乱开发节奏。
AI Usage 所做的,就是将这个“黑盒”透明化。它把成本和使用量从需要主动查询的后台,推到了你视野的“常驻前台”,从而培养开发者的“AI 资源成本意识”。这类似于云服务商提供的消费预算告警,但更实时、更贴近操作环境。
1.2 菜单栏:被低估的高效信息入口
为什么选择菜单栏(Menu Bar)?这是 macOS(和类似设计的 Linux 桌面)交互哲学的精髓之一。
- 零交互成本: 菜单栏信息是被动可见的。你不需要点击、切换窗口或执行任何操作,只需抬眼一瞥。这与需要主动唤起的 Dock 图标、需要切换的 App 窗口有本质区别。
- 全局性与持久性: 无论你当前在全屏写代码、在浏览器查文档,还是在终端调试,菜单栏始终在最顶层。它提供了一种跨应用、跨工作空间的全局状态感知。
- 轻量级与无干扰: 一个精心设计的菜单栏应用只占用极小的空间,显示最精简的信息(通常是图标和数字/短文本),不会像弹窗或通知那样打断当前任务。
因此,将 AI 使用额度放在菜单栏,是信息呈现位置与开发者需求场景的完美匹配。它不是为了让你整天盯着看,而是在你需要做决策的瞬间(“这个重构问题要不要问 Claude?”),提供即时的数据支持。
1.3 AI Usage 的精准定位:做一件事,并做到极致
当前网络上有很多功能强大的 AI 工具箱,它们可能集成了聊天、文件分析、多种模型切换等复杂功能。AI Usage 则走了另一条路:单一功能深度优化。
它的功能清单非常短:
- 连接你的 Claude Code 和/或 Codex 账户。
- 定期(可配置)从官方 API 拉取使用量数据。
- 将数据格式化后显示在菜单栏。
- 点击菜单栏图标,可以查看更详细的信息或进行简单刷新。
这种“极简主义”带来了几个好处:
- 低资源占用: 它几乎不消耗 CPU 和内存。
- 高稳定性: 功能越简单,出错的概率越低。
- 专注核心体验: 所有开发都围绕“准确获取和清晰显示数据”这一核心,避免了功能膨胀带来的界面复杂和操作繁琐。
对于追求效率和简洁的开发者来说,这样一个“安静的后台哨兵”,远比一个“喧闹的全功能前台”更有价值。
2. 核心概念与技术栈解析
要理解和使用 AI Usage,需要厘清几个关键概念和技术选择。
2.1 关键概念澄清
- Claude Code: 通常指的是 Anthropic 公司推出的 Claude 模型在编程环境中的集成,例如通过 IDE 插件(如 VS Code 的 Claude 插件)或 API 调用来辅助代码生成、解释和调试。它背后是 Claude 系列模型。
- Codex: 这里是特指一个开源项目,它提供了一个本地运行的、可连接多种 AI 模型后端(如 OpenAI API、Anthropic Claude API、本地 Ollama 模型等)的代码助手服务。它本质上是一个代理层或网关,让你可以用统一的界面和配置来管理不同的 AI 模型。注意:这与 OpenAI 的 Codex 模型(已弃用)是两回事,切勿混淆。
- API 密钥(API Key): 这是 AI Usage 与 Claude 或 Codex 服务通信的“密码”。你需要从相应的服务商(如 Anthropic 官网)获取 Claude 的 API Key;如果使用 Codex 项目,则需要在 Codex 的配置中设置其自身的访问凭证。AI Usage 需要这些密钥来查询你的用量信息。
- 用量/限额端点(Usage/Limit Endpoint): 服务商提供的特定 API 接口,用于查询某个账户或 API 密钥在当前计费周期内的使用情况和限制。AI Usage 的核心就是定期调用这些端点并解析返回的 JSON 数据。
2.2 为什么选择 SwiftUI 和原生 macOS 开发?
从项目标题和热词“SwiftUI”可以推断,AI Usage 很可能是一个使用 SwiftUI 框架开发的纯原生 macOS 应用。这是一个关键且明智的技术选型。
| 特性 | SwiftUI (原生 macOS App) | 跨平台方案 (如 Electron, Tauri) | 优势分析 |
|---|---|---|---|
| 性能与资源占用 | 极低。直接调用系统 API,内存占用通常 < 50MB。 | 较高。需要打包 Chromium 内核,内存占用常在 100MB+。 | 对于常驻菜单栏的应用,低资源消耗是首要原则。原生应用优势巨大。 |
| 系统集成度 | 深度集成。可完美适配 macOS 的深色/浅色模式、菜单栏规范、通知中心等。 | 较浅。依赖桥接层,外观和行为可能略有“不原生”的感觉。 | 菜单栏应用需要“像系统的一部分”。SwiftUI 能提供最原生的视觉和交互体验。 |
| 开发体验 | 声明式 UI。SwiftUI 语法简洁,实时预览功能强大。 | 依赖 Web 技术。对于熟悉前端生态的开发者友好。 | SwiftUI 非常适合构建这种数据驱动、UI 相对简单的状态显示应用。 |
| 分发与安装 | 可通过 App Store、公证(Notarize)的 .dmg/.pkg 或 Homebrew Cask 分发。 | 可打包为 .dmg/.app 等。 | 两者均可,但原生应用在 macOS 生态中更容易被用户信任。 |
| 适合场景 | macOS 专属、追求极致体验和效率的工具。 | 需要同时支持多桌面操作系统的应用。 | AI Usage 的目标用户明确是 macOS 开发者,原生开发是更优解。 |
这个选择清晰地传达了项目的定位:为 macOS 平台打造一个高质量、高性能的专业工具。
3. 环境准备与安装部署
假设你已经从项目的发布页面(如 GitHub Releases)下载了最新版本的AI Usage.app。我们来看看如何安全、正确地完成初始配置。
3.1 获取必要的 API 密钥
AI Usage 本身不提供 AI 服务,它只是一个“显示器”。因此,你必须先拥有可用的服务账户。
1. 获取 Claude API 密钥:
- 访问 Anthropic 官方控制台(console.anthropic.com)。
- 注册并登录你的账户。
- 在账户设置或 API 密钥管理页面,创建一个新的密钥(API Key)。
- 重要安全提示: 这个密钥具有查询你账户用量和计费信息的权限。请像保护密码一样保护它。切勿泄露到公开代码库或论坛。
2. 配置 Codex(如果使用):
- 如果你本地部署了开源的 Codex 项目,它通常会提供一个 REST API 端点。
- Codex 的配置中需要你填入上游模型(如 OpenAI, Claude)的 API 密钥,并可能设置自身的访问令牌。
- 你需要从 Codex 的配置或文档中,找到用于查询用量的 API 端点地址和所需的认证信息(可能是 API Key,也可能是 Bearer Token)。
3.2 首次运行与权限配置
将AI Usage.app拖入“应用程序”文件夹后,首次启动可能会遇到系统安全提示。
# 如果从网上下载的App无法打开,可以尝试在终端执行以下命令绕过Gatekeeper(仅限你完全信任的开发者) # 请将 /Applications/AI\ Usage.app 替换为你的实际路径 sudo xattr -rd com.apple.quarantine /Applications/AI\ Usage.app更推荐的做法是:
- 在“系统设置” -> “隐私与安全性”中,找到允许从“已识别开发者”或“App Store 和被认可的开发者”处运行应用的选项。
- 如果应用未公证,你可能需要右键点击
.app文件,选择“打开”,并在弹出的对话框中确认打开。
首次运行后,AI Usage 会出现在菜单栏,并弹出一个配置窗口(或需要你从菜单栏图标的下拉菜单中进入设置)。
4. 核心配置详解
配置是让 AI Usage 工作的关键。我们通过一个模拟的配置界面来理解每个参数。
4.1 配置 Claude Code
在设置界面中,找到 Claude 相关的配置部分:
# 这是一个概念性的配置示例,并非实际文件 Claude Configuration: - API Key: sk-ant-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - Refresh Interval: 300 # 单位:秒,即每5分钟刷新一次 - Display Format: “已用 {used} / {limit} 请求” # 自定义菜单栏显示文本- API Key: 粘贴你从 Anthropic 控制台获取的密钥。
- Refresh Interval: 数据刷新频率。太频繁(如10秒)可能对 API 造成不必要的压力并消耗更多电量;太慢(如1小时)则信息更新不及时。300秒(5分钟)是一个比较平衡的默认值。
- Display Format: 定义在菜单栏上如何显示。你可以使用
{used},{limit},{remaining}等占位符来组合信息。例如,“Claude: ${remaining}”可以显示剩余金额。
4.2 配置 Codex
如果你使用本地的 Codex 服务,配置会略有不同:
# 这是一个概念性的配置示例,并非实际文件 Codex Configuration: - Base URL: http://localhost:8080 # 你的Codex服务地址 - API Endpoint: /api/usage # Codex提供的用量查询端点 - Auth Token: your_codex_access_token_here # 或 API Key - Refresh Interval: 180 # 每3分钟刷新 - Display Format: “Codex: {model} | 剩余 {remaining_requests} 次”- Base URL & API Endpoint: 这需要你查阅所部署的 Codex 项目的 API 文档。通常,Codex 会暴露一个用于查询当前配置下各模型使用情况的端点。
- Auth Token: Codex 项目自身的认证方式。它可能直接使用你配置在其中的上游 API Key,也可能有独立的令牌系统。
- Display Format: 这里可能支持更多占位符,如
{model}来显示当前活跃的模型名称。
4.3 安全存储最佳实践
API 密钥是最高敏感信息。一个设计良好的 macOS 菜单栏应用应该使用系统的钥匙串(Keychain)来安全地存储这些凭证。
- 应用行为检查: 在 AI Usage 的配置中保存密钥后,你可以打开“钥匙串访问”应用,搜索“AI Usage”或相关服务商名称,查看密钥是否被安全地存储在了“登录”钥匙串中。这是正确的做法。
- 开发者提示: 如果你是自己编译或开发类似应用,在 Swift 中使用
KeychainAPI 来存储密码和密钥,而不是存储在UserDefaults或明文文件中。
// Swift 中使用 Keychain 存储密码的简化示例(Security框架) import Security func saveAPIKeyToKeychain(service: String, account: String, key: String) -> Bool { guard let data = key.data(using: .utf8) else { return false } let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, kSecValueData as String: data ] SecItemDelete(query as CFDictionary) // 先删除旧项 let status = SecItemAdd(query as CFDictionary, nil) return status == errSecSuccess }5. 运行状态与效果验证
配置完成后,AI Usage 应该开始正常工作。以下是验证步骤:
5.1 验证菜单栏显示
- 观察菜单栏右上角,应该会出现 AI Usage 的图标(可能是一个大脑图标、代码符号或简单的文字“AI”)。
- 图标旁边或替代图标,应该会显示你配置的
Display Format文本,例如“C: 45/500”或“$8.21”。 - 这个数字应该是动态的。你可以去使用一下 Claude Code 插件,执行几次代码生成,等待一个刷新周期(如5分钟)后,观察菜单栏的数字是否增加。
5.2 验证详细视图
点击菜单栏的 AI Usage 图标,通常会显示一个下拉菜单。这个菜单里应该包含更详细的信息,例如:
- 分别列出 Claude 和 Codex 的用量。
- 显示当前计费周期的起止时间。
- 显示已用额度、总限额和剩余额度的百分比或具体数值。
- 提供“立即刷新”、“打开设置”、“退出应用”等操作按钮。
5.3 验证网络请求
如果显示一直为“加载中”或“错误”,你需要排查网络或配置问题。macOS 提供了一个强大的内置工具Console(控制台)来查看应用日志。
- 打开“聚焦搜索”(Cmd+Space),输入“控制台”并打开。
- 在左侧设备列表下选择你的 Mac,然后在右上角搜索栏输入“AI Usage”或应用的 Bundle Identifier(如果知道)。
- 观察是否有错误日志。常见的错误可能包括:
Invalid API Key: API 密钥错误。Network connection lost: 无法连接到服务端点。Unexpected response format: API 返回的数据格式与预期不符。
6. 常见问题与排查思路
即使配置正确,你也可能会遇到一些问题。下表列出了常见问题及其解决方法:
| 问题现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
| 菜单栏无显示 | 1. 应用未成功启动。 2. 应用已启动但图标被系统菜单栏隐藏。 | 1. 检查“活动监视器”中是否有AI Usage进程。2. 按住 Cmd 键拖动菜单栏其他图标,看是否能发现被隐藏的 AI Usage 图标。 | 1. 重新启动应用。 2. 在“系统设置”->“控制中心”中调整菜单栏图标的显示设置。 |
| 显示“Error”或“No Data” | 1. API 密钥无效或过期。 2. 网络连接问题。 3. 服务端 API 端点变更。 | 1. 检查 API 密钥是否复制完整(无多余空格)。 2. 尝试在浏览器中访问 Claude/Codex 官网,确认网络通畅。 3. 查看控制台应用日志。 | 1. 重新生成并配置 API 密钥。 2. 检查防火墙或代理设置。 3. 等待开发者更新应用以适配新的 API。 |
| 数据长时间不更新 | 1. 刷新间隔设置过长。 2. 应用后台刷新被系统限制。 3. API 请求失败导致静默错误。 | 1. 检查设置中的刷新间隔。 2. 在“系统设置”->“通用”->“登录项”中,确保 AI Usage 有“在后台运行”的权限。 3. 查看控制台日志。 | 1. 将刷新间隔调整为 180-300 秒。 2. 确保应用在登录时自动打开,并授予必要的权限。 3. 手动点击菜单栏中的“刷新”按钮。 |
| 同时显示 Claude 和 Codex 时混淆 | 两者配置的显示格式(Display Format)太相似。 | 对比菜单栏显示和下拉详情。 | 修改Display Format,使其易于区分。例如:“Claude: {used}”和“Codex: {remaining}”。 |
| 应用意外退出 | 1. 与 macOS 系统版本不兼容。 2. 遇到未处理的异常错误。 | 1. 检查应用的系统要求。 2. 查看控制台在应用退出瞬间的崩溃报告。 | 1. 检查是否有新版本更新。 2. 向项目开发者提交 Issue,附上崩溃日志。 |
7. 进阶使用与最佳实践
当你熟练使用基础功能后,可以考虑以下进阶实践,让这个工具更好地为你服务。
7.1 自定义显示与通知
- 精简显示: 如果菜单栏空间紧张,可以只显示最关键的数字,比如只显示剩余请求数或剩余金额,甚至只显示一个百分比图标,将鼠标悬停时显示详情。
- 阈值告警: 高级的菜单栏应用可能支持设置阈值告警。例如,当 Claude 额度使用超过 80% 时,将菜单栏图标颜色变为橙色;超过 95% 时变为红色并发送一个系统通知。你可以关注 AI Usage 项目的更新,或者如果它是开源的,可以尝试自己实现这个功能。
- 多账户切换: 如果你有多个工作账户或个人账户,可以探索应用是否支持配置多套 API 密钥并快速切换。
7.2 与自动化工作流集成
macOS 的自动化工具非常强大,你可以将 AI Usage 的状态信息作为触发条件。
- 使用 Shortcuts(快捷指令): 虽然 AI Usage 本身可能不直接提供 AppleScript 接口,但你可以通过读取其可能存储在某个已知位置的状态缓存文件(需查阅项目文档),或者通过模拟点击菜单栏并捕获其辅助功能输出(较复杂)的方式,将额度信息接入“快捷指令”。例如,当额度低于 10% 时,自动发送一条提醒信息到 Slack 或 Telegram。
- 脚本监控: 如果你是高级用户,可以编写一个简单的 shell 脚本,定期调用 Claude 或 Codex 的用量 API(使用
curl),然后将结果输出到终端或记录到文件,实现更自定义的监控。
7.3 安全与隐私考量
- 密钥管理: 再次强调,永远不要在不受信任的第三方应用中输入你的 AI 服务 API 密钥。只从官方商店或你信任的开源项目作者处下载应用。AI Usage 这类工具,如果它是开源的,其代码透明度是建立信任的基础。
- 网络流量: 该应用发出的网络请求仅限于向 Anthropic 官方 API 或你指定的 Codex 服务地址查询用量信息。它不应该将你的密钥或用量数据发送到其他第三方服务器。你可以使用网络监控工具(如
Little Snitch或LuLu)来确认其网络行为是否符合预期。 - 权限审查: 一个菜单栏应用通常只需要网络访问权限和可能的位置服务(用于时区)。如果它要求访问通讯录、照片等不相关的权限,就需要保持警惕。
8. 对于开发者的启示:如何构建类似工具
如果你对 AI Usage 的实现原理感兴趣,或者想为自己常用的服务开发一个类似的菜单栏监控工具,这里有一些技术路径和要点。
8.1 技术架构概览
一个典型的 macOS 菜单栏状态监控应用,其核心架构可以简化为以下组件:
- UI 层 (SwiftUI Views): 负责渲染菜单栏图标、下拉菜单和设置窗口。
- 状态管理层 (ObservableObject/ViewModel): 持有当前的使用量数据、配置信息等,并驱动 UI 更新。
- 网络服务层 (APIService): 封装对 Claude、Codex 等外部 API 的调用,处理认证、请求和响应解析。
- 定时器/调度器: 按配置的间隔触发数据刷新。
- 持久化存储 (Keychain/UserDefaults): 安全存储 API 密钥,持久化用户配置。
8.2 核心代码片段示例
以下是用 SwiftUI 构建一个极简菜单栏应用骨架的示例:
// 文件:AIUsageApp.swift import SwiftUI @main struct AIUsageApp: App { // 使用 @StateObject 持有全局状态 @StateObject private var usageMonitor = UsageMonitor() var body: some Scene { // 主场景是一个 Settings,用于打开偏好设置窗口 Settings { SettingsView() .environmentObject(usageMonitor) } // 关键:定义一个 MenuBarExtra (macOS 13+) 或使用 NSStatusItem (传统方式) MenuBarExtra("AI Usage", systemImage: "brain.head.profile") { // 这里是点击菜单栏图标后显示的下拉菜单内容 MenuBarContentView() .environmentObject(usageMonitor) } .menuBarExtraStyle(.window) // 或 .menu } } // 文件:UsageMonitor.swift import Foundation import Combine class UsageMonitor: ObservableObject { @Published var claudeUsage: String = "Loading..." @Published var codexUsage: String = "Loading..." private var timer: Timer? func startMonitoring(refreshInterval: TimeInterval = 300) { fetchUsage() // 立即获取一次 timer = Timer.scheduledTimer(withTimeInterval: refreshInterval, repeats: true) { [weak self] _ in self?.fetchUsage() } } private func fetchUsage() { // 异步调用网络服务层 Task { let claudeResult = await ClaudeAPIService.fetchUsage() let codexResult = await CodexAPIService.fetchUsage() await MainActor.run { self.claudeUsage = claudeResult self.codexUsage = codexResult } } } }// 文件:MenuBarContentView.swift import SwiftUI struct MenuBarContentView: View { @EnvironmentObject var monitor: UsageMonitor var body: some View { VStack(alignment: .leading, spacing: 8) { Text("Claude: \(monitor.claudeUsage)") .font(.caption) Text("Codex: \(monitor.codexUsage)") .font(.caption) Divider() Button("Refresh Now") { monitor.startMonitoring() // 触发一次立即刷新 } Button("Settings...") { // 打开设置窗口的逻辑 NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil) } Divider() Button("Quit") { NSApplication.shared.terminate(nil) } } .padding() } }8.3 关键实现细节
- 后台运行与唤醒: 确保应用在菜单栏点击后,即使没有打开主窗口,也能保持活动状态并执行定时任务。正确配置 App Sandbox 和后台模式。
- API 响应解析: Claude 和 Codex 的用量 API 返回的 JSON 结构可能不同且会变化。代码需要有健壮的解析逻辑和错误处理。
- 线程安全: 网络请求在后台线程完成,更新 UI 必须在主线程(
MainActor)。 - 内存管理: 避免在常驻应用中产生内存泄漏,特别是在使用 Combine 或异步任务时。
AI Usage 这个项目展示了一个优秀工具应有的特质:敏锐地发现一个具体而微小的痛点,并用最恰当的技术方案优雅地解决它。它不试图取代 Claude 或 Codex,而是作为它们的“伴侣应用”,填补了工作流中“状态感知”这一环。
对于使用者而言,它意味着更精细的成本控制、更流畅的编程体验和更少的上下文切换。对于开发者而言,它是一个学习 SwiftUI、macOS 原生开发以及如何设计一款“好工具”的绝佳范例。在 AI 工具日益普及的今天,如何让它们更好地融入并增强现有工作流,而非制造新的摩擦,是每一个工具创造者都需要思考的问题。从这个角度看,AI Usage 的价值,远不止于菜单栏上的那几个数字。