Compartir a través de


Biblioteca cliente de Azure AI Agents para JavaScript: versión 1.0.0

Utilice la biblioteca cliente de AI Agents para:

  • Desarrollar agentes mediante azure AI Agent Service, aprovechando un amplio ecosistema de modelos, herramientas y funcionalidades de OpenAI, Microsoft y otros proveedores de LLM. El servicio agente de Azure AI permite la creación de agentes para una amplia gama de casos de uso de IA generativas.
  • Nota: Aunque este paquete se puede usar de forma independiente, se recomienda usar la biblioteca cliente de Azure AI Projects para una experiencia mejorada. La biblioteca de proyectos proporciona acceso simplificado a funciones avanzadas, como la creación y administración de agentes, la enumeración de modelos de IA, el trabajo con conjuntos de datos y la administración de índices de búsqueda, la evaluación del rendimiento de la IA generativa y la habilitación del seguimiento de OpenTelemetry.

Documentación del | productoMuestras | Paquete (npm) | Documentación de referencia de la API

Tabla de contenido

Cómo empezar

Prerrequisito

Autorización

  • Se necesita el ID de Entra para autenticar al cliente. La aplicación necesita un objeto que implemente la interfaz TokenCredential. Los ejemplos de código aquí usan DefaultAzureCredential. Para que funcione, necesitará lo siguiente:
    • Rol de Contributor. El rol asignado se puede realizar a través de la pestaña "Control de acceso (IAM)" del recurso del proyecto de Azure AI en Azure Portal. Obtenga más información sobre las asignaciones de roles aquí.
    • de la CLI de Azure instalada.
    • Ha iniciado sesión en su cuenta de Azure mediante la ejecución de az login.
    • Tenga en cuenta que si tiene varias suscripciones de Azure, la suscripción que contiene el recurso de Proyecto de Azure AI debe ser la suscripción predeterminada. Ejecute az account list --output table para enumerar toda la suscripción y ver cuál es el valor predeterminado. Ejecute az account set --subscription "Your Subscription ID or Name" para cambiar la suscripción predeterminada.

Instalación del paquete

npm install @azure/ai-agents @azure/identity

Conceptos clave

Creación y autenticación del cliente

Se AgentsClient utiliza para construir el cliente. Actualmente, se recomienda usar AgentsClient a través de la biblioteca cliente de client.agents .

Para obtener el punto de conexión del proyecto, puede consultar la documentación. A continuación, asumiremos que la variable PROJECT_ENDPOINT de entorno tiene este valor.

import { AgentsClient } from "@azure/ai-agents";
import { DefaultAzureCredential } from "@azure/identity";

const projectEndpoint = process.env["PROJECT_ENDPOINT"] || "<project endpoint>";
const modelDeploymentName = process.env["MODEL_DEPLOYMENT_NAME"] || "gpt-4o";
const client = new AgentsClient(projectEndpoint, new DefaultAzureCredential());

Ejemplos

Agentes

Los agentes de la biblioteca cliente de proyectos de Azure AI están diseñados para facilitar diversas interacciones y operaciones dentro de los proyectos de IA. Sirven como componentes principales que administran y ejecutan tareas, aprovechando diferentes herramientas y recursos para lograr objetivos específicos. En los pasos siguientes se describe la secuencia típica para interactuar con agentes. Consulte los ejemplos de paquetes para obtener muestras adicionales de agentes.

Crear agente

Este es un ejemplo de cómo crear un agente:

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

Para permitir que los agentes accedan a los recursos o a las funciones personalizadas, necesita herramientas. Puede pasar herramientas para createAgent a través de los argumentos tools y toolResources.

Puede usar ToolSet para hacerlo:

import { ToolSet } from "@azure/ai-agents";

// Upload file for code interpreter tool
const filePath1 = "./data/syntheticCompanyQuarterlyResults.csv";
const fileStream1 = fs.createReadStream(filePath1);
const codeInterpreterFile = await client.files.upload(fileStream1, "assistants", {
  fileName: "myLocalFile",
});
console.log(`Uploaded local file, file ID : ${codeInterpreterFile.id}`);
// Upload file for file search tool
const filePath2 = "./data/sampleFileForUpload.txt";
const fileStream2 = fs.createReadStream(filePath2);
const fileSearchFile = await client.files.upload(fileStream2, "assistants", {
  fileName: "sampleFileForUpload.txt",
});
console.log(`Uploaded file, file ID: ${fileSearchFile.id}`);
// Create vector store for file search tool
const vectorStore = await client.vectorStores
  .createAndPoll({
    fileIds: [fileSearchFile.id],
  })
  .pollUntilDone();
// Create tool set
const toolSet = new ToolSet();
toolSet.addFileSearchTool([vectorStore.id]);
toolSet.addCodeInterpreterTool([codeInterpreterFile.id]);

// Create agent with tool set
const agent = await client.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}`);

Para realizar la búsqueda de archivos mediante un agente, primero es necesario cargar un archivo, crear un almacén de vectores y asociar el archivo al almacén de vectores. Este es un ejemplo:

import { ToolUtility } from "@azure/ai-agents";

const filePath = "./data/sampleFileForUpload.txt";
const localFileStream = fs.createReadStream(filePath);
const file = await client.files.upload(localFileStream, "assistants", {
  fileName: "sampleFileForUpload.txt",
});
console.log(`Uploaded file, file ID: ${file.id}`);

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

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

const agent = await client.createAgent("gpt-4o", {
  name: "File Search Agent",
  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}`);

Creación de agente con el intérprete de código

Este es un ejemplo para cargar un archivo y usarlo para el intérprete de código por un agente:

import { ToolUtility } from "@azure/ai-agents";

const filePath = "./data/syntheticCompanyQuarterlyResults.csv";
const localFileStream = fs.createReadStream(filePath);
const localFile = await client.files.upload(localFileStream, "assistants", {
  fileName: "localFile",
});

console.log(`Uploaded local file, file ID : ${localFile.id}`);

const codeInterpreterTool = ToolUtility.createCodeInterpreterTool([localFile.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.createAgent("gpt-4o", {
  name: "my-agent",
  instructions: "You are a helpful agent",
  tools: [codeInterpreterTool.definition],
  toolResources: codeInterpreterTool.resources,
});
console.log(`Created agent, agent ID: ${agent.id}`);

Creación de un agente con Bing Grounding

Para permitir que el agente realice búsquedas a través de Bing Search API, use ToolUtility.createBingGroundingTool() junto con una conexión. Consulte aquí para obtener más información sobre la conexión a tierra con Bing Search.

Este es un ejemplo:

import { ToolUtility } from "@azure/ai-agents";

const connectionId = process.env["AZURE_BING_CONNECTION_ID"] || "<connection-name>";

// Initialize agent bing tool with the connection id
const bingTool = ToolUtility.createBingGroundingTool([{ connectionId: connectionId }]);

// Create agent with the bing tool and process assistant run
const agent = await client.createAgent("gpt-4o", {
  name: "my-agent",
  instructions: "You are a helpful agent",
  tools: [bingTool.definition],
});
console.log(`Created agent, agent ID : ${agent.id}`);

Azure AI Search es un sistema de búsqueda empresarial para aplicaciones de alto rendimiento. Se integra con Azure OpenAI Service y Azure Machine Learning, que ofrece tecnologías de búsqueda avanzadas, como la búsqueda de vectores y la búsqueda de texto completo. Ideal para la información de la base de conocimiento, la detección de información y la automatización

Este es un ejemplo para integrar Azure AI Search:

import { ToolUtility } from "@azure/ai-agents";

const connectionName = process.env["AZURE_AI_SEARCH_CONNECTION_NAME"] || "<connection-name>";

// Initialize Azure AI Search tool
const azureAISearchTool = ToolUtility.createAzureAISearchTool(connectionName, "search-index", {
  queryType: "simple",
  topK: 3,
  filter: "", // Add string here to filter results
  indexConnectionId: connectionName,
  indexName: "search-index",
});

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

Creación de agente con llamada de función

Puede mejorar los agentes mediante la definición de funciones de devolución de llamada como herramientas de función. Se pueden proporcionar para createAgent mediante la combinación de tools y toolResources. Solo se proporcionan las definiciones y descripciones de función para createAgent, sin las implementaciones. El Run o event handler of stream generará un estado de requires_action en función de las definiciones de función. El código debe controlar este estado y llamar a las funciones adecuadas.

Este es un ejemplo:

import {
  FunctionToolDefinition,
  ToolUtility,
  RequiredToolCall,
  ToolOutput,
} from "@azure/ai-agents";

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: RequiredToolCall & FunctionToolDefinition): ToolOutput | undefined {
    console.log(`Function tool call - ${toolCall.function.name}`);
    const args: any[] = [];
    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;
      }
    }
    // Create a mapping of function names to their implementations
    const functionMap = new Map(
      this.functionTools.map((tool) => [tool.definition.function.name, tool.func]),
    );
    const result = functionMap.get(toolCall.function.name)?.(...args);
    return result
      ? {
          toolCallId: toolCall.id,
          output: JSON.stringify(result),
        }
      : {
          toolCallId: toolCall.id,
          output: JSON.stringify({
            error: `No matching tool found for function: ${toolCall.function.name}`,
          }),
        };
  }

  public getFunctionDefinitions(): FunctionToolDefinition[] {
    return this.functionTools.map((tool) => {
      return tool.definition;
    });
  }
}
const functionToolExecutor = new FunctionToolExecutor();
const functionTools = functionToolExecutor.getFunctionDefinitions();
const agent = await client.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}`);

Creación de agente con OpenAPI

Las especificaciones de OpenAPI describen las operaciones REST en un punto de conexión específico. El SDK de agentes puede leer una especificación de OpenAPI, crear una función a partir de ella y llamar a esa función en el punto de conexión rest sin ejecución adicional del lado cliente. Este es un ejemplo de creación de una herramienta OpenAPI (mediante la autenticación anónima):

import { ToolUtility } from "@azure/ai-agents";

// Read in OpenApi spec
const filePath = "./data/weatherOpenApi.json";
const openApiSpec = JSON.parse(fs.readFileSync(filePath, "utf-8"));

// Define OpenApi function
const openApiFunction = {
  name: "getWeather",
  spec: openApiSpec,
  description: "Retrieve weather information for a ___location",
  auth: {
    type: "anonymous",
  },
  default_params: ["format"], // optional
};

// Create OpenApi tool
const openApiTool = ToolUtility.createOpenApiTool(openApiFunction);

// Create agent with OpenApi tool
const agent = await client.createAgent("gpt-4o", {
  name: "myAgent",
  instructions: "You are a helpful agent",
  tools: [openApiTool.definition],
});
console.log(`Created agent, agent ID: ${agent.id}`);

Crear subproceso

Para cada sesión o conversación, se requiere un subproceso. Este es un ejemplo:

const thread = await client.threads.create();
console.log(`Created thread, thread ID: ${thread.id}`);

Creación de subprocesos con recurso de herramienta

En algunos escenarios, es posible que tenga que asignar recursos específicos a subprocesos individuales. Para ello, proporcione el argumento toolResources para threads.create. En el ejemplo siguiente, creará un almacén de vectores y cargará un archivo, habilitará un agente para la búsqueda de archivos mediante el argumento tools y, a continuación, asociará el archivo al subproceso mediante el argumento toolResources.

import { ToolUtility } from "@azure/ai-agents";

const filePath = "./data/syntheticCompanyQuarterlyResults.csv";
const localFileStream = fs.createReadStream(filePath);
const file = await client.files.upload(localFileStream, "assistants", {
  fileName: "sample_file_for_upload.csv",
});
console.log(`Uploaded file, ID: ${file.id}`);

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

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

const agent = await client.agents.createAgent("gpt-4o", {
  name: "myAgent",
  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.threads.create({ toolResources: fileSearchTool.resources });

Enumerar subprocesos

Para enumerar todos los subprocesos asociados a un agente determinado, utilice threads.list:

const threads = client.threads.list();
console.log(`Threads for agent ${agent.id}:`);
for await (const t of threads) {
  console.log(`Thread ID: ${t.id}`);
  console.log(`Created at: ${t.createdAt}`);
  console.log(`Metadata: ${t.metadata}`);
  console.log(`---- `);
}

Crear mensaje

Para crear un mensaje para que el asistente procese, pase user como role y una pregunta como content:

const message = await client.messages.create(thread.id, "user", "hello, world!");
console.log(`Created message, message ID: ${message.id}`);

Crear mensaje con datos adjuntos de búsqueda de archivos

Para adjuntar un archivo a un mensaje para la búsqueda de contenido, use ToolUtility.createFileSearchTool() y el argumento attachments:

import { ToolUtility } from "@azure/ai-agents";

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

Crear mensaje con datos adjuntos del intérprete de código

Para adjuntar un archivo a un mensaje para el análisis de datos, use ToolUtility.createCodeInterpreterTool() y el argumento attachment.

Este es un ejemplo:

import { ToolUtility } from "@azure/ai-agents";

// 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-4o", {
  name: "my-assistant",
  instructions: "You are helpful assistant",
  tools: [codeInterpreterTool.definition],
});
console.log(`Created agent, agent ID: ${agent.id}`);

const thread = await client.threads.create();
console.log(`Created thread, thread ID: ${thread.id}`);

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

Creación de un mensaje con entradas de imagen

Puede enviar mensajes a agentes de Azure con entradas de imagen de las siguientes maneras:

  • Uso de una imagen almacenada como un archivo cargado
  • Uso de una imagen pública accesible a través de la dirección URL
  • Uso de una cadena de imagen codificada en base64

En el ejemplo siguiente se muestra el método base64:

Creación de un mensaje con entrada de imagen codificada en base64
function imageToBase64DataUrl(imagePath: string, mimeType: string): string {
  try {
    // Read the image file as binary
    const imageBuffer = fs.readFileSync(imagePath);
    // Convert to base64
    const base64Data = imageBuffer.toString("base64");
    // Format as a data URL
    return `data:${mimeType};base64,${base64Data}`;
  } catch (error) {
    console.error(`Error reading image file at ${imagePath}:`, error);
    throw error;
  }
}

// Convert your image file to base64 format
const filePath = "./data/image_file.png";
const imageDataUrl = imageToBase64DataUrl(filePath, "image/png");

// Create a message with both text and image content
console.log("Creating message with image content...");
const inputMessage = "Hello, what is in the image?";
const content = [
  {
    type: "text",
    text: inputMessage,
  },
  {
    type: "image_url",
    image_url: {
      url: imageDataUrl,
      detail: "high",
    },
  },
];

const message = await client.messages.create(thread.id, "user", content);
console.log(`Created message, message ID: ${message.id}`);

Crear ejecución, Run_and_Process o Stream

Este es un ejemplo de runs.create y sondeo hasta que se completa la ejecución:

// Create and poll a run
console.log("Creating run...");
const run = await client.runs.createAndPoll(thread.id, agent.id, {
  pollingOptions: {
    intervalInMs: 2000,
  },
  onResponse: (response): void => {
    console.log(`Received response with status: ${response.parsedBody.status}`);
  },
});
console.log(`Run finished with status: ${run.status}`);

Para que el SDK sondee en su nombre, use el método createThreadAndRun.

Este es un ejemplo:

const run = await client.runs.createThreadAndRun(agent.id, {
  thread: {
    messages: [
      {
        role: "user",
        content: "hello, world!",
      },
    ],
  },
});

Con el streaming, no es necesario tener en cuenta el sondeo.

Este es un ejemplo:

const streamEventMessages = await client.runs.create(thread.id, agent.id).stream();

El control de eventos se puede realizar de la siguiente manera:

import { RunStreamEvent, MessageStreamEvent, ErrorEvent, DoneEvent } from "@azure/ai-agents";

const streamEventMessages = await client.runs.create(thread.id, agent.id).stream();

for await (const eventMessage of streamEventMessages) {
  switch (eventMessage.event) {
    case RunStreamEvent.ThreadRunCreated:
      console.log(`ThreadRun status: ${eventMessage.data.status}`);
      break;
    case MessageStreamEvent.ThreadMessageDelta:
      {
        const messageDelta = eventMessage.data;
        messageDelta.delta.content.forEach((contentPart) => {
          if (contentPart.type === "text") {
            const textContent = contentPart;
            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;
  }
}

Recuperar mensaje

Para recuperar mensajes de agentes, use el ejemplo siguiente:

const messagesIterator = client.messages.list(thread.id);
const allMessages = [];
for await (const m of messagesIterator) {
  allMessages.push(m);
}
console.log("Messages:", allMessages);

// The messages are following in the reverse order,
// we will iterate them and output only text contents.
const messages = await client.messages.list(thread.id, {
  order: "asc",
});

for await (const dataPoint of messages) {
  const textContent = dataPoint.content.find((item) => item.type === "text");
  if (textContent && "text" in textContent) {
    console.log(`${dataPoint.role}: ${textContent.text.value}`);
  }
}

Recuperar archivo

No se pueden recuperar los archivos cargados por agentes. Si el caso de uso necesita acceder al contenido del archivo cargado por los agentes, se recomienda mantener una copia adicional accesible para la aplicación. Sin embargo, los archivos generados por los agentes se pueden recuperar mediante files.getContent.

Este es un ejemplo de recuperación de identificadores de archivo de mensajes:

import { isOutputOfType, MessageTextContent, MessageImageFileContent } from "@azure/ai-agents";

const messagesIterator = client.messages.list(thread.id);
const allMessages = [];
for await (const m of messagesIterator) {
  allMessages.push(m);
}
console.log("Messages:", allMessages);

// Get most recent message from the assistant
const assistantMessage = allMessages.find((msg) => msg.role === "assistant");
if (assistantMessage) {
  const textContent = assistantMessage.content.find((content) =>
    isOutputOfType<MessageTextContent>(content, "text"),
  ) as MessageTextContent;
  if (textContent) {
    console.log(`Last message: ${textContent.text.value}`);
  }
}

const imageFile = (allMessages[0].content[0] as MessageImageFileContent).imageFile;
const imageFileName = (await client.agents.files.get(imageFile.fileId)).filename;

const fileContent = await (await client.files.getContent(imageFile.fileId).asNodeStream()).body;
if (fileContent) {
  const chunks: Buffer[] = [];
  for await (const chunk of fileContent) {
    chunks.push(Buffer.isBuffer(chunk) ? chunk : 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}`);

Desmontaje

Para quitar recursos después de completar las tareas, use las funciones siguientes:

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

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

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

Solución de problemas

Excepciones

Los métodos cliente que realizan llamadas de servicio generan un restError para una respuesta de código de estado HTTP no correcta del servicio. El code de la excepción contendrá el código de estado de respuesta HTTP. El error.message de la excepción contiene un mensaje detallado que puede resultar útil para diagnosticar el problema:

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

try {
  const thread = await client.threads.create();
} catch (e) {
  if (e instanceof RestError) {
    console.log(`Status code: ${e.code}`);
    console.log(e.message);
  } else {
    console.error(e);
  }
}

Por ejemplo, cuando se proporcionan credenciales incorrectas:

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

Información sobre los problemas

Para notificar problemas con la biblioteca cliente o solicitar características adicionales, abra un problema de GitHub aquí

Pasos siguientes

Vea la carpeta de ejemplos de paquete , que contiene código totalmente ejecutable.

Contribución

Este proyecto da la bienvenida a las contribuciones y sugerencias. La mayoría de las contribuciones requieren que acepte un Contrato de licencia de colaborador (CLA) declarando que tiene derecho a, y en realidad, concedanos los derechos para usar su contribución. Para obtener más información, visite https://cla.microsoft.com.

Al enviar una solicitud de incorporación de cambios, un bot CLA determinará automáticamente si necesita proporcionar un CLA y decorar la solicitud de incorporación de cambios de forma adecuada (por ejemplo, etiqueta, comentario). Solo tiene que seguir las instrucciones proporcionadas por el bot. Solo tendrá que hacerlo una vez en todos los repositorios mediante nuestro CLA.

Este proyecto ha adoptado el código de conducta de código abierto de Microsoft. Para obtener más información, consulte las preguntas más frecuentes sobre el código de conducta o póngase en contacto con opencode@microsoft.com con preguntas o comentarios adicionales.