CodexBar 中 Vertex AI Provider 的实现剖析:gcloud ADC 凭证、Cloud Monitoring 配额查询与 Claude 日志成本识别

发布时间:2026/9/13 4:26:28
CodexBar 中 Vertex AI Provider 的实现剖析:gcloud ADC 凭证、Cloud Monitoring 配额查询与 Claude 日志成本识别 CodexBar 中 Vertex AI Provider 的实现剖析gcloud ADC 凭证、Cloud Monitoring 配额查询与 Claude 日志成本识别【免费下载链接】CodexBarShow usage stats for OpenAI Codex and Claude Code, without having to login.项目地址: https://gitcode.com/GitHub_Trending/co/CodexBarCodexBar 的 Vertex AI Provider 通过 gcloud Application Default CredentialsADC完成免登录认证调用 Cloud Monitoring timeSeries API 计算配额使用率并借助本地 Claude Code 日志~/.claude/projects/中的vrtx标识与格式模型名识别 Vertex AI 的 token 成本。读完本文你能完整理解从凭证加载、token 刷新、监控指标过滤到配额序列匹配与成本归类的整条数据链路并能独立排查「无配额数据」「无成本数据」「认证失败」三类典型问题。数据源与取数路径Vertex AI 的用量获取只有一条路径OAuth via gcloud ADC即从 gcloud 配置目录读取application_default_credentials.json再基于 Cloud Monitoring 的 time-series 指标计算配额用量。这一点在 Provider 描述文件中可以直接印证——取数管线只注册了一个策略fetchPlan: ProviderFetchPlan( sourceModes: [.auto, .oauth], pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [VertexAIOAuthFetchStrategy()] })),见 VertexAIProviderDescriptor.swift。由于不存在第二个策略该 Provider 的usesAccountFallback也为false认证失败时不会走任何账号回退逻辑只能依靠策略自身的shouldFallback判定凭证缺失、401/403 时视为可回退即直接标记为不可用。OAuth 凭证ADC 文件的定位与解析认证命令按 docs/vertexai.md 的说明前置条件只有两条命令# 1) 完成 OAuth 登录生成 application_default_credentials.json gcloud auth application-default login # 2) 指定默认项目 gcloud config set project PROJECT_IDCodexBar 内置的登录流程会弹出一个提示窗口点击 Open Terminal 后实际执行的是带完整 scope 的版本见 VertexAILoginFlow.swiftgcloud auth application-default login \ --scopesopenid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform登录窗口关闭后StatusItemController会等待 2 秒并触发一次store.refresh()无需手动刷新。凭证文件查找顺序VertexAIOAuthCredentials.swift 中的credentialsFilePath()按以下优先级定位 ADC 文件环境变量GOOGLE_APPLICATION_CREDENTIALS指向的显式路径可指向服务账号 JSON环境变量CLOUDSDK_CONFIG指定的 gcloud 配置目录下的application_default_credentials.json默认位置~/.config/gcloud/application_default_credentials.json。用户凭证解析时要求client_id、client_secret、refresh_token三者齐全缺失则分别抛出missingClientCredentials/missingTokens错误access_token允许缺失随后走刷新流程token_expiry字段以 ISO8601 格式解析email则从id_token的 JWT payload 中直接解码提取避免额外网络请求。项目 ID 的解析顺序loadProjectId()的取值链路是读取 gcloud 的默认配置~/.config/gcloud/configurations/config_default或CLOUDSDK_CONFIG下的同名文件解析 INI 风格的project PROJECT_ID行——这正是gcloud config set project写入的内容配置文件不存在或无 project 行时依次回退到环境变量GOOGLE_CLOUD_PROJECT、GCLOUD_PROJECT、CLOUDSDK_CORE_PROJECT。两者都拿不到项目 ID 时取数会直接抛出noProject错误提示执行gcloud config set project PROJECT_ID。服务账号支持从源码结构看ADC 文件若包含client_emailprivate_key服务账号特征loadForFetch不会尝试解析刷新令牌而是通过子进程执行gcloud auth application-default print-access-token由 gcloud 自身完成签名换 tokenCodexBar 只负责清洗输出并构造一个 50 分钟有效期的临时凭证。这意味着服务账号路径依赖本机 gcloud CLI 可用。Token 刷新VertexAITokenRefresher.swift 实现了标准 OAuth 刷新触发条件needsRefresh即距token_expiry不足 5 分钟无过期时间则视为需要刷新端点POST https://oauth2.googleapis.com/tokengrant_typerefresh_token携带client_id/client_secret/refresh_token错误映射invalid_grant→ refresh token 过期unauthorized_client→ refresh token 被吊销两者都提示重新执行gcloud auth application-default login刷新成功后更新access_token、按expires_in默认 3600 秒重算过期时间并尝试从新的id_token刷新账号 email。需要说明的是凭证刷新结果只在内存中缓存save()是空实现应用不会修改 gcloud 自己的凭证文件。API 端点Cloud Monitoring timeSeries配额数据来自两个监控指标过滤器在 VertexAIUsageFetcher.swift 中硬编码指标过滤条件用量serviceruntime.googleapis.com/quota/allocation/usageresource.typeconsumer_quota AND resource.label.serviceaiplatform.googleapis.com限额serviceruntime.googleapis.com/quota/limit同上请求构造为GET https://monitoring.googleapis.com/v3/projects/{PROJECT_ID}/timeSeries关键查询参数为filter上表两个过滤器之一interval.startTime/interval.endTime最近24 小时窗口usageWindowSeconds 24 * 60 * 60aggregation.alignmentPeriod3600s、aggregation.perSeriesAlignerALIGN_MAX按 1 小时对齐取峰值viewFULL并循环处理nextPageToken直到取完所有分页。响应按 HTTP 状态码分类处理401 →unauthorized提示重跑gcloud auth application-default login403 →forbidden提示检查 IAM 中 Cloud Monitoring 的访问权限其余非 200 一律包装响应体为invalidResponse。配额序列的匹配与聚合逻辑原始 timeSeries 不能直接使用makeQuotaUsageResponse完成了文档中 Mapping 一节描述的全部语义1. 构建序列键。每条序列提取为三元组QuotaKey(quotaMetric, limitName, location)quotaMetric取自metric.labels[quota_metric]回退到resource.labels[quota_id]limitName取自metric.labels[limit_name]用量序列通常没有为空串location取自resource.labels[location]缺省为global。2. 按键聚合。同一键的多条序列取点值最大值ALIGN_MAX之外的二次保护兼容doubleValue与int64Value两种点值类型。3. 用量与限额配对。matchingLimit采用两级策略精确匹配用量键与限额键三元组完全一致且限额 0唯一候选回退当用量序列没有limit_name时在同quotaMetric 同location的限额中若恰好只有 1 个候选则采用存在多个候选区域限额歧义则放弃该序列。4. 汇报最大值。对所有成功配对的序列计算usage / limit * 100最终requestsUsedPercent为其中的最大值——即文档所述 Reports the highest usage percent across matched series。两侧序列均缺失或无一配对时抛noData。这个noData在策略层被刻意降级VertexAIProviderDescriptor.swift 中捕获noData后将 usage 置空继续返回快照——因为本地 token 成本不依赖 Cloud Monitoring即使近 24 小时没有 Vertex 请求成本面板仍可用。取数成功后UsageSnapshot.identity会携带账号 email 与项目 IDloginMethod: gcloud用于菜单栏展示身份。对应的回归测试见 VertexAIUsageFetcherTests.swiftfixtures 覆盖了精确命名匹配、无 limit_name 匹配与区域限额歧义三种场景例如 exact-named-usage.json 与 ambiguous-regional-limits.json。Token 成本跟踪如何从 Claude 日志中识别 Vertex AI 条目Vertex AI 上的 Claude 使用记录与直接调用 Anthropic API 的记录写入同一批本地文件~/.claude/projects/下的.jsonl。区分两者是成本归类的核心识别逻辑集中在 CostUsageScannerClaude.swift 的isVertexAIUsageEntry实际是三层判定代码中的顺序比文档更细文档强调的后两层完全一致第一层vrtx消息/请求 ID代码中标注为 Primary。Vertex AI 的 message ID 与 request ID 带vrtx前缀例如msg_vrtx_0154LUXjFVzQGUca3yK2RUeo、req_vrtx_011CWjK86SWeFuXqZKUtgB1H。只要message.id或顶层requestId包含_vrtx_即判为 Vertex AI 条目。这是最可靠的信号因为不受模型名归一化影响。第二层模型名版本分隔符。文档标注的 primary 判据Vertex AIclaude-opus-4-520251101Anthropic APIclaude-opus-4-5-20251101实现上modelNameLooksVertex要求模型名以claude-开头且包含。注意文档的告警依然成立如果 Claude Code 在写日志时把模型名归一化为-格式且没有vrtxID 或元数据兜底条目将无法与直接 API 用量区分。第三层元数据字段fallback。对整条记录做递归遍历命中即判定键名或值包含vertex大小写不敏感的字节级扫描避免 Unicode 组合字符干扰顶层键名同时匹配gcp命中一组预定义「提供者类」键provider、platform、backend、api_provider、source、vendor、client等且其值为vertex标记——即文档中metadata.provider: vertexai这类场景。扫描器还提供vertexAIOnly/excludeVertexAI两种过滤模式供成本口径选择「仅统计 Vertex AI」或「排除 Vertex AI」。分类器行为有专门测试CostUsageClaudeVertexClassifierTests.swift。看到 Vertex AI 成本的前置条件按文档要求需要在 CodexBar 中同时满足Settings → Providers 中启用Vertex AI该 Provider 默认关闭defaultEnabled: falseSettings → General 中开启 Show cost summaryClaude Code 实际走 Vertex AI例如cv别名设置ANTHROPIC_MODELclaude-opus-4-520251101且日志保留格式或vrtxID。启用后菜单卡片会以内联 token 成本仪表盘呈现描述文件中supportsTokenCost: true、supportsInlineTokenCostDashboard: true若无成本数据提示文案为 No Vertex AI cost data found in Claude logs. Ensure entries include Vertex metadata.。故障排查结合文档的三条排查项与源码错误类型完整对照如下症状可能原因处理无配额数据项目未开启 Cloud Monitoring API或账号缺少相应 IAM 权限确认所选项目可用 Cloud Monitoring403 时检查 IAM 权限无配额数据且无报错近 24 小时无 Vertex 请求属正常noData降级本地 token 成本仍会展示无成本数据~/.claude/projects/不存在或缺少带 Vertex 标记的.jsonl检查 Claude Code 日志目录确认模型名含或存在vrtxID / vertex 元数据认证问题ADC 文件缺失、refresh token 过期或被吊销重跑gcloud auth application-default login服务账号场景检查 gcloud CLI 可用性No Google Cloud project configured未设置默认项目gcloud config set project PROJECT_ID或设置GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT/CLOUDSDK_CORE_PROJECT相关实现与测试入口凭证解析 VertexAIOAuthCredentials.swift测试 VertexAIOAuthCredentialsTests.swift、监控取数与匹配 VertexAIUsageFetcher.swift、成本分类 CostUsageScannerClaude.swift。【免费下载链接】CodexBarShow usage stats for OpenAI Codex and Claude Code, without having to login.项目地址: https://gitcode.com/GitHub_Trending/co/CodexBar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考