Совет
Каждый пример функционально эквивалентен для разных языков. Фрагмент кода TypeScript по умолчанию развернут; Выберите язык из свертых блоков, чтобы увидеть ту же логику в этом пакете SDK.
Overview
Пакет SDK предоставляет данные об использовании с помощью двух дополнительных механизмов:
- События сеанса: временные события, которые среда выполнения выдает в качестве выполнения поворота. Подпишитесь на эти данные в режиме реального времени для каждого вызова API.
- Методы RPC: вызовы запроса и ответа, которые вы выполняете по запросу. Используйте их для моментального снимка накопленных итогов или поиска квоты на уровне учетной записи.
В приведенной ниже таблице сопоставляется каждый сигнал с API, предоставляющим его.
| Сигнал | API | Объем | Type |
|---|---|---|---|
| Количество маркеров для каждого вызова | событие assistant.usage | Session | Event |
| Использование контекстного окна | событие session.usage_info | Session | Event |
| Разбивка контекстного окна (по запросу) | session.metadata.context | Session | RPC |
| Совокупные суммы кредитов и маркеров ИИ | session.usage.get | Session | RPC |
| Цены на кредиты на ИИ для модели | models.list | Сервер | RPC |
| Квота учетной записи и взаимодействие с премиумом | account.getQuota | Сервер | RPC |
Примечание.
session.usage.getMetrics, session.metadata.contextInfoи session.metadata.recomputeContextTokens помечены экспериментальными в созданной поверхности RPC. В .NET они вызывают экспериментальную GHCP001 диагностику, которая подавляется с помощью #pragma warning disable GHCP001 или уровня <NoWarn>GHCP001</NoWarn>проекта. Закрепление пакета SDK и среды выполнения cli Copilot, если приложение зависит от них.
В приведенных ниже таблицах полей перечислены только поля, используемые в примерах на этой странице. Полный, всегда текущий справочник по полю — это созданные типы ПАКЕТА SDK, а также События потоковых сессий, который повторно создается из схемы CLI на каждом ударе зависимостей. Относиться к ним как к источнику истины и этой странице в качестве ориентированного на задачи руководства.
Количество маркеров для каждого вызова
Событие assistant.usage создается один раз для каждого вызова API модели в свою очередь (включая вызовы, сделанные вложенными агентами). Он содержит количество маркеров и умножение выставления счетов для этого одного вызова.
В приведенном ниже примере используются эти поля. Полный список см. в разделе События потоковых сессий , включая кэш, причины, задержку и поля трассировки.
| Поле | Type | Description |
|---|---|---|
model | string | Идентификатор модели для этого вызова |
inputTokens | number | Расходуемые входные токены |
outputTokens | number | Выпускные токены |
cost | number | Умножение запросов уровня "Премиум", примененное к этому вызову |
Совет
assistant.usage является эфемерным, поэтому он поставляется в реальном времени, но не воспроизводился при возобновлении сеанса. Чтобы прочитать накопленные итоговые итоги после факта, вызов session.usage.getMetrics (см. сведения о накопленных кредитах и токенах ИИ).
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({ streaming: true });
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.on("assistant.usage", (event) => {
const { model, inputTokens, outputTokens, cost } = event.data;
console.log(
`${model}: in=${inputTokens ?? 0} out=${outputTokens ?? 0} cost=${cost ?? 0}`,
);
});
from copilot import CopilotClient
from copilot.session_events import SessionEventType
client = CopilotClient()
session = await client.create_session(streaming=True)
def on_usage(event):
if event.type == SessionEventType.ASSISTANT_USAGE:
data = event.data
print(f"{data.model}: in={data.input_tokens or 0} out={data.output_tokens or 0} cost={data.cost or 0}")
session.on(on_usage)
def on_usage(event):
if event.type == SessionEventType.ASSISTANT_USAGE:
data = event.data
print(f"{data.model}: in={data.input_tokens or 0} out={data.output_tokens or 0} cost={data.cost or 0}")
session.on(on_usage)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Streaming: copilot.Bool(true),
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
session.On(func(event copilot.SessionEvent) {
d, ok := event.Data.(*copilot.AssistantUsageData)
if !ok {
return
}
in, out, cost := int64(0), int64(0), float64(0)
if d.InputTokens != nil {
in = *d.InputTokens
}
if d.OutputTokens != nil {
out = *d.OutputTokens
}
if d.Cost != nil {
cost = *d.Cost
}
fmt.Printf("%s: in=%d out=%d cost=%g\n", d.Model, in, out, cost)
})
_ = session
}
session.On(func(event copilot.SessionEvent) {
d, ok := event.Data.(*copilot.AssistantUsageData)
if !ok {
return
}
in, out, cost := int64(0), int64(0), float64(0)
if d.InputTokens != nil {
in = *d.InputTokens
}
if d.OutputTokens != nil {
out = *d.OutputTokens
}
if d.Cost != nil {
cost = *d.Cost
}
fmt.Printf("%s: in=%d out=%d cost=%g\n", d.Model, in, out, cost)
})
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig { Streaming = true });
session.On<AssistantUsageEvent>(evt =>
{
var data = evt.Data;
Console.WriteLine(
$"{data.Model}: in={data.InputTokens ?? 0} out={data.OutputTokens ?? 0} cost={data.Cost ?? 0}");
});
session.On<AssistantUsageEvent>(evt =>
{
var data = evt.Data;
Console.WriteLine(
$"{data.Model}: in={data.InputTokens ?? 0} out={data.OutputTokens ?? 0} cost={data.Cost ?? 0}");
});
session.on(AssistantUsageEvent.class, event -> {
var data = event.getData();
long in = data.inputTokens() != null ? data.inputTokens() : 0;
long out = data.outputTokens() != null ? data.outputTokens() : 0;
double cost = data.cost() != null ? data.cost() : 0.0;
System.out.printf("%s: in=%d out=%d cost=%s%n", data.model(), in, out, cost);
});
use github_copilot_sdk::session_events::AssistantUsageData;
let mut events = session.subscribe();
while let Ok(event) = events.recv().await {
if event.event_type == "assistant.usage" {
if let Some(data) = event.typed_data::<AssistantUsageData>() {
println!(
"{}: in={} out={} cost={}",
data.model,
data.input_tokens.unwrap_or(0),
data.output_tokens.unwrap_or(0),
data.cost.unwrap_or(0.0),
);
}
}
}
Использование контекстного окна
Счетчики маркеров сообщают, что каждый вызов использовался. Использование контекстного окна указывает, насколько полно окно запроса модели сейчас — полезно для отображения индикатора хода выполнения или предупреждения пользователя перед автоматическим сжатием.
Динамические обновления с помощью session.usage_info
Среда выполнения выдает session.usage_info событие при изменении размера контекстного окна. Пример использования currentTokens и tokenLimit; см. в разделе События потоковых сессий для полной полезных данных.
| Поле | Type | Description |
|---|---|---|
currentTokens | number | Маркеры в настоящее время в окне контекста |
tokenLimit | number | Максимальное количество токенов для контекстного окна модели |
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({ streaming: true });
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.on("session.usage_info", (event) => {
const { currentTokens, tokenLimit } = event.data;
const pct = Math.round((currentTokens / tokenLimit) * 100);
console.log(`Context: ${currentTokens}/${tokenLimit} (${pct}%)`);
});
from copilot import CopilotClient
from copilot.session_events import SessionEventType
client = CopilotClient()
session = await client.create_session(streaming=True)
def on_usage_info(event):
if event.type == SessionEventType.SESSION_USAGE_INFO:
data = event.data
pct = round(data.current_tokens / data.token_limit * 100)
print(f"Context: {data.current_tokens}/{data.token_limit} ({pct}%)")
session.on(on_usage_info)
def on_usage_info(event):
if event.type == SessionEventType.SESSION_USAGE_INFO:
data = event.data
pct = round(data.current_tokens / data.token_limit * 100)
print(f"Context: {data.current_tokens}/{data.token_limit} ({pct}%)")
session.on(on_usage_info)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Streaming: copilot.Bool(true),
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
session.On(func(event copilot.SessionEvent) {
d, ok := event.Data.(*copilot.SessionUsageInfoData)
if !ok {
return
}
pct := int(float64(d.CurrentTokens) / float64(d.TokenLimit) * 100)
fmt.Printf("Context: %d/%d (%d%%)\n", d.CurrentTokens, d.TokenLimit, pct)
})
_ = session
}
session.On(func(event copilot.SessionEvent) {
d, ok := event.Data.(*copilot.SessionUsageInfoData)
if !ok {
return
}
pct := int(float64(d.CurrentTokens) / float64(d.TokenLimit) * 100)
fmt.Printf("Context: %d/%d (%d%%)\n", d.CurrentTokens, d.TokenLimit, pct)
})
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig { Streaming = true });
session.On<SessionUsageInfoEvent>(evt =>
{
var pct = (int)Math.Round((double)evt.Data.CurrentTokens / evt.Data.TokenLimit * 100);
Console.WriteLine($"Context: {evt.Data.CurrentTokens}/{evt.Data.TokenLimit} ({pct}%)");
});
session.On<SessionUsageInfoEvent>(evt =>
{
var pct = (int)Math.Round((double)evt.Data.CurrentTokens / evt.Data.TokenLimit * 100);
Console.WriteLine($"Context: {evt.Data.CurrentTokens}/{evt.Data.TokenLimit} ({pct}%)");
});
session.on(SessionUsageInfoEvent.class, event -> {
var data = event.getData();
long pct = Math.round((double) data.currentTokens() / data.tokenLimit() * 100);
System.out.printf("Context: %d/%d (%d%%)%n", data.currentTokens(), data.tokenLimit(), pct);
});
use github_copilot_sdk::session_events::SessionUsageInfoData;
let mut events = session.subscribe();
while let Ok(event) = events.recv().await {
if event.event_type == "session.usage_info" {
if let Some(data) = event.typed_data::<SessionUsageInfoData>() {
let pct = (data.current_tokens as f64 / data.token_limit as f64 * 100.0) as i64;
println!("Context: {}/{} ({}%)", data.current_tokens, data.token_limit, pct);
}
}
}
Разбивка по запросу с session.metadata.contextInfo
События срабатывает только при изменении контекста. Чтобы прочитать текущую разбивку в любой момент( например, сразу после возобновления сеанса— вызов session.metadata.contextInfo. Передайте для promptTokenLimit использования среды выполнения по умолчанию; передайте 0``0 значениеoutputTokenLimit, если значение неизвестно.
contextInfo Результат не null будет инициализирован до инициализации сеанса (системный запрос и метаданные инструмента были кэшированы). Он разбивает итог вниз systemTokensна , conversationTokensи toolDefinitionsTokens, наряду с promptTokenLimit.
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({});
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})`,
);
}
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})`,
);
}
from copilot import CopilotClient
from copilot.rpc import MetadataContextInfoRequest
client = CopilotClient()
session = await client.create_session()
result = await session.rpc.metadata.context_info(
MetadataContextInfoRequest(prompt_token_limit=0, output_token_limit=0)
)
info = result.context_info
if info is not None:
print(
f"Total {info.total_tokens}/{info.prompt_token_limit} "
f"(system={info.system_tokens}, conversation={info.conversation_tokens})"
)
result = await session.rpc.metadata.context_info(
MetadataContextInfoRequest(prompt_token_limit=0, output_token_limit=0)
)
info = result.context_info
if info is not None:
print(
f"Total {info.total_tokens}/{info.prompt_token_limit} "
f"(system={info.system_tokens}, conversation={info.conversation_tokens})"
)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{})
result, _ := session.RPC.Metadata.ContextInfo(ctx, &rpc.MetadataContextInfoRequest{
PromptTokenLimit: 0,
OutputTokenLimit: 0,
})
if info := result.ContextInfo; info != nil {
fmt.Printf("Total %d/%d (system=%d, conversation=%d)\n",
info.TotalTokens, info.PromptTokenLimit, info.SystemTokens, info.ConversationTokens)
}
}
result, _ := session.RPC.Metadata.ContextInfo(ctx, &rpc.MetadataContextInfoRequest{
PromptTokenLimit: 0,
OutputTokenLimit: 0,
})
if info := result.ContextInfo; info != nil {
fmt.Printf("Total %d/%d (system=%d, conversation=%d)\n",
info.TotalTokens, info.PromptTokenLimit, info.SystemTokens, info.ConversationTokens)
}
#pragma warning disable GHCP001
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig());
var result = await session.Rpc.Metadata.ContextInfoAsync(promptTokenLimit: 0, outputTokenLimit: 0);
var info = result.ContextInfo;
if (info is not null)
{
Console.WriteLine(
$"Total {info.TotalTokens}/{info.PromptTokenLimit} " +
$"(system={info.SystemTokens}, conversation={info.ConversationTokens})");
}
#pragma warning restore GHCP001
var result = await session.Rpc.Metadata.ContextInfoAsync(promptTokenLimit: 0, outputTokenLimit: 0);
var info = result.ContextInfo;
if (info is not null)
{
Console.WriteLine(
$"Total {info.TotalTokens}/{info.PromptTokenLimit} " +
$"(system={info.SystemTokens}, conversation={info.ConversationTokens})");
}
var result = session.getRpc().metadata
.contextInfo(new SessionMetadataContextInfoParams(null, 0L, 0L, null))
.join();
var info = result.contextInfo();
if (info != null) {
System.out.printf("Total %d/%d (system=%d, conversation=%d)%n",
info.totalTokens(), info.promptTokenLimit(), info.systemTokens(), info.conversationTokens());
}
use github_copilot_sdk::rpc::MetadataContextInfoRequest;
let result = session
.rpc()
.metadata()
.context_info(MetadataContextInfoRequest {
prompt_token_limit: 0,
output_token_limit: 0,
selected_model: None,
})
.await?;
if let Some(info) = result.context_info {
println!(
"Total {}/{} (system={}, conversation={})",
info.total_tokens, info.prompt_token_limit, info.system_tokens, info.conversation_tokens,
);
}
Совокупные суммы кредитов и маркеров ИИ
session.usage.getMetrics возвращает итоги выполнения для всего сеанса в одном вызове. Это самый чистый способ чтения стоимости кредита ИИ, так как он агрегирует каждый вызов API (основной агент и вложенные агенты) для вас.
В примере используются приведенные ниже поля. Созданный UsageGetMetricsResult тип является полной ссылкой.
| Поле | Type | Description |
|---|---|---|
totalNanoAiu | number | Стоимость кредита на уровне сеанса ИИ в единицах nano-AI |
total | number | Стоимость запроса уровня "Премиум" во всех моделях после умножения |
modelMetrics | Record<string, ModelMetric> | Разбивка на модель; каждая запись имеет usage.inputTokens, usage.outputи totalNanoAiu |
Примечание.
Стоимость сообщается в единицах nano-AI (это поле называется totalNanoAiu). Точное преобразование в кредиты ИИ и точное значение учета запросов уровня "Премиум" определяются GitHub Copilot выставлением счетов, а не пакетом SDK, рассматривать Copilot документации по выставлению счетов GitHub как источник истины и проверить перед отображением валюты, например значений для пользователей. Примеры делятся на 1e9 удобство, следуя префиксу SI nano ; убедитесь, что это соответствует текущему выставлению счетов, прежде чем полагаться на него.
tokenDetails Карты modelMetrics ключом являются строки среды выполнения (идентификаторы модели и имена типов маркеров), которые система типов SDK не проверяет.
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({});
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}`,
);
}
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}`,
);
}
from copilot import CopilotClient
client = CopilotClient()
session = await client.create_session()
metrics = await session.rpc.usage.get_metrics()
ai_credits = (metrics.total_nano_aiu or 0) / 1e9
print(f"AI credits used: {ai_credits:.6f}")
print(f"Premium requests: {metrics.total_premium_request_cost}")
for model, m in metrics.model_metrics.items():
print(f"{model}: in={m.usage.input_tokens} out={m.usage.output_tokens} nanoAiu={m.total_nano_aiu or 0}")
metrics = await session.rpc.usage.get_metrics()
ai_credits = (metrics.total_nano_aiu or 0) / 1e9
print(f"AI credits used: {ai_credits:.6f}")
print(f"Premium requests: {metrics.total_premium_request_cost}")
for model, m in metrics.model_metrics.items():
print(f"{model}: in={m.usage.input_tokens} out={m.usage.output_tokens} nanoAiu={m.total_nano_aiu or 0}")
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{})
metrics, _ := session.RPC.Usage.GetMetrics(ctx)
aiCredits := float64(0)
if metrics.TotalNanoAiu != nil {
aiCredits = *metrics.TotalNanoAiu / 1e9
}
fmt.Printf("AI credits used: %.6f\n", aiCredits)
fmt.Printf("Premium requests: %v\n", metrics.TotalPremiumRequestCost)
for model, m := range metrics.ModelMetrics {
nanoAiu := float64(0)
if m.TotalNanoAiu != nil {
nanoAiu = *m.TotalNanoAiu
}
fmt.Printf("%s: in=%d out=%d nanoAiu=%v\n", model, m.Usage.InputTokens, m.Usage.OutputTokens, nanoAiu)
}
}
metrics, _ := session.RPC.Usage.GetMetrics(ctx)
aiCredits := float64(0)
if metrics.TotalNanoAiu != nil {
aiCredits = *metrics.TotalNanoAiu / 1e9
}
fmt.Printf("AI credits used: %.6f\n", aiCredits)
fmt.Printf("Premium requests: %v\n", metrics.TotalPremiumRequestCost)
for model, m := range metrics.ModelMetrics {
nanoAiu := float64(0)
if m.TotalNanoAiu != nil {
nanoAiu = *m.TotalNanoAiu
}
fmt.Printf("%s: in=%d out=%d nanoAiu=%v\n", model, m.Usage.InputTokens, m.Usage.OutputTokens, nanoAiu)
}
#pragma warning disable GHCP001
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig());
var metrics = await session.Rpc.Usage.GetMetricsAsync();
var aiCredits = (metrics.TotalNanoAiu ?? 0) / 1e9;
Console.WriteLine($"AI credits used: {aiCredits:F6}");
Console.WriteLine($"Premium requests: {metrics.TotalPremiumRequestCost}");
foreach (var (model, m) in metrics.ModelMetrics)
{
Console.WriteLine(
$"{model}: in={m.Usage.InputTokens} out={m.Usage.OutputTokens} nanoAiu={m.TotalNanoAiu ?? 0}");
}
#pragma warning restore GHCP001
var metrics = await session.Rpc.Usage.GetMetricsAsync();
var aiCredits = (metrics.TotalNanoAiu ?? 0) / 1e9;
Console.WriteLine($"AI credits used: {aiCredits:F6}");
Console.WriteLine($"Premium requests: {metrics.TotalPremiumRequestCost}");
foreach (var (model, m) in metrics.ModelMetrics)
{
Console.WriteLine(
$"{model}: in={m.Usage.InputTokens} out={m.Usage.OutputTokens} nanoAiu={m.TotalNanoAiu ?? 0}");
}
var metrics = session.getRpc().usage.getMetrics().join();
double aiCredits = metrics.totalNanoAiu() != null ? metrics.totalNanoAiu() / 1e9 : 0;
System.out.printf("AI credits used: %.6f%n", aiCredits);
System.out.printf("Premium requests: %s%n", metrics.totalPremiumRequestCost());
metrics.modelMetrics().forEach((model, m) -> {
double nanoAiu = m.totalNanoAiu() != null ? m.totalNanoAiu() : 0;
System.out.printf("%s: in=%d out=%d nanoAiu=%s%n",
model, m.usage().inputTokens(), m.usage().outputTokens(), nanoAiu);
});
let metrics = session.rpc().usage().get_metrics().await?;
let ai_credits = metrics.total_nano_aiu.unwrap_or(0.0) / 1e9;
println!("AI credits used: {ai_credits:.6}");
println!("Premium requests: {}", metrics.total_premium_request_cost);
for (model, m) in &metrics.model_metrics {
let nano_aiu = m.total_nano_aiu.unwrap_or(0.0);
println!(
"{model}: in={} out={} nanoAiu={nano_aiu}",
m.usage.input_tokens, m.usage.output_tokens,
);
}
Цены на кредиты на ИИ для модели
Чтобы оценить стоимость перед выполнением поворота, ознакомьтесь с ценами на маркеры каждой модели.models.list Это вызов на уровне сервера на клиенте, поэтому он не нуждается в сеансе. Цены выражаются в кредитах ИИ на пакет токенов выставления счетов. Созданный тип перечисляет каждое ModelBillingTokenPrices поле, в том числе cachePrice.
| Поле | Type | Description |
|---|---|---|
billing.multiplier | number | Умножение затрат на премиум по отношению к базовой ставке |
billing.token | number | Затраты на кредит ИИ на пакет входных маркеров |
billing.token | number | Затраты на кредит ИИ на пакет выходных маркеров |
billing.token | number | Количество маркеров на пакет выставления счетов |
Примечание.
Ценовые значения изменяются по мере развития планов и моделей. Прочитайте их во время выполнения, как показано ниже; никогда не жестко кодируйте числа в приложении.
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
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})`,
);
}
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})`,
);
}
from copilot import CopilotClient
from copilot.rpc import ModelsListRequest
client = CopilotClient()
result = await client.rpc.models.list(ModelsListRequest())
for model in result.models:
prices = model.billing.token_prices if model.billing else None
if prices is None:
continue
multiplier = model.billing.multiplier if model.billing else 1
print(
f"{model.id}: input={prices.input_price} output={prices.output_price} "
f"per {prices.batch_size} tokens (x{multiplier})"
)
result = await client.rpc.models.list(ModelsListRequest())
for model in result.models:
prices = model.billing.token_prices if model.billing else None
if prices is None:
continue
multiplier = model.billing.multiplier if model.billing else 1
print(
f"{model.id}: input={prices.input_price} output={prices.output_price} "
f"per {prices.batch_size} tokens (x{multiplier})"
)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
list, _ := client.RPC.Models.List(ctx, &rpc.ModelsListRequest{})
for _, model := range list.Models {
if model.Billing == nil || model.Billing.TokenPrices == nil {
continue
}
prices := model.Billing.TokenPrices
multiplier := 1.0
if model.Billing.Multiplier != nil {
multiplier = *model.Billing.Multiplier
}
in, out := 0.0, 0.0
if prices.InputPrice != nil {
in = *prices.InputPrice
}
if prices.OutputPrice != nil {
out = *prices.OutputPrice
}
batch := int64(0)
if prices.BatchSize != nil {
batch = *prices.BatchSize
}
fmt.Printf("%s: input=%v output=%v per %d tokens (x%v)\n", model.ID, in, out, batch, multiplier)
}
}
list, _ := client.RPC.Models.List(ctx, &rpc.ModelsListRequest{})
for _, model := range list.Models {
if model.Billing == nil || model.Billing.TokenPrices == nil {
continue
}
prices := model.Billing.TokenPrices
multiplier := 1.0
if model.Billing.Multiplier != nil {
multiplier = *model.Billing.Multiplier
}
in, out := 0.0, 0.0
if prices.InputPrice != nil {
in = *prices.InputPrice
}
if prices.OutputPrice != nil {
out = *prices.OutputPrice
}
batch := int64(0)
if prices.BatchSize != nil {
batch = *prices.BatchSize
}
fmt.Printf("%s: input=%v output=%v per %d tokens (x%v)\n", model.ID, in, out, batch, multiplier)
}
using GitHub.Copilot;
await using var client = new CopilotClient();
var list = await client.Rpc.Models.ListAsync();
foreach (var model in list.Models)
{
var prices = model.Billing?.TokenPrices;
if (prices is null) continue;
Console.WriteLine(
$"{model.Id}: input={prices.InputPrice} output={prices.OutputPrice} " +
$"per {prices.BatchSize} tokens (x{model.Billing?.Multiplier ?? 1})");
}
var list = await client.Rpc.Models.ListAsync();
foreach (var model in list.Models)
{
var prices = model.Billing?.TokenPrices;
if (prices is null) continue;
Console.WriteLine(
$"{model.Id}: input={prices.InputPrice} output={prices.OutputPrice} " +
$"per {prices.BatchSize} tokens (x{model.Billing?.Multiplier ?? 1})");
}
var list = client.getRpc().models.list().join();
for (var model : list.models()) {
var billing = model.billing();
if (billing == null || billing.tokenPrices() == null) {
continue;
}
var prices = billing.tokenPrices();
double multiplier = billing.multiplier() != null ? billing.multiplier() : 1;
System.out.printf("%s: input=%s output=%s per %d tokens (x%s)%n",
model.id(), prices.inputPrice(), prices.outputPrice(), prices.batchSize(), multiplier);
}
let list = client.rpc().models().list().await?;
for model in &list.models {
let Some(billing) = &model.billing else { continue };
let Some(prices) = &billing.token_prices else { continue };
let multiplier = billing.multiplier.unwrap_or(1.0);
println!(
"{}: input={} output={} per {} tokens (x{multiplier})",
model.id,
prices.input_price.unwrap_or(0.0),
prices.output_price.unwrap_or(0.0),
prices.batch_size.unwrap_or(0),
);
}
Квота учетной записи и взаимодействие с премиумом
account.getQuotaсообщает о оставшейся Copilot права пользователя, прошедшего проверку подлинности. Карта результата quotaSnapshots определяется типом квоты, как правило premium_interactions, chatи completions. Используйте его, чтобы показать пользователям, сколько их ежемесячных пособий осталось, или ворот работы, прежде чем они достигли предела.
В примере используются приведенные ниже поля; Созданный AccountQuotaSnapshot тип является полной ссылкой. Ключи quotaSnapshots — это строки среды выполнения, которые система типов ПАКЕТА SDK не проверяет, поэтому защита подстановок.
| Поле | Type | Description |
|---|---|---|
entitlement | number | Запросы, включенные в право, или -1 для неограниченных |
usedRequests | number | Запросы, используемые до сих пор в этот период |
remaining | number | Процент оставшихся прав |
resetDate | string | Дата ISO 8601 при сбросе квоты |
Совет
Чтобы считывать квоту для конкретного пользователя, а не глобального контекста проверки подлинности подключения (например, в серверной части с несколькими клиентами), передайте этот пользователь GitHub маркерgetQuota. См . раздел AUTOTITLE.
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
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"})`,
);
}
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"})`,
);
}
from copilot import CopilotClient
from copilot.rpc import AccountGetQuotaRequest
client = CopilotClient()
result = await client.rpc.account.get_quota(AccountGetQuotaRequest())
premium = result.quota_snapshots.get("premium_interactions")
if premium is not None:
print(
f"Premium interactions: {premium.used_requests}/{premium.entitlement_requests} "
f"({premium.remaining_percentage:.1f}% left, resets {premium.reset_date or 'n/a'})"
)
result = await client.rpc.account.get_quota(AccountGetQuotaRequest())
premium = result.quota_snapshots.get("premium_interactions")
if premium is not None:
print(
f"Premium interactions: {premium.used_requests}/{premium.entitlement_requests} "
f"({premium.remaining_percentage:.1f}% left, resets {premium.reset_date or 'n/a'})"
)
package main
import (
"context"
"fmt"
"time"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
result, _ := client.RPC.Account.GetQuota(ctx, &rpc.AccountGetQuotaRequest{})
if premium, ok := result.QuotaSnapshots["premium_interactions"]; ok {
resets := "n/a"
if premium.ResetDate != nil {
resets = premium.ResetDate.Format(time.RFC3339)
}
fmt.Printf("Premium interactions: %d/%d (%.1f%% left, resets %s)\n",
premium.UsedRequests, premium.EntitlementRequests, premium.RemainingPercentage, resets)
}
}
result, _ := client.RPC.Account.GetQuota(ctx, &rpc.AccountGetQuotaRequest{})
if premium, ok := result.QuotaSnapshots["premium_interactions"]; ok {
resets := "n/a"
if premium.ResetDate != nil {
resets = premium.ResetDate.Format(time.RFC3339)
}
fmt.Printf("Premium interactions: %d/%d (%.1f%% left, resets %s)\n",
premium.UsedRequests, premium.EntitlementRequests, premium.RemainingPercentage, resets)
}
using GitHub.Copilot;
await using var client = new CopilotClient();
var result = await client.Rpc.Account.GetQuotaAsync();
if (result.QuotaSnapshots.TryGetValue("premium_interactions", out var premium))
{
Console.WriteLine(
$"Premium interactions: {premium.UsedRequests}/{premium.EntitlementRequests} " +
$"({premium.RemainingPercentage:F1}% left, resets {premium.ResetDate?.ToString("o") ?? "n/a"})");
}
var result = await client.Rpc.Account.GetQuotaAsync();
if (result.QuotaSnapshots.TryGetValue("premium_interactions", out var premium))
{
Console.WriteLine(
$"Premium interactions: {premium.UsedRequests}/{premium.EntitlementRequests} " +
$"({premium.RemainingPercentage:F1}% left, resets {premium.ResetDate?.ToString("o") ?? "n/a"})");
}
var result = client.getRpc().account.getQuota().join();
var premium = result.quotaSnapshots().get("premium_interactions");
if (premium != null) {
System.out.printf("Premium interactions: %d/%d (%.1f%% left, resets %s)%n",
premium.usedRequests(), premium.entitlementRequests(),
premium.remainingPercentage(), premium.resetDate());
}
let result = client.rpc().account().get_quota().await?;
if let Some(premium) = result.quota_snapshots.get("premium_interactions") {
let resets = premium.reset_date.as_deref().unwrap_or("n/a");
println!(
"Premium interactions: {}/{} ({:.1}% left, resets {resets})",
premium.used_requests, premium.entitlement_requests, premium.remaining_percentage,
);
}
Выбор правильного API
Используйте эту сводку, чтобы решить, какой API соответствует вашему варианту использования:
- Отрисовка динамической стоимости или счетчика токенов в виде выполнения: подписка на
assistant.usageиsession.usage_info. - Отображение итоговой суммы затрат после поворота или сеанса: вызов
session.usage.getMetrics. - Отображение использования контекстного окна при возобновлении перед любым новым поворотом: вызов
session.metadata.contextInfo. - Оценка стоимости перед выполнением работы: чтение
models.listцен токенов. - Предупреждайте пользователей, прежде чем они исчерпают свой план: вызов
account.getQuota.
Дополнительные материалы
- События потоковых сессий: полный справочник по уровню поля для
assistant.usage,session.usage_infoи каждое другое событие сеанса - Observability: экспорт данных об использовании в OpenTelemetry для присвоения затрат
- Мультиарендные и серверные развертывания: разрешение квоты и моделей на пользователя с помощью маркера GitHub