SDK 미들웨어
SDK 미들웨어
Anthropic SDK의 미들웨어(인터셉터) 훅으로 요청을 보내기 전과 응답을 받은 후에 코드를 실행하는 방법을 알아보아요. 로깅, 커스텀 재시도, 요청 주석, 거절 폴백 처리 같은 횡단 관심사를 처리하기에 좋아요.
출처: 문서
본문
Anthropic SDK는 요청이 보내지기 전과 응답이 수신된 후에 코드를 실행할 수 있는 미들웨어(인터셉터) 훅을 제공해요. 로깅, 커스텀 재시도, 요청 주석, 거절 폴백 처리 같은 횡단 관심사에 미들웨어를 쓰세요.
sequenceDiagram
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
각 미들웨어는 next()를 호출하기 전에 요청을 검사하거나 교체하고, next()가 반환된 후에 응답을 검사하거나 교체할 수 있어요.
미들웨어 등록하기
각 미들웨어는 나가는 요청과 next 콜러블을 받는 함수예요. next를 호출해 요청을 나머지 체인으로(마지막 미들웨어라면 SDK 코어로 직접) 전달하고, 그 응답을 반환해요. next 호출 전의 코드는 나가는 길에, 이후의 코드는 돌아오는 길에 실행돼요.
# Forward the request to the rest of the chain
response = call_next(request)
# After the request
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) => {
// Before the request
ctx.logger.debug("->", request.method, request.url);
// Forward the request to the rest of the chain
const response = await next(request);
// After the request
ctx.logger.debug("<-", response.status, request.url);
return response;
};
const client = new Anthropic({ middleware: [loggingMiddleware] });
AnthropicClient client = new()
{
Handlers =
[
Handler.Create(async (request, next, cancellationToken) =>
{
// Before the request
Console.WriteLine($"Sending {request.Method} {request.RequestUri}");
// Forward the request to the next handler
var response = await next(request, cancellationToken);
// After the request
Console.WriteLine($"Received {(int)response.StatusCode}");
return response;
}),
],
};
client := anthropic.NewClient(
option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) {
// Before the request
start := time.Now()
slog.Info("sending request", "method", req.Method, "url", req.URL)
// Forward the request to the rest of the chain
res, err := next(req)
if err != nil {
return nil, err
}
// After the request
slog.Info("received response", "status", res.StatusCode, "duration", time.Since(start))
return res, nil
}),
)
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.addInterceptor(Interceptor.syncOnly((nextClient, request, requestOptions) -> {
// Before the request
IO.println(request.method() + " /" + String.join("/", request.pathSegments()));
// Forward the request to the next handler
HttpResponse response = nextClient.execute(request, requestOptions);
// After the request
IO.println(response.statusCode());
return response;
}))
.build();
$loggingMiddleware = function (RequestInterface $request, callable $next): ResponseInterface {
// Before the request
error_log("-> {$request->getMethod()} {$request->getUri()}");
// Forward the request to the rest of the chain
$response = $next($request);
// After the request
error_log("<- {$response->getStatusCode()}");
return $response;
};
$client = new Client(requestOptions: ['middleware' => [$loggingMiddleware]]);
logging_middleware = lambda do |request, call_next|
# Before the request
puts "-> #{request.method.upcase} #{request.url}"
# Forward the request to the rest of the chain
response = call_next.call(request)
# After the request
puts "<- #{response.status}"
response
end
client = Anthropic::Client.new(middleware: [logging_middleware])
미들웨어 순서
미들웨어를 여러 개 등록하면 주어진 순서대로 적용돼요. 첫 미들웨어의 "before" 코드가 먼저 실행되고, 그 "after" 코드가 마지막에 실행돼요. 클라이언트에 등록한 미들웨어는 요청별 옵션으로 넘긴 미들웨어보다 먼저 실행돼요.
Go SDK에서는 반복된 option.WithMiddleware 호출이 연결돼요(클라이언트 먼저, 그다음 메서드). 다른 SDK에서는 배열을 넘기고, 나중 항목이 안쪽을 감싸요.
HTTP 클라이언트 교체하기
각 SDK는 커스텀 HTTP 클라이언트도 받아들여요(프록시 설정, 커스텀 TLS, 연결 풀링용). SDK 클라이언트당 하나의 HTTP 클라이언트만 사용되며, 설정하면 기본값을 대체해요. 커스텀 HTTP 클라이언트는 모든 미들웨어가 실행된 뒤 요청을 받아요.
내장 미들웨어
SDK는 Claude Fable 5가 거절한 요청을 폴백 모델로 자동 재시도하는 거절 폴백 미들웨어를 제공해요. 설정과 언어별 예제는 폴백 모델에서 감지하고 재시도하기를 참고하세요.