Am besten geeignet für: SaaS-Produkte, Partnerintegrationen, interne Plattformen und Back-End-Dienste, die gleichzeitige Benutzer verarbeiten.
Verwenden Sie dieses Handbuch, wenn
Verwenden Sie diesen Leitfaden, wenn Sie Folgendes erstellen:
- Ein Mehrbenutzer-SaaS-Produkt, das Copilot-gestützte Agenten einbettet
- Ein Backend für eine Partnerintegration, beispielsweise ein Muster im Stil von Copilot Studio oder Fabric
- Jeder Server, der gleichzeitige Benutzer, Arbeitsbereiche, Mandanten oder Anforderungen verarbeitet
- Eine freigegebene Laufzeit, bei der mehrere SDK-Clients eine Verbindung mit einem Copilot Laufzeitprozess herstellen
Dieser Leitfaden ist eine Schwester von Skalierung und Mehrinstanzenfähigkeit. Verwenden Sie dieses Handbuch für Topologie, Lastenausgleich und Speichermuster. Verwenden Sie dieses Handbuch für Optionen auf SDK-Ebene und Optionen für die Laufzeitisolation.
Schlüssel-SDK-Optionen
| Auswahl | Verwenden Sie es für | Hinweise |
|---|---|---|
mode: "empty" | Deaktivieren von Umgebungsbetriebssystem-Tools und CLI-Standardwerten | Erforderlich für Szenarien mit mehreren Benutzern oder gemeinsam genutzten Szenarien. |
sessionIdleTimeoutSeconds | Bereinigen von Leerlaufsitzungen | Festlegen eines serverseitigen Timeouts für lange ausgeführte Prozesse. |
baseDirectory | Isolieren COPILOT_HOME pro Laufzeitinstanz | Wird ignoriert, wenn eine Verbindung mit einer vorhandenen Laufzeit hergestellt wird. |
sessionFs | Umleitung des Dateisystemspeichers für Sitzungen weg vom lokalen Datenträger | Mit Dateisystemanbietern je Sitzung koppeln. |
RuntimeConnection.forUri(url) | Teilen einer bereits laufenden Runtime | Sprachnamen variieren; siehe Beispiele unten. |
Pro Sitzung gitHubToken | Authentifizierung auf den anfragenden Benutzer beschränken | Verwenden Sie dies anstelle eines gemeinsam genutzten Benutzertokens. |
mode: "empty"
mode: "empty" deaktiviert standardmäßig optionales Copilot CLI-Verhalten. Im Servermodus mit mehreren Benutzern ist dies der sichere Basisplan, da Ihre Anwendung explizit entscheiden muss, auf welche Tools, MCP-Server, Fähigkeiten und Arbeitsbereichspfade eine Sitzung zugreifen kann.
Verwenden Sie für gemeinsam genutzte Server nicht die Standardeinstellung mode: "copilot-cli". Dieser Modus ist für CLI-ähnliche Codierungs-Agents vorgesehen und kann Umgebungshost-Dateisystemfunktionen verfügbar machen.
import { CopilotClient, RuntimeConnection } from "@github/copilot-sdk";
// baseDirectory and sessionIdleTimeoutSeconds apply when the SDK spawns the
// runtime. With RuntimeConnection.forUri(...) configure COPILOT_HOME and the
// idle timeout on the runtime process itself.
const client = new CopilotClient({
mode: "empty",
connection: RuntimeConnection.forUri(process.env.COPILOT_RUNTIME_URL!),
});
const session = await client.createSession({
sessionId: `user-${user.id}-${crypto.randomUUID()}`,
model: "gpt-4.1",
availableTools: ["custom:lookupOrder", "custom:createTicket"],
gitHubToken: user.githubToken,
});
from copilot import CopilotClient, RuntimeConnection
from copilot.session import PermissionHandler
client = CopilotClient(
mode="empty",
base_directory=f"/var/lib/my-app/copilot/{runtime_instance_id}",
session_idle_timeout_seconds=900,
connection=RuntimeConnection.for_uri(runtime_url),
)
await client.start()
session = await client.create_session(
session_id=f"user-{user.id}-{request_id}",
model="gpt-4.1",
available_tools=["custom:lookupOrder", "custom:createTicket"],
github_token=user.github_token,
on_permission_request=PermissionHandler.approve_all,
)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
)
type appUser struct {
ID string
GitHubToken string
}
func main() {
ctx := context.Background()
runtimeInstanceID := "instance-1"
runtimeURL := "http://127.0.0.1:8080"
requestID := "req-1"
user := appUser{ID: "alice", GitHubToken: "YOUR_GITHUB_TOKEN"}
client := copilot.NewClient(&copilot.ClientOptions{
Mode: copilot.ModeEmpty,
BaseDirectory: fmt.Sprintf("/var/lib/my-app/copilot/%s", runtimeInstanceID),
SessionIdleTimeoutSeconds: 900,
Connection: copilot.URIConnection{URL: runtimeURL},
})
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
SessionID: fmt.Sprintf("user-%s-%s", user.ID, requestID),
Model: "gpt-4.1",
AvailableTools: []string{"custom:lookupOrder", "custom:createTicket"},
GitHubToken: user.GitHubToken,
})
_ = session
_ = err
}
client := copilot.NewClient(&copilot.ClientOptions{
Mode: copilot.ModeEmpty,
BaseDirectory: fmt.Sprintf("/var/lib/my-app/copilot/%s", runtimeInstanceID),
SessionIdleTimeoutSeconds: 900,
Connection: copilot.URIConnection{URL: runtimeURL},
})
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
SessionID: fmt.Sprintf("user-%s-%s", user.ID, requestID),
Model: "gpt-4.1",
AvailableTools: []string{"custom:lookupOrder", "custom:createTicket"},
GitHubToken: user.GitHubToken,
})
using GitHub.Copilot;
var runtimeInstanceId = "instance-1";
var runtimeUrl = "http://127.0.0.1:8080";
var requestId = "req-1";
var user = new { Id = "alice", GitHubToken = "YOUR_GITHUB_TOKEN" };
var client = new CopilotClient(new CopilotClientOptions
{
Mode = CopilotClientMode.Empty,
BaseDirectory = $"/var/lib/my-app/copilot/{runtimeInstanceId}",
SessionIdleTimeoutSeconds = 900,
Connection = RuntimeConnection.ForUri(runtimeUrl),
});
await using var session = await client.CreateSessionAsync(new SessionConfig
{
SessionId = $"user-{user.Id}-{requestId}",
Model = "gpt-4.1",
AvailableTools = ["custom:lookupOrder", "custom:createTicket"],
GitHubToken = user.GitHubToken,
});
var client = new CopilotClient(new CopilotClientOptions
{
Mode = CopilotClientMode.Empty,
BaseDirectory = $"/var/lib/my-app/copilot/{runtimeInstanceId}",
SessionIdleTimeoutSeconds = 900,
Connection = RuntimeConnection.ForUri(runtimeUrl),
});
await using var session = await client.CreateSessionAsync(new SessionConfig
{
SessionId = $"user-{user.Id}-{requestId}",
Model = "gpt-4.1",
AvailableTools = ["custom:lookupOrder", "custom:createTicket"],
GitHubToken = user.GitHubToken,
});
import java.util.List;
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.CopilotClientOptions;
import com.github.copilot.rpc.CopilotClientMode;
import com.github.copilot.rpc.SessionConfig;
public class MultiTenancyExample {
record User(String id, String gitHubToken) {}
public static void main(String[] args) throws Exception {
String runtimeUrl = "http://localhost:4321";
String requestId = "req-1";
User user = new User("u1", "ghu_token");
// setCopilotHome and setSessionIdleTimeoutSeconds are ignored when
// setCliUrl is used; configure those on the runtime process instead.
var client = new CopilotClient(new CopilotClientOptions()
.setMode(CopilotClientMode.EMPTY)
.setCliUrl(runtimeUrl)
);
var session = client.createSession(new SessionConfig()
.setSessionId("user-" + user.id() + "-" + requestId)
.setModel("gpt-4.1")
.setAvailableTools(List.of("custom:lookupOrder", "custom:createTicket"))
.setGitHubToken(user.gitHubToken())
).get();
}
}
// setCopilotHome and setSessionIdleTimeoutSeconds are ignored when
// setCliUrl is used; configure those on the runtime process instead.
var client = new CopilotClient(new CopilotClientOptions()
.setMode(CopilotClientMode.EMPTY)
.setCliUrl(runtimeUrl)
);
var session = client.createSession(new SessionConfig()
.setSessionId("user-" + user.id() + "-" + requestId)
.setModel("gpt-4.1")
.setAvailableTools(List.of("custom:lookupOrder", "custom:createTicket"))
.setGitHubToken(user.gitHubToken())
).get();
use std::path::PathBuf;
use github_copilot_sdk::{Client, ClientOptions, Transport};
use github_copilot_sdk::mode::ClientMode;
use github_copilot_sdk::types::SessionConfig;
let client = Client::start(
ClientOptions::new()
.with_mode(ClientMode::Empty)
.with_base_directory(PathBuf::from(format!(
"/var/lib/my-app/copilot/{runtime_instance_id}"
)))
.with_session_idle_timeout_seconds(900)
.with_transport(Transport::External {
host: runtime_host.to_string(),
port: runtime_port,
connection_token: None,
}),
).await?;
let session = client.create_session(
SessionConfig::default()
.with_session_id(format!("user-{}-{request_id}", user.id))
.with_model("gpt-4.1")
.with_available_tools(["custom:lookupOrder", "custom:createTicket"])
.with_github_token(user.github_token),
).await?;
sessionIdleTimeoutSeconds
Legen Sie sessionIdleTimeoutSeconds auf Servern fest, damit inaktive Sitzungen automatisch beendet werden. Dies verhindert Zombie-Sitzungen in lang laufenden Prozessen und reduziert den Speicher- und Dateisystemdruck.
| Language | Öffentliche Option |
|---|---|
| Typescript | sessionIdleTimeoutSeconds |
| Python | session_idle_timeout_seconds |
| Go | SessionIdleTimeoutSeconds |
| .NET | SessionIdleTimeoutSeconds |
| Java | setSessionIdleTimeoutSeconds(...) |
| Rust | with_session_idle_timeout_seconds(...) |
Verwenden Sie einen Wert, der der Lebensdauer einer Konversation in Ihrem Produkt entspricht. Bei Chat-Back-Ends ist in der Regel 15 bis 30 Minuten ein guter Ausgangspunkt. Verwenden Sie für Workflow-Agents ein längeres Timeout und explizites Löschen, wenn der Workflow abgeschlossen ist.
baseDirectory
baseDirectory legt COPILOT_HOME für eine Laufzeitinstanz fest. Verwenden Sie sie, um Laufzeitstatus, Anmeldeinformationen und Sitzungsdaten pro Prozess, Pod, Worker oder Mandantengrenze zu isolieren.
const client = new CopilotClient({
mode: "empty",
baseDirectory: `/var/lib/my-app/copilot/runtime-${process.env.HOSTNAME}`,
sessionIdleTimeoutSeconds: 900,
});
Die Laufzeit speichert den Sitzungszustand unter dem konfigurierten COPILOT_HOME, einschließlich session-state/{sessionId}. Wenn Ihre App mehrere Laufzeitinstanzen ausführt, weisen Sie jeder Instanz ein eigenes Verzeichnis zu, es sei denn, Sie verwenden absichtlich freigegebenen Speicher.
Wenn das SDK eine Verbindung mit einer bereits ausgeführten Laufzeit herstellt RuntimeConnection.forUri(url), baseDirectory wird vom SDK-Client ignoriert. Konfigurieren Sie COPILOT_HOME stattdessen für den Laufzeitprozess.
sessionFs
sessionFs registriert einen benutzerdefinierten Sitzungsdateisystemanbieter, sodass sitzungsbezogene Datei-E/A über den Anwendungsspeicher statt über die lokale Festplatte der Laufzeitumgebung geleitet werden kann. Verwenden Sie sie, wenn der lokale Datenträger kurzlebig ist, wenn der Sitzungszustand im Objektspeicher gespeichert werden muss oder wenn eine Plattform mandantenbezogene Speicherpfade erzwingen muss.
const client = new CopilotClient({
mode: "empty",
sessionFs: {
initialCwd: "/workspace",
sessionStatePath: "/session-state",
conventions: "posix",
},
});
Konfigurieren Sie für Sprachen, die einen Provider-Callback bereitstellen, sessionFs auf Client-Ebene, und stellen Sie beim Erstellen oder Fortsetzen einer Sitzung einen sitzungsspezifischen Dateisystem-Handler bereit. Siehe Wiederaufnahme und Persistenz der Sitzung für Persistenzkonzepte und Speicherabschläge.
Überprüfte öffentliche SDK-Oberflächen:
| Language | Konfiguration auf Clientebene | Sitzungsbasierter Anbieter |
|---|---|---|
| Typescript | sessionFs | |
createSessionFsAdapter / Anbieterrückrufe | ||
| Python | session_fs | create_session_fs_handler |
| Go | SessionFS | CreateSessionFSProvider |
| .NET | SessionFs | CreateSessionFsProvider |
| Rust | with_session_fs(...) | with_session_fs_provider(...) |
Java stellt derzeit keine überprüfte öffentliche sessionFs-Option zur Verfügung, sodass in diesem Handbuch kein Java sessionFs-Beispiel angezeigt wird.
RuntimeConnection.forUri(url)
Verwenden Sie eine externe Laufzeitverbindung, wenn mehrere SDK-Clients eine bereits ausgeführte Laufzeit gemeinsam nutzen sollten. Dies ist in Back-End-Diensten üblich, bei denen der Laufzeitprozess getrennt von Anforderungshandlern verwaltet wird.
| Language | Externe Laufzeitverbindung |
|---|---|
| Typescript | RuntimeConnection.forUri(url) |
| Python | RuntimeConnection.for_uri(url) |
| Go | copilot.URIConnection{URL: url} |
| .NET | RuntimeConnection.ForUri(url) |
| Java | setCliUrl(url) |
| Rust | Transport::External { host, port, connection_token } |
Externe Laufzeiten verwalten ihre eigene Authentifizierung und Speicherung auf Prozessebene. Übergeben Sie Token pro Sitzung an createSession oder resumeSession wenn Sie eine benutzerspezifische Authentifizierung benötigen.
Pro Sitzung gitHubToken
Legen Sie gitHubToken in jeder Sitzung fest, um die GitHub-Authentifizierung auf den anfordernden Benutzer zu beschränken. Dies unterscheidet sich von einem Token auf Clientebene, das den Laufzeitprozess authentifiziert.
const session = await client.createSession({
sessionId: `user-${user.id}-support`,
model: "gpt-4.1",
availableTools: ["custom:*"],
gitHubToken: user.githubToken,
});
Verwenden Sie sitzungsbezogene Tokens für den Ausschluss von Inhalten, das Modellrouting, Kontingentprüfungen und den benutzerspezifischen Copilot-Zugriff. Vermeiden Sie die Freigabe eines Diensttokens für alle Benutzer, es sei denn, Ihr Produkt verwendet absichtlich die Semantik des Dienstkontos.
Integration-ID
Partner, die Branding-Agents erstellen, können eine Integrations-ID für Mission Control-Anforderungen festlegen. Die Laufzeit liest GITHUB_COPILOT_INTEGRATION_ID und stempelt sie als Copilot-Integration-Id HTTP-Header für jede Mission Control-Anforderung.
GITHUB_COPILOT_INTEGRATION_ID=my-product-agent copilot --headless --port 4321
Die Standardintegrations-ID lautet copilot-developer-cli. Verwenden Sie einen stabilen Wert wie my-product-agent für Attribution und Routing. Die Integrations-ID wird derzeit nur von der Umgebungsvariablen konfiguriert. Es handelt sich nicht um eine erstklassige SDK-Option.
Wenn das SDK die Laufzeit startet, übergeben Sie die Umgebungsvariable über die Client-Umgebungsoption. Wenn Sie eine Verbindung mit RuntimeConnection.forUri(url) herstellen, legen Sie die Umgebungsvariable direkt für den Laufzeitprozess selbst fest.
Isolationsgarantien auf Sitzungsebene
Die Isolation auf Sitzungsebene bedeutet, dass die Laufzeit benutzerspezifische Modell- und Zustandsinformationen auf eine Sitzung beschränkt und nicht in einem global gemeinsam genutzten Zustand hält.
| Oberfläche | Isolationsverhalten |
|---|---|
| Cache der Modellliste | Pro Sitzung. Die Modellsuche verwendet den Cache der Modellliste der Sitzung. |
| Sitzungszustand | Pro Sitzungs-ID unter COPILOT_HOME/session-state/{sessionId}. |
| GitHub Identität | Pro Sitzung, wenn gitHubToken für die Sitzung festgelegt wird. |
| Tools | Explizit in mode: "empty"; Umgebung in mode: "copilot-cli". |
| Dateisystem des Hosts | Wird vom Laufzeitprozess gemeinsam genutzt, wenn Host-Tools verfügbar sind. |
mode: "empty" macht freigegebene Laufzeitmuster lebensfähig: Es werden keine Umgebungsbetriebssystem-Tools verfügbar gemacht, es sei denn, Ihre Anwendung registriert oder lässt sie zu. Mit mode: "copilot-cli" wird der Zugriff auf das Dateisystem des Betriebssystems über den Hostprozess gemeinsam genutzt. Verwenden Sie diesen Modus daher nicht im Mehrbenutzer-Servermodus.
Der Sitzungszustand wird unter COPILOT_HOME/session-state/{sessionId} gespeichert, es sei denn, Sie leiten ihn über sessionFs um. Verwenden Sie eindeutige Sitzungs-IDs, die Ihre eigene Mandanten- oder Benutzergrenze enthalten, und erzwingen Sie die Zugriffssteuerung, bevor Sie Sitzungen fortsetzen oder löschen.
Mustervergleich
| Schema | Verwenden Sie, wenn | Trade-offs |
|---|---|---|
| Muster 1: isolierte CLI pro Benutzer | Sie benötigen die stärkste Isolationsgrenze oder separate Prozessanmeldeinformationen pro Benutzer. | Starke Isolation; höhere Ressourcenkosten. Siehe Skalierung und Mehrinstanzenfähigkeit. |
Muster 2: gemeinsame CLI mit mode: "empty" | Sie möchten, dass eine Laufzeit viele Benutzer bedient, während Ihre App Tools, Authentifizierung und Sitzungs-IDs steuert. | Effiziente; erfordert sorgfältige Toolregistrierung, Zugriffstoken pro Sitzung und Zugriffsprüfungen auf Anwendungsebene. |
| Muster 3: Hybrid | Sie verlagern rechenintensive Aufgaben in Cloud-Sitzungen und weniger rechenintensive Aufgaben in lokale Sitzungen. | Flexibel; erfordert Workload-Routing und Richtlinienverwaltung. Siehe Cloud-Sitzungen. |
Muster 2: gemeinsame CLI mit mode: "empty"
In diesem Muster verbinden sich alle Benutzer über Ihr Back-End mit einem Laufzeitpool. Die Anwendung führt die Benutzerauthentifizierung aus, wählt eine Sitzungs-ID aus, übergibt das GitHub-Token des Benutzers in der Sitzung und stellt eine explizite Tool-Zulassungsliste bereit.

Verwenden Sie die folgenden Regeln:
- Starten Sie den Client oder die Runtime immer in
mode: "empty". - Verwenden Sie eindeutige Sitzungs-IDs, und speichern Sie Besitzermetadaten in Ihrer Anwendungsdatenbank.
- Überprüfen Sie die Inhaberschaft vor
resumeSession,deleteSessionoder jeder UI-Aktion, die auf eine Sitzungs-ID verweist. - Übergeben Sie
gitHubTokenpro Sitzung, wenn Anforderungen als Benutzer ausgeführt werden sollen. - Registrieren Sie nur die Tools, die die Sitzung benötigt, und bevorzugen Sie quellqualifizierte Zulassungslisten wie
custom:*odermcp:search_docs. - Legen Sie
sessionIdleTimeoutSecondsfest und löschen Sie abgeschlossene Workflow-Sitzungen explizit.
Häufige Fallstricke
mode: "empty"Vergessen . Der Standardmoduscopilot-climacht das CLI-Stilverhalten verfügbar und kann das Hostdateisystem über Umgebungstools verfügbar machen.- Keine Festlegung von
sessionIdleTimeoutSeconds. Server mit langen Laufzeiten können inaktive Sitzungen ansammeln, wenn diese nicht bereinigt werden. - Ein
gitHubTokenfür mehrere Benutzer gemeinsam nutzen, anstatt ein sitzungsspezifisches Token zu übergeben. - Blindes Vertrauen in vom Client übermittelte Sitzungs-IDs, ohne im Backend ihre Zugehörigkeit zu prüfen.
- Festlegen
baseDirectoryauf einem Client, der eine Verbindung mit einer vorhandenen Laufzeit herstellt und erwartet, dass der Laufzeitspeicher verschoben wird. Konfigurieren Sie stattdessen den Laufzeitprozess. - Das Zulassen weit gefasster Toolmuster wie
builtin:*, ohne zu prüfen, ob jedes Tool für Ihre Benutzer geeignet ist.
Siehe auch
- Skalierung und Mehrinstanzenfähigkeit: Bereitstellungstopologien, Speichermuster und Isolationsvergleiche
- Einrichtung von Back-End-Diensten: Ausführen der Runtime im Headless-Servermodus
- BYOK (Bring Your Own Key): Verwendung der Anmeldedaten Ihres eigenen Modellanbieters
- Cloud-Sitzungen: Routing ausgewählter Arbeit an Cloudsitzungen
- Wiederaufnahme und Persistenz der Sitzung: Verwalten des fortsetzungsfähigen Sitzungszustands
- Funktionen: Tools, Ereignisse, Hooks und erweiterte SDK-Features