|
| 1 | +--- |
| 2 | +manager: nitinme |
| 3 | +author: aahill |
| 4 | +ms.author: aahi |
| 5 | +ms.service: azure-ai-agent-service |
| 6 | +ms.topic: include |
| 7 | +ms.date: 01/28/2025 |
| 8 | +ms.custom: devx-track-ts |
| 9 | +--- |
| 10 | + |
| 11 | + |
| 12 | +| [Reference documentation](/javascript/api/overview/azure/ai-projects-readme) | [Samples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/ai/ai-projects/README.md) | [Library source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/ai/ai-projects) | [Package (npm)](https://www.npmjs.com/package/@azure/ai-projects) | |
| 13 | + |
| 14 | +## Prerequisites |
| 15 | + |
| 16 | +* An Azure subscription - [Create one for free](https://azure.microsoft.com/free/cognitive-services). |
| 17 | +* [Node.js LTS](https://nodejs.org/) |
| 18 | +* [TypeScript 5.x](https://www.typescriptlang.org/) |
| 19 | +* Make sure you have the **Azure AI Developer** [RBAC role](../../../ai-studio/concepts/rbac-ai-studio.md) assigned at the appropriate level. |
| 20 | +* Install [the Azure CLI and the machine learning extension](/azure/machine-learning/how-to-configure-cli). If you have the CLI already installed, make sure it's updated to the latest version. |
| 21 | + |
| 22 | +[!INCLUDE [bicep-setup](bicep-setup.md)] |
| 23 | + |
| 24 | +## Configure and run an agent |
| 25 | + |
| 26 | +| Component | Description | |
| 27 | +| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 28 | +| Agent | Custom AI that uses AI models in conjunction with tools. | |
| 29 | +| Tool | Tools help extend an agent’s ability to reliably and accurately respond during conversation. Such as connecting to user-defined knowledge bases to ground the model, or enabling web search to provide current information. | |
| 30 | +| Thread | A conversation session between an agent and a user. Threads store Messages and automatically handle truncation to fit content into a model’s context. | |
| 31 | +| Message | A message created by an agent or a user. Messages can include text, images, and other files. Messages are stored as a list on the Thread. | |
| 32 | +| Run | Activation of an agent to begin running based on the contents of Thread. The agent uses its configuration and Thread’s Messages to perform tasks by calling models and tools. As part of a Run, the agent appends Messages to the Thread. | |
| 33 | +| Run Step | A detailed list of steps the agent took as part of a Run. An agent can call tools or create Messages during its run. Examining Run Steps allows you to understand how the agent is getting to its results. | |
| 34 | + |
| 35 | +Run the following commands to install the npm packages. |
| 36 | + |
| 37 | +```console |
| 38 | +npm install @azure/ai-projects |
| 39 | +npm install @azure/identity |
| 40 | +``` |
| 41 | + |
| 42 | +Use the following code to create and run an agent. To run this code, you will need to create a connection string using information from your project. This string is in the format: |
| 43 | + |
| 44 | +`<HostName>;<AzureSubscriptionId>;<ResourceGroup>;<ProjectName>` |
| 45 | + |
| 46 | +[!INCLUDE [connection-string-portal](connection-string-portal.md)] |
| 47 | + |
| 48 | +`HostName` can be found by navigating to your `discovery_url` and removing the leading `https://` and trailing `/discovery`. To find your `discovery_url`, run this CLI command: |
| 49 | + |
| 50 | +```azurecli |
| 51 | +az ml workspace show -n {project_name} --resource-group {resource_group_name} --query discovery_url |
| 52 | +``` |
| 53 | + |
| 54 | +For example, your connection string may look something like: |
| 55 | + |
| 56 | +`eastus.api.azureml.ms;12345678-abcd-1234-9fc6-62780b3d3e05;my-resource-group;my-project-name` |
| 57 | + |
| 58 | +Set this connection string as an environment variable named `PROJECT_CONNECTION_STRING`. |
| 59 | + |
| 60 | +```typescript |
| 61 | +// index.ts |
| 62 | + |
| 63 | +import type { |
| 64 | + MessageDeltaChunk, |
| 65 | + MessageDeltaTextContent, |
| 66 | + MessageTextContentOutput, |
| 67 | +} from "@azure/ai-projects"; |
| 68 | +import { |
| 69 | + AIProjectsClient, |
| 70 | + DoneEvent, |
| 71 | + ErrorEvent, |
| 72 | + isOutputOfType, |
| 73 | + MessageStreamEvent, |
| 74 | + RunStreamEvent, |
| 75 | + ToolUtility, |
| 76 | +} from "@azure/ai-projects"; |
| 77 | +import { DefaultAzureCredential } from "@azure/identity"; |
| 78 | + |
| 79 | +const connectionString = |
| 80 | + process.env["AZURE_AI_PROJECTS_CONNECTION_STRING"] || "<project connection string>"; |
| 81 | + |
| 82 | +if (!connectionString) { |
| 83 | + throw new Error("AZURE_AI_PROJECTS_CONNECTION_STRING must be set in the environment variables"); |
| 84 | +} |
| 85 | + |
| 86 | +export async function main(): Promise<void> { |
| 87 | + const client = AIProjectsClient.fromConnectionString( |
| 88 | + connectionString || "", |
| 89 | + new DefaultAzureCredential(), |
| 90 | + ); |
| 91 | + |
| 92 | + // Step 1: Create code interpreter tool |
| 93 | + const codeInterpreterTool = ToolUtility.createCodeInterpreterTool(); |
| 94 | + |
| 95 | + // Step 2: Create an agent |
| 96 | + const agent = await client.agents.createAgent("gpt-35-turbo", { |
| 97 | + name: "my-agent", |
| 98 | + instructions: "You are a helpful agent", |
| 99 | + tools: [codeInterpreterTool.definition], |
| 100 | + toolResources: codeInterpreterTool.resources, |
| 101 | + }); |
| 102 | + |
| 103 | + // Step 3: Create a thread |
| 104 | + const thread = await client.agents.createThread(); |
| 105 | + |
| 106 | + // Step 4: Add a message to thread |
| 107 | + await client.agents.createMessage( |
| 108 | + thread.id, { |
| 109 | + role: "user", |
| 110 | + content: "I need to solve the equation `3x + 11 = 14`. Can you help me?", |
| 111 | + }); |
| 112 | + |
| 113 | + // Intermission: message is now correlated with thread |
| 114 | + // Intermission: listing messages will retrieve the message just added |
| 115 | + |
| 116 | + // Step 5: Run the agent |
| 117 | + const streamEventMessages = await client.agents.createRun(thread.id, agent.id).stream(); |
| 118 | + |
| 119 | + for await (const eventMessage of streamEventMessages) { |
| 120 | + switch (eventMessage.event) { |
| 121 | + case RunStreamEvent.ThreadRunCreated: |
| 122 | + break; |
| 123 | + case MessageStreamEvent.ThreadMessageDelta: |
| 124 | + { |
| 125 | + const messageDelta = eventMessage.data as MessageDeltaChunk; |
| 126 | + messageDelta.delta.content.forEach((contentPart) => { |
| 127 | + if (contentPart.type === "text") { |
| 128 | + const textContent = contentPart as MessageDeltaTextContent; |
| 129 | + const textValue = textContent.text?.value || "No text"; |
| 130 | + } |
| 131 | + }); |
| 132 | + } |
| 133 | + break; |
| 134 | + |
| 135 | + case RunStreamEvent.ThreadRunCompleted: |
| 136 | + break; |
| 137 | + case ErrorEvent.Error: |
| 138 | + console.log(`An error occurred. Data ${eventMessage.data}`); |
| 139 | + break; |
| 140 | + case DoneEvent.Done: |
| 141 | + break; |
| 142 | + } |
| 143 | + } |
| 144 | + |
| 145 | + // 6. Print the messages from the agent |
| 146 | + const messages = await client.agents.listMessages(thread.id); |
| 147 | + |
| 148 | + // Messages iterate from oldest to newest |
| 149 | + // messages[0] is the most recent |
| 150 | + for (let i = messages.data.length - 1; i >= 0; i--) { |
| 151 | + const m = messages.data[i]; |
| 152 | + if (isOutputOfType<MessageTextContentOutput>(m.content[0], "text")) { |
| 153 | + const textContent = m.content[0] as MessageTextContentOutput; |
| 154 | + console.log(`${textContent.text.value}`); |
| 155 | + console.log(`---------------------------------`); |
| 156 | + } |
| 157 | + } |
| 158 | + |
| 159 | + // 7. Delete the agent once done |
| 160 | + await client.agents.deleteAgent(agent.id); |
| 161 | +} |
| 162 | + |
| 163 | +main().catch((err) => { |
| 164 | + console.error("The sample encountered an error:", err); |
| 165 | +}); |
| 166 | +``` |
| 167 | + |
0 commit comments