Клиентская библиотека Проектов ИИ Azure для JavaScript версии 1.0.0-beta.2
Использование клиентской библиотеки проектов ИИ (в предварительной версии) для:
- Перечисление подключений в проекте Azure AI Foundry и получение свойств подключения. Например, получите URL-адрес конечной точки вывода и учетные данные, связанные с подключением Azure OpenAI.
- Разработка агентов с помощью службы агента ИИ Azure, используя обширную экосистему моделей, инструментов и возможностей openAI, Майкрософт и других поставщиков LLM. Служба агента ИИ Azure позволяет создавать агенты для широкого спектра вариантов использования сгенерируемым ИИ. Пакет в настоящее время находится в закрытой предварительной версии.
- Включить трассировку OpenTelemetry.
документации по продукту
Оглавление
- начало работы
- основные понятия
-
примеры
- Перечисление подключений
- агентов
(предварительная версия) - создание агента с помощью:
-
создание потока с помощью
- ресурса средства
- ресурса средства
-
Создание сообщения с помощью:
- вложения поиска файлов
- вложение интерпретатора кода
- выполнение, создание потока и запуска или потоковая
- получение сообщения
- получение файла
- Удаление ресурса
- трассировки
-
трассировки
- установка
- Пример трассировки
-
устранение неполадок
- исключений
- проблемы с отчетами
- исключений
- участие
Начало работы
Предпосылка
- версии LTS Node.js
- подписка Azure.
- Проект в Azure AI Foundry.
- Строка подключения проекта. Его можно найти на странице обзора проекта Azure AI Foundry в разделе "Сведения о проекте". Ниже предполагается, что переменная среды
AZURE_AI_PROJECTS_CONNECTION_STRING
определена для хранения этого значения. - Идентификатор записи необходим для проверки подлинности клиента. Приложению требуется объект, реализующий интерфейс TokenCredential. Примеры кода здесь используют DefaultAzureCredential. Чтобы получить эту работу, вам потребуется:
- Роль
Contributor
. На портале Azure можно назначить роль с помощью вкладки "Управление доступом (IAM)" ресурса проекта Azure AI. - установленной Azure CLI.
- Вы вошли в учетную запись Azure, выполнив
az login
. - Обратите внимание, что если у вас несколько подписок Azure, подписка, содержащая ресурс Проекта Azure AI, должна быть вашей подпиской по умолчанию. Запустите
az account list --output table
, чтобы вывести список всех подписок и увидеть, какой из них используется по умолчанию. Запуститеaz account set --subscription "Your Subscription ID or Name"
, чтобы изменить подписку по умолчанию.
- Роль
Установка пакета
npm install @azure/ai-projects
Основные понятия
Создание и проверка подлинности клиента
Метод фабрики классов fromConnectionString
используется для создания клиента. Чтобы создать клиент, выполните приведенные действия.
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(),
);
Примеры
Перечисление подключений
Проект Azure AI Foundry имеет центр управления. При вводе в проект появится вкладка с именем "Подключенные ресурсы". Операции .connections
на клиенте позволяют перечислять подключения и получать свойства подключения. Свойства подключения включают URL-адрес ресурса и учетные данные проверки подлинности, помимо прочего.
Ниже приведены примеры кода операций подключения. Полные примеры можно найти в папке "подключения" в [примерах пакетов][примеры].
Получение свойств всех подключений
Чтобы получить список свойств всех подключений в проекте Azure AI Foundry:
const connections = await client.connections.listConnections();
for (const connection of connections) {
console.log(connection);
}
Получение свойств всех подключений определенного типа
Список свойств подключений определенного типа (здесь Azure OpenAI):
const connections = await client.connections.listConnections({ category: "AzureOpenAI" });
for (const connection of connections) {
console.log(connection);
}
Получение свойств подключения по имени подключения
Чтобы получить свойства подключения с именем connectionName
:
const connection = await client.connections.getConnection("connectionName");
console.log(connection);
Чтобы получить свойства подключения с учетными данными проверки подлинности, выполните следующие действия.
const connection = await client.connections.getConnectionWithSecrets("connectionName");
console.log(connection);
Агенты (предварительная версия)
Агенты в клиентской библиотеке проектов ИИ Azure предназначены для упрощения различных взаимодействий и операций в проектах ИИ. Они служат основными компонентами, которые управляют и выполняют задачи, используя различные средства и ресурсы для достижения конкретных целей. Ниже описана типичная последовательность взаимодействия с агентами. Дополнительные примеры агента см. в папке "Агенты" в [примерах пакетов][примеры].
Агенты активно разрабатываются. В ближайшее время появится форма регистрации для частной предварительной версии.
Создание агента
Ниже приведен пример создания агента:
const agent = await client.agents.createAgent("gpt-4o", {
name: "my-agent",
instructions: "You are a helpful assistant",
});
Чтобы разрешить агентам доступ к ресурсам или пользовательским функциям, вам потребуются средства. Средства можно передать в createAgent
через аргументы tools
и toolResources
.
Для этого можно использовать ToolSet
:
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}`);
Создание агента с помощью поиска файлов
Чтобы выполнить поиск по файлам агентом, сначала необходимо отправить файл, создать векторное хранилище и связать файл с векторным хранилищем. Ниже приведен пример:
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}`);
Создание агента с интерпретатором кода
Ниже приведен пример отправки файла и его использования для интерпретатора кода агентом:
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}`);
Создание агента с помощью Bing Grounding
Чтобы разрешить агенту выполнять поиск через API поиска Bing, вы используете ToolUtility.createConnectionTool()
вместе с подключением.
Ниже приведен пример:
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
Поиск ИИ Azure — это корпоративная система поиска для высокопроизводительных приложений. Он интегрируется со службой Azure OpenAI и Машинным обучением Azure, предлагая расширенные технологии поиска, такие как векторный поиск и полнотекстовый поиск. Идеально подходит для аналитики базы знаний, обнаружения информации и автоматизации
Ниже приведен пример интеграции службы "Поиск ИИ Azure":
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}`);
Создание агента с вызовом функции
Вы можете улучшить агенты, определив функции обратного вызова в качестве инструментов функции. Их можно предоставить для createAgent
с помощью сочетания tools
и toolResources
. Только определения и описания функций предоставляются для createAgent
без реализации.
Run
или event handler of stream
вызовет состояние requires_action
на основе определений функций. Код должен обрабатывать это состояние и вызывать соответствующие функции.
Ниже приведен пример:
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}`);
Создание потока
Для каждого сеанса или беседы требуется поток. Ниже приведен пример:
const thread = await client.agents.createThread();
Создание потока с помощью ресурса средства
В некоторых сценариях может потребоваться назначить определенные ресурсы отдельным потокам. Для этого укажите аргумент toolResources
для createThread
. В следующем примере вы создадите векторное хранилище и отправьте файл, включите агент для поиска файлов с помощью аргумента tools
, а затем свяжите файл с потоком с помощью аргумента 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 });
Создание сообщения
Чтобы создать сообщение для помощника по обработке, передайте user
как role
и вопрос в виде content
:
const message = await client.agents.createMessage(thread.id, {
role: "user",
content: "hello, world!",
});
Создание сообщения с вложением поиска файлов
Чтобы вложить файл в сообщение для поиска содержимого, используйте ToolUtility.createFileSearchTool()
и аргумент 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],
},
});
Создание сообщения с вложением интерпретатора кода
Чтобы подключить файл к сообщению для анализа данных, используйте ToolUtility.createCodeInterpreterTool()
и аргумент attachment
.
Ниже приведен пример:
// 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}`);
Создание запуска, Run_and_Process или stream
Ниже приведен пример createRun
и опроса до завершения выполнения:
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);
}
Чтобы провести опрос пакета SDK от вашего имени, используйте метод createThreadAndRun
.
Ниже приведен пример:
const run = await client.agents.createThreadAndRun(thread.id, agent.id);
При потоковой передаче опросы также не должны рассматриваться.
Ниже приведен пример:
const streamEventMessages = await client.agents.createRun(thread.id, agent.id).stream();
Обработку событий можно выполнить следующим образом:
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;
}
}
Получение сообщения
Чтобы получить сообщения от агентов, используйте следующий пример:
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}`);
}
}
Получение файла
Файлы, отправленные агентами, не могут быть извлечены обратно. Если ваш вариант использования должен получить доступ к содержимому файла, отправленного агентами, рекомендуется сохранить дополнительную копию, доступную приложению. Однако файлы, созданные агентами, извлекаются getFileContent
.
Ниже приведен пример получения идентификаторов файлов из сообщений:
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}`);
Слеза
Чтобы удалить ресурсы после выполнения задач, используйте следующие функции:
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}`);
Калька
Вы можете добавить ресурс Application Insights Azure в проект Azure AI Foundry. Перейдите на вкладку "Трассировка" в студии. Если он включен, вы можете получить строку подключения Application Insights, настроить агенты и просмотреть полный путь выполнения с помощью Azure Monitor. Как правило, перед созданием агента может потребоваться начать трассировку.
Установка
Обязательно установите OpenTelemetry и подключаемый модуль трассировки пакета SDK Azure с помощью
npm install @opentelemetry/api \
@opentelemetry/instrumentation \
@opentelemetry/sdk-trace-node \
@azure/opentelemetry-instrumentation-azure-sdk \
@azure/monitor-opentelemetry-exporter
Вам также потребуется экспортер для отправки телеметрии в серверную часть наблюдаемости. Трассировки можно распечатать в консоли или использовать локальное средство просмотра, например панели мониторинга Aspire.
Чтобы подключиться к панели мониторинга Aspire или другой серверной части, совместимой с OpenTelemetry, установите экспортер OTLP:
npm install @opentelemetry/exporter-trace-otlp-proto \
@opentelemetry/exporter-metrics-otlp-proto
Пример трассировки
Ниже приведен пример кода для включения выше 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})
// ...
Устранение неполадок
Исключения
Клиентские методы, которые вызывают службы, вызывают RestError для ответа кода состояния HTTP без успешного выполнения из службы.
code
исключения будет содержать код состояния HTTP-ответа.
error.message
исключения содержит подробное сообщение, которое может оказаться полезным при диагностике проблемы:
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);
}
Например, если указать неправильные учетные данные:
Status code: 401 (Unauthorized)
Operation returned an invalid status 'Unauthorized'
Проблемы с отчетами
Чтобы сообщить о проблемах с клиентской библиотекой или запросить дополнительные функции, откройте проблему GitHub здесь
Способствует
Этот проект приветствует взносы и предложения. Большинство вкладов требуют, чтобы вы согласились с соглашением о лицензии участника (CLA), заявив, что у вас есть право, и на самом деле, предоставьте нам права на использование вашего вклада. Дополнительные сведения см. в https://cla.microsoft.com.
При отправке запроса на вытягивание бот CLA автоматически определяет, нужно ли предоставить соглашение об уровне обслуживания и украсить pr соответствующим образом (например, метка, комментарий). Просто следуйте инструкциям, предоставленным ботом. Это необходимо сделать только один раз во всех репозиториях с помощью нашего CLA.
Этот проект принял Microsoft Open Source Code of Conduct. Дополнительные сведения см. в разделе "Часто задаваемые вопросы о поведении" или opencode@microsoft.com с дополнительными вопросами или комментариями.
Azure SDK for JavaScript