Delen via


Azure AI Projects-clientbibliotheek voor JavaScript - versie 1.0.0-beta.2

Gebruik de AI Projects-clientbibliotheek (in preview) om het volgende te doen:

  • verbindingen opsommen in uw Azure AI Foundry-project en verbindingseigenschappen ophalen. Haal bijvoorbeeld de EINDPUNT-URL en referenties voor deductie op die zijn gekoppeld aan uw Azure OpenAI-verbinding.
  • Agents ontwikkelen met behulp van de Azure AI Agent Service, gebruikmakend van een uitgebreid ecosysteem van modellen, hulpprogramma's en mogelijkheden van OpenAI, Microsoft en andere LLM-providers. De Azure AI Agent Service maakt het bouwen van agents mogelijk voor een breed scala aan generatieve AI-gebruiksvoorbeelden. Het pakket bevindt zich momenteel in de beperkte preview-versie.
  • OpenTelemetry-tracering inschakelen.

productdocumentatie

Inhoudsopgave

Slag

Voorwaarde

  • LTS-versies van Node.js
  • Een Azure-abonnement.
  • Een project in Azure AI Foundry.
  • De verbindingsreeks van het project. U vindt deze op de overzichtspagina van uw Azure AI Foundry-project onder Projectdetails. Hieronder wordt ervan uitgegaan dat de omgevingsvariabele AZURE_AI_PROJECTS_CONNECTION_STRING is gedefinieerd voor deze waarde.
  • Entra-id is nodig om de client te verifiëren. Uw toepassing heeft een object nodig waarmee de interface TokenCredential wordt geïmplementeerd. Codevoorbeelden hier gebruiken DefaultAzureCredential-. Om dat te kunnen doen, hebt u het volgende nodig:
    • De Contributor rol. De toegewezen rol kan worden uitgevoerd via het tabblad Toegangsbeheer (IAM) van uw Azure AI-projectresource in Azure Portal.
    • Azure CLI geïnstalleerd.
    • U bent aangemeld bij uw Azure-account door az loginuit te voeren.
    • Houd er rekening mee dat als u meerdere Azure-abonnementen hebt, het abonnement dat uw Azure AI Project-resource bevat, uw standaardabonnement moet zijn. Voer az account list --output table uit om al uw abonnement weer te geven en te zien welke standaard is. Voer az account set --subscription "Your Subscription ID or Name" uit om uw standaardabonnement te wijzigen.

Het pakket installeren

npm install @azure/ai-projects

Sleutelbegrippen

De client maken en verifiëren

De klassefactorymethode fromConnectionString wordt gebruikt om de client samen te stellen. Een client maken:

import { AIProjectsClient } from "@azure/ai-projects";
import { DefaultAzureCredential } from "@azure/identity";

import "dotenv/config";  

const connectionString = process.env["AZURE_AI_PROJECTS_CONNECTION_STRING"] || "<connectionString>";

const client = AIProjectsClient.fromConnectionString(
  connectionString,
  new DefaultAzureCredential(),
);

Voorbeelden

Verbindingen opsommen

Uw Azure AI Foundry-project heeft een 'Beheercentrum'. Wanneer u het invoert, ziet u een tabblad met de naam Verbonden resources onder uw project. Met de .connections bewerkingen op de client kunt u de verbindingen inventariseren en verbindingseigenschappen ophalen. Verbindingseigenschappen omvatten onder andere de resource-URL en verificatiereferenties.

Hieronder ziet u codevoorbeelden van de verbindingsbewerkingen. Volledige voorbeelden vindt u in de map 'verbindingen' in [pakketvoorbeelden][voorbeelden].

Eigenschappen van alle verbindingen ophalen

De eigenschappen van alle verbindingen in het Azure AI Foundry-project weergeven:

const connections = await client.connections.listConnections();
for (const connection of connections) {
  console.log(connection);
}

Eigenschappen van alle verbindingen van een bepaald type ophalen

De eigenschappen van verbindingen van een bepaald type weergeven (hier Azure OpenAI):

const connections = await client.connections.listConnections({ category: "AzureOpenAI" });
for (const connection of connections) {
  console.log(connection);
}

Eigenschappen van een verbinding ophalen op basis van de naam van de verbinding

De verbindingseigenschappen van een verbinding met de naam connectionNameophalen:

const connection = await client.connections.getConnection("connectionName");
console.log(connection);

De verbindingseigenschappen met de bijbehorende verificatiereferenties ophalen:

const connection = await client.connections.getConnectionWithSecrets("connectionName");
console.log(connection);

Agents (preview)

Agents in de Azure AI Projects-clientbibliotheek zijn ontworpen om verschillende interacties en bewerkingen binnen uw AI-projecten te vergemakkelijken. Ze fungeren als de kernonderdelen die taken beheren en uitvoeren, waarbij gebruik wordt gemaakt van verschillende hulpprogramma's en resources om specifieke doelen te bereiken. De volgende stappen geven een overzicht van de typische volgorde voor interactie met agents. Zie de map Agents in de map [package samples][samples] voor aanvullende agentvoorbeelden.

Agents worden actief ontwikkeld. Binnenkort wordt er een aanmeldingsformulier voor een persoonlijke preview-versie beschikbaar.

Agent maken

Hier volgt een voorbeeld van het maken van een agent:

const agent = await client.agents.createAgent("gpt-4o", {
  name: "my-agent",
  instructions: "You are a helpful assistant",
});

Als u agents toegang wilt geven tot uw resources of aangepaste functies, hebt u hulpprogramma's nodig. U kunt hulpprogramma's doorgeven aan createAgent via de argumenten tools en toolResources.

U kunt ToolSet gebruiken om dit te doen:

const toolSet = new ToolSet();
toolSet.addFileSearchTool([vectorStore.id]);
toolSet.addCodeInterpreterTool([codeInterpreterFile.id]);

// Create agent with tool set
const agent = await client.agents.createAgent("gpt-4o", {
  name: "my-agent",
  instructions: "You are a helpful agent",
  tools: toolSet.toolDefinitions,
  toolResources: toolSet.toolResources,
});
console.log(`Created agent, agent ID: ${agent.id}`);

Als u bestanden wilt zoeken door een agent, moeten we eerst een bestand uploaden, een vectorarchief maken en het bestand koppelen aan het vectorarchief. Hier volgt een voorbeeld:

const localFileStream = fs.createReadStream("sample_file_for_upload.txt");
const file = await client.agents.uploadFile(localFileStream, "assistants", {
  fileName: "sample_file_for_upload.txt",
});
console.log(`Uploaded file, ID: ${file.id}`);

const vectorStore = await client.agents.createVectorStore({
  fileIds: [file.id],
  name: "my_vector_store",
});
console.log(`Created vector store, ID: ${vectorStore.id}`);

const fileSearchTool = ToolUtility.createFileSearchTool([vectorStore.id]);

const agent = await client.agents.createAgent("gpt-4o", {
  name: "SDK Test Agent - Retrieval",
  instructions: "You are helpful agent that can help fetch data from files you know about.",
  tools: [fileSearchTool.definition],
  toolResources: fileSearchTool.resources,
});
console.log(`Created agent, agent ID : ${agent.id}`);

Agent maken met code-interpreter

Hier volgt een voorbeeld om een bestand te uploaden en te gebruiken voor code-interpreter door een agent:

const fileStream = fs.createReadStream("nifty_500_quarterly_results.csv");
const fFile = await client.agents.uploadFile(fileStream, "assistants", {
  fileName: "nifty_500_quarterly_results.csv",
});
console.log(`Uploaded local file, file ID : ${file.id}`);

const codeInterpreterTool = ToolUtility.createCodeInterpreterTool([file.id]);

// Notice that CodeInterpreter must be enabled in the agent creation, otherwise the agent will not be able to see the file attachment
const agent = await client.agents.createAgent("gpt-4o-mini", {
  name: "my-agent",
  instructions: "You are a helpful agent",
  tools: [codeInterpreterTool.definition],
  toolResources: codeInterpreterTool.resources,
});
console.log(`Created agent, agent ID: ${agent.id}`);

Agent maken met Bing Grounding

Als u wilt dat uw agent zoekopdrachten kan uitvoeren via de Bing Search-API, gebruikt u ToolUtility.createConnectionTool() samen met een verbinding.

Hier volgt een voorbeeld:

const bingGroundingConnectionId = "<bingGroundingConnectionId>";
const bingTool = ToolUtility.createConnectionTool(connectionToolType.BingGrounding, [
  bingGroundingConnectionId,
]);

const agent = await client.agents.createAgent("gpt-4-0125-preview", {
  name: "my-agent",
  instructions: "You are a helpful agent",
  tools: [bingTool.definition],
});
console.log(`Created agent, agent ID : ${agent.id}`);

Azure AI Search is een zoeksysteem voor ondernemingen voor hoogwaardige toepassingen. Het is geïntegreerd met Azure OpenAI Service en Azure Machine Learning, met geavanceerde zoektechnologieën zoals vectorzoekopdrachten en zoeken in volledige tekst. Ideaal voor kennisdatabaseinzichten, informatiedetectie en automatisering

Hier volgt een voorbeeld voor het integreren van Azure AI Search:

const cognitiveServicesConnectionName = "<cognitiveServicesConnectionName>";
const cognitiveServicesConnection = await client.connections.getConnection(
  cognitiveServicesConnectionName,
);
const azureAISearchTool = ToolUtility.createAzureAISearchTool(
  cognitiveServicesConnection.id,
  cognitiveServicesConnection.name,
);

// Create agent with the Azure AI search tool
const agent = await client.agents.createAgent("gpt-4-0125-preview", {
  name: "my-agent",
  instructions: "You are a helpful agent",
  tools: [azureAISearchTool.definition],
  toolResources: azureAISearchTool.resources,
});
console.log(`Created agent, agent ID : ${agent.id}`);

Agent maken met functieoproep

U kunt uw agents verbeteren door callbackfuncties als functiehulpprogramma's te definiëren. Deze kunnen worden verstrekt aan createAgent via de combinatie van tools en toolResources. Alleen de functiedefinities en -beschrijvingen worden verstrekt aan createAgent, zonder de implementaties. De Run of event handler of stream krijgt een requires_action status op basis van de functiedefinities. Uw code moet deze status afhandelen en de juiste functies aanroepen.

Hier volgt een voorbeeld:

class FunctionToolExecutor {
  private functionTools: { func: Function, definition: FunctionToolDefinition }[];

  constructor() {
    this.functionTools = [{
      func: this.getUserFavoriteCity,
      ...ToolUtility.createFunctionTool({
        name: "getUserFavoriteCity",
        description: "Gets the user's favorite city.",
        parameters: {}
      })
    }, {
      func: this.getCityNickname,
      ...ToolUtility.createFunctionTool({
        name: "getCityNickname",
        description: "Gets the nickname of a city, e.g. 'LA' for 'Los Angeles, CA'.",
        parameters: { type: "object", properties: { location: { type: "string", description: "The city and state, e.g. Seattle, Wa" } } }
      })
    }, {
      func: this.getWeather,
      ...ToolUtility.createFunctionTool({
        name: "getWeather",
        description: "Gets the weather for a location.",
        parameters: { type: "object", properties: { location: { type: "string", description: "The city and state, e.g. Seattle, Wa" }, unit: { type: "string", enum: ['c', 'f'] } } }
      })
    }];
  }

  private getUserFavoriteCity(): {} {
    return { "location": "Seattle, WA" };
  }

  private getCityNickname(location: string): {} {
    return { "nickname": "The Emerald City" };
  }

  private getWeather(location: string, unit: string): {} {
    return { "weather": unit === "f" ? "72f" : "22c" };
  }

  public invokeTool(toolCall: RequiredToolCallOutput & FunctionToolDefinitionOutput): ToolOutput | undefined {
    console.log(`Function tool call - ${toolCall.function.name}`);
    const args = [];
    if (toolCall.function.parameters) {
      try {
        const params = JSON.parse(toolCall.function.parameters);
        for (const key in params) {
          if (Object.prototype.hasOwnProperty.call(params, key)) {
            args.push(params[key]);
          }
        }
      } catch (error) {
        console.error(`Failed to parse parameters: ${toolCall.function.parameters}`, error);
        return undefined;
      }
    }
    const result = this.functionTools.find((tool) => tool.definition.function.name === toolCall.function.name)?.func(...args);
    return result ? {
      toolCallId: toolCall.id,
      output: JSON.stringify(result)
    } : undefined;
  }

  public getFunctionDefinitions(): FunctionToolDefinition[] {
    return this.functionTools.map(tool => {return tool.definition});
  }
}

const functionToolExecutor = new FunctionToolExecutor();
const functionTools = functionToolExecutor.getFunctionDefinitions();
const agent = await client.agents.createAgent("gpt-4o",
  {
    name: "my-agent",
    instructions: "You are a weather bot. Use the provided functions to help answer questions. Customize your responses to the user's preferences as much as possible and use friendly nicknames for cities whenever possible.",
    tools: functionTools
  });
console.log(`Created agent, agent ID: ${agent.id}`);

Thread maken

Voor elke sessie of gesprek is een thread vereist. Hier volgt een voorbeeld:

const thread = await client.agents.createThread();

Thread maken met toolresource

In sommige scenario's moet u mogelijk specifieke resources toewijzen aan afzonderlijke threads. Hiervoor geeft u het argument toolResources op voor createThread. In het volgende voorbeeld maakt u een vectorarchief en uploadt u een bestand, schakelt u een agent in voor het zoeken naar bestanden met behulp van het argument tools en koppelt u het bestand aan de thread met behulp van het argument toolResources.

const localFileStream = fs.createReadStream("sample_file_for_upload.txt");
const file = await client.agents.uploadFile(localFileStream, "assistants", {
  fileName: "sample_file_for_upload.txt",
});
console.log(`Uploaded file, ID: ${file.id}`);

const vectorStore = await client.agents.createVectorStore({
  fileIds: [file.id],
  name: "my_vector_store",
});
console.log(`Created vector store, ID: ${vectorStore.id}`);

const fileSearchTool = ToolUtility.createFileSearchTool([vectorStore.id]);

const agent = await client.agents.createAgent("gpt-4o", {
  name: "SDK Test Agent - Retrieval",
  instructions: "You are helpful agent that can help fetch data from files you know about.",
  tools: [fileSearchTool.definition],
});
console.log(`Created agent, agent ID : ${agent.id}`);

// Create thread with file resources.
// If the agent has multiple threads, only this thread can search this file.
const thread = await client.agents.createThread({ toolResources: fileSearchTool.resources });

Bericht maken

Als u een bericht wilt maken dat assistent moet verwerken, geeft u user door als role en een vraag als content:

const message = await client.agents.createMessage(thread.id, {
  role: "user",
  content: "hello, world!",
});

Bericht maken met bestandszoekbijlage

Als u een bestand wilt toevoegen aan een bericht voor het zoeken naar inhoud, gebruikt u ToolUtility.createFileSearchTool() en het argument attachments:

const fileSearchTool = ToolUtility.createFileSearchTool();
const message = await client.agents.createMessage(thread.id, {
  role: "user",
  content: "What feature does Smart Eyewear offer?",
  attachments: {
    fileId: file.id,
    tools: [fileSearchTool.definition],
  },
});

Bericht maken met code-interpreterbijlage

Als u een bestand wilt toevoegen aan een bericht voor gegevensanalyse, gebruikt u ToolUtility.createCodeInterpreterTool() en het argument attachment.

Hier volgt een voorbeeld:

// notice that CodeInterpreter must be enabled in the agent creation,
// otherwise the agent will not be able to see the file attachment for code interpretation
const codeInterpreterTool = ToolUtility.createCodeInterpreterTool();
const agent = await client.agents.createAgent("gpt-4-1106-preview", {
  name: "my-assistant",
  instructions: "You are helpful assistant",
  tools: [codeInterpreterTool.definition],
});
console.log(`Created agent, agent ID: ${agent.id}`);

const thread = client.agents.createThread();
console.log(`Created thread, thread ID: ${thread.id}`);

const message = await client.agents.createMessage(thread.id, {
  role: "user",
  content:
    "Could you please create bar chart in TRANSPORTATION sector for the operating profit from the uploaded csv file and provide file to me?",
  attachments: {
    fileId: file.id,
    tools: [codeInterpreterTool.definition],
  },
});
console.log(`Created message, message ID: ${message.id}`);

Uitvoeren, Run_and_Process of Stream maken

Hier volgt een voorbeeld van createRun en poll totdat de uitvoering is voltooid:

let run = await client.agents.createRun(thread.id, agent.id);

// Poll the run as long as run status is queued or in progress
while (
  run.status === "queued" ||
  run.status === "in_progress" ||
  run.status === "requires_action"
) {
  // Wait for a second
  await new Promise((resolve) => setTimeout(resolve, 1000));
  run = await client.agents.getRun(thread.id, run.id);
}

Gebruik de createThreadAndRun methode om de SDK namens u te laten peilen.

Hier volgt een voorbeeld:

const run = await client.agents.createThreadAndRun(thread.id, agent.id);

Bij streaming hoeft polling ook niet te worden overwogen.

Hier volgt een voorbeeld:

const streamEventMessages = await client.agents.createRun(thread.id, agent.id).stream();

Gebeurtenisafhandeling kan als volgt worden uitgevoerd:

for await (const eventMessage of streamEventMessages) {
switch (eventMessage.event) {
  case RunStreamEvent.ThreadRunCreated:
    console.log(`ThreadRun status: ${(eventMessage.data as ThreadRunOutput).status}`)
    break;
  case MessageStreamEvent.ThreadMessageDelta:
    {
      const messageDelta = eventMessage.data as MessageDeltaChunk;
      messageDelta.delta.content.forEach((contentPart) => {
        if (contentPart.type === "text") {
          const textContent = contentPart as MessageDeltaTextContent
          const textValue = textContent.text?.value || "No text"
          console.log(`Text delta received:: ${textValue}`)
        }
      });
    }
    break;

  case RunStreamEvent.ThreadRunCompleted:
    console.log("Thread Run Completed");
    break;
  case ErrorEvent.Error:
    console.log(`An error occurred. Data ${eventMessage.data}`);
    break;
  case DoneEvent.Done:
    console.log("Stream completed.");
    break;
  }
}

Bericht ophalen

Gebruik het volgende voorbeeld om berichten van agents op te halen:

const messages = await client.agents.listMessages(thread.id);

// The messages are following in the reverse order,
// we will iterate them and output only text contents.
for (const dataPoint of messages.data.reverse()) {
    const lastMessageContent: MessageContentOutput = dataPoint.content[dataPoint.content.length - 1];
    console.log( lastMessageContent);
    if (isOutputOfType<MessageTextContentOutput>(lastMessageContent, "text")) {
      console.log(`${dataPoint.role}: ${(lastMessageContent as MessageTextContentOutput).text.value}`);
    }
  }

Bestand ophalen

Bestanden die door agents zijn geüpload, kunnen niet worden teruggehaald. Als uw use-case toegang nodig heeft tot de bestandsinhoud die door de agents is geüpload, wordt u aangeraden een extra kopie toegankelijk te houden voor uw toepassing. Bestanden die door agents worden gegenereerd, kunnen echter worden opgehaald door getFileContent.

Hier volgt een voorbeeld van het ophalen van bestands-id's uit berichten:

const messages = await client.agents.listMessages(thread.id);
const imageFile = (messages.data[0].content[0] as MessageImageFileContentOutput).imageFile;
const imageFileName = (await client.agents.getFile(imageFile.fileId)).filename;

const fileContent = await (await client.agents.getFileContent(imageFile.fileId).asNodeStream()).body;
if (fileContent) {
  const chunks: Buffer[] = [];
  for await (const chunk of fileContent) {
    chunks.push(Buffer.from(chunk));
  }
  const buffer = Buffer.concat(chunks);
  fs.writeFileSync(imageFileName, buffer);
} else {
  console.error("Failed to retrieve file content: fileContent is undefined");
}
console.log(`Saved image file to: ${imageFileName}`);

Teardown

Als u resources wilt verwijderen nadat u taken hebt voltooid, gebruikt u de volgende functies:

await client.agents.deleteVectorStore(vectorStore.id);
console.log(`Deleted vector store, vector store ID: ${vectorStore.id}`);

await client.agents.deleteFile(file.id);
console.log(`Deleted file, file ID: ${file.id}`);

client.agents.deleteAgent(agent.id);
console.log(`Deleted agent, agent ID: ${agent.id}`);

Tracering

U kunt een Application Insights Azure-resource toevoegen aan uw Azure AI Foundry-project. Zie het tabblad Tracering in uw studio. Als er een is ingeschakeld, kunt u de Application Insights-verbindingsreeks ophalen, uw agents configureren en het volledige uitvoeringspad bekijken via Azure Monitor. Normaal gesproken wilt u tracering starten voordat u een agent maakt.

Installatie

Zorg ervoor dat u OpenTelemetry en de Azure SDK-traceringsinvoegtoepassing installeert via

npm install @opentelemetry/api \
  @opentelemetry/instrumentation \
  @opentelemetry/sdk-trace-node \
  @azure/opentelemetry-instrumentation-azure-sdk \
  @azure/monitor-opentelemetry-exporter

U hebt ook een exporteur nodig om telemetrie te verzenden naar uw back-end voor waarneembaarheid. U kunt traceringen afdrukken naar de console of een lokale viewer zoals Aspire Dashboardgebruiken.

Installeer OTLP-exporteur om verbinding te maken met Aspire Dashboard of een andere openTelemetry-compatibele back-end:

npm install @opentelemetry/exporter-trace-otlp-proto \
  @opentelemetry/exporter-metrics-otlp-proto

Voorbeeld van tracering

Hier volgt een codevoorbeeld dat hierboven moet worden opgenomen createAgent:

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

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

const tracer = trace.getTracer("Agents Sample", "1.0.0");

const client = AIProjectsClient.fromConnectionString(
  connectionString || "", new DefaultAzureCredential()
);

if (!appInsightsConnectionString) {
  appInsightsConnectionString = await client.telemetry.getConnectionString();
}

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

await tracer.startActiveSpan("main", async (span) => {
    client.telemetry.updateSettings({enableContentRecording: true})
// ...

Probleemoplossing

Uitzonderingen

Clientmethoden waarmee serviceaanroepen worden uitgevoerd, genereren een RestError- voor een niet-geslaagd HTTP-statuscodeantwoord van de service. De code van de uitzondering bevat de HTTP-antwoordstatuscode. De error.message van de uitzondering bevat een gedetailleerd bericht dat nuttig kan zijn bij het diagnosticeren van het probleem:

import { RestError } from "@azure/core-rest-pipeline"

// ...

try {
  const result = await client.connections.listConnections();
} catch (e as RestError) {
  console.log(`Status code: ${e.code}`);
  console.log(e.message);
}

Als u bijvoorbeeld onjuiste referenties opgeeft:

Status code: 401 (Unauthorized)
Operation returned an invalid status 'Unauthorized'

Problemen melden

Als u problemen met de clientbibliotheek wilt melden of aanvullende functies wilt aanvragen, opent u hier een GitHub-probleem

Bijdragen

Dit project verwelkomt bijdragen en suggesties. Voor de meeste bijdragen moet u akkoord gaan met een Licentieovereenkomst voor inzenders (CLA) waarin wordt aangegeven dat u het recht hebt om, en daadwerkelijk, ons de rechten te verlenen om uw bijdrage te gebruiken. Ga naar https://cla.microsoft.comvoor meer informatie.

Wanneer u een pull-aanvraag indient, bepaalt een CLA-bot automatisch of u een CLA moet opgeven en de pull-aanvraag op de juiste wijze moet inrichten (bijvoorbeeld label, opmerking). Volg gewoon de instructies van de bot. U hoeft dit slechts eenmaal te doen voor alle opslagplaatsen met behulp van onze CLA.

Dit project heeft de Microsoft Open Source-gedragscodeaangenomen. Zie de veelgestelde vragen over gedragscodes voor meer informatie of neem contact op met opencode@microsoft.com met eventuele aanvullende vragen of opmerkingen.