Thanks to visit codestin.com
Credit goes to docs.github.com

Skip to main content

BYOK(사용자 고유의 키 가져오기)

BYOK를 사용하면 GitHub Copilot 인증을 우회하여 모델 공급자의 고유한 API 키와 함께 Copilot SDK를 사용할 수 있습니다. 엔터프라이즈 배포, 사용자 지정 모델 호스팅 또는 모델 공급자에게 직접 청구하려는 경우에 유용합니다.

지원되는 공급자

Provider타입 값Notes
OpenAI"openai"OpenAI API 및 OpenAI 호환 엔드포인트
Azure OpenAI/Azure AI Foundry"azure"Azure 호스트된 모델
Anthropic"anthropic"클로드 모델
Ollama"openai"OpenAI 호환 API를 통한 로컬 모델
Microsoft Foundry 로컬"openai"OpenAI 호환 API를 통해 디바이스에서 로컬로 AI 모델 실행
기타 OpenAI 호환"openai"vLLM, LiteLLM 등

빠른 시작: Azure AI Foundry

Azure AI Foundry(이전의 Azure OpenAI)는 엔터프라이즈의 일반적인 BYOK 배포 대상입니다. 전체 예제는 다음과 같습니다.

Python
import asyncio
import os
from copilot import CopilotClient
from copilot.session import PermissionHandler

FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/"
# Set FOUNDRY_API_KEY environment variable

async def main():
    client = CopilotClient()
    await client.start()

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-5.2-codex", provider={
        "type": "openai",
        "base_url": FOUNDRY_MODEL_URL,
        "wire_api": "responses",  # Use "completions" for older models
        "api_key": os.environ["FOUNDRY_API_KEY"],
    })

    done = asyncio.Event()

    def on_event(event):
        if event.type.value == "assistant.message":
            print(event.data.content)
        elif event.type.value == "session.idle":
            done.set()

    session.on(on_event)
    await session.send("What is 2+2?")
    await done.wait()

    await session.disconnect()
    await client.stop()

asyncio.run(main())
TypeScript
import { CopilotClient } from "@github/copilot-sdk";

const FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-5.2-codex",  // Your deployment name
    provider: {
        type: "openai",
        baseUrl: FOUNDRY_MODEL_URL,
        wireApi: "responses",  // Use "completions" for older models
        apiKey: process.env.FOUNDRY_API_KEY,
    },
});

session.on("assistant.message", (event) => {
    console.log(event.data.content);
});

await session.sendAndWait({ prompt: "What is 2+2?" });
await client.stop();
Go
package main

import (
    "context"
    "fmt"
    "os"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    ctx := context.Background()
    client := copilot.NewClient(nil)
    if err := client.Start(ctx); err != nil {
        panic(err)
    }
    defer client.Stop()

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Model: "gpt-5.2-codex",  // Your deployment name
        Provider: &copilot.ProviderConfig{
            Type:    "openai",
            BaseURL: "https://your-resource.openai.azure.com/openai/v1/",
            WireAPI: "responses",  // Use "completions" for older models
            APIKey:  os.Getenv("FOUNDRY_API_KEY"),
        },
    })
    if err != nil {
        panic(err)
    }

    response, err := session.SendAndWait(ctx, copilot.MessageOptions{
        Prompt: "What is 2+2?",
    })
    if err != nil {
        panic(err)
    }

    if d, ok := response.Data.(*copilot.AssistantMessageData); ok {
        fmt.Println(d.Content)
    }
}
.NET
using GitHub.Copilot;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5.2-codex",  // Your deployment name
    Provider = new ProviderConfig
    {
        Type = "openai",
        BaseUrl = "https://your-resource.openai.azure.com/openai/v1/",
        WireApi = "responses",  // Use "completions" for older models
        ApiKey = Environment.GetEnvironmentVariable("FOUNDRY_API_KEY"),
    },
});

var response = await session.SendAndWaitAsync(new MessageOptions
{
    Prompt = "What is 2+2?",
});
Console.WriteLine(response?.Data.Content);
Java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

var client = new CopilotClient();
client.start().get();

var session = client.createSession(new SessionConfig()
    .setModel("gpt-5.2-codex")  // Your deployment name
    .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
    .setProvider(new ProviderConfig()
        .setType("openai")
        .setBaseUrl("https://your-resource.openai.azure.com/openai/v1/")
        .setWireApi("responses")  // Use "completions" for older models
        .setApiKey(System.getenv("FOUNDRY_API_KEY")))
).get();

var response = session.sendAndWait(new MessageOptions()
    .setPrompt("What is 2+2?")).get();
System.out.println(response.getData().content());

client.stop().get();

공급자 구성 참조

ProviderConfig 필드

FieldTypeDescription
type
"openai"
|
"azure"
|
"anthropic"
공급자 유형(기본값: "openai")
baseUrl / base_urlstring
필수입니다. API 엔드포인트 URL
apiKey / api_keystringAPI 키(Ollama와 같은 로컬 공급자의 경우 선택 사항)
bearerToken / bearer_tokenstring전달자 토큰 인증(apiKey보다 우선)
wireApi / wire_api
"completions"
|
"responses"
광범위한 모델 호환성(채팅 완료 API)을 선택하고, 다중 턴 상태 관리, 도구 이름 간격 및 추론 지원(응답 API)을 선택합니다 "completions"``"responses" . Anthropic 모델은 이 설정에 관계없이 항상 메시지 API를 사용합니다.
azure.apiVersion / azure.api_versionstringAzure API 버전(기본값: "2024-10-21")

Wire API 형식

이 설정은 wireApi 사용할 OpenAI API 형식을 결정합니다.

  • "completions" (기본값) - 광범위한 모델 호환성을 위한 채팅 완료 API(/chat/completions)입니다.
  • "responses" - 다중 턴 상태 관리, 도구 이름 간격 및 추론 지원을 위한 응답 API입니다.

Anthropic 모델은 이 설정에 관계없이 항상 Anthropic 메시지 API를 사용합니다.

유형별 참고 사항

OpenAI(type: "openai")

  • OpenAI API 및 OpenAI 호환 엔드포인트에서 작동
  • baseUrl 에는 전체 경로(예: https://api.openai.com/v1)가 포함되어야 합니다.

Azure(type: "azure")

  • 네이티브 Azure OpenAI 엔드포인트에 사용
  • baseUrl 는 호스트(예: https://my-resource.openai.azure.com)일 뿐입니다.
  • URL에 포함하지 /openai/v1 마세요. SDK는 경로 생성을 처리합니다.

Anthropic(type: "anthropic")

  • 직접 Anthropic API 액세스
  • 클로드별 API 형식 사용

구성 예

OpenAI 직통

provider: {
    type: "openai",
    baseUrl: "https://api.openai.com/v1",
    apiKey: process.env.OPENAI_API_KEY,
}

Azure OpenAI(네이티브 Azure 엔드포인트)

type: "azure"을(를) *.openai.azure.com에 있는 엔드포인트에 사용하십시오.

provider: {
    type: "azure",
    baseUrl: "https://my-resource.openai.azure.com",  // Just the host
    apiKey: process.env.AZURE_OPENAI_KEY,
    azure: {
        apiVersion: "2024-10-21",
    },
}

Azure AI Foundry(OpenAI 호환 엔드포인트)

Azure AI Foundry 배포의 /openai/v1/ 엔드포인트를 사용하려면 type: "openai"을(를) 사용하세요.

provider: {
    type: "openai",
    baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
    apiKey: process.env.FOUNDRY_API_KEY,
    wireApi: "responses",  // For GPT-5 series models
}

Ollama (로컬)

provider: {
    type: "openai",
    baseUrl: "http://localhost:11434/v1",
    // No apiKey needed for local Ollama
}

Microsoft Foundry 로컬

Microsoft Foundry Local을 사용하면 OpenAI 호환 API를 사용하여 자체 디바이스에서 로컬로 AI 모델을 실행할 수 있습니다. Foundry 로컬 CLI를 통해 설치한 다음 로컬 엔드포인트에서 SDK를 가리킵니다.

provider: {
    type: "openai",
    baseUrl: "http://localhost:<PORT>/v1",
    // No apiKey needed for local Foundry Local
}

참고

Foundry Local은 동적 포트에서 시작되며 포트는 고정되지 않습니다. foundry service status 서비스에서 현재 수신 대기 중인 포트를 확인한 다음, 해당 포트를 baseUrl사용합니다.

Foundry Local을 시작하려면 다음을 수행합니다.

# Windows: Install Foundry Local CLI (requires winget)
winget install Microsoft.FoundryLocal

# macOS / Linux: see https://foundrylocal.ai for installation instructions
# List available models
foundry model list

# Run a model (starts the local server automatically)
foundry model run phi-4-mini

# Check the port the service is running on
foundry service status

Anthropic

provider: {
    type: "anthropic",
    baseUrl: "https://api.anthropic.com",
    apiKey: process.env.ANTHROPIC_API_KEY,
}

전달자 토큰 인증

일부 공급자는 API 키 대신 전달자 토큰 인증이 필요합니다.

provider: {
    type: "openai",
    baseUrl: "https://my-custom-endpoint.example.com/v1",
    bearerToken: process.env.MY_BEARER_TOKEN,  // Sets Authorization header
}

참고

bearerToken 옵션은 정적 토큰 문자열 만 허용합니다. SDK는 이 토큰을 자동으로 새로 고치지 않습니다. 토큰이 만료되면 요청이 실패하고 새 토큰으로 새 세션을 만들어야 합니다.

사용자 지정 모델 목록

BYOK를 사용하는 경우 CLI 서버는 공급자가 지원하는 모델을 모를 수 있습니다. 공급자의 모델을 표준 ModelInfo 형식으로 반환할 수 있도록 client.listModels() 클라이언트 수준에서 사용자 지정 onListModels 처리기를 제공할 수 있습니다. 이를 통해 다운스트림 소비자는 CLI를 쿼리하지 않고 사용 가능한 모델을 검색할 수 있습니다.

TypeScript
import { CopilotClient } from "@github/copilot-sdk";
import type { ModelInfo } from "@github/copilot-sdk";

const client = new CopilotClient({
    onListModels: () => [
        {
            id: "my-custom-model",
            name: "My Custom Model",
            capabilities: {
                supports: { vision: false, reasoningEffort: false },
                limits: { max_context_window_tokens: 128000 },
            },
        },
    ],
});
Python
from copilot import CopilotClient
from copilot.client import ModelInfo, ModelCapabilities, ModelSupports, ModelLimits

client = CopilotClient(
    on_list_models=lambda: [
        ModelInfo(
            id="my-custom-model",
            name="My Custom Model",
            capabilities=ModelCapabilities(
                supports=ModelSupports(vision=False, reasoning_effort=False),
                limits=ModelLimits(max_context_window_tokens=128000),
            ),
        )
    ],
)
Go
package main

import (
    "context"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    client := copilot.NewClient(&copilot.ClientOptions{
        OnListModels: func(ctx context.Context) ([]copilot.ModelInfo, error) {
            return []copilot.ModelInfo{
                {
                    ID:   "my-custom-model",
                    Name: "My Custom Model",
                    Capabilities: copilot.ModelCapabilities{
                        Supports: copilot.ModelSupports{Vision: false, ReasoningEffort: false},
                        Limits:   copilot.ModelLimits{MaxContextWindowTokens: 128000},
                    },
                },
            }, nil
        },
    })
    _ = client
}
.NET
using GitHub.Copilot;

var client = new CopilotClient(new CopilotClientOptions
{
    OnListModels = (ct) => Task.FromResult<IList<ModelInfo>>(new List<ModelInfo>
    {
        new()
        {
            Id = "my-custom-model",
            Name = "My Custom Model",
            Capabilities = new ModelCapabilities
            {
                Supports = new ModelSupports { Vision = false, ReasoningEffort = false },
                Limits = new ModelLimits { MaxContextWindowTokens = 128000 }
            }
        }
    })
});
Java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;
import java.util.List;
import java.util.concurrent.CompletableFuture;

var client = new CopilotClient(new CopilotClientOptions()
    .setOnListModels(() -> CompletableFuture.completedFuture(List.of(
        new ModelInfo()
            .setId("my-custom-model")
            .setName("My Custom Model")
            .setCapabilities(new ModelCapabilities()
                .setSupports(new ModelSupports().setVision(false).setReasoningEffort(false))
                .setLimits(new ModelLimits().setMaxContextWindowTokens(128000)))
    )))
);

결과는 기본 동작과 마찬가지로 첫 번째 호출 후에 캐시됩니다. 처리기는 CLI의 models.list RPC를 완전히 대체합니다. 서버로의 대체는 발생하지 않습니다.

제한점

BYOK를 사용하는 경우 다음과 같은 제한 사항에 유의하세요.

ID 제한 사항

BYOK 인증은 정적 자격 증명만 사용합니다.

직접 관리하는 API 키 또는 정적 전달자 토큰을 사용해야 합니다.

기능 제한 사항

일부 Copilot 기능은 BYOK에서 다르게 동작할 수 있습니다.

  • 모델 가용성 - 공급자가 지원하는 모델만 사용할 수 있습니다.
  • ** 속도 제한** - Copilot 아닌 공급자의 속도 제한에 따라 다릅니다.
  • 우사지 추적 - 사용량은 공급자가 추적하지 않고 GitHub Copilot
  • 프레미스 요청 - Copilot 프리미엄 요청 할당량에 대해 계산하지 마세요.

공급자별 제한 사항

Provider제한점
Azure AI Foundry (에이아이 파운드리)Entra ID 인증 없음. API 키를 사용해야 합니다.
OllamaAPI 키가 없습니다. 로컬 전용; 모델 지원은 다양합니다.
Microsoft Foundry Local로컬 전용; 모델 가용성은 디바이스 하드웨어에 따라 달라집니다. API 키가 필요하지 않음
OpenAIOpenAI 속도 제한 및 할당량 적용

Troubleshooting

"모델을 지정하지 않음" 오류

BYOK를 model 사용하는 경우 매개 변수가 필요합니다.

// ❌ Error: Model required with custom provider
const session = await client.createSession({
    provider: { type: "openai", baseUrl: "..." },
});

// ✅ Correct: Model specified
const session = await client.createSession({
    model: "gpt-4",  // Required!
    provider: { type: "openai", baseUrl: "..." },
});

Azure 엔드포인트 유형 혼동

Azure OpenAI 엔드포인트(*.openai.azure.com)의 경우 올바른 형식을 사용합니다.

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-4.1",
    provider: {
        type: "azure",
        baseUrl: "https://my-resource.openai.azure.com",
    },
});
// ❌ Wrong: Using "openai" type with native Azure endpoint
provider: {
    type: "openai",  // This won't work correctly
    baseUrl: "https://my-resource.openai.azure.com",
}

// ✅ Correct: Using "azure" type
provider: {
    type: "azure",
    baseUrl: "https://my-resource.openai.azure.com",
}

그러나 Azure AI Foundry 배포에서 OpenAI 호환 엔드포인트 경로(예: /openai/v1/)를 제공하는 경우 type: "openai" 사용합니다.

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-4.1",
    provider: {
        type: "openai",
        baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
    },
});
// ✅ Correct: OpenAI-compatible Azure AI Foundry endpoint
provider: {
    type: "openai",
    baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
}

연결이 거부됨(Ollama)

Ollama가 실행 중이고 액세스할 수 있는지 확인합니다.

# Check Ollama is running
curl http://localhost:11434/v1/models

# Start Ollama if not running
ollama serve

연결이 거부됨(Foundry Local)

Foundry Local은 다시 시작 사이에 변경 될 수 있는 동적 포트를 사용합니다. 활성 포트를 확인합니다.

# Check the service status and port
foundry service status

출력에 표시된 포트와 일치하도록 업데이트합니다 baseUrl . 서비스가 실행되지 않으면, 서비스를 시작하기 위한 모델을 시작하십시오.

foundry model run phi-4-mini

인증 실패

  1. API 키가 올바르고 만료되지 않았는지 확인합니다.
  2. 공급자의 baseUrl 예상 형식과 일치하는지 확인합니다.
  3. 전달자 토큰의 경우 전체 토큰이 제공되었는지 확인합니다(접두사뿐만 아니라).

다음 단계