{"meta":{"title":"使用情况和计费指标","intro":"本指南演示如何从 Copilot SDK 应用程序读取令牌计数、上下文窗口利用率、AI 信用额度和帐户配额。 TypeScript、Python、Go、.NET、Java 和 Rust 都显示了示例。","product":"GitHub Copilot","breadcrumbs":[{"href":"/zh/copilot","title":"GitHub Copilot"},{"href":"/zh/copilot/how-tos","title":"操作方法"},{"href":"/zh/copilot/how-tos/copilot-sdk","title":"Copilot SDK"},{"href":"/zh/copilot/how-tos/copilot-sdk/features","title":"功能"},{"href":"/zh/copilot/how-tos/copilot-sdk/features/usage-and-billing","title":"使用情况和计费"}],"documentType":"article"},"body":"# 使用情况和计费指标\n\n本指南演示如何从 Copilot SDK 应用程序读取令牌计数、上下文窗口利用率、AI 信用额度和帐户配额。 TypeScript、Python、Go、.NET、Java 和 Rust 都显示了示例。\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n> \\[!TIP]\n> 每个示例在不同语言中在功能上都是等效的。 默认情况下，TypeScript 代码片段已展开;从可折叠块中选择语言，以查看该 SDK 中的相同逻辑。\n\n## 概述\n\nSDK 通过两种互补机制显示使用情况数据：\n\n* ```\n            **会话事件**：运行时在轮次运行期间发出的临时事件。 订阅这些内容，即可获取实时的每次 API 调用数据。\n  ```\n* **RPC 方法**：按需发起的请求/响应调用。 使用这些功能可对累计总数进行快照，或查询账户级配额。\n\n下表将每个信号映射到公开它的 API。\n\n| 信号                      | API                            | Scope | 类型  |\n| ----------------------- | ------------------------------ | ----- | --- |\n| 每次调用的令牌计数               |                                |       |     |\n| `assistant.usage` 事件    | 会话                             | 事件    |     |\n| 上下文窗口利用率                |                                |       |     |\n| `session.usage_info` 事件 | 会话                             | 事件    |     |\n| 上下文窗口细分（按需）             | `session.metadata.contextInfo` | 会话    | RPC |\n| 累积的 AI 信用额度和令牌总计        | `session.usage.getMetrics`     | 会话    | RPC |\n| 按模型的 AI 积分定价            | `models.list`                  | 服务器   | RPC |\n| 账户配额与高级版的相互作用           | `account.getQuota`             | 服务器   | RPC |\n\n> \\[!NOTE]\n> `session.usage.getMetrics`、`session.metadata.contextInfo` 和 `session.metadata.recomputeContextTokens` 在生成的 RPC 接口中被标记为实验性。 在 .NET 中，它们会触发 `GHCP001` 实验性诊断信息，您可以通过 `#pragma warning disable GHCP001` 或项目级别的 `<NoWarn>GHCP001</NoWarn>` 来抑制该信息。 如果您的应用程序依赖于 SDK 和 Copilot CLI 运行时，请将二者均固定版本。\n\n下面的字段表仅列出本页上示例中使用的字段。 完整且始终保持最新的字段参考由生成的 SDK 类型和 [流式处理会话事件](/zh/copilot/how-tos/copilot-sdk/features/streaming-events) 构成，后者会在每次依赖项升级时根据 CLI 架构重新生成。 将这些内容视为事实来源，此页面作为面向任务的指南。\n\n## 每次调用的令牌计数\n\n在一次轮次中，每发生一次模型 API 调用（包括由子代理发起的调用），都会发出一次 `assistant.usage` 事件。 其中包含该次调用的 token 数量和计费乘数。\n\n下面的示例使用这些字段。 有关完整列表，请参阅 [流式处理会话事件](/zh/copilot/how-tos/copilot-sdk/features/streaming-events#assistantusage) ，包括缓存、推理、延迟和跟踪字段。\n\n| 领域             | 类型       | Description    |\n| -------------- | -------- | -------------- |\n| `model`        | `string` | 此调用的模型标识符      |\n| `inputTokens`  | `number` | 消耗的输入令牌        |\n| `outputTokens` | `number` | 生成的输出令牌        |\n| `cost`         | `number` | 应用于此次调用的高级请求倍数 |\n\n> \\[!TIP]\n> `assistant.usage` 是临时的，因此在恢复会话时会实时传送，但不会重播。 若要事后读取累计总数，请调用 `session.usage.getMetrics`（请参阅 [累计 AI 额度和令牌总数](#accumulated-ai-credit-and-token-totals)）。\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\nconst session = await client.createSession({ streaming: true });\n\nsession.on(\"assistant.usage\", (event) => {\n    const { model, inputTokens, outputTokens, cost } = event.data;\n    console.log(\n        `${model}: in=${inputTokens ?? 0} out=${outputTokens ?? 0} cost=${cost ?? 0}`,\n    );\n});\n```\n\n```typescript\nsession.on(\"assistant.usage\", (event) => {\n    const { model, inputTokens, outputTokens, cost } = event.data;\n    console.log(\n        `${model}: in=${inputTokens ?? 0} out=${outputTokens ?? 0} cost=${cost ?? 0}`,\n    );\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient\nfrom copilot.session_events import SessionEventType\n\nclient = CopilotClient()\nsession = await client.create_session(streaming=True)\n\ndef on_usage(event):\n    if event.type == SessionEventType.ASSISTANT_USAGE:\n        data = event.data\n        print(f\"{data.model}: in={data.input_tokens or 0} out={data.output_tokens or 0} cost={data.cost or 0}\")\n\nsession.on(on_usage)\n```\n\n```python\ndef on_usage(event):\n    if event.type == SessionEventType.ASSISTANT_USAGE:\n        data = event.data\n        print(f\"{data.model}: in={data.input_tokens or 0} out={data.output_tokens or 0} cost={data.cost or 0}\")\n\nsession.on(on_usage)\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n\n    copilot \"github.com/github/copilot-sdk/go\"\n    \"github.com/github/copilot-sdk/go/rpc\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    client := copilot.NewClient(nil)\n    client.Start(ctx)\n\n    session, _ := client.CreateSession(ctx, &copilot.SessionConfig{\n        Streaming: copilot.Bool(true),\n        OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {\n            return &rpc.PermissionDecisionApproveOnce{}, nil\n        },\n    })\n\n    session.On(func(event copilot.SessionEvent) {\n        d, ok := event.Data.(*copilot.AssistantUsageData)\n        if !ok {\n            return\n        }\n        in, out, cost := int64(0), int64(0), float64(0)\n        if d.InputTokens != nil {\n            in = *d.InputTokens\n        }\n        if d.OutputTokens != nil {\n            out = *d.OutputTokens\n        }\n        if d.Cost != nil {\n            cost = *d.Cost\n        }\n        fmt.Printf(\"%s: in=%d out=%d cost=%g\\n\", d.Model, in, out, cost)\n    })\n    _ = session\n}\n```\n\n```golang\nsession.On(func(event copilot.SessionEvent) {\n    d, ok := event.Data.(*copilot.AssistantUsageData)\n    if !ok {\n        return\n    }\n    in, out, cost := int64(0), int64(0), float64(0)\n    if d.InputTokens != nil {\n        in = *d.InputTokens\n    }\n    if d.OutputTokens != nil {\n        out = *d.OutputTokens\n    }\n    if d.Cost != nil {\n        cost = *d.Cost\n    }\n    fmt.Printf(\"%s: in=%d out=%d cost=%g\\n\", d.Model, in, out, cost)\n})\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nusing GitHub.Copilot;\n\nawait using var client = new CopilotClient();\nawait using var session = await client.CreateSessionAsync(new SessionConfig { Streaming = true });\n\nsession.On<AssistantUsageEvent>(evt =>\n{\n    var data = evt.Data;\n    Console.WriteLine(\n        $\"{data.Model}: in={data.InputTokens ?? 0} out={data.OutputTokens ?? 0} cost={data.Cost ?? 0}\");\n});\n```\n\n```csharp\nsession.On<AssistantUsageEvent>(evt =>\n{\n    var data = evt.Data;\n    Console.WriteLine(\n        $\"{data.Model}: in={data.InputTokens ?? 0} out={data.OutputTokens ?? 0} cost={data.Cost ?? 0}\");\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nsession.on(AssistantUsageEvent.class, event -> {\n    var data = event.getData();\n    long in = data.inputTokens() != null ? data.inputTokens() : 0;\n    long out = data.outputTokens() != null ? data.outputTokens() : 0;\n    double cost = data.cost() != null ? data.cost() : 0.0;\n    System.out.printf(\"%s: in=%d out=%d cost=%s%n\", data.model(), in, out, cost);\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nuse github_copilot_sdk::session_events::AssistantUsageData;\n\nlet mut events = session.subscribe();\nwhile let Ok(event) = events.recv().await {\n    if event.event_type == \"assistant.usage\" {\n        if let Some(data) = event.typed_data::<AssistantUsageData>() {\n            println!(\n                \"{}: in={} out={} cost={}\",\n                data.model,\n                data.input_tokens.unwrap_or(0),\n                data.output_tokens.unwrap_or(0),\n                data.cost.unwrap_or(0.0),\n            );\n        }\n    }\n}\n```\n\n</div>\n\n</div>\n\n## 上下文窗口利用率\n\n令牌计数可以告诉你每次调用消耗了多少令牌。 上下文窗口利用率会告诉你模型提示窗口现在有多完整，这对于在自动压缩开始之前显示进度栏或警告用户非常有用。\n\n### 通过  获取实时更新\n\n每当上下文窗口大小发生更改时，运行时都会发出事件 `session.usage_info` 。 该示例使用 `currentTokens` 并 `tokenLimit`;有关完整有效负载，请参阅 [流式处理会话事件](/zh/copilot/how-tos/copilot-sdk/features/streaming-events#sessionusage_info) 。\n\n| 领域              | 类型       | Description   |\n| --------------- | -------- | ------------- |\n| `currentTokens` | `number` | 当前位于上下文窗口中的令牌 |\n| `tokenLimit`    | `number` | 模型上下文窗口的最大标记数 |\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\nconst session = await client.createSession({ streaming: true });\n\nsession.on(\"session.usage_info\", (event) => {\n    const { currentTokens, tokenLimit } = event.data;\n    const pct = Math.round((currentTokens / tokenLimit) * 100);\n    console.log(`Context: ${currentTokens}/${tokenLimit} (${pct}%)`);\n});\n```\n\n```typescript\nsession.on(\"session.usage_info\", (event) => {\n    const { currentTokens, tokenLimit } = event.data;\n    const pct = Math.round((currentTokens / tokenLimit) * 100);\n    console.log(`Context: ${currentTokens}/${tokenLimit} (${pct}%)`);\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient\nfrom copilot.session_events import SessionEventType\n\nclient = CopilotClient()\nsession = await client.create_session(streaming=True)\n\ndef on_usage_info(event):\n    if event.type == SessionEventType.SESSION_USAGE_INFO:\n        data = event.data\n        pct = round(data.current_tokens / data.token_limit * 100)\n        print(f\"Context: {data.current_tokens}/{data.token_limit} ({pct}%)\")\n\nsession.on(on_usage_info)\n```\n\n```python\ndef on_usage_info(event):\n    if event.type == SessionEventType.SESSION_USAGE_INFO:\n        data = event.data\n        pct = round(data.current_tokens / data.token_limit * 100)\n        print(f\"Context: {data.current_tokens}/{data.token_limit} ({pct}%)\")\n\nsession.on(on_usage_info)\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n\n    copilot \"github.com/github/copilot-sdk/go\"\n    \"github.com/github/copilot-sdk/go/rpc\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    client := copilot.NewClient(nil)\n    client.Start(ctx)\n\n    session, _ := client.CreateSession(ctx, &copilot.SessionConfig{\n        Streaming: copilot.Bool(true),\n        OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {\n            return &rpc.PermissionDecisionApproveOnce{}, nil\n        },\n    })\n\n    session.On(func(event copilot.SessionEvent) {\n        d, ok := event.Data.(*copilot.SessionUsageInfoData)\n        if !ok {\n            return\n        }\n        pct := int(float64(d.CurrentTokens) / float64(d.TokenLimit) * 100)\n        fmt.Printf(\"Context: %d/%d (%d%%)\\n\", d.CurrentTokens, d.TokenLimit, pct)\n    })\n    _ = session\n}\n```\n\n```golang\nsession.On(func(event copilot.SessionEvent) {\n    d, ok := event.Data.(*copilot.SessionUsageInfoData)\n    if !ok {\n        return\n    }\n    pct := int(float64(d.CurrentTokens) / float64(d.TokenLimit) * 100)\n    fmt.Printf(\"Context: %d/%d (%d%%)\\n\", d.CurrentTokens, d.TokenLimit, pct)\n})\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nusing GitHub.Copilot;\n\nawait using var client = new CopilotClient();\nawait using var session = await client.CreateSessionAsync(new SessionConfig { Streaming = true });\n\nsession.On<SessionUsageInfoEvent>(evt =>\n{\n    var pct = (int)Math.Round((double)evt.Data.CurrentTokens / evt.Data.TokenLimit * 100);\n    Console.WriteLine($\"Context: {evt.Data.CurrentTokens}/{evt.Data.TokenLimit} ({pct}%)\");\n});\n```\n\n```csharp\nsession.On<SessionUsageInfoEvent>(evt =>\n{\n    var pct = (int)Math.Round((double)evt.Data.CurrentTokens / evt.Data.TokenLimit * 100);\n    Console.WriteLine($\"Context: {evt.Data.CurrentTokens}/{evt.Data.TokenLimit} ({pct}%)\");\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nsession.on(SessionUsageInfoEvent.class, event -> {\n    var data = event.getData();\n    long pct = Math.round((double) data.currentTokens() / data.tokenLimit() * 100);\n    System.out.printf(\"Context: %d/%d (%d%%)%n\", data.currentTokens(), data.tokenLimit(), pct);\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nuse github_copilot_sdk::session_events::SessionUsageInfoData;\n\nlet mut events = session.subscribe();\nwhile let Ok(event) = events.recv().await {\n    if event.event_type == \"session.usage_info\" {\n        if let Some(data) = event.typed_data::<SessionUsageInfoData>() {\n            let pct = (data.current_tokens as f64 / data.token_limit as f64 * 100.0) as i64;\n            println!(\"Context: {}/{} ({}%)\", data.current_tokens, data.token_limit, pct);\n        }\n    }\n}\n```\n\n</div>\n\n</div>\n\n### 使用 `session.metadata.contextInfo` 进行按需分解\n\n事件仅在上下文发生变化时触发。 若要随时读取当前细目（例如，在恢复会话后）调用 `session.metadata.contextInfo`。 将 `0` 传递给 `promptTokenLimit` 以使用运行时默认值；如果 `0` 的值未知，则将 `outputTokenLimit` 传递给 `0`。\n\n在会话初始化完成之前（即系统提示和工具元数据已被缓存），结果的 `contextInfo` 为 `null`。 它把总数分解成 `systemTokens`， `conversationTokens`并 `toolDefinitionsTokens`和 `promptTokenLimit`。\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\nconst session = await client.createSession({});\n\nconst { contextInfo } = await session.rpc.metadata.contextInfo({\n    promptTokenLimit: 0,\n    outputTokenLimit: 0,\n});\n\nif (contextInfo) {\n    console.log(\n        `Total ${contextInfo.totalTokens}/${contextInfo.promptTokenLimit} ` +\n            `(system=${contextInfo.systemTokens}, conversation=${contextInfo.conversationTokens})`,\n    );\n}\n```\n\n```typescript\nconst { contextInfo } = await session.rpc.metadata.contextInfo({\n    promptTokenLimit: 0,\n    outputTokenLimit: 0,\n});\n\nif (contextInfo) {\n    console.log(\n        `Total ${contextInfo.totalTokens}/${contextInfo.promptTokenLimit} ` +\n            `(system=${contextInfo.systemTokens}, conversation=${contextInfo.conversationTokens})`,\n    );\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient\nfrom copilot.rpc import MetadataContextInfoRequest\n\nclient = CopilotClient()\nsession = await client.create_session()\n\nresult = await session.rpc.metadata.context_info(\n    MetadataContextInfoRequest(prompt_token_limit=0, output_token_limit=0)\n)\ninfo = result.context_info\n\nif info is not None:\n    print(\n        f\"Total {info.total_tokens}/{info.prompt_token_limit} \"\n        f\"(system={info.system_tokens}, conversation={info.conversation_tokens})\"\n    )\n```\n\n```python\nresult = await session.rpc.metadata.context_info(\n    MetadataContextInfoRequest(prompt_token_limit=0, output_token_limit=0)\n)\ninfo = result.context_info\n\nif info is not None:\n    print(\n        f\"Total {info.total_tokens}/{info.prompt_token_limit} \"\n        f\"(system={info.system_tokens}, conversation={info.conversation_tokens})\"\n    )\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n\n    copilot \"github.com/github/copilot-sdk/go\"\n    \"github.com/github/copilot-sdk/go/rpc\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    client := copilot.NewClient(nil)\n    client.Start(ctx)\n\n    session, _ := client.CreateSession(ctx, &copilot.SessionConfig{})\n\n    result, _ := session.RPC.Metadata.ContextInfo(ctx, &rpc.MetadataContextInfoRequest{\n        PromptTokenLimit: 0,\n        OutputTokenLimit: 0,\n    })\n\n    if info := result.ContextInfo; info != nil {\n        fmt.Printf(\"Total %d/%d (system=%d, conversation=%d)\\n\",\n            info.TotalTokens, info.PromptTokenLimit, info.SystemTokens, info.ConversationTokens)\n    }\n}\n```\n\n```golang\nresult, _ := session.RPC.Metadata.ContextInfo(ctx, &rpc.MetadataContextInfoRequest{\n    PromptTokenLimit: 0,\n    OutputTokenLimit: 0,\n})\n\nif info := result.ContextInfo; info != nil {\n    fmt.Printf(\"Total %d/%d (system=%d, conversation=%d)\\n\",\n        info.TotalTokens, info.PromptTokenLimit, info.SystemTokens, info.ConversationTokens)\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\n#pragma warning disable GHCP001\nusing GitHub.Copilot;\n\nawait using var client = new CopilotClient();\nawait using var session = await client.CreateSessionAsync(new SessionConfig());\n\nvar result = await session.Rpc.Metadata.ContextInfoAsync(promptTokenLimit: 0, outputTokenLimit: 0);\nvar info = result.ContextInfo;\n\nif (info is not null)\n{\n    Console.WriteLine(\n        $\"Total {info.TotalTokens}/{info.PromptTokenLimit} \" +\n        $\"(system={info.SystemTokens}, conversation={info.ConversationTokens})\");\n}\n#pragma warning restore GHCP001\n```\n\n```csharp\nvar result = await session.Rpc.Metadata.ContextInfoAsync(promptTokenLimit: 0, outputTokenLimit: 0);\nvar info = result.ContextInfo;\n\nif (info is not null)\n{\n    Console.WriteLine(\n        $\"Total {info.TotalTokens}/{info.PromptTokenLimit} \" +\n        $\"(system={info.SystemTokens}, conversation={info.ConversationTokens})\");\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nvar result = session.getRpc().metadata\n    .contextInfo(new SessionMetadataContextInfoParams(null, 0L, 0L, null))\n    .join();\nvar info = result.contextInfo();\n\nif (info != null) {\n    System.out.printf(\"Total %d/%d (system=%d, conversation=%d)%n\",\n        info.totalTokens(), info.promptTokenLimit(), info.systemTokens(), info.conversationTokens());\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nuse github_copilot_sdk::rpc::MetadataContextInfoRequest;\n\nlet result = session\n    .rpc()\n    .metadata()\n    .context_info(MetadataContextInfoRequest {\n        prompt_token_limit: 0,\n        output_token_limit: 0,\n        selected_model: None,\n    })\n    .await?;\n\nif let Some(info) = result.context_info {\n    println!(\n        \"Total {}/{} (system={}, conversation={})\",\n        info.total_tokens, info.prompt_token_limit, info.system_tokens, info.conversation_tokens,\n    );\n}\n```\n\n</div>\n\n</div>\n\n## 累积的 AI 信用额度和令牌总计\n\n`session.usage.getMetrics` 返回单个调用中整个会话的运行总计。 这是查看 AI 点数成本最简洁的方式，因为它会为你汇总所有 API 调用（包括主代理和子代理）。\n\n该示例使用下面的字段。 生成的 `UsageGetMetricsResult` 类型是完整引用。\n\n| 领域                        | 类型                            | Description                                                            |\n| ------------------------- | ----------------------------- | ---------------------------------------------------------------------- |\n| `totalNanoAiu`            | `number`                      | 整个会话的 AI 额度成本，以 nano-AI 单位计                                            |\n| `totalPremiumRequestCost` | `number`                      | 所有模型的高级请求成本（经乘数调整后）                                                    |\n| `modelMetrics`            | `Record<string, ModelMetric>` | 按模型细分;每个条目都有 `usage.inputTokens`， `usage.outputTokens`和 `totalNanoAiu` |\n\n> \\[!NOTE]\n> 成本以**nano-AI 单位**报告（该字段名为`totalNanoAiu`）。 AI 积分的具体换算方式以及“高级请求”计费的准确含义，均由 GitHub Copilot 的计费规则定义，而非 SDK——请将 [GitHub 的 Copilot 计费文档](/zh/copilot/concepts/billing) 视为权威依据，并在向用户展示类似货币的数值之前先进行核实。 这些示例为了方便起见，采用除以 `1e9` 的方式，并遵循 SI 的 `nano` 前缀；在据此操作之前，请先确认这与当前的计费方式一致。\n> `modelMetrics` 和 `tokenDetails` 映射以运行时字符串（模型 ID 和令牌类型名称）为键，而 SDK 类型系统不会验证这些字符串。\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\nconst session = await client.createSession({});\n\nconst metrics = await session.rpc.usage.getMetrics();\n\nconst aiCredits = (metrics.totalNanoAiu ?? 0) / 1e9;\nconsole.log(`AI credits used: ${aiCredits.toFixed(6)}`);\nconsole.log(`Premium requests: ${metrics.totalPremiumRequestCost}`);\n\nfor (const [model, m] of Object.entries(metrics.modelMetrics)) {\n    if (!m) continue;\n    console.log(\n        `${model}: in=${m.usage.inputTokens} out=${m.usage.outputTokens} ` +\n            `nanoAiu=${m.totalNanoAiu ?? 0}`,\n    );\n}\n```\n\n```typescript\nconst metrics = await session.rpc.usage.getMetrics();\n\nconst aiCredits = (metrics.totalNanoAiu ?? 0) / 1e9;\nconsole.log(`AI credits used: ${aiCredits.toFixed(6)}`);\nconsole.log(`Premium requests: ${metrics.totalPremiumRequestCost}`);\n\nfor (const [model, m] of Object.entries(metrics.modelMetrics)) {\n    if (!m) continue;\n    console.log(\n        `${model}: in=${m.usage.inputTokens} out=${m.usage.outputTokens} ` +\n            `nanoAiu=${m.totalNanoAiu ?? 0}`,\n    );\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient\n\nclient = CopilotClient()\nsession = await client.create_session()\n\nmetrics = await session.rpc.usage.get_metrics()\n\nai_credits = (metrics.total_nano_aiu or 0) / 1e9\nprint(f\"AI credits used: {ai_credits:.6f}\")\nprint(f\"Premium requests: {metrics.total_premium_request_cost}\")\n\nfor model, m in metrics.model_metrics.items():\n    print(f\"{model}: in={m.usage.input_tokens} out={m.usage.output_tokens} nanoAiu={m.total_nano_aiu or 0}\")\n```\n\n```python\nmetrics = await session.rpc.usage.get_metrics()\n\nai_credits = (metrics.total_nano_aiu or 0) / 1e9\nprint(f\"AI credits used: {ai_credits:.6f}\")\nprint(f\"Premium requests: {metrics.total_premium_request_cost}\")\n\nfor model, m in metrics.model_metrics.items():\n    print(f\"{model}: in={m.usage.input_tokens} out={m.usage.output_tokens} nanoAiu={m.total_nano_aiu or 0}\")\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n\n    copilot \"github.com/github/copilot-sdk/go\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    client := copilot.NewClient(nil)\n    client.Start(ctx)\n\n    session, _ := client.CreateSession(ctx, &copilot.SessionConfig{})\n\n    metrics, _ := session.RPC.Usage.GetMetrics(ctx)\n\n    aiCredits := float64(0)\n    if metrics.TotalNanoAiu != nil {\n        aiCredits = *metrics.TotalNanoAiu / 1e9\n    }\n    fmt.Printf(\"AI credits used: %.6f\\n\", aiCredits)\n    fmt.Printf(\"Premium requests: %v\\n\", metrics.TotalPremiumRequestCost)\n\n    for model, m := range metrics.ModelMetrics {\n        nanoAiu := float64(0)\n        if m.TotalNanoAiu != nil {\n            nanoAiu = *m.TotalNanoAiu\n        }\n        fmt.Printf(\"%s: in=%d out=%d nanoAiu=%v\\n\", model, m.Usage.InputTokens, m.Usage.OutputTokens, nanoAiu)\n    }\n}\n```\n\n```golang\nmetrics, _ := session.RPC.Usage.GetMetrics(ctx)\n\naiCredits := float64(0)\nif metrics.TotalNanoAiu != nil {\n    aiCredits = *metrics.TotalNanoAiu / 1e9\n}\nfmt.Printf(\"AI credits used: %.6f\\n\", aiCredits)\nfmt.Printf(\"Premium requests: %v\\n\", metrics.TotalPremiumRequestCost)\n\nfor model, m := range metrics.ModelMetrics {\n    nanoAiu := float64(0)\n    if m.TotalNanoAiu != nil {\n        nanoAiu = *m.TotalNanoAiu\n    }\n    fmt.Printf(\"%s: in=%d out=%d nanoAiu=%v\\n\", model, m.Usage.InputTokens, m.Usage.OutputTokens, nanoAiu)\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\n#pragma warning disable GHCP001\nusing GitHub.Copilot;\n\nawait using var client = new CopilotClient();\nawait using var session = await client.CreateSessionAsync(new SessionConfig());\n\nvar metrics = await session.Rpc.Usage.GetMetricsAsync();\n\nvar aiCredits = (metrics.TotalNanoAiu ?? 0) / 1e9;\nConsole.WriteLine($\"AI credits used: {aiCredits:F6}\");\nConsole.WriteLine($\"Premium requests: {metrics.TotalPremiumRequestCost}\");\n\nforeach (var (model, m) in metrics.ModelMetrics)\n{\n    Console.WriteLine(\n        $\"{model}: in={m.Usage.InputTokens} out={m.Usage.OutputTokens} nanoAiu={m.TotalNanoAiu ?? 0}\");\n}\n#pragma warning restore GHCP001\n```\n\n```csharp\nvar metrics = await session.Rpc.Usage.GetMetricsAsync();\n\nvar aiCredits = (metrics.TotalNanoAiu ?? 0) / 1e9;\nConsole.WriteLine($\"AI credits used: {aiCredits:F6}\");\nConsole.WriteLine($\"Premium requests: {metrics.TotalPremiumRequestCost}\");\n\nforeach (var (model, m) in metrics.ModelMetrics)\n{\n    Console.WriteLine(\n        $\"{model}: in={m.Usage.InputTokens} out={m.Usage.OutputTokens} nanoAiu={m.TotalNanoAiu ?? 0}\");\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nvar metrics = session.getRpc().usage.getMetrics().join();\n\ndouble aiCredits = metrics.totalNanoAiu() != null ? metrics.totalNanoAiu() / 1e9 : 0;\nSystem.out.printf(\"AI credits used: %.6f%n\", aiCredits);\nSystem.out.printf(\"Premium requests: %s%n\", metrics.totalPremiumRequestCost());\n\nmetrics.modelMetrics().forEach((model, m) -> {\n    double nanoAiu = m.totalNanoAiu() != null ? m.totalNanoAiu() : 0;\n    System.out.printf(\"%s: in=%d out=%d nanoAiu=%s%n\",\n        model, m.usage().inputTokens(), m.usage().outputTokens(), nanoAiu);\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nlet metrics = session.rpc().usage().get_metrics().await?;\n\nlet ai_credits = metrics.total_nano_aiu.unwrap_or(0.0) / 1e9;\nprintln!(\"AI credits used: {ai_credits:.6}\");\nprintln!(\"Premium requests: {}\", metrics.total_premium_request_cost);\n\nfor (model, m) in &metrics.model_metrics {\n    let nano_aiu = m.total_nano_aiu.unwrap_or(0.0);\n    println!(\n        \"{model}: in={} out={} nanoAiu={nano_aiu}\",\n        m.usage.input_tokens, m.usage.output_tokens,\n    );\n}\n```\n\n</div>\n\n</div>\n\n## 按模型的 AI 积分定价\n\n若要在运行轮次之前估算成本，请从 `models.list`中读取每个模型的令牌价格。 这是客户端上的服务器作用域调用，因此不需要会话。 价格以每批计费令牌对应的 AI 积分表示。 生成的 `ModelBillingTokenPrices` 类型列出每个字段，包括 `cachePrice`。\n\n| 领域                                | 类型       | Description       |\n| --------------------------------- | -------- | ----------------- |\n| `billing.multiplier`              | `number` | 相对于基础费率的高级请求成本乘数  |\n| `billing.tokenPrices.inputPrice`  | `number` | 每批输入令牌对应的 AI 积分成本 |\n| `billing.tokenPrices.outputPrice` | `number` | 每批输出令牌的 AI 积分成本   |\n| `billing.tokenPrices.batchSize`   | `number` | 每个计费批次中的令牌数量      |\n\n> \\[!NOTE]\n> 随着计划和模型的发展，价格值会发生变化。 在运行时读取它们，如下所示;切勿将数字硬编码到应用程序中。\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\n\nconst { models } = await client.rpc.models.list({});\n\nfor (const model of models) {\n    const prices = model.billing?.tokenPrices;\n    if (!prices) continue;\n    console.log(\n        `${model.id}: input=${prices.inputPrice} output=${prices.outputPrice} ` +\n            `per ${prices.batchSize} tokens (x${model.billing?.multiplier ?? 1})`,\n    );\n}\n```\n\n```typescript\nconst { models } = await client.rpc.models.list({});\n\nfor (const model of models) {\n    const prices = model.billing?.tokenPrices;\n    if (!prices) continue;\n    console.log(\n        `${model.id}: input=${prices.inputPrice} output=${prices.outputPrice} ` +\n            `per ${prices.batchSize} tokens (x${model.billing?.multiplier ?? 1})`,\n    );\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient\nfrom copilot.rpc import ModelsListRequest\n\nclient = CopilotClient()\n\nresult = await client.rpc.models.list(ModelsListRequest())\n\nfor model in result.models:\n    prices = model.billing.token_prices if model.billing else None\n    if prices is None:\n        continue\n    multiplier = model.billing.multiplier if model.billing else 1\n    print(\n        f\"{model.id}: input={prices.input_price} output={prices.output_price} \"\n        f\"per {prices.batch_size} tokens (x{multiplier})\"\n    )\n```\n\n```python\nresult = await client.rpc.models.list(ModelsListRequest())\n\nfor model in result.models:\n    prices = model.billing.token_prices if model.billing else None\n    if prices is None:\n        continue\n    multiplier = model.billing.multiplier if model.billing else 1\n    print(\n        f\"{model.id}: input={prices.input_price} output={prices.output_price} \"\n        f\"per {prices.batch_size} tokens (x{multiplier})\"\n    )\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n\n    copilot \"github.com/github/copilot-sdk/go\"\n    \"github.com/github/copilot-sdk/go/rpc\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    client := copilot.NewClient(nil)\n    client.Start(ctx)\n\n    list, _ := client.RPC.Models.List(ctx, &rpc.ModelsListRequest{})\n\n    for _, model := range list.Models {\n        if model.Billing == nil || model.Billing.TokenPrices == nil {\n            continue\n        }\n        prices := model.Billing.TokenPrices\n        multiplier := 1.0\n        if model.Billing.Multiplier != nil {\n            multiplier = *model.Billing.Multiplier\n        }\n        in, out := 0.0, 0.0\n        if prices.InputPrice != nil {\n            in = *prices.InputPrice\n        }\n        if prices.OutputPrice != nil {\n            out = *prices.OutputPrice\n        }\n        batch := int64(0)\n        if prices.BatchSize != nil {\n            batch = *prices.BatchSize\n        }\n        fmt.Printf(\"%s: input=%v output=%v per %d tokens (x%v)\\n\", model.ID, in, out, batch, multiplier)\n    }\n}\n```\n\n```golang\nlist, _ := client.RPC.Models.List(ctx, &rpc.ModelsListRequest{})\n\nfor _, model := range list.Models {\n    if model.Billing == nil || model.Billing.TokenPrices == nil {\n        continue\n    }\n    prices := model.Billing.TokenPrices\n    multiplier := 1.0\n    if model.Billing.Multiplier != nil {\n        multiplier = *model.Billing.Multiplier\n    }\n    in, out := 0.0, 0.0\n    if prices.InputPrice != nil {\n        in = *prices.InputPrice\n    }\n    if prices.OutputPrice != nil {\n        out = *prices.OutputPrice\n    }\n    batch := int64(0)\n    if prices.BatchSize != nil {\n        batch = *prices.BatchSize\n    }\n    fmt.Printf(\"%s: input=%v output=%v per %d tokens (x%v)\\n\", model.ID, in, out, batch, multiplier)\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nusing GitHub.Copilot;\n\nawait using var client = new CopilotClient();\n\nvar list = await client.Rpc.Models.ListAsync();\n\nforeach (var model in list.Models)\n{\n    var prices = model.Billing?.TokenPrices;\n    if (prices is null) continue;\n    Console.WriteLine(\n        $\"{model.Id}: input={prices.InputPrice} output={prices.OutputPrice} \" +\n        $\"per {prices.BatchSize} tokens (x{model.Billing?.Multiplier ?? 1})\");\n}\n```\n\n```csharp\nvar list = await client.Rpc.Models.ListAsync();\n\nforeach (var model in list.Models)\n{\n    var prices = model.Billing?.TokenPrices;\n    if (prices is null) continue;\n    Console.WriteLine(\n        $\"{model.Id}: input={prices.InputPrice} output={prices.OutputPrice} \" +\n        $\"per {prices.BatchSize} tokens (x{model.Billing?.Multiplier ?? 1})\");\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nvar list = client.getRpc().models.list().join();\n\nfor (var model : list.models()) {\n    var billing = model.billing();\n    if (billing == null || billing.tokenPrices() == null) {\n        continue;\n    }\n    var prices = billing.tokenPrices();\n    double multiplier = billing.multiplier() != null ? billing.multiplier() : 1;\n    System.out.printf(\"%s: input=%s output=%s per %d tokens (x%s)%n\",\n        model.id(), prices.inputPrice(), prices.outputPrice(), prices.batchSize(), multiplier);\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nlet list = client.rpc().models().list().await?;\n\nfor model in &list.models {\n    let Some(billing) = &model.billing else { continue };\n    let Some(prices) = &billing.token_prices else { continue };\n    let multiplier = billing.multiplier.unwrap_or(1.0);\n    println!(\n        \"{}: input={} output={} per {} tokens (x{multiplier})\",\n        model.id,\n        prices.input_price.unwrap_or(0.0),\n        prices.output_price.unwrap_or(0.0),\n        prices.batch_size.unwrap_or(0),\n    );\n}\n```\n\n</div>\n\n</div>\n\n## 账户配额与高级版的相互作用\n\n`account.getQuota` 显示已通过身份验证的用户的剩余 Copilot 配额。 结果 `quotaSnapshots` 映射以配额类型为键 — 通常为 `premium_interactions`、`chat` 和 `completions`。 使用它可向用户显示每月津贴的剩余量，或在达到限制之前限制工作。\n\n该示例使用下面的字段;生成的 `AccountQuotaSnapshot` 类型是完整引用。\n`quotaSnapshots` 键是 SDK 类型系统不会验证的运行时字符串，因此请对查找操作做好防护。\n\n| 领域                    | 类型       | Description            |\n| --------------------- | -------- | ---------------------- |\n| `entitlementRequests` | `number` | 包含在配额内的请求，或 `-1` 表示无限制 |\n| `usedRequests`        | `number` | 本周期迄今已使用的请求            |\n| `remainingPercentage` | `number` | 剩余权利百分比                |\n| `resetDate`           | `string` | 配额重置日期（ISO 8601 格式）    |\n\n> \\[!TIP]\n> 若要读取特定用户的配额，而不是连接的全局身份验证上下文（例如，在多租户后端中），请将该用户的GitHub令牌传递给`getQuota`。 请参阅“[多租户与服务器部署](/zh/copilot/how-tos/copilot-sdk/setup/multi-tenancy)”。\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\n\nconst { quotaSnapshots } = await client.rpc.account.getQuota({});\nconst premium = quotaSnapshots[\"premium_interactions\"];\n\nif (premium) {\n    console.log(\n        `Premium interactions: ${premium.usedRequests}/${premium.entitlementRequests} ` +\n            `(${premium.remainingPercentage.toFixed(1)}% left, resets ${premium.resetDate ?? \"n/a\"})`,\n    );\n}\n```\n\n```typescript\nconst { quotaSnapshots } = await client.rpc.account.getQuota({});\nconst premium = quotaSnapshots[\"premium_interactions\"];\n\nif (premium) {\n    console.log(\n        `Premium interactions: ${premium.usedRequests}/${premium.entitlementRequests} ` +\n            `(${premium.remainingPercentage.toFixed(1)}% left, resets ${premium.resetDate ?? \"n/a\"})`,\n    );\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient\nfrom copilot.rpc import AccountGetQuotaRequest\n\nclient = CopilotClient()\n\nresult = await client.rpc.account.get_quota(AccountGetQuotaRequest())\npremium = result.quota_snapshots.get(\"premium_interactions\")\n\nif premium is not None:\n    print(\n        f\"Premium interactions: {premium.used_requests}/{premium.entitlement_requests} \"\n        f\"({premium.remaining_percentage:.1f}% left, resets {premium.reset_date or 'n/a'})\"\n    )\n```\n\n```python\nresult = await client.rpc.account.get_quota(AccountGetQuotaRequest())\npremium = result.quota_snapshots.get(\"premium_interactions\")\n\nif premium is not None:\n    print(\n        f\"Premium interactions: {premium.used_requests}/{premium.entitlement_requests} \"\n        f\"({premium.remaining_percentage:.1f}% left, resets {premium.reset_date or 'n/a'})\"\n    )\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"time\"\n\n    copilot \"github.com/github/copilot-sdk/go\"\n    \"github.com/github/copilot-sdk/go/rpc\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    client := copilot.NewClient(nil)\n    client.Start(ctx)\n\n    result, _ := client.RPC.Account.GetQuota(ctx, &rpc.AccountGetQuotaRequest{})\n\n    if premium, ok := result.QuotaSnapshots[\"premium_interactions\"]; ok {\n        resets := \"n/a\"\n        if premium.ResetDate != nil {\n            resets = premium.ResetDate.Format(time.RFC3339)\n        }\n        fmt.Printf(\"Premium interactions: %d/%d (%.1f%% left, resets %s)\\n\",\n            premium.UsedRequests, premium.EntitlementRequests, premium.RemainingPercentage, resets)\n    }\n}\n```\n\n```golang\nresult, _ := client.RPC.Account.GetQuota(ctx, &rpc.AccountGetQuotaRequest{})\n\nif premium, ok := result.QuotaSnapshots[\"premium_interactions\"]; ok {\n    resets := \"n/a\"\n    if premium.ResetDate != nil {\n        resets = premium.ResetDate.Format(time.RFC3339)\n    }\n    fmt.Printf(\"Premium interactions: %d/%d (%.1f%% left, resets %s)\\n\",\n        premium.UsedRequests, premium.EntitlementRequests, premium.RemainingPercentage, resets)\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nusing GitHub.Copilot;\n\nawait using var client = new CopilotClient();\n\nvar result = await client.Rpc.Account.GetQuotaAsync();\n\nif (result.QuotaSnapshots.TryGetValue(\"premium_interactions\", out var premium))\n{\n    Console.WriteLine(\n        $\"Premium interactions: {premium.UsedRequests}/{premium.EntitlementRequests} \" +\n        $\"({premium.RemainingPercentage:F1}% left, resets {premium.ResetDate?.ToString(\"o\") ?? \"n/a\"})\");\n}\n```\n\n```csharp\nvar result = await client.Rpc.Account.GetQuotaAsync();\n\nif (result.QuotaSnapshots.TryGetValue(\"premium_interactions\", out var premium))\n{\n    Console.WriteLine(\n        $\"Premium interactions: {premium.UsedRequests}/{premium.EntitlementRequests} \" +\n        $\"({premium.RemainingPercentage:F1}% left, resets {premium.ResetDate?.ToString(\"o\") ?? \"n/a\"})\");\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nvar result = client.getRpc().account.getQuota().join();\nvar premium = result.quotaSnapshots().get(\"premium_interactions\");\n\nif (premium != null) {\n    System.out.printf(\"Premium interactions: %d/%d (%.1f%% left, resets %s)%n\",\n        premium.usedRequests(), premium.entitlementRequests(),\n        premium.remainingPercentage(), premium.resetDate());\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nlet result = client.rpc().account().get_quota().await?;\n\nif let Some(premium) = result.quota_snapshots.get(\"premium_interactions\") {\n    let resets = premium.reset_date.as_deref().unwrap_or(\"n/a\");\n    println!(\n        \"Premium interactions: {}/{} ({:.1}% left, resets {resets})\",\n        premium.used_requests, premium.entitlement_requests, premium.remaining_percentage,\n    );\n}\n```\n\n</div>\n\n</div>\n\n## 选择正确的 API\n\n使用此摘要来确定哪种 API 适合你的用例：\n\n* ```\n            **在回合运行时渲染实时成本或代币计量表**：订阅 `assistant.usage` 和 `session.usage_info`。\n  ```\n* **在每轮对话或会话结束后显示最终成本摘要**：调用 `session.usage.getMetrics`。\n* ```\n            **恢复时，在任何新回合开始前显示上下文窗口的使用情况**：调用 `session.metadata.contextInfo`。\n  ```\n* **在运行工作之前估算成本**：读取 `models.list` 令牌价格。\n* **在用户耗尽计划之前警告用户**：呼叫 `account.getQuota`。\n\n## 延伸阅读\n\n* [流式处理会话事件](/zh/copilot/how-tos/copilot-sdk/features/streaming-events)：适用于 `assistant.usage`、`session.usage_info` 及所有其他会话事件的完整字段级参考\n* [可观察性](/zh/copilot/how-tos/copilot-sdk/observability)：将使用情况数据导出到 OpenTelemetry 以获取成本归因\n* [多租户与服务器部署](/zh/copilot/how-tos/copilot-sdk/setup/multi-tenancy)：使用GitHub令牌解析每用户配额和模型"}