지원되는 공급자
| Provider | 타입 값 | Notes |
|---|---|---|
| OpenAI | "openai" | OpenAI API 및 OpenAI 호환 엔드포인트 |
| Microsoft Foundry/Azure OpenAI | ||
"openai" 또는 "azure" | 네이 / 티브 Azure 엔드포인트에 사용 "openai" | |
| Anthropic | "anthropic" | 클로드 모델 |
| Ollama | "openai" | OpenAI 호환 API를 통한 로컬 모델 |
| Microsoft Foundry 로컬 | "openai" | OpenAI 호환 API를 통해 디바이스에서 로컬로 AI 모델 실행 |
| 기타 OpenAI 호환 | "openai" | vLLM, LiteLLM 등 |
빠른 시작: Microsoft Foundry
Microsoft Foundry는 기업의 일반적인 BYOK 배포 대상입니다. 전체 예제는 다음과 같습니다.
코드 언어 navigation
import asyncio
import os
from copilot import CopilotClient
from copilot.session import PermissionHandler
FOUNDRY_MODEL_URL = "https://<resource-name>.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())
import { CopilotClient } from "@github/copilot-sdk";
const FOUNDRY_MODEL_URL = "https://<resource-name>.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();
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://<resource-name>.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)
}
}
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://<resource-name>.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);
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://<resource-name>.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 필드
| Field | Type | Description |
|---|---|---|
type | ||
"openai" | ||
| | | ||
"azure" | ||
| | | ||
"anthropic" | ||
공급자 유형(기본값: "openai") | ||
baseUrl / base_url | string | |
| 필수입니다. API 엔드포인트 URL | ||
apiKey / api_key | string | API 키(Ollama와 같은 로컬 공급자의 경우 선택 사항) |
bearerToken / bearer_token | string | 전달자 토큰 인증(apiKey보다 우선) |
bearer / bearer_token_ | 콜백(callback) | 요청 시에 Bearer 토큰을 반환합니다(apiKey 및 bearerToken보다 우선 적용됨) |
wireApi / wire_api | ||
"completions" | ||
| | | ||
"responses" | ||
광범위한 모델 호환성을 위해서는 "completions"을 선택하세요(Chat Completions API). 다중 턴 상태 관리, 도구 네임스페이싱 및 추론 지원을 위해서는 "responses"을 선택하세요(Responses API). Anthropic 모델은 이 설정에 관계없이 항상 메시지 API를 사용합니다. | ||
azure.apiVersion / azure.api_version | string | Azure API 버전입니다. 설정되면 런타임은 버전이 지정된 배포 경로를 사용합니다. 생략하면 GA 버전 없는 v1 경로를 사용합니다. |
Wire API 형식
이 설정은 wireApi 사용할 OpenAI API 형식을 결정합니다.
"completions"(기본값) - 광범위한 모델 호환성을 위한 채팅 완료 API(/chat/completions)입니다."responses"- 다중 턴 상태 관리, 도구 네임스페이싱 및 추론 지원을 위한 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",
},
}
Microsoft Foundry(OpenAI 호환 엔드포인트)
엔드포인트가 있는 Microsoft Foundry 배포의 /openai/v1/ 경우 다음을 사용합니다type: "openai".
provider: {
type: "openai",
baseUrl: "https://<resource-name>.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 키 대신 전달자 토큰 인증이 필요합니다.
bearerToken와 함께 정적 토큰을 제공하거나, GitHub Copilot SDK 런타임이 아웃바운드 공급자 요청 전에 호출하는 bearerTokenProvider 콜백을 제공하세요. 래핑하는 콜백 또는 ID 라이브러리는 토큰 캐싱 및 새로 고침을 관리합니다.
애플리케이션에 이미 토큰이 있는 경우 사용합니다 bearerToken .
provider: {
type: "openai",
baseUrl: "https://<resource-name>.openai.azure.com/openai/v1/",
bearerToken: process.env.MY_BEARER_TOKEN, // Sets Authorization header
}
참고
이 bearerToken 옵션은 정적 토큰 문자열 만 허용합니다. SDK는 이 토큰을 자동으로 새로 고치지 않습니다. 토큰이 만료되면 요청이 실패하고 새 토큰으로 새 세션을 만들어야 합니다.
요청 시 토큰을 획득하는 데 사용합니다 bearerTokenProvider .
provider: {
type: "openai",
baseUrl: "https://my-custom-endpoint.example.com/v1",
bearerTokenProvider: async () => {
return await acquireBearerToken();
},
}
Microsoft Entra 전달자 토큰을 획득하고 새로 고치는 방법에 대한 자세한 내용은 BYOK를 사용하는 Azure 관리 ID을 참조하세요.
사용자 지정 모델 목록
BYOK를 사용하는 경우 CLI 서버는 공급자가 지원하는 모델을 모를 수 있습니다. 공급자의 모델을 표준 onListModels 형식으로 반환할 수 있도록 client.listModels() 클라이언트 수준에서 사용자 지정 ModelInfo 처리기를 제공할 수 있습니다. 이를 통해 다운스트림 소비자는 CLI를 쿼리하지 않고 사용 가능한 모델을 검색할 수 있습니다.
코드 언어 navigation
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 },
},
},
],
});
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),
),
)
],
)
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: copilot.Int(128000)},
},
},
}, nil
},
})
_ = client
}
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 }
}
}
})
});
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를 완전히 대체합니다. 서버로의 대체는 발생하지 않습니다.
제한점
기능 제한 사항
일부 Copilot 기능은 BYOK에서 다르게 동작할 수 있습니다.
- 모델 가용성 - 공급자가 지원하는 모델만 사용할 수 있습니다.
- ** 속도 제한** - Copilot 아닌 공급자의 속도 제한에 따라 다릅니다.
- 사용량 추적 - 사용량은 GitHub Copilot이 아니라 공급자가 추적합니다.
- 프레미스 요청 - Copilot 프리미엄 요청 할당량에 대해 계산하지 마세요.
공급자별 제한 사항
| Provider | 제한점 |
|---|---|
| Microsoft Foundry Local | 로컬 전용; 모델 가용성은 디바이스 하드웨어에 따라 달라집니다. API 키가 필요하지 않음 |
| Ollama | API 키가 없습니다. 로컬 전용; 모델 지원은 다양합니다. |
| OpenAI | OpenAI 속도 제한 및 할당량 적용 |
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-5.4",
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",
}
그러나 Microsoft Foundry 배포에서 OpenAI 호환 엔드포인트 경로(예/openai/v1/: )를 제공하는 경우 다음을 사용합니다type: "openai".
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-5.4",
provider: {
type: "openai",
baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
},
});
// ✅ Correct: OpenAI-compatible Microsoft 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
인증 실패
- API 키가 올바르고 만료되지 않았는지 확인합니다.
- 공급자의
baseUrl예상 형식과 일치하는지 확인합니다. - 전달자 토큰의 경우 전체 토큰이 제공되었는지 확인합니다(접두사뿐만 아니라).
다음 단계
- 인증 - 모든 인증 방법에 대해 알아보기
- 첫 번째 Copilot 기반 앱 빌드 - 첫 번째 Copilot 지원 앱 빌드