GitHub Copilot SDK: C# ile Kendi Modelinizi Bağlayın
GitHub Copilot SDK ile uygulama yazanların sık sorduğu sorulardan biri, model çıkarımının (inference) kendi dağıtımınıza yönlendirilip yönlendirilemeyeceği. Yönlendirilebiliyor. Copilot SDK size ajan çalışma zamanını (runtime) veriyor, ProviderConfig ise model isteğinin hangi sağlayıcıya ve hangi kimlik doğrulamayla gideceğini belirliyor. Bruno Capuano’nun.NET Blog’daki yazısı bu senaryoyu Microsoft Foundry üzerindeki bir dağıtıma bağlanan küçük bir.NET 10 konsol uygulamasıyla örnekliyor.
Örneğin tamamı Generative AI for Beginners.NET deposunun bir parçası. Akış sade: yapılandırmayı oku, BYOK sağlayıcısını oluştur, Copilot runtime’ı başlat, tek bir oturum aç, tek bir soru sor.
BYOK burada ne anlama geliyor?
BYOK, “Bring Your Own Key” kısaltması ama buradaki fikir anahtardan geniş; kendi model sağlayıcınızı getiriyorsunuz. İstemciyi, oturumu, sistem mesajını ve ajan yapılandırmasını Copilot SDK yönetmeye devam ediyor, ProviderConfig yalnızca model çıkarımının hedefini ve kimlik doğrulamasını değiştiriyor.
Yazıda geçen BYOK, müşteri tarafından yönetilen şifreleme anahtarlarını ya da depolama şifreleme yapılandırmasını kastetmiyor. Kastedilen, çıkarım için kendi uç noktanızı ve kimlik bilgilerinizi kullanmak.
Copilot SDK’nın resmi olarak desteklediği sağlayıcılar arasında OpenAI, Anthropic, Ollama, Microsoft Foundry Local ve vLLM ya da LiteLLM gibi OpenAI uyumlu uç noktalar var. Örnekte Microsoft Foundry kullanılıyor, doğrulama Microsoft Entra ID ile yapılıyor, gerektiğinde API anahtarıyla da olabiliyor.
Proje ve bağımlılıklar
Uygulama standart bir.NET 10 konsol projesi:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>genai-beginners-dotnet</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.21.0" />
<PackageReference Include="GitHub.Copilot.SDK" Version="1.0.11" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.3" />
</ItemGroup>
</Project>
GitHub.Copilot.SDK, Copilot runtime için.NET istemcisini sağlıyor. Azure.Identity ise AzureCliCredential üzerinden az login ile oluşturulan kimliğin yeniden kullanılmasına imkan veriyor. Configuration paketleri sayesinde uç nokta ve kimlik bilgileri kaynak kontrolüne girmeden yalnızca geliştirme ortamında yükleniyor.
Ön koşullar
.NET 10 SDK ve GitHub Copilot CLI kurulu olmalı; dotnet --version bir.NET 10 SDK bildirmeli, copilot --version çalışmalı. Varsayılan Entra ID yolu için Azure CLI da gerekiyor ve az --version sorunsuz çalışmalı. API anahtarı yolunda Azure CLI şart değil. Örnek, yerel Copilot runtime’ını RuntimeConnection.ForStdio("copilot") ile başlatıyor.
Yapılandırmayı okuma
Örnek, deponun ortak User Secrets değerlerini kullanıyor:
// User Secrets keeps the endpoint and credentials outside the repository.
var configuration = new ConfigurationBuilder()
.AddUserSecrets<Program>(optional: true)
.Build();
// This sample uses the repo's shared AzureOpenAI secrets.
var modelName = GetRequiredValue(configuration, "AzureOpenAI:Deployment");
var endpoint = GetRequiredValue(configuration, "AzureOpenAI:Endpoint");
var apiKey = configuration["AzureOpenAI:ApiKey"]?.Trim();
AzureOpenAI:Deployment: Microsoft Foundry veya Azure OpenAI üzerindeki model dağıtımınızın adı. ÖrnekWireApi = "responses"kullandığı için Responses API destekleyen bir dağıtım seçilmeli.AzureOpenAI:Endpoint: Foundry ya da Azure OpenAI kaynağının uç noktası.AzureOpenAI:ApiKey: İsteğe bağlı. YoksaAzureCliCredentialüzerinden Entra ID kullanılıyor, varsaapi-keybaşlığıyla gönderiliyor.
Sağlayıcı yapılandırması
Örneğin merkezinde bu blok var:
// Microsoft Foundry exposes an API compatible with OpenAI Responses.
var provider = new ProviderConfig
{
Type = "openai",
BaseUrl = NormalizeEndpoint(endpoint),
WireApi = "responses",
ModelId = modelName,
WireModel = modelName,
MaxPromptTokens = 8000,
MaxOutputTokens = 512
};
Type = "openai" OpenAI uyumlu sağlayıcı biçimini seçiyor, BaseUrl OpenAI uyumlu API yüzeyini gösteriyor, WireApi = "responses" Responses API’yi işaret ediyor, ModelId modeli Copilot runtime’a tanıtıyor, WireModel de sağlayıcıya gönderilen model adı oluyor. Bu örnekte iki değer aynı; ayrı özellik olmalarının nedeni, her entegrasyonda runtime tarafındaki tanımlayıcı ile sağlayıcı tarafındaki adın birebir aynı olmak zorunda olmaması.
Token sınırları örneği küçük tutmak için konmuş. Muhakeme (reasoning) modellerinde MaxOutputTokens görünür yanıtın yanı sıra reasoning token’larını da kapsıyor, yani 512’lik sınıra model daha yanıt üretmeden ulaşılabilir. Böyle bir dağıtımda bu sınırı yükseltmek ya da tamamen kaldırıp iş yüküne göre ayarlamak gerekiyor.
Uç nokta yardımcı metodu hem kaynak URL’sini hem de zaten /openai/v1/ içeren bir URL’yi kabul ediyor, HTTPS’i de zorunlu tutuyor:
static string NormalizeEndpoint(string endpoint)
{
var candidate = endpoint.Trim();
if (!Uri.TryCreate(candidate, UriKind.Absolute, out var uri) ||
uri.Scheme != Uri.UriSchemeHttps ||
string.IsNullOrWhiteSpace(uri.Host))
{
throw new ArgumentException("The configured AzureOpenAI:Endpoint must be an HTTPS URL.");
}
// Accept the resource URL or a URL that already ends in /openai/v1.
// Trimming first means a trailing slash does not need a separate check.
var trimmed = candidate.TrimEnd('/');
if (trimmed.EndsWith("/openai/v1", StringComparison.OrdinalIgnoreCase))
{
return trimmed + "/";
}
return $"{uri.GetLeftPart(UriPartial.Authority).TrimEnd('/')}/openai/v1/";
}
Hatalı biçimli bir uç noktayı ilk model isteğinden sonra fark etmektense, oturum oluşturulmadan reddetmek daha isabetli.
Kimlik doğrulama: Entra ID varsayılan, API anahtarı seçenek
Varsayılan yol Azure CLI oturumunu yeniden kullanıyor:
if (string.IsNullOrWhiteSpace(apiKey))
{
// AzureCliCredential reuses the session created with `az login`.
var credential = new AzureCliCredential();
var scope = "https://cognitiveservices.azure.com/.default";
#pragma warning disable GHCP001 // BYOK auth callbacks are experimental in the Copilot SDK.
provider.BearerTokenProvider = async _ =>
{
var token = await credential.GetTokenAsync(
new TokenRequestContext([scope]),
cancellation.Token);
return token.Token;
};
#pragma warning restore GHCP001
}
Oturum açmadan önce kimliğinizin ilgili kaynakta Cognitive Services OpenAI User rolüne sahip olması gerekiyor. Ardından:
az login
BearerTokenProvider bir geri çağırma (callback), SDK token’a ihtiyaç duyduğunda bunu çağırıyor, böylece uygulamanın tek bir token değerini kendi başına yönetmesi gerekmiyor. BYOK kimlik doğrulama geri çağırmaları SDK’da deneysel sayılıyor (GHCP001 uyarısı).
API anahtarı gerektiren ortamlar için ikinci yol, sağlayıcı yapılandırmasının geri kalanına dokunmadan çalışıyor:
else
{
provider.Headers = new Dictionary<string, string>
{
["api-key"] = apiKey
};
}
dotnet user-secrets set "AzureOpenAI:ApiKey" "<your-api-key>"
Değer tanımlıysa örnek api-key başlığını kullanıyor, az login gerekmiyor. Konsol çıktısı yalnızca kullanılan kimlik doğrulama modunu bildiriyor, uç noktayı veya kimlik bilgisini yazdırmıyor. Yerel geliştirmede User Secrets, dağıtılmış uygulamalarda ortam tarafından yönetilen yapılandırma öneriliyor; anahtarın kaynak dosyaya ya da README’ye yapıştırılmaması ayrıca vurgulanıyor.
Runtime ve kasıtlı olarak sade bir oturum
Model çıkarımını sağlayıcı yönetse de Copilot runtime hala gerekli:
await using var client = new CopilotClient(new CopilotClientOptions
{
Connection = RuntimeConnection.ForStdio("copilot"),
WorkingDirectory = AppContext.BaseDirectory
});
await client.StartAsync(cancellation.Token);
BYOK, “Copilot olmadan Copilot SDK” demek değil. Yerel Copilot CLI runtime’ı orkestrasyon sürecini sağlamaya devam ediyor, BYOK yalnızca model isteğinin nereye gideceğini değiştiriyor.
Oturum yapılandırması model adını ve sağlayıcıyı bağlarken, bu ilk örneğin kapsamı dışındaki yetenekleri bilinçli olarak kapatıyor:
// Disable tools, skills, and Git operations to isolate the model request.
await using var session = await client.CreateSessionAsync(new SessionConfig
{
ClientName = "github-copilot-sdk-byok",
Model = modelName,
Provider = provider,
SystemMessage = new SystemMessageConfig
{
Mode = SystemMessageMode.Replace,
Content = "Answer every user question in English. Be concise and factual."
},
AvailableTools = [],
Tools = [],
EnableConfigDiscovery = false,
EnableSkills = false,
EnableHostGitOperations = false
}, cancellation.Token);
Boş araç koleksiyonları ve kapatılan özellikler kasıtlı; sağlayıcı yapılandırmasını öğrenirken örneği hem anlaşılır hem güvenli tutuyorlar. SystemMessageMode.Replace ise varsayılan sistem mesajına ek yapmak yerine onu tamamen değiştiriyor, çok dilli canlı oturumlarda çıktıyı öngörülebilir kılan da bu.
Tek soru, tek yanıt
var response = await session.SendAndWaitAsync(
new MessageOptions { Prompt = question },
TimeSpan.FromMinutes(3),
cancellation.Token);
var content = response?.Data.Content;
if (string.IsNullOrWhiteSpace(content))
{
throw new InvalidOperationException("The model returned an empty response.");
}
Console.WriteLine();
Console.WriteLine("Answer:");
Console.WriteLine(content);
Varsayılan soru şu: What is Microsoft Foundry, and how does it relate to the GitHub Copilot SDK? Farklı bir soruyu komut satırı argümanı olarak geçebiliyorsunuz:
dotnet run -- "Explain BYOK in one sentence."
Çalıştırma adımları
dotnet user-secrets set "AzureOpenAI:Endpoint" "https://<resource>.services.ai.azure.com"
dotnet user-secrets set "AzureOpenAI:Deployment" "<your-deployment-name>"
Ardından varsayılan Entra ID yolu:
az login
dotnet run
Çıktı şu biçimde oluyor:
Model: <your-deployment-name>
Authentication: AzureCliCredential
Question: What is Microsoft Foundry, and how does it relate to the GitHub Copilot SDK?
Answer:
<modelresponse>
Çıkarım: runtime ile sağlayıcıyı ayırmak
Yazının temel mesajı, Copilot SDK runtime’ı ile model sağlayıcısının birbirinden bağımsız iki parça olduğu. GitHub’ın verdiği istemci, oturum, sistem mesajı ve ajan altyapısı yerinde kalıyor, siz yalnızca çıkarımı başka bir hedefe yönlendiriyorsunuz. Bu hedef kendi Foundry dağıtımınız olabilir, kendi OpenAI anahtarınız olabilir, yerel Ollama kurulumunuz da olabilir.
Varsayılan olarak Entra ID kullanılması, döndürülmesi, sızması veya yanlışlıkla commit edilmesi gereken bir anahtar bırakmıyor, tercih sebebi de bu. API anahtarı dalı yalnızca gerçekten gerektiğinde devreye giriyor.
Oturumun bilinçli şekilde “sıkıcı” tutulması da aynı amaca hizmet ediyor. Araç, skill, MCP ve Git erişimi kapalıyken ilk çalıştırmanın tek bir işi kalıyor, o da modelin yanıt verdiğini kanıtlamak. Konsolda yanıtı gördükten sonra elinizde çalışan bir temel oluyor; araçları, MCP sunucularını, skill’leri, onay akışlarını ve akışlı (streaming) yanıtı teker teker eklediğinizde bir şey bozulduğunda hangi parçanın sorumlu olduğunu bilebiliyorsunuz.
Kaynaklar ve İleri Okuma
- Bring Your Own Model to the GitHub Copilot SDK with C# —.NET Blog (orijinal yazı)
- GitHubCopilotSDK-01-BYOK örnek projesi
- Generative AI for Beginners.NET deposu
- GitHub Copilot SDK
- Copilot SDK BYOK kimlik doğrulama dokümantasyonu
- Build Your Own AI Agent Harness in C#
- From dotnet run to Foundry Hosted Agent in 3 lines of C#
- Let’s Learn.NET ve etkinlik sayfası
- Building Agentic AI Apps with GitHub Copilot SDK (Coursera Professional Certificate)
- Microsoft Foundry
- İlgili yazı: GitHub Copilot Model Yönetiminde Yeni Dönem
- İlgili yazı: azd AI Agent uzantısıyla Foundry ajanlarını Azure’a taşımak







Yorum gönder