Skip to main content
Skip to content

使用情况和计费指标

本指南演示如何从 Copilot SDK 应用程序读取令牌计数、上下文窗口利用率、AI 信用额度和帐户配额。 TypeScript、Python、Go、.NET、Java 和 Rust 都显示了示例。

提示

每个示例在不同语言中在功能上都是等效的。 默认情况下,TypeScript 代码片段已展开;从可折叠块中选择语言,以查看该 SDK 中的相同逻辑。

概述

SDK 通过两种互补机制显示使用情况数据:

  • 会话事件:运行时在轮次运行期间发出的临时事件。 订阅这些内容,即可获取实时的每次 API 调用数据。
  • RPC 方法:按需发起的请求/响应调用。 使用这些功能可对累计总数进行快照,或查询账户级配额。

下表将每个信号映射到公开它的 API。

信号APIScope类型
每次调用的令牌计数
assistant.usage 事件会话事件
上下文窗口利用率
session.usage_info 事件会话事件
上下文窗口细分(按需)session.metadata.contextInfo会话RPC
累积的 AI 信用额度和令牌总计session.usage.getMetrics会话RPC
按模型的 AI 积分定价models.list服务器RPC
账户配额与高级版的相互作用account.getQuota服务器RPC
会话所有的提供程序配额观测值
session.quota.get 和 session.quota.refresh会话RPC
提供方准入状态更新session.quota_observation会话事件

session.quota.get 读取本地运行时状态; session.quota.refresh 刷新提供程序目录和配额源。 两者都返回 providerQuotas,以提供程序标识、配额 ID 和观察类型为键。 运行时保留一个观测存储。 旧 snapshots 字段是权威预算的派生兼容性视图,而不是配额状态的第二个源。

提供程序基数是提供给 seam 的实际使用情况和观测的涌现属性。 此 API 既不知道也不强制用户可能使用的提供程序数量:它以相同方式记录和投影零个、一个或多个条目。 生产者提供稳定的提供程序/帐户范围的引用标识;使用情况添加了模型标识,配额增加了配额标识和观察类型。 get() 返回完整的已知集合,因此调用方可以选择确切的键、子集或所有条目,而无需提供程序特定的方法。 Acquisition 使用上游账户/模型层提供的源;它不会构造联合,也不会在读取时应用所选提供程序筛选条件。

在解读读数之前,检查observationKind、quantityKind和acquisitionStatus。 一个 authoritative_budget 可以提供进度和重置元数据。 advisory_balance 报告独立的已签名 64 位数量,无需承诺百分比、重置窗口或呼叫后余额。 admission_state 在请求准入时报告权限/容量,不携带数量;它不会替代账户余额。 保留缺失的值和显式 null,而不是将它们转换为零。 失败或不可用的获取操作不是配额耗尽。

对于 智能 Microsoft 365 Copilot 副驾驶®,访问和容量是服务判定,而数量是建议性的。 例如,allowed/available 如果两个数量显式为零,则表示 0/ 0 AIC 已报告,而不是 100% 已使用或不一致状态。 缺少授权不同于零个授权。 -1授权哨兵值表示无限授权,而无需更改报告的容量状态。 推理标头可以反映缓存的准入状态;这些标头和按需配额刷新都不会确定前一次调用的费用。

使用情况总计属于会话,而不是活动帐户。 在 CLI 中,切换离开非空的 智能 Microsoft 365 Copilot 副驾驶® 会话时,需要启动新会话。 上一个会话保留其使用情况和历史记录,以便恢复时使用;新会话将启动其自己的总计。

注意

session.quota、session.usage.getMetrics、session.metadata.contextInfo 和 session.metadata.recomputeContextTokens 在生成的 RPC 界面中被标记为实验性。 在 .NET 中,它们会触发 GHCP001 实验性诊断信息,您可以通过 #pragma warning disable GHCP001 或项目级别的 <NoWarn>GHCP001</NoWarn> 来抑制该信息。 如果您的应用程序依赖于 SDK 和 Copilot CLI 运行时,请将二者均固定版本。

下面的字段表仅列出本页上示例中使用的字段。 完整且始终保持最新的字段参考由生成的 SDK 类型和 流式处理会话事件 构成,后者会在每次依赖项升级时根据 CLI 架构重新生成。 将这些内容视为事实来源,此页面作为面向任务的指南。

每次调用的令牌计数

在一次轮次中,每发生一次模型 API 调用(包括由子代理发起的调用),都会发出一次 assistant.usage 事件。 其中包含该次调用的 token 数量和计费乘数。

下面的示例使用这些字段。 有关完整列表,请参阅 流式处理会话事件 ,包括缓存、推理、延迟和跟踪字段。

领域类型Description
modelstring此调用的模型标识符
inputTokensnumber消耗的输入令牌
outputTokensnumber生成的输出令牌
costnumber应用于此次调用的高级请求倍数

提示

assistant.usage 是临时的,因此在恢复会话时会实时传送,但不会重播。 若要事后读取累计总数,请调用 session.usage.getMetrics(请参阅 累计 AI 额度和令牌总数)。

代码语言 navigation

TypeScript
session.on("assistant.usage", (event) => {
    const { model, inputTokens, outputTokens, cost } = event.data;
    console.log(
        `${model}: in=${inputTokens ?? 0} out=${outputTokens ?? 0} cost=${cost ?? 0}`,
    );
});

上下文窗口利用率

令牌计数可以告诉你每次调用消耗了多少令牌。 上下文窗口利用率会告诉你模型提示窗口现在有多完整,这对于在自动压缩开始之前显示进度栏或警告用户非常有用。

通过 获取实时更新

每当上下文窗口大小发生更改时,运行时都会发出事件 session.usage_info 。 该示例使用 currentTokens 并 tokenLimit;有关完整有效负载,请参阅 流式处理会话事件 。

领域类型Description
currentTokensnumber当前位于上下文窗口中的令牌
tokenLimitnumber模型上下文窗口的最大标记数

代码语言 navigation

TypeScript
session.on("session.usage_info", (event) => {
    const { currentTokens, tokenLimit } = event.data;
    const pct = Math.round((currentTokens / tokenLimit) * 100);
    console.log(`Context: ${currentTokens}/${tokenLimit} (${pct}%)`);
});

使用 session.metadata.contextInfo 进行按需分解

事件仅在上下文发生变化时触发。 若要随时读取当前细目(例如,在恢复会话后)调用 session.metadata.contextInfo。 将 0 传递给 promptTokenLimit 以使用运行时默认值;如果 0 的值未知,则将 outputTokenLimit 传递给 0。

在会话初始化完成之前(即系统提示和工具元数据已被缓存),结果的 contextInfo 为 null。 它把总数分解成 systemTokens, conversationTokens并 toolDefinitionsTokens和 promptTokenLimit。

代码语言 navigation

TypeScript
const { contextInfo } = await session.rpc.metadata.contextInfo({
    promptTokenLimit: 0,
    outputTokenLimit: 0,
});

if (contextInfo) {
    console.log(
        `Total ${contextInfo.totalTokens}/${contextInfo.promptTokenLimit} ` +
            `(system=${contextInfo.systemTokens}, conversation=${contextInfo.conversationTokens})`,
    );
}

累积的 AI 信用额度和令牌总计

session.usage.getMetrics 返回单个调用中整个会话的运行总计。 这是查看 AI 点数成本最简洁的方式,因为它会为你汇总所有 API 调用(包括主代理和子代理)。

该示例使用下面的字段。 生成的 UsageGetMetricsResult 类型是完整引用。

领域类型Description
totalNanoAiunumber整个会话的 AI 额度成本,以 nano-AI 单位计
totalPremiumRequestCostnumber所有模型的高级请求成本(经乘数调整后)
modelMetricsRecord<string, ModelMetric>按模型细分;每个条目都有 usage.inputTokens, usage.outputTokens和 totalNanoAiu

注意

成本以nano-AI 单位报告(该字段名为totalNanoAiu)。 AI 积分的具体换算方式以及“高级请求”计费的准确含义,均由 GitHub Copilot 的计费规则定义,而非 SDK——请将 GitHub 的 Copilot 计费文档 视为权威依据,并在向用户展示类似货币的数值之前先进行核实。 这些示例为了方便起见,采用除以 1e9 的方式,并遵循 SI 的 nano 前缀;在据此操作之前,请先确认这与当前的计费方式一致。 modelMetrics 和 tokenDetails 映射以运行时字符串(模型 ID 和令牌类型名称)为键,而 SDK 类型系统不会验证这些字符串。

代码语言 navigation

TypeScript
const metrics = await session.rpc.usage.getMetrics();

const aiCredits = (metrics.totalNanoAiu ?? 0) / 1e9;
console.log(`AI credits used: ${aiCredits.toFixed(6)}`);
console.log(`Premium requests: ${metrics.totalPremiumRequestCost}`);

for (const [model, m] of Object.entries(metrics.modelMetrics)) {
    if (!m) continue;
    console.log(
        `${model}: in=${m.usage.inputTokens} out=${m.usage.outputTokens} ` +
            `nanoAiu=${m.totalNanoAiu ?? 0}`,
    );
}

按模型的 AI 积分定价

若要在运行轮次之前估算成本,请从 models.list中读取每个模型的令牌价格。 这是客户端上的服务器作用域调用,因此不需要会话。 价格以每批计费令牌对应的 AI 积分表示。 生成的 ModelBillingTokenPrices 类型列出每个字段,包括 cachePrice。

领域类型Description
billing.multipliernumber相对于基础费率的高级请求成本乘数
billing.tokenPrices.inputPricenumber每批输入令牌对应的 AI 积分成本
billing.tokenPrices.outputPricenumber每批输出令牌的 AI 积分成本
billing.tokenPrices.batchSizenumber每个计费批次中的令牌数量

注意

随着计划和模型的发展,价格值会发生变化。 在运行时读取它们,如下所示;切勿将数字硬编码到应用程序中。

代码语言 navigation

TypeScript
const { models } = await client.rpc.models.list({});

for (const model of models) {
    const prices = model.billing?.tokenPrices;
    if (!prices) continue;
    console.log(
        `${model.id}: input=${prices.inputPrice} output=${prices.outputPrice} ` +
            `per ${prices.batchSize} tokens (x${model.billing?.multiplier ?? 1})`,
    );
}

账户配额与高级版的相互作用

account.getQuota 显示已通过身份验证的用户的剩余 Copilot 配额。 结果 quotaSnapshots 映射以配额类型为键 — 通常为 premium_interactions、chat 和 completions。 使用它可向用户显示每月津贴的剩余量,或在达到限制之前限制工作。

该示例使用下面的字段;生成的 AccountQuotaSnapshot 类型是完整引用。 quotaSnapshots 键是 SDK 类型系统不会验证的运行时字符串,因此请对查找操作做好防护。

领域类型Description
entitlementRequestsnumber包含在配额内的请求,或 -1 表示无限制
usedRequestsnumber本周期迄今已使用的请求
remainingPercentagenumber剩余权利百分比
resetDatestring配额重置日期(ISO 8601 格式)

提示

若要读取特定用户的配额,而不是连接的全局身份验证上下文(例如,在多租户后端中),请将该用户的GitHub令牌传递给getQuota。 请参阅“多租户与服务器部署”。

代码语言 navigation

TypeScript
const { quotaSnapshots } = await client.rpc.account.getQuota({});
const premium = quotaSnapshots["premium_interactions"];

if (premium) {
    console.log(
        `Premium interactions: ${premium.usedRequests}/${premium.entitlementRequests} ` +
            `(${premium.remainingPercentage.toFixed(1)}% left, resets ${premium.resetDate ?? "n/a"})`,
    );
}

选择正确的 API

使用此摘要来确定哪种 API 适合你的用例:

  • 在回合运行时渲染实时成本或代币计量表:订阅 assistant.usage 和 session.usage_info。
  • 在每轮对话或会话结束后显示最终成本摘要:调用 session.usage.getMetrics。
  • 恢复时,在任何新回合开始前显示上下文窗口的使用情况:调用 session.metadata.contextInfo。
  • 在运行工作之前估算成本:读取 models.list 令牌价格。
  • 在用户耗尽计划之前警告用户:呼叫 account.getQuota。

延伸阅读