# Erstellen Sie Ihre erste Copilot-gestützte App

In diesem Lernprogramm verwenden Sie das Copilot SDK, um einen Befehlszeilen-Assistenten zu erstellen. Sie beginnen mit den Grundlagen, fügen Streaming-Antworten hinzu und ergänzen dann benutzerdefinierte Tools, wodurch Copilot Ihren Code aufrufen kann.

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

**Was Sie erstellen werden:**

```text
You: What's the weather like in Seattle?
Copilot: Let me check the weather for Seattle...
         Currently 62°F and cloudy with a chance of rain.
         Typical Seattle weather!

You: How about Tokyo?
Copilot: In Tokyo it's 75°F and sunny. Great day to be outside!
```

## Voraussetzungen

Bevor Sie beginnen, stellen Sie sicher, dass Sie folgendes haben:

* **GitHub Copilot CLI** installiert und authentifiziert (die Node.js, Python und .NET SDKs stellen die CLI automatisch bereit – siehe [Standardsetup (gebündelte CLI)](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/bundled-cli). Erforderlich für Go, Java und Rust, es sei denn, sie verwenden ihre CLI-Bündelungsfunktionen auf Anwendungsebene.)
* Ihre bevorzugte Sprachlaufzeit:
  * <c0>Node.js</c0> 20+ oder <c1>Python</c1> 3,11+ oder <c2>Go</c2> 1,24+ oder < <c2>c3>Rust</c3> 1,94+ oder <c4>Java</c4> 17+ oder <c5>.NET</c5> 8,0+

Überprüfen Sie, ob die CLI funktioniert:

```bash
copilot --version
```

## Schritt 1: Installieren des SDK

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

Erstellen Sie zunächst ein neues Verzeichnis, und initialisieren Sie Ihr Projekt:

```bash
mkdir copilot-demo && cd copilot-demo
npm init -y --init-type module
```

Installieren Sie dann das SDK und typeScript runner:

```bash
npm install @github/copilot-sdk tsx
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```bash
pip install github-copilot-sdk
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

Erstellen Sie zunächst ein neues Verzeichnis, und initialisieren Sie Ihr Modul:

```bash
mkdir copilot-demo && cd copilot-demo
go mod init copilot-demo
```

Installieren Sie dann das SDK:

```bash
go get github.com/github/copilot-sdk/go
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

Erstellen Sie zunächst ein neues binäres Crate:

```bash
cargo new copilot-demo && cd copilot-demo
```

Installieren Sie dann das SDK und die direkten Abhängigkeiten, die von den Beispielen verwendet werden:

```bash
cargo add github-copilot-sdk --features derive
# Used by #[tokio::main] and tokio::spawn
cargo add tokio --features rt-multi-thread,macros
# Used by custom-tool parameter derives later in this guide
cargo add serde --features derive
cargo add schemars
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

Erstellen Sie zunächst ein neues Konsolenprojekt:

```bash
dotnet new console -n CopilotDemo && cd CopilotDemo
```

Fügen Sie dann das SDK hinzu:

```bash
dotnet add package GitHub.Copilot.SDK
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

Erstellen Sie zunächst ein neues Verzeichnis, und initialisieren Sie Ihr Projekt.

**Maven** – zu Ihrem `pom.xml` hinzufügen:

```xml
<dependency>
    <groupId>com.github</groupId>
    <artifactId>copilot-sdk-java</artifactId>
    <version>${copilot.sdk.version}</version>
</dependency>
```

**Gradle** – zu Ihrem `build.gradle` hinzufügen:

```groovy
implementation 'com.github:copilot-sdk-java:${copilotSdkVersion}'
```

</div>

</div>

## Schritt 2: Senden Ihrer ersten Nachricht

Erstellen Sie eine neue Datei, und fügen Sie den folgenden Code hinzu. Dies ist die einfachste Möglichkeit, das SDK zu verwenden – etwa 5 Codezeilen.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

Erstellen Sie `index.ts`:

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

const client = new CopilotClient();
const session = await client.createSession({ model: "auto" });

const response = await session.sendAndWait({ prompt: "What is 2 + 2?" });
console.log(response?.data.content);

await client.stop();
process.exit(0);
```

Ausführen:

```bash
npx tsx index.ts
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

Erstellen Sie `main.py`:

```python
import asyncio
from copilot import CopilotClient
from copilot.session import PermissionHandler

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

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="auto")
    response = await session.send_and_wait("What is 2 + 2?")
    print(response.data.content)

    await client.stop()

asyncio.run(main())
```

Ausführen:

```bash
python main.py
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

Erstellen Sie `main.go`:

```golang
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    copilot "github.com/github/copilot-sdk/go"
)

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

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "auto"})
    if err != nil {
        log.Fatal(err)
    }

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

    if d, ok := response.Data.(*copilot.AssistantMessageData); ok {
        fmt.Println(d.Content)
    }
    os.Exit(0)
}
```

Ausführen:

```bash
go run main.go
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

Erstellen Sie `src/main.rs`:

```rust
use std::sync::Arc;
use std::time::Duration;

use github_copilot_sdk::handler::ApproveAllHandler;
use github_copilot_sdk::{Client, ClientOptions, MessageOptions, SessionConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::start(ClientOptions::default()).await?;
    let session = client
        .create_session(SessionConfig::default().with_permission_handler(Arc::new(ApproveAllHandler)))
        .await?;

    let response = session
        .send_and_wait(
            MessageOptions::new("What is 2 + 2?").with_wait_timeout(Duration::from_secs(120)),
        )
        .await?;

    if let Some(event) = response {
        if let Some(content) = event.data.get("content").and_then(|value| value.as_str()) {
            println!("{content}");
        }
    }

    session.disconnect().await?;
    client.stop().await?;
    Ok(())
}
```

Ausführen:

```bash
cargo run
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

Erstellen Sie ein neues Konsolenprojekt, und fügen Sie folgendes hinzu:`Program.cs`

```csharp
using GitHub.Copilot;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "auto",
    OnPermissionRequest = PermissionHandler.ApproveAll
});

var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" });
Console.WriteLine(response?.Data.Content);
```

Ausführen:

```bash
dotnet run
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

Erstellen Sie `HelloCopilot.java`:

<!-- docs-validate: skip -->

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

public class HelloCopilot {
    public static void main(String[] args) throws Exception {
        try (var client = new CopilotClient()) {
            client.start().get();

            var session = client.createSession(
                new SessionConfig()
                    .setModel("auto")
                    .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
            ).get();

            var response = session.sendAndWait(
                new MessageOptions().setPrompt("What is 2 + 2?")
            ).get();

            System.out.println(response.getData().content());

            client.stop().get();
        }
    }
}
```

Ausführen:

```bash
javac -cp copilot-sdk.jar HelloCopilot.java && java -cp .:copilot-sdk.jar HelloCopilot
```

</div>

</div>

**Sie sollten Folgendes sehen:**

```text
4
```

Glückwunsch! Sie haben gerade Ihre erste Copilot-basierte App erstellt.

## Schritt 3: Hinzufügen von Streamingantworten

Im Moment warten Sie auf die vollständige Antwort, bevor Sie etwas sehen. Lassen Sie uns dies interaktiv machen, indem sie die Antwort streamen, während sie generiert wird.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

Aktualisieren Sie `index.ts`:

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

const client = new CopilotClient();
const session = await client.createSession({
    model: "auto",
    streaming: true,
});

// Listen for response chunks
session.on("assistant.message_delta", (event) => {
    process.stdout.write(event.data.deltaContent);
});
session.on("session.idle", () => {
    console.log(); // New line when done
});

await session.sendAndWait({ prompt: "Tell me a short joke" });

await client.stop();
process.exit(0);
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

Aktualisieren Sie `main.py`:

```python
import asyncio
import sys
from copilot import CopilotClient
from copilot.session import PermissionHandler
from copilot.session_events import SessionEventType

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

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="auto", streaming=True)

    # Listen for response chunks
    def handle_event(event):
        if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
            sys.stdout.write(event.data.delta_content)
            sys.stdout.flush()
        if event.type == SessionEventType.SESSION_IDLE:
            print()  # New line when done

    session.on(handle_event)

    await session.send_and_wait("Tell me a short joke")

    await client.stop()

asyncio.run(main())
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

Aktualisieren Sie `main.go`:

```golang
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    copilot "github.com/github/copilot-sdk/go"
)

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

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Model:     "auto",
        Streaming: copilot.Bool(true),
    })
    if err != nil {
        log.Fatal(err)
    }

    // Listen for response chunks
    session.On(func(event copilot.SessionEvent) {
        switch d := event.Data.(type) {
        case *copilot.AssistantMessageDeltaData:
            fmt.Print(d.DeltaContent)
        case *copilot.SessionIdleData:
            _ = d
            fmt.Println()
        }
    })

    _, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Tell me a short joke"})
    if err != nil {
        log.Fatal(err)
    }
    os.Exit(0)
}
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

Aktualisieren Sie `src/main.rs`:

```rust
use std::io::{self, Write};
use std::sync::Arc;
use std::time::Duration;

use github_copilot_sdk::handler::ApproveAllHandler;
use github_copilot_sdk::{Client, ClientOptions, MessageOptions, SessionConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::start(ClientOptions::default()).await?;

    let mut config = SessionConfig::default();
    config.streaming = Some(true);
    let session = client
        .create_session(config.with_permission_handler(Arc::new(ApproveAllHandler)))
        .await?;

    // Listen for response chunks
    let mut events = session.subscribe();
    tokio::spawn(async move {
        while let Ok(event) = events.recv().await {
            match event.event_type.as_str() {
                "assistant.message_delta" => {
                    if let Some(text) =
                        event.data.get("deltaContent").and_then(|value| value.as_str())
                    {
                        print!("{text}");
                        io::stdout().flush().ok();
                    }
                }
                "assistant.message" => println!(),
                _ => {}
            }
        }
    });

    session
        .send_and_wait(
            MessageOptions::new("Tell me a short joke")
                .with_wait_timeout(Duration::from_secs(120)),
        )
        .await?;

    session.disconnect().await?;
    client.stop().await?;
    Ok(())
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

Aktualisieren Sie `Program.cs`:

```csharp
using GitHub.Copilot;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "auto",
    OnPermissionRequest = PermissionHandler.ApproveAll,
    Streaming = true,
});

// Listen for response chunks
session.On<SessionEvent>(ev =>
{
    if (ev is AssistantMessageDeltaEvent deltaEvent)
    {
        Console.Write(deltaEvent.Data.DeltaContent);
    }
    if (ev is SessionIdleEvent)
    {
        Console.WriteLine();
    }
});

await session.SendAndWaitAsync(new MessageOptions { Prompt = "Tell me a short joke" });
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

Aktualisieren Sie `HelloCopilot.java`:

<!-- docs-validate: skip -->

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

public class HelloCopilot {
    public static void main(String[] args) throws Exception {
        try (var client = new CopilotClient()) {
            client.start().get();

            var session = client.createSession(
                new SessionConfig()
                    .setModel("auto")
                    .setStreaming(true)
                    .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
            ).get();

            // Listen for response chunks
            session.on(AssistantMessageDeltaEvent.class, delta -> {
                System.out.print(delta.getData().deltaContent());
            });
            session.on(SessionIdleEvent.class, idle -> {
                System.out.println(); // New line when done
            });

            session.sendAndWait(
                new MessageOptions().setPrompt("Tell me a short joke")
            ).get();

            client.stop().get();
        }
    }
}
```

</div>

</div>

Führen Sie den Code erneut aus. Du siehst, wie die Antwort Wort für Wort erscheint.

### Ereignisabonnementmethoden

Das SDK stellt Methoden zum Abonnieren von Sitzungsereignissen bereit:

| Methode                  | Description                                                                                                      |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| `on(handler)`            | Alle Ereignisse abonnieren; gibt eine Funktion zum Abbestellen zurück.                                           |
| `on(eventType, handler)` | Einen bestimmten Ereignistyp abonnieren (nur für Node.js/TypeScript); gibt eine Funktion zum Abbestellen zurück. |
| `subscribe()`            | Abonnieren Sie alle Veranstaltungen (Rust); filtern nach `event_type`                                            |

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
// Subscribe to all events
const unsubscribeAll = session.on((event) => {
    console.log("Event:", event.type);
});

// Subscribe to specific event type
const unsubscribeIdle = session.on("session.idle", (event) => {
    console.log("Session is idle");
});

// Later, to unsubscribe:
unsubscribeAll();
unsubscribeIdle();
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
# Subscribe to all events
unsubscribe = session.on(lambda event: print(f"Event: {event.type}"))

# Filter by event type in your handler
def handle_event(event):
    if event.type == SessionEventType.SESSION_IDLE:
        print("Session is idle")
    elif event.type == SessionEventType.ASSISTANT_MESSAGE:
        print(f"Message: {event.data.content}")

unsubscribe = session.on(handle_event)

# Later, to unsubscribe:
unsubscribe()
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
// Subscribe to all events
unsubscribe := session.On(func(event copilot.SessionEvent) {
    fmt.Println("Event:", event.Type)
})

// Filter by event type in your handler
session.On(func(event copilot.SessionEvent) {
    switch d := event.Data.(type) {
    case *copilot.SessionIdleData:
        _ = d
        fmt.Println("Session is idle")
    case *copilot.AssistantMessageData:
        fmt.Println("Message:", d.Content)
    }
})

// Later, to unsubscribe:
unsubscribe()
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

```rust
let mut events = session.subscribe();

tokio::spawn(async move {
    while let Ok(event) = events.recv().await {
        println!("Event: {}", event.event_type);

        match event.event_type.as_str() {
            "session.idle" => println!("Session is idle"),
            "assistant.message" => {
                if let Some(content) = event.data.get("content").and_then(|value| value.as_str()) {
                    println!("Message: {content}");
                }
            }
            _ => {}
        }
    }
});
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
// Subscribe to all events
var unsubscribe = session.On<SessionEvent>(ev => Console.WriteLine($"Event: {ev.Type}"));

// Filter by event type using pattern matching
session.On<SessionEvent>(ev =>
{
    switch (ev)
    {
        case SessionIdleEvent:
            Console.WriteLine("Session is idle");
            break;
        case AssistantMessageEvent msg:
            Console.WriteLine($"Message: {msg.Data.Content}");
            break;
    }
});

// Later, to unsubscribe:
unsubscribe.Dispose();
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
// Subscribe to all events
var unsubscribe = session.on(event -> {
    System.out.println("Event: " + event.getType());
});

// Subscribe to a specific event type
session.on(AssistantMessageEvent.class, msg -> {
    System.out.println("Message: " + msg.getData().content());
});

session.on(SessionIdleEvent.class, idle -> {
    System.out.println("Session is idle");
});

// Later, to unsubscribe:
unsubscribe.close();
```

</div>

</div>

## Schritt 4: Hinzufügen eines benutzerdefinierten Tools

Nun zum leistungsstarken Teil. Lassen Sie uns Copilot die Möglichkeit geben, Ihren Code aufzurufen, indem wir ein benutzerdefiniertes Tool definieren. Wir erstellen ein einfaches Wetter-Nachschlagetool.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

Aktualisieren Sie `index.ts`:

```typescript
import { CopilotClient, defineTool } from "@github/copilot-sdk";

// Define a tool that Copilot can call
const getWeather = defineTool("get_weather", {
    description: "Get the current weather for a city",
    parameters: {
        type: "object",
        properties: {
            city: { type: "string", description: "The city name" },
        },
        required: ["city"],
    },
    handler: async (args: { city: string }) => {
        const { city } = args;
        // In a real app, you'd call a weather API here
        const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
        const temp = Math.floor(Math.random() * 30) + 50;
        const condition = conditions[Math.floor(Math.random() * conditions.length)];
        return { city, temperature: `${temp}°F`, condition };
    },
});

const client = new CopilotClient();
const session = await client.createSession({
    model: "auto",
    streaming: true,
    tools: [getWeather],
});

session.on("assistant.message_delta", (event) => {
    process.stdout.write(event.data.deltaContent);
});

session.on("session.idle", () => {
    console.log(); // New line when done
});

await session.sendAndWait({
    prompt: "What's the weather like in Seattle and Tokyo?",
});

await client.stop();
process.exit(0);
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

Aktualisieren Sie `main.py`:

```python
import asyncio
import random
import sys
from copilot import CopilotClient
from copilot.session import PermissionHandler
from copilot.tools import define_tool
from copilot.session_events import SessionEventType
from pydantic import BaseModel, Field

# Define the parameters for the tool using Pydantic
class GetWeatherParams(BaseModel):
    city: str = Field(description="The name of the city to get weather for")

# Define a tool that Copilot can call
@define_tool(description="Get the current weather for a city")
async def get_weather(params: GetWeatherParams) -> dict:
    city = params.city
    # In a real app, you'd call a weather API here
    conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]
    temp = random.randint(50, 80)
    condition = random.choice(conditions)
    return {"city": city, "temperature": f"{temp}°F", "condition": condition}

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

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="auto", streaming=True, tools=[get_weather])

    def handle_event(event):
        if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
            sys.stdout.write(event.data.delta_content)
            sys.stdout.flush()
        if event.type == SessionEventType.SESSION_IDLE:
            print()

    session.on(handle_event)

    await session.send_and_wait("What's the weather like in Seattle and Tokyo?")

    await client.stop()

asyncio.run(main())
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

Aktualisieren Sie `main.go`:

```golang
package main

import (
    "context"
    "fmt"
    "log"
    "math/rand"
    "os"

    copilot "github.com/github/copilot-sdk/go"
)

// Define the parameter type
type WeatherParams struct {
    City string `json:"city" jsonschema:"The city name"`
}

// Define the return type
type WeatherResult struct {
    City        string `json:"city"`
    Temperature string `json:"temperature"`
    Condition   string `json:"condition"`
}

func main() {
    ctx := context.Background()

    // Define a tool that Copilot can call
    getWeather := copilot.DefineTool(
        "get_weather",
        "Get the current weather for a city",
        func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) {
            // In a real app, you'd call a weather API here
            conditions := []string{"sunny", "cloudy", "rainy", "partly cloudy"}
            temp := rand.Intn(30) + 50
            condition := conditions[rand.Intn(len(conditions))]
            return WeatherResult{
                City:        params.City,
                Temperature: fmt.Sprintf("%d°F", temp),
                Condition:   condition,
            }, nil
        },
    )

    client := copilot.NewClient(nil)
    if err := client.Start(ctx); err != nil {
        log.Fatal(err)
    }
    defer client.Stop()

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Model:     "auto",
        Streaming: copilot.Bool(true),
        Tools:     []copilot.Tool{getWeather},
    })
    if err != nil {
        log.Fatal(err)
    }

    session.On(func(event copilot.SessionEvent) {
        switch d := event.Data.(type) {
        case *copilot.AssistantMessageDeltaData:
            fmt.Print(d.DeltaContent)
        case *copilot.SessionIdleData:
            _ = d
            fmt.Println()
        }
    })

    _, err = session.SendAndWait(ctx, copilot.MessageOptions{
        Prompt: "What's the weather like in Seattle and Tokyo?",
    })
    if err != nil {
        log.Fatal(err)
    }
    os.Exit(0)
}
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

Aktualisieren Sie `src/main.rs`:

```rust
use std::io::{self, Write};
use std::sync::Arc;
use std::time::Duration;

use github_copilot_sdk::handler::ApproveAllHandler;
use github_copilot_sdk::tool::{define_tool, JsonSchema};
use github_copilot_sdk::{Client, ClientOptions, MessageOptions, SessionConfig, ToolResult};
use serde::Deserialize;

#[derive(Deserialize, JsonSchema)]
struct GetWeatherParams {
    city: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Define a tool that Copilot can call
    let tools = vec![define_tool(
        "get_weather",
        "Get the current weather for a city",
        |_inv, params: GetWeatherParams| async move {
            Ok(ToolResult::Text(format!(
                "{}: 62°F and sunny",
                params.city
            )))
        },
    )];

    let client = Client::start(ClientOptions::default()).await?;

    let mut config = SessionConfig::default();
    config.streaming = Some(true);
    let session = client
        .create_session(
            config
                .with_tools(tools)
                .with_permission_handler(Arc::new(ApproveAllHandler)),
        )
        .await?;

    let mut events = session.subscribe();
    tokio::spawn(async move {
        while let Ok(event) = events.recv().await {
            match event.event_type.as_str() {
                "assistant.message_delta" => {
                    if let Some(text) =
                        event.data.get("deltaContent").and_then(|value| value.as_str())
                    {
                        print!("{text}");
                        io::stdout().flush().ok();
                    }
                }
                "assistant.message" => println!(),
                _ => {}
            }
        }
    });

    session
        .send_and_wait(
            MessageOptions::new("What's the weather like in Seattle and Tokyo?")
                .with_wait_timeout(Duration::from_secs(120)),
        )
        .await?;

    session.disconnect().await?;
    client.stop().await?;
    Ok(())
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

Aktualisieren Sie `Program.cs`:

```csharp
using GitHub.Copilot;
using Microsoft.Extensions.AI;
using System.ComponentModel;

await using var client = new CopilotClient();

// Define a tool that Copilot can call
var getWeather = CopilotTool.DefineTool(
    ([Description("The city name")] string city) =>
    {
        // In a real app, you'd call a weather API here
        var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy" };
        var temp = Random.Shared.Next(50, 80);
        var condition = conditions[Random.Shared.Next(conditions.Length)];
        return new { city, temperature = $"{temp}°F", condition };
    },
    factoryOptions: new AIFunctionFactoryOptions
    {
        Name = "get_weather",
        Description = "Get the current weather for a city",
    }
);

await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "auto",
    OnPermissionRequest = PermissionHandler.ApproveAll,
    Streaming = true,
    Tools = [getWeather],
});

session.On<SessionEvent>(ev =>
{
    if (ev is AssistantMessageDeltaEvent deltaEvent)
    {
        Console.Write(deltaEvent.Data.DeltaContent);
    }
    if (ev is SessionIdleEvent)
    {
        Console.WriteLine();
    }
});

await session.SendAndWaitAsync(new MessageOptions
{
    Prompt = "What's the weather like in Seattle and Tokyo?",
});
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

Aktualisieren Sie `HelloCopilot.java`:

<!-- docs-validate: skip -->

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CompletableFuture;

public class HelloCopilot {
    public static void main(String[] args) throws Exception {
        var random = new Random();
        var conditions = List.of("sunny", "cloudy", "rainy", "partly cloudy");

        // Define a tool that Copilot can call
        var getWeather = ToolDefinition.create(
            "get_weather",
            "Get the current weather for a city",
            Map.of(
                "type", "object",
                "properties", Map.of(
                    "city", Map.of("type", "string", "description", "The city name")
                ),
                "required", List.of("city")
            ),
            invocation -> {
                var city = (String) invocation.getArguments().get("city");
                var temp = random.nextInt(30) + 50;
                var condition = conditions.get(random.nextInt(conditions.size()));
                return CompletableFuture.completedFuture(Map.of(
                    "city", city,
                    "temperature", temp + "°F",
                    "condition", condition
                ));
            }
        );

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

            var session = client.createSession(
                new SessionConfig()
                    .setModel("auto")
                    .setStreaming(true)
                    .setTools(List.of(getWeather))
                    .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
            ).get();

            session.on(AssistantMessageDeltaEvent.class, delta -> {
                System.out.print(delta.getData().deltaContent());
            });
            session.on(SessionIdleEvent.class, idle -> {
                System.out.println();
            });

            session.sendAndWait(
                new MessageOptions().setPrompt("What's the weather like in Seattle and Tokyo?")
            ).get();

            client.stop().get();
        }
    }
}
```

</div>

</div>

Führen Sie es aus, und Sie werden sehen, dass Copilot Ihr Tool aufruft, um Wetterdaten abzurufen, und anschließend mit den Ergebnissen antwortet!

## Schritt 5: Erstellen eines interaktiven Assistenten

Lassen Sie uns alles in einen nützlichen interaktiven Assistenten zusammenfassen:

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
import { CopilotClient, defineTool } from "@github/copilot-sdk";
import * as readline from "readline";

const getWeather = defineTool("get_weather", {
    description: "Get the current weather for a city",
    parameters: {
        type: "object",
        properties: {
            city: { type: "string", description: "The city name" },
        },
        required: ["city"],
    },
    handler: async ({ city }) => {
        const conditions = ["sunny", "cloudy", "rainy", "partly cloudy"];
        const temp = Math.floor(Math.random() * 30) + 50;
        const condition = conditions[Math.floor(Math.random() * conditions.length)];
        return { city, temperature: `${temp}°F`, condition };
    },
});

const client = new CopilotClient();
const session = await client.createSession({
    model: "auto",
    streaming: true,
    tools: [getWeather],
});

session.on("assistant.message_delta", (event) => {
    process.stdout.write(event.data.deltaContent);
});

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

console.log("🌤️  Weather Assistant (type 'exit' to quit)");
console.log("   Try: 'What's the weather in Paris?'\n");

const prompt = () => {
    rl.question("You: ", async (input) => {
        if (input.toLowerCase() === "exit") {
            await client.stop();
            rl.close();
            return;
        }

        process.stdout.write("Assistant: ");
        await session.sendAndWait({ prompt: input });
        console.log("\n");
        prompt();
    });
};

prompt();
```

Ausführen mit:

```bash
npx tsx weather-assistant.ts
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

Erstellen Sie `weather_assistant.py`:

```python
import asyncio
import random
import sys
from copilot import CopilotClient
from copilot.session import PermissionHandler
from copilot.tools import define_tool
from copilot.session_events import SessionEventType
from pydantic import BaseModel, Field

class GetWeatherParams(BaseModel):
    city: str = Field(description="The name of the city to get weather for")

@define_tool(description="Get the current weather for a city")
async def get_weather(params: GetWeatherParams) -> dict:
    city = params.city
    conditions = ["sunny", "cloudy", "rainy", "partly cloudy"]
    temp = random.randint(50, 80)
    condition = random.choice(conditions)
    return {"city": city, "temperature": f"{temp}°F", "condition": condition}

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

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="auto", streaming=True, tools=[get_weather])

    def handle_event(event):
        if event.type == SessionEventType.ASSISTANT_MESSAGE_DELTA:
            sys.stdout.write(event.data.delta_content)
            sys.stdout.flush()

    session.on(handle_event)

    print("🌤️  Weather Assistant (type 'exit' to quit)")
    print("   Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n")

    while True:
        try:
            user_input = input("You: ")
        except EOFError:
            break

        if user_input.lower() == "exit":
            break

        sys.stdout.write("Assistant: ")
        await session.send_and_wait(user_input)
        print("\n")

    await client.stop()

asyncio.run(main())
```

Ausführen mit:

```bash
python weather_assistant.py
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

Erstellen Sie `weather-assistant.go`:

```golang
package main

import (
    "bufio"
    "context"
    "fmt"
    "log"
    "math/rand"
    "os"
    "strings"

    copilot "github.com/github/copilot-sdk/go"
)

type WeatherParams struct {
    City string `json:"city" jsonschema:"The city name"`
}

type WeatherResult struct {
    City        string `json:"city"`
    Temperature string `json:"temperature"`
    Condition   string `json:"condition"`
}

func main() {
    ctx := context.Background()

    getWeather := copilot.DefineTool(
        "get_weather",
        "Get the current weather for a city",
        func(params WeatherParams, inv copilot.ToolInvocation) (WeatherResult, error) {
            conditions := []string{"sunny", "cloudy", "rainy", "partly cloudy"}
            temp := rand.Intn(30) + 50
            condition := conditions[rand.Intn(len(conditions))]
            return WeatherResult{
                City:        params.City,
                Temperature: fmt.Sprintf("%d°F", temp),
                Condition:   condition,
            }, nil
        },
    )

    client := copilot.NewClient(nil)
    if err := client.Start(ctx); err != nil {
        log.Fatal(err)
    }
    defer client.Stop()

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Model:     "auto",
        Streaming: copilot.Bool(true),
        Tools:     []copilot.Tool{getWeather},
    })
    if err != nil {
        log.Fatal(err)
    }

    session.On(func(event copilot.SessionEvent) {
        switch d := event.Data.(type) {
        case *copilot.AssistantMessageDeltaData:
            fmt.Print(d.DeltaContent)
        case *copilot.SessionIdleData:
            _ = d
            fmt.Println()
        }
    })

    fmt.Println("🌤️  Weather Assistant (type 'exit' to quit)")
    fmt.Println("   Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n")

    scanner := bufio.NewScanner(os.Stdin)
    for {
        fmt.Print("You: ")
        if !scanner.Scan() {
            break
        }
        input := scanner.Text()
        if strings.ToLower(input) == "exit" {
            break
        }

        fmt.Print("Assistant: ")
        _, err = session.SendAndWait(ctx, copilot.MessageOptions{Prompt: input})
        if err != nil {
            fmt.Fprintf(os.Stderr, "Error: %v\n", err)
            break
        }
        fmt.Println()
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintf(os.Stderr, "Input error: %v\n", err)
    }
}
```

Ausführen mit:

```bash
go run weather-assistant.go
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

Erstellen Sie `src/main.rs`:

```rust
use std::io::{self, BufRead, Write};
use std::sync::Arc;
use std::time::Duration;

use github_copilot_sdk::handler::ApproveAllHandler;
use github_copilot_sdk::tool::{define_tool, JsonSchema};
use github_copilot_sdk::{Client, ClientOptions, MessageOptions, SessionConfig, ToolResult};
use serde::Deserialize;

#[derive(Deserialize, JsonSchema)]
struct GetWeatherParams {
    city: String,
}

fn read_line() -> Option<String> {
    let stdin = io::stdin();
    let mut line = String::new();
    stdin.lock().read_line(&mut line).ok()?;
    if line.is_empty() {
        return None;
    }
    Some(line.trim_end_matches(&['\n', '\r'][..]).to_string())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let tools = vec![define_tool(
        "get_weather",
        "Get the current weather for a city",
        |_inv, params: GetWeatherParams| async move {
            Ok(ToolResult::Text(format!(
                "{}: 62°F and sunny",
                params.city
            )))
        },
    )];

    let client = Client::start(ClientOptions::default()).await?;

    let mut config = SessionConfig::default();
    config.streaming = Some(true);
    let session = client
        .create_session(
            config
                .with_tools(tools)
                .with_permission_handler(Arc::new(ApproveAllHandler)),
        )
        .await?;

    let mut events = session.subscribe();
    tokio::spawn(async move {
        while let Ok(event) = events.recv().await {
            match event.event_type.as_str() {
                "assistant.message_delta" => {
                    if let Some(text) =
                        event.data.get("deltaContent").and_then(|value| value.as_str())
                    {
                        print!("{text}");
                        io::stdout().flush().ok();
                    }
                }
                "assistant.message" => println!(),
                _ => {}
            }
        }
    });

    println!("Weather Assistant (type 'exit' to quit)");
    println!("Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n");

    loop {
        print!("You: ");
        io::stdout().flush().ok();

        let Some(input) = read_line() else { break };
        if input.eq_ignore_ascii_case("exit") {
            break;
        }

        print!("Assistant: ");
        io::stdout().flush().ok();
        session
            .send_and_wait(MessageOptions::new(input).with_wait_timeout(Duration::from_secs(120)))
            .await?;
        println!();
    }

    session.disconnect().await?;
    client.stop().await?;
    Ok(())
}
```

Ausführen mit:

```bash
cargo run
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

Erstellen Sie ein neues Konsolenprojekt und aktualisieren Sie `Program.cs`:

```csharp
using GitHub.Copilot;
using Microsoft.Extensions.AI;
using System.ComponentModel;

// Define the weather tool
var getWeather = CopilotTool.DefineTool(
    ([Description("The city name")] string city) =>
    {
        var conditions = new[] { "sunny", "cloudy", "rainy", "partly cloudy" };
        var temp = Random.Shared.Next(50, 80);
        var condition = conditions[Random.Shared.Next(conditions.Length)];
        return new { city, temperature = $"{temp}°F", condition };
    },
    factoryOptions: new AIFunctionFactoryOptions
    {
        Name = "get_weather",
        Description = "Get the current weather for a city",
    });

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "auto",
    OnPermissionRequest = PermissionHandler.ApproveAll,
    Streaming = true,
    Tools = [getWeather]
});

// Listen for response chunks
session.On<SessionEvent>(ev =>
{
    if (ev is AssistantMessageDeltaEvent deltaEvent)
    {
        Console.Write(deltaEvent.Data.DeltaContent);
    }
    if (ev is SessionIdleEvent)
    {
        Console.WriteLine();
    }
});

Console.WriteLine("🌤️  Weather Assistant (type 'exit' to quit)");
Console.WriteLine("   Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n");

while (true)
{
    Console.Write("You: ");
    var input = Console.ReadLine();

    if (string.IsNullOrEmpty(input) || input.Equals("exit", StringComparison.OrdinalIgnoreCase))
    {
        break;
    }

    Console.Write("Assistant: ");
    await session.SendAndWaitAsync(new MessageOptions { Prompt = input });
    Console.WriteLine("\n");
}
```

Ausführen mit:

```bash
dotnet run
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

Erstellen Sie `WeatherAssistant.java`:

<!-- docs-validate: skip -->

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.CompletableFuture;

public class WeatherAssistant {
    public static void main(String[] args) throws Exception {
        var random = new Random();
        var conditions = List.of("sunny", "cloudy", "rainy", "partly cloudy");

        var getWeather = ToolDefinition.create(
            "get_weather",
            "Get the current weather for a city",
            Map.of(
                "type", "object",
                "properties", Map.of(
                    "city", Map.of("type", "string", "description", "The city name")
                ),
                "required", List.of("city")
            ),
            invocation -> {
                var city = (String) invocation.getArguments().get("city");
                var temp = random.nextInt(30) + 50;
                var condition = conditions.get(random.nextInt(conditions.size()));
                return CompletableFuture.completedFuture(Map.of(
                    "city", city,
                    "temperature", temp + "°F",
                    "condition", condition
                ));
            }
        );

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

            var session = client.createSession(
                new SessionConfig()
                    .setModel("auto")
                    .setStreaming(true)
                    .setOnPermissionRequest(request ->
                        CompletableFuture.completedFuture(PermissionDecision.allow())
                    )
                    .setTools(List.of(getWeather))
            ).get();

            session.on(AssistantMessageDeltaEvent.class, delta -> {
                System.out.print(delta.getData().deltaContent());
            });
            session.on(SessionIdleEvent.class, idle -> {
                System.out.println();
            });

            System.out.println("🌤️  Weather Assistant (type 'exit' to quit)");
            System.out.println("   Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'\n");

            var scanner = new Scanner(System.in);
            while (true) {
                System.out.print("You: ");
                if (!scanner.hasNextLine()) break;
                var input = scanner.nextLine();
                if (input.equalsIgnoreCase("exit")) break;

                System.out.print("Assistant: ");
                session.sendAndWait(
                    new MessageOptions().setPrompt(input)
                ).get();
                System.out.println("\n");
            }

            client.stop().get();
        }
    }
}
```

Ausführen mit:

```bash
javac -cp copilot-sdk.jar WeatherAssistant.java && java -cp .:copilot-sdk.jar WeatherAssistant
```

</div>

</div>

**Beispielsitzung:**

```text
🌤️  Weather Assistant (type 'exit' to quit)
   Try: 'What's the weather in Paris?' or 'Compare weather in NYC and LA'

You: What's the weather in Seattle?
Assistant: Let me check the weather for Seattle...
It's currently 62°F and cloudy in Seattle.

You: How about Tokyo and London?
Assistant: I'll check both cities for you:
- Tokyo: 75°F and sunny
- London: 58°F and rainy

You: exit
```

Sie haben einen Assistenten mit einem benutzerdefinierten Tool erstellt, das Copilot aufrufen kann!

## Funktionsweise von Tools

Wenn Sie ein Tool definieren, sagen Sie Copilot:

1. **Funktionsweise des Tools** (Beschreibung)
2. **Welche Parameter benötigt werden** (Schema)
3. **Auszuführender Code** (Handler)

Copilot entscheidet, wann Ihr Tool basierend auf der Frage des Benutzers aufgerufen werden soll. Wann dies der Fall ist:

1. Copilot sendet eine Toolaufrufanforderung mit den Parametern
2. Das SDK führt die Handlerfunktion aus.
3. Das Ergebnis wird an Copilot zurückgesendet.
4. Copilot enthält das Ergebnis in seine Antwort

## Wie geht es weiter?

Jetzt, da Sie die Grundlagen haben, finden Sie hier leistungsfähigere Features, die Sie erkunden können:

### Herstellen einer Verbindung mit MCP-Servern

MCP-Server (Model Context Protocol) stellen vordefinierte Tools bereit. Stellen Sie eine Verbindung mit dem MCP-Server von GitHub her, um Copilot Zugriff auf Repositorys, Probleme und Pullanforderungen zu gewähren:

```typescript
const session = await client.createSession({
    mcpServers: {
        github: {
            type: "http",
            url: "https://api.githubcopilot.com/mcp/",
        },
    },
});
```

📖
\*\*
[Verwenden von MCP-Servern mit dem GitHub Copilot SDK](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/mcp)\*\* – Erfahren Sie mehr über lokale und Remoteserver, alle Konfigurationsoptionen und die Problembehandlung.

### Erstellen von benutzerdefinierten Agents

Definieren Sie spezielle KI-Personas für bestimmte Aufgaben:

```typescript
const session = await client.createSession({
    customAgents: [{
        name: "pr-reviewer",
        displayName: "PR Reviewer",
        description: "Reviews pull requests for best practices",
        prompt: "You are an expert code reviewer. Focus on security, performance, and maintainability.",
    }],
});
```

> \[!TIP]
> Sie können auch in der Sitzungskonfiguration festlegen `agent: "pr-reviewer"` , dass dieser Agent von Anfang an vorab ausgewählt wird. Weitere Einzelheiten finden Sie unter [Angepasste Agents und Orchestrierung von Unteragenten](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/custom-agents#selecting-an-agent-at-session-creation).

### Anpassen der Systemnachricht

Steuern Sie das Verhalten und die Persönlichkeit der KI, indem Sie Anweisungen anfügen:

```typescript
const session = await client.createSession({
    systemMessage: {
        content: "You are a helpful assistant for our engineering team. Always be concise.",
    },
});
```

Für eine granularere Steuerung verwenden Sie `mode: "customize"`, um einzelne Abschnitte des Systemprompts zu überschreiben, während der Rest erhalten bleibt:

```typescript
const session = await client.createSession({
    systemMessage: {
        mode: "customize",
        sections: {
            tone: { action: "replace", content: "Respond in a warm, professional tone. Be thorough in explanations." },
            code_change_rules: { action: "remove" },
            guidelines: { action: "append", content: "\n* Always cite data sources" },
        },
        content: "Focus on financial analysis and reporting.",
    },
});
```

Verfügbare Abschnitts-IDs: `preamble`, `environment_context`, `tone`, `tool_efficiency`, `identity`, `code_change_rules`, `guidelines`, `tool_instructions`, `custom_instructions`, `safety`, `last_instructions`, `runtime_instructions`.

`identity` und `tool_instructions` sind *Abschnittsgruppen*: Sie richten sich an eine Sammlung verwandter Unterabschnitte als Einheit. Verwenden Sie `preamble`, um nur die Identitätspräambel gezielt anzusprechen, ohne die benachbarten Unterabschnitte zu beeinflussen.

Jede Außerkraftsetzung unterstützt fünf Aktionen: `replace`, `remove`, `append`, `prepend` und `preserve`. Die Aktion `preserve` ist eine Nulloperation, die einen einzeln adressierbaren Abschnitt von einem `remove` auf Gruppenebene ausnimmt (z. B. `tone` beibehalten, wenn die Gruppe `identity` entfernt wird). Unbekannte Abschnitts-IDs werden ordnungsgemäß verarbeitet: Inhalte aus `replace`/`append`/`prepend`-Außerkraftsetzungen werden zusätzlichen Anweisungen angehängt und `remove`-Außerkraftsetzungen werden stillschweigend ignoriert.

Beispiele für sprachspezifische SDK-READMEs finden Sie in [TypeScript](https://github.com/github/copilot-sdk/tree/main/nodejs/README.md), [Python](https://github.com/github/copilot-sdk/tree/main/python/README.md), [Go](https://github.com/github/copilot-sdk/tree/main/go/README.md), [Rust](https://github.com/github/copilot-sdk/tree/main/rust/README.md), [Java](https://github.com/github/copilot-sdk/tree/main/java/README.md) und [C#](https://github.com/github/copilot-sdk/tree/main/dotnet/README.md).

## Herstellen einer Verbindung mit einem externen CLI-Server

Standardmäßig verwaltet das SDK automatisch den Copilot CLI-Prozesslebenszyklus, startet und beendet die CLI bei Bedarf. Sie können die CLI jedoch auch separat im Servermodus ausführen und über das SDK eine Verbindung damit herstellen. Dies kann nützlich sein für:

* **Debuggen**: Führen Sie die CLI zwischen SDK-Neustarts aus, um Protokolle zu prüfen
* **Ressourcenfreigabe**: Mehrere SDK-Clients können eine Verbindung mit demselben CLI-Server herstellen.
* **Entwicklung**: Ausführen der CLI mit benutzerdefinierten Einstellungen oder in einer anderen Umgebung

### Ausführen der CLI im Servermodus

Starten Sie die CLI im Servermodus mit dem `--headless` Flag, und geben Sie optional einen Port an:

```bash
copilot --headless --port 4321
```

Wenn Sie keinen Port angeben, wählt die CLI einen zufällig verfügbaren Port aus.

Standardmäßig akzeptiert der Headless-Server nur Verbindungen von Loopback (`127.0.0.1`), sodass das SDK auf demselben Computer ausgeführt werden muss. Um Verbindungen von anderen Hosts zu akzeptieren (z. B. beim Ausführen der CLI in einem Container oder auf einem separaten Server), binden Sie eine Bindung an eine Nicht-Loopbackadresse mit `--host`:

```bash
# Listen on all interfaces
copilot --headless --host 0.0.0.0 --port 4321
```

> \[!WARNING]
> Wenn Sie den Headless-Server über eine andere Adresse als eine Loopback-Adresse zugänglich machen, ist er für jeden erreichbar, der eine Route zu dieser Adresse hat. Koppeln Sie sie mit Netzwerksteuerelementen (Firewall, privates Netzwerk, Reverseproxy) und Authentifizierung, die für Ihre Umgebung geeignet ist.

### Verbinden des SDK mit dem externen Server

Nachdem die CLI im Servermodus ausgeführt wird, konfigurieren Sie Ihren SDK-Client so, dass er über die Option "cli url" eine Verbindung mit ihr herstellt:

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
import { CopilotClient, approveAll } from "@github/copilot-sdk";

const client = new CopilotClient({
    cliUrl: "localhost:4321"
});

// Use the client normally
const session = await client.createSession({ onPermissionRequest: approveAll });
// ...
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
from copilot import CopilotClient, RuntimeConnection
from copilot.session import PermissionHandler

client = CopilotClient(connection=RuntimeConnection.for_uri("localhost:4321"))
await client.start()

# Use the client normally
session = await client.create_session(on_permission_request=PermissionHandler.approve_all)
# ...
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
import copilot "github.com/github/copilot-sdk/go"

client := copilot.NewClient(&copilot.ClientOptions{
    Connection: copilot.URIConnection{URL: "localhost:4321"},
})

if err := client.Start(ctx); err != nil {
    log.Fatal(err)
}
defer client.Stop()

// Use the client normally
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
    OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
})
// ...
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

```rust
use std::sync::Arc;

use github_copilot_sdk::handler::ApproveAllHandler;
use github_copilot_sdk::{Client, ClientOptions, SessionConfig, Transport};

let mut options = ClientOptions::default();
options.transport = Transport::External {
    host: "localhost".to_string(),
    port: 4321,
    connection_token: None,
};
let client = Client::start(options).await?;

// Use the client normally
let session = client
    .create_session(SessionConfig::default().with_permission_handler(Arc::new(ApproveAllHandler)))
    .await?;
// ...
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
using GitHub.Copilot;

using var client = new CopilotClient(new CopilotClientOptions
{
    Connection = RuntimeConnection.ForUri("localhost:4321"),
});

// Use the client normally
await using var session = await client.CreateSessionAsync(new()
{
    OnPermissionRequest = PermissionHandler.ApproveAll
});
// ...
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

var client = new CopilotClient(
    new CopilotClientOptions().setCliUrl("localhost:4321")
);
client.start().get();

// Use the client normally
var session = client.createSession(
    new SessionConfig().setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
// ...
```

</div>

</div>

**Hinweis:** Wenn `cli_url` / `cliUrl` / Go `URIConnection` bereitgestellt wird oder Rust `Transport::External` verwendet, wird das SDK keinen CLI-Prozess starten oder verwalten – es verbindet sich nur mit dem vorhandenen Server unter der angegebenen URL.

## Telemetrie und Observierbarkeit

Das Copilot-SDK unterstützt [OpenTelemetry](https://opentelemetry.io/) zur verteilten Nachverfolgung. Stellen Sie dem Client eine `telemetry`-Konfiguration bereit, um den Trace-Export aus dem CLI-Prozess und die automatische Weitergabe des [W3C Trace Context](https://www.w3.org/TR/trace-context/) zwischen dem SDK und der CLI zu ermöglichen.

### Aktivieren der Telemetrie

Übergeben Sie beim Erstellen des Clients eine Konfiguration vom Typ `telemetry` (oder `Telemetry`). Dies ist das Opt-In– es ist kein separates "enabled"-Flag erforderlich.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

<!-- docs-validate: skip -->

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

const client = new CopilotClient({
  telemetry: {
    otlpEndpoint: "http://localhost:4318",
  },
});
```

Optionale Peer-Abhängigkeit: `@opentelemetry/api`

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

<!-- docs-validate: skip -->

```python
from copilot import CopilotClient, CopilotClientOptions

client = CopilotClient(CopilotClientOptions(
    telemetry={
        "otlp_endpoint": "http://localhost:4318",
    },
))
```

Installation mit Telemetrie-Erweiterungen: `pip install copilot-sdk[telemetry]` (stellt `opentelemetry-api` bereit)

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

<!-- docs-validate: skip -->

```golang
client := copilot.NewClient(&copilot.ClientOptions{
    Telemetry: &copilot.TelemetryConfig{
        OTLPEndpoint: "http://localhost:4318",
    },
})
```

Abhängigkeit: `go.opentelemetry.io/otel`

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

<!-- docs-validate: skip -->

```rust
use github_copilot_sdk::{Client, ClientOptions, OtelExporterType, TelemetryConfig};

let mut options = ClientOptions::default();
options.telemetry = Some(
    TelemetryConfig::new()
        .with_exporter_type(OtelExporterType::OtlpHttp)
        .with_otlp_endpoint("http://localhost:4318"),
);
let client = Client::start(options).await?;
```

Keine zusätzlichen Abhängigkeiten – das SDK fügt Telemetrieumgebungsvariablen für den spawned CLI-Prozess ein.

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

<!-- docs-validate: skip -->

```csharp
var client = new CopilotClient(new CopilotClientOptions
{
    Telemetry = new TelemetryConfig
    {
        OtlpEndpoint = "http://localhost:4318",
    },
});
```

Keine zusätzlichen Abhängigkeiten – verwendet integrierte `System.Diagnostics.Activity`.

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

var client = new CopilotClient(new CopilotClientOptions()
    .setTelemetry(new TelemetryConfig()
        .setOtlpEndpoint("http://localhost:4318")));
```

Abhängigkeit: `io.opentelemetry:opentelemetry-api`

</div>

</div>

### TelemetryConfig-Optionen

| Auswahl                     | Node.js          | Python            | Go               | Rust              | Java             | .NET             | Description                                                                |
| --------------------------- | ---------------- | ----------------- | ---------------- | ----------------- | ---------------- | ---------------- | -------------------------------------------------------------------------- |
| OTLP-Endpunkt               | `otlpEndpoint`   | `otlp_endpoint`   | `OTLPEndpoint`   | `otlp_endpoint`   | `otlpEndpoint`   | `OtlpEndpoint`   | OTLP HTTP-Endpunkt-URL                                                     |
| OTLP-Protokoll              | `otlpProtocol`   | `otlp_protocol`   | `OTLPProtocol`   | `otlp_protocol`   | `otlpProtocol`   | `OtlpProtocol`   | OTLP HTTP-Protokoll für alle Signale: `"http/json"` oder `"http/protobuf"` |
| Dateipfad                   | `filePath`       | `file_path`       | `FilePath`       | `file_path`       | `filePath`       | `FilePath`       | Dateipfad für JSON-Zeilen-Ablaufverfolgungsausgabe                         |
| Exportertyp                 | `exporterType`   | `exporter_type`   | `ExporterType`   | `exporter_type`   | `exporterType`   | `ExporterType`   |                                                                            |
| `"otlp-http"` oder `"file"` |                  |                   |                  |                   |                  |                  |                                                                            |
| Quellname                   | `sourceName`     | `source_name`     | `SourceName`     | `source_name`     | `sourceName`     | `SourceName`     | Name des Instrumentierungsbereichs                                         |
| Erfassen von Inhalten       | `captureContent` | `capture_content` | `CaptureContent` | `capture_content` | `captureContent` | `CaptureContent` | Gibt an, ob Nachrichteninhalte erfasst werden sollen.                      |

Das Feld für das OTLP-Protokoll konfiguriert den `"otlp-http"`-Exporter der CLI für alle Signale. Lassen Sie es nicht gesetzt, um die CLI-Standardeinstellung zu verwenden, oder setzen Sie es auf `"http/protobuf"`, um Protobuf über HTTP zu exportieren.

### Dateiexport

So schreiben Sie Ablaufverfolgungen in eine lokale Datei anstelle eines OTLP-Endpunkts:

<!-- docs-validate: skip -->

```typescript
const client = new CopilotClient({
  telemetry: {
    filePath: "./traces.jsonl",
    exporterType: "file",
  },
});
```

### Ablaufverfolgungskontext-Propagierung

Der Trace-Kontext wird automatisch weitergegeben – eine manuelle Instrumentierung ist nicht erforderlich:

* **SDK → CLI**: `traceparent`- und `tracestate`-Header aus dem aktuellen Span/der aktuellen Aktivität sind in `session.create`-, `session.resume`- und `session.send`-RPC-Aufrufen enthalten.
* **CLI → SDK**: Wenn die CLI Tool-Handler aufruft, wird der Trace-Kontext aus der CLI-Span weitergegeben, sodass Ihr Toolcode im richtigen übergeordneten Span ausgeführt wird.

📖
\*\*
[OpenTelemetry-Instrumentierung für Copilot SDK](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/observability/opentelemetry)\*\*—TelemetryConfig-Optionen, Weitergabe des Trace-Kontexts und sprachspezifische Abhängigkeiten.

## Weitere Informationen

* [Authentication](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/auth/authenticate) - GitHub OAuth, Umgebungsvariablen und BYOK
* [Bring Your Own Key (BYOK)](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/auth/byok) - Verwenden Sie Ihre eigenen API-Schlüssel aus Microsoft Foundry, OpenAI usw.
* [Node.js SDK-Referenz](https://github.com/github/copilot-sdk/tree/main/nodejs/README.md)
* [Python SDK-Referenz](https://github.com/github/copilot-sdk/tree/main/python/README.md)
* [Go SDK-Referenz](https://github.com/github/copilot-sdk/tree/main/go/README.md)
* [Rust SDK-Referenz](https://github.com/github/copilot-sdk/tree/main/rust/README.md)
* [.NET SDK-Referenz](https://github.com/github/copilot-sdk/tree/main/dotnet/README.md)
* [Java SDK-Referenz](https://github.com/github/copilot-sdk/tree/main/java/README.md)
* [Verwenden von MCP-Servern mit dem GitHub Copilot SDK](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/mcp) – Integrieren externer Tools über das Modellkontextprotokoll
* [GitHub MCP-Serverdokumentation](https://github.com/github/github-mcp-server)
* [MCP-Serververzeichnis – Weitere MCP-Server](https://github.com/modelcontextprotocol/servers) erkunden
* [OpenTelemetry-Instrumentierung für Copilot SDK](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/observability/opentelemetry) – TelemetryConfig, Weitergabe des Trace-Kontexts und sprachspezifische Abhängigkeiten

**Du hast es geschafft!** Sie haben die Kernkonzepte des GitHub Copilot SDK kennengelernt:

* ✅ Erstellen eines Clients und einer Sitzung
* ✅ Senden von Nachrichten und Empfangen von Antworten
* ✅ Streaming für Echtzeitausgabe
* ✅ Definieren von benutzerdefinierten Tools, die Copilot aufrufen können

Jetzt schaffen Sie etwas Erstaunliches!
🚀