Lo mejor para: Productos SaaS, integraciones de asociados, plataformas internas y servicios back-end que controlan usuarios simultáneos.
Use esta guía cuando
Utiliza esta guía cuando estés compilando:
- Un producto SaaS multiusuario que inserta agentes con tecnología Copilot
- Un backend para una integración de socio, como un patrón de Copilot Studio o de estilo Fabric
- Cualquier servidor que controle usuarios simultáneos, áreas de trabajo, inquilinos o solicitudes
- Un entorno de ejecución compartido en el que varios clientes del SDK se conectan a un proceso de tiempo de ejecución de Copilot
Esta guía es una hermana de Escalabilidad y multitenencia. Use esa guía para la topología, el equilibrio de carga y los patrones de almacenamiento. Use esta guía para las opciones de nivel de SDK y las opciones de aislamiento en tiempo de ejecución.
Opciones clave del SDK
| Opción | Úselo para | Notas |
|---|---|---|
mode: "empty" | Deshabilitación de las herramientas del sistema operativo ambiental y los valores predeterminados de la CLI | Necesario para escenarios multiusuario o compartido. |
sessionIdleTimeoutSeconds | Depuración de sesiones inactivas | Establezca un tiempo de espera del lado servidor para los procesos de ejecución prolongada. |
baseDirectory | Aislamiento de COPILOT_HOME por instancia del entorno de ejecución | Se omite al conectarse a un entorno de ejecución existente. |
sessionFs | Enrutamiento del almacenamiento del sistema de archivos de sesión fuera del disco local | Emparejar con proveedores de sistema de archivos por sesión. |
RuntimeConnection.forUri(url) | Uso compartido de un entorno de ejecución ya en ejecución | Los nombres de idioma varían; consulte los ejemplos siguientes. |
Por sesión gitHubToken | Limitar la autenticación al usuario solicitante | Es preferible a un solo token de usuario compartido. |
mode: "empty"
mode: "empty" deshabilita el comportamiento opcional de la CLI de Copilot de forma predeterminada. En el modo de servidor multiusuario, esta es la línea base segura porque la aplicación debe decidir explícitamente qué herramientas, servidores MCP, aptitudes y rutas de acceso del área de trabajo a las que puede acceder una sesión.
No use el valor predeterminado mode: "copilot-cli" para los servidores compartidos. Ese modo está diseñado para agentes de codificación similares a la CLI y puede exponer funcionalidades del sistema de archivos de host ambiente.
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
Establezca sessionIdleTimeoutSeconds en servidores para que las sesiones inactivas se limpien automáticamente. Esto evita sesiones zombi en procesos de larga duración y reduce la presión del sistema de archivos y la memoria.
| Language | Opción pública |
|---|---|
| TypeScript | sessionIdleTimeoutSeconds |
| Python | session_idle_timeout_seconds |
| Ir | SessionIdleTimeoutSeconds |
| .NET | SessionIdleTimeoutSeconds |
| Java | setSessionIdleTimeoutSeconds(...) |
| Óxido | with_session_idle_timeout_seconds(...) |
Use un valor que coincida con la duración de la conversación del producto. En el caso de los back-end de chat, de 15 a 30 minutos suele ser un buen punto de partida. En el caso de los agentes de flujo de trabajo, use un tiempo de espera más largo y una eliminación explícita cuando se complete el flujo de trabajo.
baseDirectory
baseDirectory establece COPILOT_HOME para una instancia en tiempo de ejecución. Úselo para aislar el estado en tiempo de ejecución, las credenciales y los datos de sesión por proceso, pod, trabajador o límite entre inquilinos.
const client = new CopilotClient({
mode: "empty",
baseDirectory: `/var/lib/my-app/copilot/runtime-${process.env.HOSTNAME}`,
sessionIdleTimeoutSeconds: 900,
});
El entorno de ejecución almacena el estado de la sesión en el COPILOT_HOME configurado, incluyendo session-state/{sessionId}. Si la aplicación ejecuta varias instancias en tiempo de ejecución, asigne a cada instancia un directorio distinto a menos que use intencionadamente el almacenamiento compartido.
Cuando el SDK se conecta a un entorno de ejecución que ya está en ejecución con RuntimeConnection.forUri(url), el cliente del SDK ignora baseDirectory. Configure COPILOT_HOME en su lugar en el proceso en tiempo de ejecución.
sessionFs
sessionFs registra un proveedor de sistema de archivos de sesión personalizado para que la E/S de archivos con ámbito de sesión se pueda enrutar a través del almacenamiento de aplicaciones en lugar del disco local del entorno de ejecución. Úselo cuando el disco local sea efímero, cuando el estado de la sesión deba almacenarse en el almacenamiento de objetos o cuando una plataforma necesite aplicar rutas de almacenamiento específicas por tenant.
const client = new CopilotClient({
mode: "empty",
sessionFs: {
initialCwd: "/workspace",
sessionStatePath: "/session-state",
conventions: "posix",
},
});
Para los lenguajes que exponen una función de retorno del proveedor, configure sessionFs en el cliente y proporcione un controlador del sistema de archivos para cada sesión al crear o reanudar una sesión. Consulte Reanudación y persistencia de sesión para conocer los conceptos de persistencia y las ventajas de almacenamiento.
Superficies comprobadas del SDK público:
| Language | Configuración de nivel de cliente | Proveedor por sesión |
|---|---|---|
| TypeScript | sessionFs | |
createSessionFsAdapter / funciones de devolución de llamada del proveedor | ||
| Python | session_fs | create_session_fs_handler |
| Ir | SessionFS | CreateSessionFSProvider |
| .NET | SessionFs | CreateSessionFsProvider |
| Óxido | with_session_fs(...) | with_session_fs_provider(...) |
Java no expone actualmente una opción de <c0 pública comprobada />, por lo que esta guía no muestra un ejemplo de Java
RuntimeConnection.forUri(url)
Use una conexión externa en tiempo de ejecución cuando varios clientes del SDK deben compartir un entorno de ejecución ya en ejecución. Esto es habitual en los servicios back-end en los que el proceso en tiempo de ejecución se administra independientemente de los controladores de solicitudes.
| Language | Conexión externa en tiempo de ejecución |
|---|---|
| TypeScript | RuntimeConnection.forUri(url) |
| Python | RuntimeConnection.for_uri(url) |
| Ir | copilot.URIConnection{URL: url} |
| .NET | RuntimeConnection.ForUri(url) |
| Java | setCliUrl(url) |
| Óxido | Transport::External { host, port, connection_token } |
Los entornos de ejecución externos administran su propia autenticación y almacenamiento de nivel de proceso. Pase tokens de sesión en createSession o resumeSession cuando necesite autenticación específica para cada usuario.
Por sesión gitHubToken
Establezca gitHubToken en cada sesión para delimitar la autenticación de GitHub al usuario solicitante. Esto es diferente de un token de nivel de cliente, que autentica el proceso en tiempo de ejecución.
const session = await client.createSession({
sessionId: `user-${user.id}-support`,
model: "gpt-4.1",
availableTools: ["custom:*"],
gitHubToken: user.githubToken,
});
Use tokens por sesión para la exclusión de contenido, el enrutamiento de modelos, las comprobaciones de cuota y el acceso Copilot específico del usuario. Evite compartir un token de servicio entre los usuarios a menos que el producto use intencionadamente la semántica de la cuenta de servicio.
Id. de integración
Los asociados que crean agentes con marca pueden establecer un identificador de integración para las solicitudes de Mission Control. El entorno de ejecución lee GITHUB_COPILOT_INTEGRATION_ID y lo establece como la cabecera HTTP Copilot-Integration-Id en cada solicitud a Mission Control.
GITHUB_COPILOT_INTEGRATION_ID=my-product-agent copilot --headless --port 4321
El identificador de integración predeterminado es copilot-developer-cli. Use un valor estable como my-product-agent para la atribución y el enrutamiento. Actualmente, el identificador de integración solo se puede configurar mediante una variable de entorno; no es una opción nativa del SDK.
Si el SDK genera el entorno de ejecución, pase la variable de entorno a través de la opción de entorno de cliente. Si se conecta a través de RuntimeConnection.forUri(url), establezca la variable de entorno en el propio proceso de ejecución.
Garantías de aislamiento de nivel de sesión
El aislamiento a nivel de sesión significa que el entorno de ejecución mantiene la información del modelo y del estado específica del usuario dentro del ámbito de una sesión, y no en un estado compartido global.
| Superficie | Comportamiento de aislamiento |
|---|---|
| Caché de lista de modelos | Por sesión. La búsqueda de modelos usa la caché de lista de modelos de la sesión. |
| Estado de sesión | Por identificador de sesión debajo de COPILOT_HOME/session-state/{sessionId}. |
| identidad de GitHub | Por sesión cuando gitHubToken se establece en la sesión. |
| Herramientas | Explícito en mode: "empty"; implícito en mode: "copilot-cli". |
| Sistema de archivos del host | Compartido por el proceso en tiempo de ejecución si hay herramientas de host disponibles. |
mode: "empty" es lo que hace que los patrones de tiempo de ejecución compartidos sean viables: no se exponen herramientas del sistema operativo ambiente a menos que la aplicación se registre o las permita. Con mode: "copilot-cli", el acceso al sistema de archivos del sistema operativo se comparte a través del proceso de host, por lo que no use ese modo para el modo de servidor multiusuario.
El estado de sesión se almacena en COPILOT_HOME/session-state/{sessionId} a menos que se enrute a través de sessionFs. Use identificadores de sesión únicos que incluyan su propio inquilino o límite de usuario y aplique el control de acceso antes de reanudar o eliminar sesiones.
Comparación de patrones
| Pattern | Se utiliza cuando | Ventajas y desventajas |
|---|---|---|
| Patrón 1: CLI aislada por usuario | Necesita el límite de aislamiento más seguro o credenciales de proceso independientes por usuario. | Aislamiento fuerte; mayor costo de recursos. Consulte Escalabilidad y multitenencia. |
Patrón 2: CLI compartida con mode: "empty" | Quiere que un entorno de ejecución sirva a muchos usuarios mientras la aplicación controla las herramientas, la autenticación y los identificadores de sesión. | Eficiente; requiere un registro cuidadoso de herramientas, tokens por sesión y comprobaciones de acceso a nivel de aplicación. |
| Patrón 3: híbrido | Diriges las tareas con uso intensivo de procesamiento a las sesiones en la nube y las tareas ligeras a las sesiones locales. | Flexible; requiere encaminamiento de cargas de trabajo y gestión de directivas. Consulte Sesiones en la nube. |
Patrón 2: CLI compartida con mode: "empty"
En este patrón, todos los usuarios se conectan a un pool de entornos de ejecución a través de tu backend. La aplicación realiza la autenticación de usuario, elige un identificador de sesión, pasa el token de GitHub del usuario en la sesión y proporciona una lista de permitidos de herramientas explícita.

Use estas reglas:
- Inicie siempre el cliente o el entorno de ejecución en
mode: "empty". - Use identificadores de sesión únicos y almacene los metadatos de propiedad en la base de datos de la aplicación.
- Compruebe la titularidad antes de
resumeSession,deleteSessiono cualquier acción de la interfaz de usuario que haga referencia a un ID de sesión. - Pasa
gitHubTokenpor sesión cuando las solicitudes deban ejecutarse como el usuario. - Registre solo las herramientas que necesita la sesión y prefiera listas de permitidos calificadas por el origen, como
custom:*omcp:search_docs. - Establezca
sessionIdleTimeoutSecondsy elimine las sesiones de flujo de trabajo completadas explícitamente.
Dificultades habituales
- Olvidar
mode: "empty". El modo predeterminadocopilot-cliofrece un comportamiento similar al de la CLI y puede exponer el sistema de archivos del host a través de herramientas del entorno. - Sin establecer
sessionIdleTimeoutSeconds. Los servidores de larga duración pueden acumular sesiones inactivas si no las limpian. - Compartir uno
gitHubTokenentre usuarios en lugar de pasar un token por sesión. - Confiar en los identificadores de sesión proporcionados por el cliente sin comprobar la propiedad en el back-end.
- Establecer
baseDirectoryen un cliente que se conecta a un entorno de ejecución existente y esperar que mueva el almacenamiento en tiempo de ejecución. Configure en su lugar el proceso de ejecución. - Permitir patrones de herramientas amplios, como
builtin:*sin revisar si cada herramienta es adecuada para los usuarios.
Consulte también
- Escalabilidad y multitenencia: topologías de implementación, patrones de almacenamiento y comparaciones de aislamiento
- Configuración de servicios back-end: ejecutar el tiempo de ejecución en modo de servidor sin interfaz gráfica
- BYOK (traiga su propia clave): uso de tus propias credenciales del proveedor de modelos
- Sesiones en la nube: enrutamiento del trabajo seleccionado a sesiones en la nube
- Reanudación y persistencia de sesión: gestión del estado de sesión reanudable
- Características: herramientas, eventos, enlaces y características avanzadas del SDK