Condividi tramite


Libreria client REST di inferenza di Azure per JavaScript - versione 1.0.0-beta.4

API di inferenza per i modelli di intelligenza artificiale supportati da Azure

Per usare questa libreria, della documentazione del client REST

Collegamenti chiave:

Introduttiva

import ModelClient, { isUnexpected } from "@azure-rest/ai-inference";
import { AzureKeyCredential } from "@azure/core-auth";
const client = new ModelClient(
  "https://<Azure Model endpoint>",
  new AzureKeyCredential("<Azure API key>")
);

const response = await client.path("/chat/completions").post({
  body: {
    messages: [
      {role: "user", content: "How many feet are in a mile?"},
    ],
  }
});

if(isUnexpected(response)) {
  throw response.body.error;
}
console.log(response.body.choices[0].message.content);

Ambienti attualmente supportati

  • Versioni LTS di Node.js

Prerequisiti

  • Per usare questo pacchetto, è necessario disporre di una sottoscrizione di Azure .

Installare il pacchetto @azure-rest/ai-inference

Installare la libreria client REST client REST di Azure ModelClient per JavaScript con npm:

npm install @azure-rest/ai-inference

Creare ed autenticare un ModelClient

Uso di una chiave API da Azure

È possibile eseguire l'autenticazione con una chiave API di Azure usando la libreria azure Core Auth. Per usare il provider AzureKeyCredential illustrato di seguito, installare il pacchetto @azure/core-auth:

npm install @azure/core-auth

Usare portale di Azure per passare alla distribuzione del modello e recuperare una chiave API.

Nota: A volte la chiave API viene definita "chiave di sottoscrizione" o "chiave API di sottoscrizione".

Dopo aver creato una chiave API e un endpoint, è possibile usare la classe AzureKeyCredential per autenticare il client come indicato di seguito:

import ModelClient from "@azure-rest/ai-inference";
import { AzureKeyCredential } from "@azure/core-auth";

const client = new ModelClient("<endpoint>", new AzureKeyCredential("<API key>"));

Uso di credenziali di Azure Active Directory

È anche possibile eseguire l'autenticazione con Azure Active Directory usando libreria di identità di Azure. Per usare il provider DefaultAzureCredential illustrato di seguito o altri provider di credenziali forniti con Azure SDK, installare il pacchetto :

npm install @azure/identity

Impostare i valori dell'ID client, dell'ID tenant e del segreto client dell'applicazione AAD come variabili di ambiente: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET.

import ModelClient from "@azure-rest/ai-inference";
import { DefaultAzureCredential }  from "@azure/identity";

const client = new ModelClient("<endpoint>", new DefaultAzureCredential());

Concetti chiave

Il concetto principale da comprendere è completamenti. Brevemente spiegato, i completamenti forniscono la relativa funzionalità sotto forma di richiesta di testo, che usando un modello specifico, tenterà quindi di trovare una corrispondenza con il contesto e i modelli, fornendo un testo di output. Il frammento di codice seguente offre una panoramica approssimativa:

import ModelClient, { isUnexpected } from "@azure-rest/ai-inference";
import { AzureKeyCredential } from "@azure/core-auth";

async function main(){
  const client = new ModelClient(
  "https://your-model-endpoint/",
  new AzureKeyCredential("your-model-api-key"));

  const response = await client.path("/chat/completions").post({
    body: {
      messages: [
        {role: "user", content: "Hello, world!"},
      ],
    }
  });

  if(isUnexpected(response)) {
    throw response.body.error;
  }

  console.log(response.body.choices[0].message.content);
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

Esempi

Generare la risposta del chatbot

La chat di streaming con Inference SDK richiede il supporto per lo streaming principale; per abilitare questo supporto, installare il pacchetto @azure/core-sse:

npm install @azure/core-sse

Questo esempio esegue l'autenticazione usando defaultAzureCredential, quindi genera risposte di chat per immettere domande e messaggi di chat.

import ModelClient from "@azure-rest/ai-inference";
import { DefaultAzureCredential } from "@azure/identity";
import { createSseStream } from "@azure/core-sse";

async function main(){
  const endpoint = "https://myaccount.openai.azure.com/";
  const client = new ModelClient(endpoint, new DefaultAzureCredential());

  const messages = [
    // NOTE: "system" role is not supported on all Azure Models
    { role: "system", content: "You are a helpful assistant. You will talk like a pirate." },
    { role: "user", content: "Can you help me?" },
    { role: "assistant", content: "Arrrr! Of course, me hearty! What can I do for ye?" },
    { role: "user", content: "What's the best way to train a parrot?" },
  ];

  console.log(`Messages: ${messages.map((m) => m.content).join("\n")}`);

  const response = await client.path("/chat/completions").post({
    body: {
      messages,
      stream: true,
      max_tokens: 128
    }
  }).asNodeStream();

  const stream = response.body;
  if (!stream) {
    throw new Error("The response stream is undefined");
  }

  if (response.status !== "200") {
    throw new Error(`Failed to get chat completions: ${response.body.error}`);
  }

  const sses = createSseStream(stream);

  for await (const event of sses) {
    if (event.data === "[DONE]") {
      return;
    }
    for (const choice of (JSON.parse(event.data)).choices) {
      console.log(choice.delta?.content ?? "");
    }
  }
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

Generare più completamenti con la chiave di sottoscrizione

Questo esempio genera risposte di testo ai prompt di input usando una chiave di sottoscrizione di Azure

import ModelClient from "@azure-rest/ai-inference";
import { AzureKeyCredential } from "@azure/core-auth";

async function main(){
  // Replace with your Model API key
  const key = "YOUR_MODEL_API_KEY";
  const endpoint = "https://your-model-endpoint/";
  const client = new ModelClient(endpoint, new AzureKeyCredential(key));

  const messages = [
    { role: "user", content: "How are you today?" },
    { role: "user", content: "What is inference in the context of AI?" },
    { role: "user", content: "Why do children love dinosaurs?" },
    { role: "user", content: "Generate a proof of Euler's identity" },
    { role: "user", content: "Describe in single words only the good things that come into your mind about your mother." },
  ];

  let promptIndex = 0;
  const response = await client.path("/chat/completions").post({
    body: {
      messages
    }
  });

  if(response.status !== "200") {
    throw response.body.error;
  }
  for (const choice of response.body.choices) {
    const completion = choice.message.content;
    console.log(`Input: ${messages[promptIndex++].content}`);
    console.log(`Chatbot: ${completion}`);
  }
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

Riepilogare il testo con completamento

In questo esempio viene generato un riepilogo del prompt di input specificato.

import ModelClient from "@azure-rest/ai-inference";
import { DefaultAzureCredential } from "@azure/identity";

async function main(){
  const endpoint = "https://your-model-endpoint/";
  const client = new ModelClient(endpoint, new DefaultAzureCredential());

  const textToSummarize = `
    Two independent experiments reported their results this morning at CERN, Europe's high-energy physics laboratory near Geneva in Switzerland. Both show convincing evidence of a new boson particle weighing around 125 gigaelectronvolts, which so far fits predictions of the Higgs previously made by theoretical physicists.

    ""As a layman I would say: 'I think we have it'. Would you agree?"" Rolf-Dieter Heuer, CERN's director-general, asked the packed auditorium. The physicists assembled there burst into applause.
  :`;

  const summarizationPrompt = `
    Summarize the following text.

    Text:
    """"""
    ${textToSummarize}
    """"""

    Summary:
  `;

  console.log(`Input: ${summarizationPrompt}`);

  const response = await client.path("/chat/completions").post({
    body: {
      messages: [
        { role: "user", content: summarizationPrompt }
      ],
      max_tokens: 64
    }
  });

  if(response.status !== "200") {
    throw response.body.error;
  }
  const completion = response.body.choices[0].message.content;
  console.log(`Summarization: ${completion}`);
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

Usare gli strumenti di chat

Strumenti estendere i completamenti delle chat consentendo a un assistente di richiamare funzioni definite e altre funzionalità nel processo di soddisfare una richiesta di completamento della chat. Per usare gli strumenti di chat, iniziare definendo uno strumento per le funzioni:

const getCurrentWeather = {
    name: "get_current_weather",
    description: "Get the current weather in a given location",
    parameters: {
      type: "object",
      properties: {
        location: {
          type: "string",
          description: "The city and state, e.g. San Francisco, CA",
        },
        unit: {
          type: "string",
          enum: ["celsius", "fahrenheit"],
        },
      },
      required: ["location"],
    },
  };

Con lo strumento definito, includere tale nuova definizione nelle opzioni per una richiesta di completamento della chat:

const messages = [{ role: "user", content: "What is the weather like in Boston?" }];
const tools = [
  {
    type: "function",
    function: getCurrentWeather,
  },
];
const result = await client.path("/chat/completions").post({
  body: {
    messages,
    tools
  }
});

Quando l'assistente decide che è necessario usare uno o più strumenti, il messaggio di risposta include una o più chiamate di strumenti che devono essere risolte tramite "messaggi degli strumenti" nella richiesta successiva. Questa risoluzione delle chiamate degli strumenti in nuovi messaggi di richiesta può essere considerata come una sorta di "callback" per i completamenti della chat.

// Purely for convenience and clarity, this function handles tool call responses.
function applyToolCall({ function: call, id }) {
    if (call.name === "get_current_weather") {
      const { location, unit } = JSON.parse(call.arguments);
      // In a real application, this would be a call to a weather API with location and unit parameters
      return {
        role: "tool",
        content: `The weather in ${location} is 72 degrees ${unit} and sunny.`,
        toolCallId: id,
      }
    }
    throw new Error(`Unknown tool call: ${call.name}`);
}

Per fornire risoluzioni delle chiamate degli strumenti all'assistente per consentire la continuazione della richiesta, fornire tutto il contesto cronologico precedente, inclusi i messaggi di sistema e utente originali, la risposta dell'assistente che includeva le chiamate allo strumento e i messaggi degli strumenti che hanno risolto ognuno di questi strumenti, quando si effettua una richiesta successiva.

const choice = result.body.choices[0];
const responseMessage = choice.message;
if (responseMessage?.role === "assistant") {
  const requestedToolCalls = responseMessage?.toolCalls;
  if (requestedToolCalls?.length) {
    const toolCallResolutionMessages = [
      ...messages,
      responseMessage,
      ...requestedToolCalls.map(applyToolCall),
    ];
    const toolCallResolutionResult = await client.path("/chat/completions").post({
      body: {
        messages: toolCallResolutionMessages
      }
    });
    // continue handling the response as normal
  }
}

Chat con immagini (usando modelli che supportano la chat di immagini, ad esempio gpt-4o)

Alcuni modelli di Azure consentono di usare le immagini come componenti di input nei completamenti della chat.

A tale scopo, fornire elementi di contenuto distinti nei messaggi utente per la richiesta di completamento della chat:

const url = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg",
const messages = [{
    role: "user", content: [{
    type: "image_url",
    image_url: {
      url,
      detail: "auto"
    }
  }]},
  {role: "user", content: "describe the image"}];

I completamenti della chat procederanno come di consueto, anche se il modello potrebbe segnalare le finish_details più informative al posto di finish_reason:

const response = await client.path("/chat/completions").post({
  body: {
    messages 
});
console.log(`Chatbot: ${response.choices[0].message?.content}`);

Esempio di incorporamento di testo

Questo esempio illustra come ottenere incorporamenti di testo con l'autenticazione entra ID.

import ModelClient, { isUnexpected } from "@azure-rest/ai-inference";
import { DefaultAzureCredential } from "@azure/identity";

const endpoint = "<your_model_endpoint>";
const credential = new DefaultAzureCredential();

async function main(){
  const client = ModelClient(endpoint, credential);
  const response = await client.path("/embeddings").post({
    body: {
      input: ["first phrase", "second phrase", "third phrase"]
    }
  });

  if (isUnexpected(response)) {
    throw response.body.error;
  }
  for (const data of response.body.data) {
    console.log(`data length: ${data.length}, [${data[0]}, ${data[1]}, ..., ${data[data.length - 2]}, ${data[data.length - 1]}]`);
  }
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

La lunghezza del vettore di incorporamento dipende dal modello, ma dovrebbe essere visualizzato un aspetto simile al seguente:

data: length=1024, [0.0013399124, -0.01576233, ..., 0.007843018, 0.000238657]
data: length=1024, [0.036590576, -0.0059547424, ..., 0.011405945, 0.004863739]
data: length=1024, [0.04196167, 0.029083252, ..., -0.0027484894, 0.0073127747]

Per generare incorporamenti per frasi aggiuntive, è sufficiente chiamare client.path("/embeddings").post più volte usando lo stesso client.

Strumentazione

Attualmente la strumentazione è supportata solo per Chat Completion without streaming. Per abilitare la strumentazione, è necessario registrare gli esportatori.

Di seguito è riportato un esempio per aggiungere console come utilità di esportazione:

import { ConsoleSpanExporter, NodeTracerProvider, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-node";

const provider = new NodeTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
provider.register();

Di seguito è riportato un esempio per aggiungere application insight come utilità di esportazione:

import { NodeTracerProvider, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-node";
import { AzureMonitorTraceExporter } from "@azure/monitor-opentelemetry-exporter";

// provide a connection string
const connectionString = "<connection string>";

const provider = new NodeTracerProvider();
if (connectionString) {
  const exporter = new AzureMonitorTraceExporter({ connectionString });
  provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
}
provider.register();

Per usare la strumentazione per Azure SDK, è necessario registrarla prima di importare eventuali dipendenze da @azure/core-tracing, ad esempio @azure-rest/ai-inference.

import { registerInstrumentations } from "@opentelemetry/instrumentation";
import { createAzureSdkInstrumentation } from "@azure/opentelemetry-instrumentation-azure-sdk";

registerInstrumentations({
  instrumentations: [createAzureSdkInstrumentation()],
});

import ModelClient from "@azure-rest/ai-inference";

Infine, quando si effettua una chiamata per il completamento della chat, è necessario includere

tracingOptions: { tracingContext: context.active() }

Ecco un esempio:

import { context } from "@opentelemetry/api";
client.path("/chat/completions").post({
      body: {...},
      tracingOptions: { tracingContext: context.active() }
});

Traccia delle funzioni personalizzate

Open Telemetry (Apri telemetria) fornisce startActiveSpan per instrumentare il codice. Ecco un esempio:

import { trace } from "@opentelemetry/api";
const tracer = trace.getTracer("sample", "0.1.0");

const getWeatherFunc = (location: string, unit: string): string => {
  return tracer.startActiveSpan("getWeatherFunc", span => {
    if (unit !== "celsius") {
      unit = "fahrenheit";
    }
    const result = `The temperature in ${location} is 72 degrees ${unit}`;
    span.setAttribute("result", result);
    span.end();
    return result;
  });
}

Risoluzione dei problemi

Registrazione

L'abilitazione della registrazione può aiutare a individuare informazioni utili sugli errori. Per visualizzare un log di richieste e risposte HTTP, impostare la variabile di ambiente AZURE_LOG_LEVEL su info. In alternativa, la registrazione può essere abilitata in fase di esecuzione chiamando setLogLevel nel @azure/logger:

const { setLogLevel } = require("@azure/logger");

setLogLevel("info");

Per istruzioni più dettagliate su come abilitare i log, è possibile esaminare la documentazione del pacchetto @azure/logger.