Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
APLICA-SE A: todas as camadas do Gerenciamento de API
Neste artigo, você importará uma API de modelo de linguagem do Amazon Bedrock para sua instância de Gerenciamento de API como uma API de passagem. Este é um exemplo de um modelo hospedado em um provedor de inferência diferente dos serviços de IA do Azure. Use políticas de gateway de IA e outros recursos no Gerenciamento de API para simplificar a integração, melhorar a observabilidade e aprimorar o controle sobre os pontos de extremidade do modelo.
Saiba mais sobre como gerenciar APIs de IA no Gerenciamento de API:
- Funcionalidades do gateway de IA no Gerenciamento de API do Azure
- Importar uma API de modelo de idioma
Saiba mais sobre a Amazon Bedrock:
Pré-requisitos
- Uma instância de Gerenciamento de API existente. Crie uma, se ainda não tiver.
- Uma conta do Amazon Web Services (AWS) com acesso à Amazon Bedrock e acesso a um ou mais modelos da Amazon Bedrock Foundation. Saiba mais
Criar chaves de acesso para usuário do IAM
Para autenticar sua instância de Gerenciamento de API no Gateway de API da Amazon, você precisa de chaves de acesso para um usuário do IAM do AWS.
Para gerar a ID da chave de acesso e a chave secreta necessárias usando o AWS Management Console, confira a página Criar uma chave de acesso para você mesmo na documentação da AWS.
Salve suas chaves de acesso em um local seguro. Você os armazenará como valores nomeados na próxima etapa.
Cuidado
As chaves de acesso são credenciais de longo prazo e você deve gerenciá-las com a mesma segurança de uma senha. Saiba mais sobre como proteger chaves de acesso
Armazenar chaves de acesso de usuário do IAM como valores nomeados
Armazene com segurança as duas chaves de acesso do usuário do IAM como valores nomeados secretos em sua instância de Gerenciamento de API do Azure usando a configuração recomendada na tabela a seguir.
| Segredo da AWS | Nome | Valor secreto |
|---|---|---|
| Chave de acesso | accesskey | ID da chave de acesso recuperada da AWS |
| Chave de acesso secreta | secretkey | Chave secreta de acesso recuperada da AWS |
Importar uma API bedrock usando o portal
Para importar uma API do Amazon Bedrock para o Gerenciamento de API:
No portal do Azure, navegue até a instância do Gerenciamento de API.
No menu do lado esquerdo, em APIs, selecione APIs>+ Adicionar API.
Em Definir uma nova API, selecione API de Modelo de Idioma.
Na guia Configurar API :
Insira um Nome de exibição e uma Descrição opcional para a API.
Insira a seguinte URL para o ponto de extremidade padrão do Amazon Bedrock:
https://bedrock-runtime.<aws-region>.amazonaws.com.Exemplo:
https://bedrock-runtime.us-east-1.amazonaws.comOpcionalmente, selecione um ou mais Produtos a serem associados à API.
No Caminho, acrescente um caminho que sua instância de Gerenciamento de API usa para acessar os pontos de extremidade da API LLM.
Em Tipo, selecione Criar uma API de passagem direta.
Deixe os valores na chave do Access em branco.
Nas guias restantes, opcionalmente, configure políticas para gerenciar o consumo de token, o cache semântico e a segurança do conteúdo de IA. Para obter detalhes, consulte Importar uma API de modelo de idioma.
Selecione Examinar.
Após as configurações terem sido validadas, selecione Criar.
O Gerenciamento de API cria a API e (opcionalmente) políticas para ajudá-lo a monitorar e gerenciar a API.
Configurar políticas para autenticar solicitações na API do Amazon Bedrock
Configure políticas de gestão de API para assinar solicitações para a API do Amazon Bedrock. Saiba mais sobre como assinar solicitações de API do AWS
O exemplo a seguir usa os valores de chave de acesso e secretkey nomeados que você criou anteriormente para a chave de acesso do AWS e a chave secreta. Defina a region variável como o valor apropriado para sua API do Amazon Bedrock. O exemplo usa us-east-1 para a região.
No portal do Azure, navegue até a instância do Gerenciamento de API.
No menu do lado esquerdo, em APIs, selecione APIs.
Selecione a API que você criou na seção anterior.
No menu à esquerda, em Design, selecione Todas as operações.
Selecione a guia Processamento de Entrada .
No editor de política de processamento de entrada , selecione </> para abrir o editor de políticas.
Configure as seguintes políticas:
<policies> <inbound> <base /> <set-variable name="now" value="@(DateTime.UtcNow)" /> <set-header name="X-Amz-Date" exists-action="override"> <value>@(((DateTime)context.Variables["now"]).ToString("yyyyMMddTHHmmssZ"))</value> </set-header> <set-header name="X-Amz-Content-Sha256" exists-action="override"> <value>@{ var body = context.Request.Body.As<string>(preserveContent: true); using (var sha256 = System.Security.Cryptography.SHA256.Create()) { var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(body)); return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } }</value> </set-header> <set-header name="Authorization" exists-action="override"> <value>@{ var accessKey = "{{accesskey}}"; var secretKey = "{{secretkey}}"; var region = "us-east-1"; var service = "bedrock"; var method = context.Request.Method; var uri = context.Request.Url; var host = uri.Host; // Create canonical path var path = uri.Path; var modelSplit = path.Split(new[] { "model/" }, 2, StringSplitOptions.None); var afterModel = modelSplit.Length > 1 ? modelSplit[1] : ""; var parts = afterModel.Split(new[] { '/' }, 2); var model = System.Uri.EscapeDataString(parts[0]); var remainder = parts.Length > 1 ? parts[1] : ""; var canonicalPath = $"/model/{model}/{remainder}"; var amzDate = ((DateTime)context.Variables["now"]).ToString("yyyyMMddTHHmmssZ"); var dateStamp = ((DateTime)context.Variables["now"]).ToString("yyyyMMdd"); // Hash the payload var body = context.Request.Body.As<string>(preserveContent: true); string hashedPayload; using (var sha256 = System.Security.Cryptography.SHA256.Create()) { var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(body)); hashedPayload = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } // Create canonical query string var queryDict = context.Request.Url.Query; var canonicalQueryString = ""; if (queryDict != null && queryDict.Count > 0) { var encodedParams = new List<string>(); foreach (var kvp in queryDict) { var encodedKey = System.Uri.EscapeDataString(kvp.Key); var encodedValue = System.Uri.EscapeDataString(kvp.Value.First() ?? ""); encodedParams.Add($"{encodedKey}={encodedValue}"); } canonicalQueryString = string.Join("&", encodedParams.OrderBy(p => p)); } // Create signed headers and canonical headers var headers = context.Request.Headers; var canonicalHeaderList = new List<string[]>(); // Add content-type if present var contentType = headers.GetValueOrDefault("Content-Type", "").ToLowerInvariant(); if (!string.IsNullOrEmpty(contentType)) { canonicalHeaderList.Add(new[] { "content-type", contentType }); } // Always add host canonicalHeaderList.Add(new[] { "host", host }); // Add x-amz-* headers (excluding x-amz-date, x-amz-content-sha256) foreach (var header in headers) { var name = header.Key.ToLowerInvariant(); if (string.Equals(name, "x-amz-content-sha256", StringComparison.OrdinalIgnoreCase) || string.Equals(name, "x-amz-date", StringComparison.OrdinalIgnoreCase)) { continue; } if (name.StartsWith("x-amz-")) { var value = header.Value.First()?.Trim(); canonicalHeaderList.Add(new[] { name, value }); } } canonicalHeaderList.Add(new[] { "x-amz-content-sha256", hashedPayload }); canonicalHeaderList.Add(new[] { "x-amz-date", amzDate }); var canonicalHeadersOrdered = canonicalHeaderList.OrderBy(h => h[0]); var canonicalHeaders = string.Join("\n", canonicalHeadersOrdered.Select(h => $"{h[0]}:{h[1].Trim()}")) + "\n"; var signedHeaders = string.Join(";", canonicalHeadersOrdered.Select(h => h[0])); // Create and hash the canonical request var canonicalRequest = $"{method}\n{canonicalPath}\n{canonicalQueryString}\n{canonicalHeaders}\n{signedHeaders}\n{hashedPayload}"; string hashedCanonicalRequest = ""; using (var sha256 = System.Security.Cryptography.SHA256.Create()) { var hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(canonicalRequest)); hashedCanonicalRequest = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } // Build string to sign var credentialScope = $"{dateStamp}/{region}/{service}/aws4_request"; var stringToSign = $"AWS4-HMAC-SHA256\n{amzDate}\n{credentialScope}\n{hashedCanonicalRequest}"; // Sign it using secret key byte[] kSecret = System.Text.Encoding.UTF8.GetBytes("AWS4" + secretKey); byte[] kDate, kRegion, kService, kSigning; using (var h1 = new System.Security.Cryptography.HMACSHA256(kSecret)) { kDate = h1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(dateStamp)); } using (var h2 = new System.Security.Cryptography.HMACSHA256(kDate)) { kRegion = h2.ComputeHash(System.Text.Encoding.UTF8.GetBytes(region)); } using (var h3 = new System.Security.Cryptography.HMACSHA256(kRegion)) { kService = h3.ComputeHash(System.Text.Encoding.UTF8.GetBytes(service)); } using (var h4 = new System.Security.Cryptography.HMACSHA256(kService)) { kSigning = h4.ComputeHash(System.Text.Encoding.UTF8.GetBytes("aws4_request")); } // Auth header string signature; using (var hmac = new System.Security.Cryptography.HMACSHA256(kSigning)) { var sigBytes = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringToSign)); signature = BitConverter.ToString(sigBytes).Replace("-", "").ToLowerInvariant(); } return $"AWS4-HMAC-SHA256 Credential={accessKey}/{credentialScope}, SignedHeaders={signedHeaders}, Signature={signature}"; }</value> </set-header> <set-header name="Host" exists-action="override"> <value>@(context.Request.Url.Host)</value> </set-header> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
Chamar a API Bedrock
Para chamar a API Bedrock por meio do Gerenciamento de API, você pode usar o SDK do Bedrock da AWS. Este exemplo usa o SDK do .NET, mas você pode usar qualquer linguagem que dê suporte à API Bedrock da AWS.
O exemplo a seguir usa um cliente HTTP personalizado que instancia classes definidas no arquivo BedrockHttpClientFactory.csde acompanhamento. O cliente HTTP personalizado roteia solicitações para o ponto de extremidade de Gerenciamento de API e inclui a chave de assinatura de Gerenciamento de API (se necessário) nos cabeçalhos de solicitação.
using Amazon;
using Amazon.BedrockRuntime;
using Amazon.BedrockRuntime.Model;
using Amazon.Runtime;
using BedrockClient;
// Leave accessKey and secretKey values as empty strings. Authentication to AWS API is handled through policies in API Management.
var accessKey = "";
var secretKey = "";
var credentials = new BasicAWSCredentials(accessKey, secretKey);
// Create custom configuration to route requests through API Management
// apimUrl is the API Management endpoint, such as https://apim-hello-word.azure-api.net/bedrock
var apimUrl = "<api-management-endpoint">;
// Provide name and value for the API Management subscription key header.
var apimSubscriptionHeaderName = "api-key";
var apimSubscriptionKey = "<your-apim-subscription-key>";
var config = new AmazonBedrockRuntimeConfig()
{
HttpClientFactory = new BedrockHttpClientFactory(apimUrl, apimSubscriptionHeaderName, apimSubscriptionKey),
// Set the AWS region where your Bedrock model is hosted.
RegionEndpoint = RegionEndpoint.USEast1
};
var client = new AmazonBedrockRuntimeClient(credentials, config);
// Set the model ID, e.g., Claude 3 Haiku. Find the supported models in Amazon Bedrock documentation: https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html.
var modelId = "us.anthropic.claude-3-5-haiku-20241022-v1:0";
// Define the user message.
var userMessage = "Describe the purpose of a 'hello world' program in one line.";
// Create a request with the model ID, the user message, and an inference configuration.
var request = new ConverseRequest
{
ModelId = modelId,
Messages = new List<Message>
{
new Message
{
Role = ConversationRole.User,
Content = new List<ContentBlock> { new ContentBlock { Text = userMessage } }
}
},
InferenceConfig = new InferenceConfiguration()
{
MaxTokens = 512,
Temperature = 0.5F,
TopP = 0.9F
}
};
try
{
// Send the request to the Bedrock runtime and wait for the result.
var response = await client.ConverseAsync(request);
// Extract and print the response text.
string responseText = response?.Output?.Message?.Content?[0]?.Text ?? "";
Console.WriteLine(responseText);
}
catch (AmazonBedrockRuntimeException e)
{
Console.WriteLine($"ERROR: Can't invoke '{modelId}'. Reason: {e.Message}");
throw;
}
BedrockHttpClientFactory.cs
O código a seguir implementa classes para criar um cliente HTTP personalizado que roteia solicitações para a API Bedrock por meio do Gerenciamento de API, incluindo uma chave de assinatura do Gerenciamento de API nos cabeçalhos.
using Amazon.Runtime;
namespace BedrockClient
{
public class BedrockHttpClientFactory : HttpClientFactory
{
readonly string subscriptionKey;
readonly string subscriptionHeaderName;
readonly string rerouteUrl;
public BedrockHttpClientFactory(string rerouteUrl, string subscriptionHeaderName, string subscriptionKey)
{
this.rerouteUrl = rerouteUrl;
this.subscriptionHeaderName = subscriptionHeaderName;
this.subscriptionKey = subscriptionKey;
}
public override HttpClient CreateHttpClient(IClientConfig clientConfig)
{
var handler = new RerouteHandler(rerouteUrl)
{
InnerHandler = new HttpClientHandler()
};
var httpClient = new HttpClient(handler);
httpClient.DefaultRequestHeaders.Add(this.subscriptionHeaderName, this.subscriptionKey);
return httpClient;
}
}
public class RerouteHandler : DelegatingHandler
{
readonly string rerouteUrl;
readonly string host;
public RerouteHandler(string rerouteUrl)
{
this.rerouteUrl = rerouteUrl;
this.host = rerouteUrl.Split("/")[2].Split(":")[0];
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var originalUri = request.RequestUri;
request.RequestUri = new Uri($"{this.rerouteUrl}{originalUri.PathAndQuery}");
request.Headers.Host = this.host;
return base.SendAsync(request, cancellationToken);
}
}
}
Conteúdo relacionado
- Funcionalidades do gateway de IA no Gerenciamento de API do Azure