Azure.AI.Agents.Persistent (.NET)
SDK bas niveau pour créer et gérer des agents IA persistants avec threads, messages, exécutions et outils.
Installation
dotnet add package Azure.AI.Agents.Persistent --prerelease
dotnet add package Azure.Identity
Versions actuelles : Stable v1.1.0, Preview v1.2.0-beta.8
Variables d'environnement
PROJECT_ENDPOINT=https://<resource>.services.ai.azure.com/api/projects/<project>
MODEL_DEPLOYMENT_NAME=gpt-4o-mini
AZURE_BING_CONNECTION_ID=<bing-connection-resource-id>
AZURE_AI_SEARCH_CONNECTION_ID=<search-connection-resource-id>
Authentification
using Azure.AI.Agents.Persistent;
using Azure.Identity;
var projectEndpoint = Environment.GetEnvironmentVariable("PROJECT_ENDPOINT");
PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());
Hiérarchie du client
PersistentAgentsClient
├── Administration → Opérations CRUD sur les agents
├── Threads → Gestion des threads
├── Messages → Opérations sur les messages
├── Runs → Exécution et streaming des runs
├── Files → Upload/téléchargement de fichiers
└── VectorStores → Gestion des magasins vectoriels
Flux de travail principal
1. Créer un agent
var modelDeploymentName = Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME");
PersistentAgent agent = await client.Administration.CreateAgentAsync(
model: modelDeploymentName,
name: "Math Tutor",
instructions: "You are a personal math tutor. Write and run code to answer math questions.",
tools: [new CodeInterpreterToolDefinition()]
);
2. Créer un thread et un message
// Créer un thread
PersistentAgentThread thread = await client.Threads.CreateThreadAsync();
// Créer un message
await client.Messages.CreateMessageAsync(
thread.Id,
MessageRole.User,
"I need to solve the equation `3x + 11 = 14`. Can you help me?"
);
3. Exécuter l'agent (polling)
// Créer une exécution
ThreadRun run = await client.Runs.CreateRunAsync(
thread.Id,
agent.Id,
additionalInstructions: "Please address the user as Jane Doe."
);
// Interroger l'état jusqu'à la fin
do
{
await Task.Delay(TimeSpan.FromMilliseconds(500));
run = await client.Runs.GetRunAsync(thread.Id, run.Id);
}
while (run.Status == RunStatus.Queued || run.Status == RunStatus.InProgress);
// Récupérer les messages
await foreach (PersistentThreadMessage message in client.Messages.GetMessagesAsync(
threadId: thread.Id,
order: ListSortOrder.Ascending))
{
Console.Write($"{message.Role}: ");
foreach (MessageContent content in message.ContentItems)
{
if (content is MessageTextContent textContent)
Console.WriteLine(textContent.Text);
}
}
4. Réponse en streaming
AsyncCollectionResult<StreamingUpdate> stream = client.Runs.CreateRunStreamingAsync(
thread.Id,
agent.Id
);
await foreach (StreamingUpdate update in stream)
{
if (update.UpdateKind == StreamingUpdateReason.RunCreated)
{
Console.WriteLine("--- Run started! ---");
}
else if (update is MessageContentUpdate contentUpdate)
{
Console.Write(contentUpdate.Text);
}
else if (update.UpdateKind == StreamingUpdateReason.RunCompleted)
{
Console.WriteLine("\n--- Run completed! ---");
}
}
5. Function calling
// Définir un outil de fonction
FunctionToolDefinition weatherTool = new(
name: "getCurrentWeather",
description: "Gets the current weather at a location.",
parameters: BinaryData.FromObjectAsJson(new
{
Type = "object",
Properties = new
{
Location = new { Type = "string", Description = "City and state, e.g. San Francisco, CA" },
Unit = new { Type = "string", Enum = new[] { "c", "f" } }
},
Required = new[] { "location" }
}, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })
);
// Créer un agent avec la fonction
PersistentAgent agent = await client.Administration.CreateAgentAsync(
model: modelDeploymentName,
name: "Weather Bot",
instructions: "You are a weather bot.",
tools: [weatherTool]
);
// Gérer les appels de fonction pendant le polling
do
{
await Task.Delay(500);
run = await client.Runs.GetRunAsync(thread.Id, run.Id);
if (run.Status == RunStatus.RequiresAction
&& run.RequiredAction is SubmitToolOutputsAction submitAction)
{
List<ToolOutput> outputs = [];
foreach (RequiredToolCall toolCall in submitAction.ToolCalls)
{
if (toolCall is RequiredFunctionToolCall funcCall)
{
// Exécuter la fonction et obtenir le résultat
string result = ExecuteFunction(funcCall.Name, funcCall.Arguments);
outputs.Add(new ToolOutput(toolCall, result));
}
}
run = await client.Runs.SubmitToolOutputsToRunAsync(run, outputs, toolApprovals: null);
}
}
while (run.Status == RunStatus.Queued || run.Status == RunStatus.InProgress);
6. Recherche de fichiers avec magasin vectoriel
// Télécharger un fichier
PersistentAgentFileInfo file = await client.Files.UploadFileAsync(
filePath: "document.txt",
purpose: PersistentAgentFilePurpose.Agents
);
// Créer un magasin vectoriel
PersistentAgentsVectorStore vectorStore = await client.VectorStores.CreateVectorStoreAsync(
fileIds: [file.Id],
name: "my_vector_store"
);
// Créer une ressource de recherche de fichiers
FileSearchToolResource fileSearchResource = new();
fileSearchResource.VectorStoreIds.Add(vectorStore.Id);
// Créer un agent avec recherche de fichiers
PersistentAgent agent = await client.Administration.CreateAgentAsync(
model: modelDeploymentName,
name: "Document Assistant",
instructions: "You help users find information in documents.",
tools: [new FileSearchToolDefinition()],
toolResources: new ToolResources { FileSearch = fileSearchResource }
);
7. Bing Grounding
var bingConnectionId = Environment.GetEnvironmentVariable("AZURE_BING_CONNECTION_ID");
BingGroundingToolDefinition bingTool = new(
new BingGroundingSearchToolParameters(
[new BingGroundingSearchConfiguration(bingConnectionId)]
)
);
PersistentAgent agent = await client.Administration.CreateAgentAsync(
model: modelDeploymentName,
name: "Search Agent",
instructions: "Use Bing to answer questions about current events.",
tools: [bingTool]
);
8. Azure AI Search
AzureAISearchToolResource searchResource = new(
connectionId: searchConnectionId,
indexName: "my_index",
topK: 5,
filter: "category eq 'documentation'",
queryType: AzureAISearchQueryType.Simple
);
PersistentAgent agent = await client.Administration.CreateAgentAsync(
model: modelDeploymentName,
name: "Search Agent",
instructions: "Search the documentation index to answer questions.",
tools: [new AzureAISearchToolDefinition()],
toolResources: new ToolResources { AzureAISearch = searchResource }
);
9. Nettoyage
await client.Threads.DeleteThreadAsync(thread.Id);
await client.Administration.DeleteAgentAsync(agent.Id);
await client.VectorStores.DeleteVectorStoreAsync(vectorStore.Id);
await client.Files.DeleteFileAsync(file.Id);
Outils disponibles
| Outil |
Classe |
Objectif |
| Code Interpreter |
CodeInterpreterToolDefinition |
Exécuter du code Python, générer des visualisations |
| File Search |
FileSearchToolDefinition |
Rechercher dans les fichiers téléchargés via magasins vectoriels |
| Function Calling |
FunctionToolDefinition |
Appeler des fonctions personnalisées |
| Bing Grounding |
BingGroundingToolDefinition |
Recherche web via Bing |
| Azure AI Search |
AzureAISearchToolDefinition |
Rechercher dans les index Azure AI Search |
| OpenAPI |
OpenApiToolDefinition |
Appeler des API externes via spécification OpenAPI |
| Azure Functions |
AzureFunctionToolDefinition |
Invoquer des Azure Functions |
| MCP |
MCPToolDefinition |
Outils Model Context Protocol |
| SharePoint |
SharepointToolDefinition |
Accéder au contenu SharePoint |
| Microsoft Fabric |
MicrosoftFabricToolDefinition |
Accéder aux données Fabric |
Types de mise à jour du streaming
| Type de mise à jour |
Description |
StreamingUpdateReason.RunCreated |
Run démarré |
StreamingUpdateReason.RunInProgress |
Run en cours de traitement |
StreamingUpdateReason.RunCompleted |
Run terminé |
StreamingUpdateReason.RunFailed |
Run en erreur |
MessageContentUpdate |
Fragment de contenu texte |
RunStepUpdate |
Changement d'état de l'étape |
Référence des types clés
| Type |
Objectif |
PersistentAgentsClient |
Point d'entrée principal |
PersistentAgent |
Agent avec modèle, instructions, outils |
PersistentAgentThread |
Thread de conversation |
PersistentThreadMessage |
Message dans un thread |
ThreadRun |
Exécution d'un agent sur un thread |
RunStatus |
Queued, InProgress, RequiresAction, Completed, Failed |
ToolResources |
Ressources d'outils combinées |
ToolOutput |
Réponse d'appel de fonction |
Bonnes pratiques
- Toujours supprimer les clients — Utiliser les déclarations
using ou suppression explicite
- Interroger avec des délais appropriés — 500 ms recommandés entre les vérifications d'état
- Nettoyer les ressources — Supprimer les threads et agents quand terminé
- Gérer tous les statuts de run — Vérifier
RequiresAction, Failed, Cancelled
- Utiliser le streaming pour une UX en temps réel — Meilleure expérience utilisateur que le polling
- Stocker les IDs, pas les objets — Référencer les agents/threads par ID
- Utiliser les méthodes async — Toutes les opérations doivent être asynchrones
Gestion des erreurs
using Azure;
try
{
var agent = await client.Administration.CreateAgentAsync(...);
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
Console.WriteLine("Resource not found");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
}
SDKs connexes
| SDK |
Objectif |
Installation |
Azure.AI.Agents.Persistent |
Agents bas niveau (ce SDK) |
dotnet add package Azure.AI.Agents.Persistent |
Azure.AI.Projects |
Client projet haut niveau |
dotnet add package Azure.AI.Projects |
Liens de référence