次の方法で共有


JavaScript 用 Azure 推論 REST クライアント ライブラリ - バージョン 1.0.0-beta.6

Azure でサポートされている AI モデルの推論 API

このライブラリを使用するには、REST クライアント ドキュメント に大きく依存してください

主要なリンク:

はじめ

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

const client = 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);

現在サポートされている環境

  • Node.js の LTS バージョン

前提 条件

@azure-rest/ai-inference パッケージをインストールする

npmを使用して JavaScript 用の Azure Inference REST クライアント ライブラリをインストールします。

npm install @azure-rest/ai-inference

推論クライアントを作成して認証する

Azure からの API キーの使用

Azure Core 認証ライブラリを使用して、Azure API キーを使用して認証できます。 次に示す AzureKeyCredential プロバイダーを使用するには、@azure/core-auth パッケージをインストールしてください。

npm install @azure/core-auth

Azure Portal を使用して、モデル デプロイを参照し、API キーを取得します。

注: API キーが "サブスクリプション キー" または "サブスクリプション API キー" と呼ばれる場合があります。

API キーとエンドポイントを取得したら、AzureKeyCredential クラスを使用して、次のようにクライアントを認証できます。

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

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

Azure Active Directory 資格情報の使用

Azure Id ライブラリを使用して、Azure Active Directory で認証することもできます。 以下に示す DefaultAzureCredential プロバイダー、または Azure SDK で提供されているその他の資格情報プロバイダーを使用するには、@azure/identity パッケージをインストールしてください。

npm install @azure/identity

AAD アプリケーションのクライアント ID、テナント ID、クライアント シークレットの値を環境変数 (AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_CLIENT_SECRET) として設定します。

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

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

主な概念

理解する主な概念は、完了です。 簡単に説明すると、入力候補はテキスト プロンプトの形式で機能を提供します。これは、特定の モデルを使用して、コンテキストとパターンの照合を試み、出力テキストを提供します。 次のコード スニペットは、概要を示しています。

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

const client = 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);

チャットボットの応答を生成する

Inference SDK を使用したストリーミング チャットには、コア ストリーミング サポートが必要です。このサポートを有効にするには、@azure/core-sse パッケージをインストールしてください。

npm install @azure/core-sse

この例では、DefaultAzureCredential を使用して認証を行い、入力チャットの質問とメッセージに対するチャット応答を生成します。

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

const endpoint = "https://myaccount.openai.azure.com/";
const client = 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");
}

const sses = createSseStream(stream as IncomingMessage);

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 ?? "");
  }
}

サブスクリプション キーを使用して複数の入力候補を生成する

この例では、Azure サブスクリプション キーを使用して入力プロンプトに対するテキスト応答を生成します

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

// Replace with your Model API key
const key = "YOUR_MODEL_API_KEY";
const endpoint = "https://your-model-endpoint/";
const client = 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 (isUnexpected(response)) {
  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}`);
}

入力候補を含むテキストの集計

次の使用例は、指定された入力プロンプトの概要を生成します。

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

const endpoint = "https://myaccount.openai.azure.com/";
const client = 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 (isUnexpected(response)) {
  throw response.body.error;
}
const completion = response.body.choices[0].message.content;
console.log(`Summarization: ${completion}`);

チャット ツールを使用する

Tools、アシスタントがチャット完了要求を満たすプロセスで定義済みの関数やその他の機能を呼び出せるようにすることで、チャットの完了を拡張できます。 チャット ツールを使用するには、まず getCurrentWeatherという名前の関数ツールを定義します。 ツールを定義した状態で、チャット完了要求のオプションにその新しい定義を含めます。

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

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

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"],
  },
};

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

アシスタントが 1 つ以上のツールを使用する必要があると判断した場合、応答メッセージには 1 つ以上の "ツール呼び出し" が含まれます。このメッセージはすべて、後続の要求で "ツール メッセージ" を介して解決する必要があります。 この新しい要求メッセージへのツール呼び出しの解決は、チャット完了の一種の "コールバック" と考えることができます。

// 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}`);
}

要求の続行を許可するツール呼び出し解決をアシスタントに提供するには、以前のすべての履歴コンテキスト (元のシステムメッセージとユーザー メッセージ、ツール呼び出しを含むアシスタントからの応答、それらの各ツールを解決したツール メッセージなど) を、後続の要求を行うときに提供します。

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

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

// From previous snippets
const messages = [{ role: "user", content: "What is the weather like in Boston?" }];

function applyToolCall({ function: call, id }) {
  // from previous snippet
}

// Handle result from previous snippet
async function handleResponse(result) {
  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
    }
  }
}

画像とのチャット (gpt-4o などのイメージ チャットをサポートするモデルを使用)

一部の Azure モデルでは、チャットの完了に画像を入力コンポーネントとして使用できます。

これを行うには、チャット完了要求のユーザー メッセージに個別のコンテンツ 項目を指定します。 チャットの完了は通常どおりに進みますが、モデルは finish_reasonの代わりにより有益な finish_details を報告する可能性があります。

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

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

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" },
];

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

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

テキスト埋め込みの例

この例では、Entra ID 認証を使用してテキスト埋め込みを取得する方法を示します。

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

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

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.embedding.length}, [${data[0]}, ${data[1]}, ..., ${data[data.embedding.length - 2]}, ${data[data.embedding.length - 1]}]`,
  );
}

埋め込みベクターの長さはモデルによって異なりますが、次のようになります。

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]

追加のフレーズの埋め込みを生成するには、同じ client.path("/embeddings").postを使用して client を複数回呼び出すだけです。

Image Embeddings の例

この例では、Entra ID 認証を使用して画像の埋め込みを取得する方法を示します。

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

const endpoint = "https://myaccount.openai.azure.com/";
const credential = new DefaultAzureCredential();

function getImageDataUrl(imageFile, imageFormat) {
  try {
    const imageBuffer = readFileSync(imageFile);
    const imageBase64 = imageBuffer.toString("base64");
    return `data:image/${imageFormat};base64,${imageBase64}`;
  } catch (error) {
    console.error(`Could not read '${imageFile}'.`);
    console.error("Set the correct path to the image file before running this sample.");
    process.exit(1);
  }
}

const client = ModelClient(endpoint, credential);
const image = getImageDataUrl("<image_file>", "<image_format>");
const response = await client.path("/images/embeddings").post({
  body: {
    input: [{ image }],
  },
});

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

埋め込みベクターの長さはモデルによって異なりますが、次のようになります。

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]

計装

現在、インストルメンテーションは Chat Completion without streamingでのみサポートされています。 インストルメンテーションを有効にするには、エクスポーターを登録する必要があります。

コンソールをエクスポーターとして追加する例を次に示します。

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

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

アプリケーションの分析情報をエクスポーターとして追加する例を次に示します。

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();

Azure SDK のインストルメンテーションを使用するには、@azure/core-tracingなど、@azure-rest/ai-inferenceから依存関係をインポートする前に登録する必要があります。

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

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

最後に、チャット完了の呼び出しを行うときは、要求に tracingOptions を含める必要があります。 次に例を示します:

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

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

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?" },
];

client.path("/chat/completions").post({
  body: {
    messages,
  },
  tracingOptions: { tracingContext: context.active() },
});

独自の関数のトレース

Open Telemetry には、独自のコードをインストルメント化するための startActiveSpan が用意されています。 次に例を示します:

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;
  });
};

トラブルシューティング

伐採

ログ記録を有効にすると、エラーに関する有用な情報を明らかにするのに役立つ場合があります。 HTTP 要求と応答のログを表示するには、AZURE_LOG_LEVEL 環境変数を infoに設定します。 または、setLogLevel@azure/logger を呼び出すことによって、実行時にログを有効にすることもできます。

import { setLogLevel } from "@azure/logger";

setLogLevel("info");

ログを有効にする方法の詳細な手順については、@azure/logger パッケージのドキュメントを参照してください。