---
title: SDK-Middleware
url: https://platform.claude.com/docs/de/cli-sdks-libraries/middleware
description: Fange die Anfragen und Antworten des SDK ab und ändere sie.
---

Das Claude SDK bietet einen „middleware“ (Middleware)-Hook (auch „interceptor“ (Abfangfunktion) genannt), mit dem du Code ausführen kannst, bevor eine Anfrage gesendet wird und nachdem die Antwort empfangen wurde. Verwende Middleware für übergreifende Anliegen wie Logging, benutzerdefinierte Wiederholungsversuche, Annotation von Anfragen und die Behandlung von Fallbacks bei Ablehnungen.

```mermaid
sequenceDiagram
    accTitle: How a request and its response pass through middleware
    accDescr: Your code sends the request to Middleware A. Middleware A calls next(request) to pass it to Middleware B, and Middleware B calls next(request) to pass it to the SDK core. The SDK core sends the HTTP request to the Claude API and receives the HTTP response. The response returns through Middleware B, then Middleware A, to your code.
    autonumber
    participant App as Your code
    participant M1 as Middleware A
    participant M2 as Middleware B
    participant Core as SDK core
    participant API as Claude API
    App->>M1: request
    M1->>M2: next(request)
    M2->>Core: next(request)
    Core->>API: HTTP request
    API-->>Core: HTTP response
    Core-->>M2: response
    M2-->>M1: response
    M1-->>App: response
```

Jede Middleware kann die Anfrage vor dem Aufruf von `next()` und die Antwort nach der Rückkehr von `next()` inspizieren oder ersetzen.

## Middleware registrieren

Jede Middleware ist eine Funktion, die die ausgehende Anfrage und den nächsten Handler erhält. Rufe `call_next(request)` (typescript: `next(request)`; csharp: `next(request, cancellationToken)`; go: `next(req)`; java: `nextClient.execute(request, requestOptions)`; php: `$next($request)`; ruby: `call_next.call(request)`) auf, um die Anfrage an den Rest der Kette weiterzuleiten (oder direkt an den SDK-Kern, wenn dies die letzte Middleware ist), und gib deren Antwort zurück. Alles vor diesem Aufruf wird auf dem Hinweg ausgeführt; alles danach auf dem Rückweg.

<CodeGroup exclude="shell">
  ```python Python
  def logging_middleware(request: APIRequest, call_next: CallNext) -> APIResponse[Any]:
      # Vor der Anfrage
      print(f"-> {request.method} {request.url}")

      # Leite die Anfrage an den Rest der Kette weiter
      response = call_next(request)

      # Nach der Anfrage
      print(f"<- {response.status_code}")

      return response


  client = Anthropic(middleware=[logging_middleware])
  ```

  ```typescript TypeScript
  import type { Middleware } from "@anthropic-ai/sdk";

  const loggingMiddleware: Middleware = async (request, next, ctx) => {
    // Vor der Anfrage
    ctx.logger.debug("->", request.method, request.url);

    // Leite die Anfrage an den Rest der Kette weiter
    const response = await next(request);

    // Nach der Anfrage
    ctx.logger.debug("<-", response.status, request.url);

    return response;
  };

  const client = new Anthropic({ middleware: [loggingMiddleware] });
  ```

  ```csharp C#
  AnthropicClient client = new()
  {
      Handlers =
      [
          Handler.Create(async (request, next, cancellationToken) =>
          {
              // Vor der Anfrage
              Console.WriteLine($"Sending {request.Method} {request.RequestUri}");

              // Leite die Anfrage an den nächsten Handler weiter
              var response = await next(request, cancellationToken);

              // Nach der Anfrage
              Console.WriteLine($"Received {(int)response.StatusCode}");

              return response;
          }),
      ],
  };
  ```

  ```go Go
  client := anthropic.NewClient(
  	option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) {
  		// Vor der Anfrage
  		start := time.Now()
  		slog.Info("sending request", "method", req.Method, "url", req.URL)

  		// Leite die Anfrage an den Rest der Kette weiter
  		res, err := next(req)
  		if err != nil {
  			return nil, err
  		}

  		// Nach der Anfrage
  		slog.Info("received response", "status", res.StatusCode, "duration", time.Since(start))

  		return res, nil
  	}),
  )
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.builder()
      .fromEnv()
      .addInterceptor(Interceptor.syncOnly((nextClient, request, requestOptions) -> {
          // Vor der Anfrage
          IO.println(request.method() + " /" + String.join("/", request.pathSegments()));

          // Leite die Anfrage an den nächsten Handler weiter
          HttpResponse response = nextClient.execute(request, requestOptions);

          // Nach der Anfrage
          IO.println(response.statusCode());

          return response;
      }))
      .build();
  ```

  ```php PHP
  $loggingMiddleware = function (RequestInterface $request, callable $next): ResponseInterface {
      // Vor der Anfrage
      error_log("-> {$request->getMethod()} {$request->getUri()}");

      // Leite die Anfrage an den Rest der Kette weiter
      $response = $next($request);

      // Nach der Anfrage
      error_log("<- {$response->getStatusCode()}");

      return $response;
  };

  $client = new Client(requestOptions: ['middleware' => [$loggingMiddleware]]);
  ```

  ```ruby Ruby
  logging_middleware = lambda do |request, call_next|
    # Vor der Anfrage
    puts "-> #{request.method.upcase} #{request.url}"

    # Leite die Anfrage an den Rest der Kette weiter
    response = call_next.call(request)

    # Nach der Anfrage
    puts "<- #{response.status}"

    response
  end

  client = Anthropic::Client.new(middleware: [logging_middleware])
  ```
</CodeGroup>

## Reihenfolge der Middleware

Wenn du mehrere Middlewares registrierst, werden sie in der angegebenen Reihenfolge angewendet: Der „Vorher“-Code der ersten Middleware läuft zuerst, und ihr „Nachher“-Code läuft zuletzt. Auf dem Client registrierte Middleware läuft vor Middleware, die als Option pro Anfrage übergeben wird.

Im Go SDK werden wiederholte `option.WithMiddleware`-Aufrufe verkettet (zuerst Client, dann Methode). In den anderen SDKs übergibst du ein Array; spätere Einträge umschließen die inneren.

## Den HTTP-Client ersetzen

Das SDK akzeptiert auch einen benutzerdefinierten HTTP-Client (für Proxy-Konfiguration, benutzerdefiniertes TLS oder Connection-Pooling). Pro SDK-Client wird nur ein HTTP-Client verwendet; wenn du ihn festlegst, ersetzt er den Standard-Client. Der benutzerdefinierte HTTP-Client erhält Anfragen, nachdem alle Middleware ausgeführt wurde.

## Integrierte Middleware

Das SDK enthält eine Refusal-Fallback-Middleware, die eine Anfrage, die Claude ablehnt (`stop_reason: "refusal"`), automatisch mit einem Fallback-Modell wiederholt. [Ablehnungen und Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback) listet die Modelle auf, deren Sicherheitsklassifikatoren Anfragen ablehnen können, und [Clientseitiger Fallback mit der SDK-Middleware](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#client-side-fallback) behandelt die Einrichtung und Beispiele für die einzelnen Sprachen.
