azure-ai-agents-persistent-dotnet

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Azure.AI.Agents.Persistent (.NET)

Azure.AI.Agents.Persistent(.NET)

Low-level SDK for creating and managing persistent AI agents with threads, messages, runs, and tools.
用于创建和管理具备线程、消息、运行和工具的持久化AI Agent的底层SDK。

Installation

安装

bash
dotnet add package Azure.AI.Agents.Persistent --prerelease
dotnet add package Azure.Identity
Current Versions: Stable v1.1.0, Preview v1.2.0-beta.8
bash
dotnet add package Azure.AI.Agents.Persistent --prerelease
dotnet add package Azure.Identity
当前版本:稳定版 v1.1.0,预览版 v1.2.0-beta.8

Environment Variables

环境变量

bash
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>
bash
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>

Authentication

认证

csharp
using Azure.AI.Agents.Persistent;
using Azure.Identity;

var projectEndpoint = Environment.GetEnvironmentVariable("PROJECT_ENDPOINT");
PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());
csharp
using Azure.AI.Agents.Persistent;
using Azure.Identity;

var projectEndpoint = Environment.GetEnvironmentVariable("PROJECT_ENDPOINT");
PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());

Client Hierarchy

客户端层级

PersistentAgentsClient
├── Administration  → Agent CRUD operations
├── Threads         → Thread management
├── Messages        → Message operations
├── Runs            → Run execution and streaming
├── Files           → File upload/download
└── VectorStores    → Vector store management
PersistentAgentsClient
├── Administration  → Agent的增删改查(CRUD)操作
├── Threads         → 线程管理
├── Messages        → 消息操作
├── Runs            → 运行执行与流式处理
├── Files           → 文件上传/下载
└── VectorStores    → 向量库管理

Core Workflow

核心工作流

1. Create Agent

1. 创建Agent

csharp
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()]
);
csharp
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. Create Thread and Message

2. 创建线程与消息

csharp
// Create thread
PersistentAgentThread thread = await client.Threads.CreateThreadAsync();

// Create message
await client.Messages.CreateMessageAsync(
    thread.Id,
    MessageRole.User,
    "I need to solve the equation `3x + 11 = 14`. Can you help me?"
);
csharp
// 创建线程
PersistentAgentThread thread = await client.Threads.CreateThreadAsync();

// 创建消息
await client.Messages.CreateMessageAsync(
    thread.Id,
    MessageRole.User,
    "I need to solve the equation `3x + 11 = 14`. Can you help me?"
);

3. Run Agent (Polling)

3. 运行Agent(轮询方式)

csharp
// Create run
ThreadRun run = await client.Runs.CreateRunAsync(
    thread.Id,
    agent.Id,
    additionalInstructions: "Please address the user as Jane Doe."
);

// Poll for completion
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);

// Retrieve 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);
    }
}
csharp
// 创建运行任务
ThreadRun run = await client.Runs.CreateRunAsync(
    thread.Id,
    agent.Id,
    additionalInstructions: "Please address the user as Jane Doe."
);

// 轮询等待完成
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);

// 获取消息
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. Streaming Response

4. 流式响应

csharp
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! ---");
    }
}
csharp
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

5. 函数调用

csharp
// Define function tool
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 })
);

// Create agent with function
PersistentAgent agent = await client.Administration.CreateAgentAsync(
    model: modelDeploymentName,
    name: "Weather Bot",
    instructions: "You are a weather bot.",
    tools: [weatherTool]
);

// Handle function calls during 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)
            {
                // Execute function and get result
                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);
csharp
// 定义函数工具
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 })
);

// 创建带函数的Agent
PersistentAgent agent = await client.Administration.CreateAgentAsync(
    model: modelDeploymentName,
    name: "Weather Bot",
    instructions: "You are a weather bot.",
    tools: [weatherTool]
);

// 轮询期间处理函数调用
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)
            {
                // 执行函数并获取结果
                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. File Search with Vector Store

6. 基于向量库的文件搜索

csharp
// Upload file
PersistentAgentFileInfo file = await client.Files.UploadFileAsync(
    filePath: "document.txt",
    purpose: PersistentAgentFilePurpose.Agents
);

// Create vector store
PersistentAgentsVectorStore vectorStore = await client.VectorStores.CreateVectorStoreAsync(
    fileIds: [file.Id],
    name: "my_vector_store"
);

// Create file search resource
FileSearchToolResource fileSearchResource = new();
fileSearchResource.VectorStoreIds.Add(vectorStore.Id);

// Create agent with file search
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 }
);
csharp
// 上传文件
PersistentAgentFileInfo file = await client.Files.UploadFileAsync(
    filePath: "document.txt",
    purpose: PersistentAgentFilePurpose.Agents
);

// 创建向量库
PersistentAgentsVectorStore vectorStore = await client.VectorStores.CreateVectorStoreAsync(
    fileIds: [file.Id],
    name: "my_vector_store"
);

// 创建文件搜索资源
FileSearchToolResource fileSearchResource = new();
fileSearchResource.VectorStoreIds.Add(vectorStore.Id);

// 创建带文件搜索的Agent
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

7. Bing grounding

csharp
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]
);
csharp
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

8. Azure AI Search

csharp
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 }
);
csharp
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. Cleanup

9. 资源清理

csharp
await client.Threads.DeleteThreadAsync(thread.Id);
await client.Administration.DeleteAgentAsync(agent.Id);
await client.VectorStores.DeleteVectorStoreAsync(vectorStore.Id);
await client.Files.DeleteFileAsync(file.Id);
csharp
await client.Threads.DeleteThreadAsync(thread.Id);
await client.Administration.DeleteAgentAsync(agent.Id);
await client.VectorStores.DeleteVectorStoreAsync(vectorStore.Id);
await client.Files.DeleteFileAsync(file.Id);

Available Tools

可用工具

ToolClassPurpose
Code Interpreter
CodeInterpreterToolDefinition
Execute Python code, generate visualizations
File Search
FileSearchToolDefinition
Search uploaded files via vector stores
Function Calling
FunctionToolDefinition
Call custom functions
Bing Grounding
BingGroundingToolDefinition
Web search via Bing
Azure AI Search
AzureAISearchToolDefinition
Search Azure AI Search indexes
OpenAPI
OpenApiToolDefinition
Call external APIs via OpenAPI spec
Azure Functions
AzureFunctionToolDefinition
Invoke Azure Functions
MCP
MCPToolDefinition
Model Context Protocol tools
SharePoint
SharepointToolDefinition
Access SharePoint content
Microsoft Fabric
MicrosoftFabricToolDefinition
Access Fabric data
工具用途
代码解释器
CodeInterpreterToolDefinition
执行Python代码、生成可视化内容
文件搜索
FileSearchToolDefinition
通过向量库搜索上传的文件
函数调用
FunctionToolDefinition
调用自定义函数
Bing Grounding
BingGroundingToolDefinition
通过Bing进行网页搜索
Azure AI Search
AzureAISearchToolDefinition
搜索Azure AI Search索引
OpenAPI
OpenApiToolDefinition
通过OpenAPI规范调用外部API
Azure Functions
AzureFunctionToolDefinition
调用Azure Functions
MCP
MCPToolDefinition
模型上下文协议工具
SharePoint
SharepointToolDefinition
访问SharePoint内容
Microsoft Fabric
MicrosoftFabricToolDefinition
访问Fabric数据

Streaming Update Types

流式更新类型

Update TypeDescription
StreamingUpdateReason.RunCreated
Run started
StreamingUpdateReason.RunInProgress
Run processing
StreamingUpdateReason.RunCompleted
Run finished
StreamingUpdateReason.RunFailed
Run errored
MessageContentUpdate
Text content chunk
RunStepUpdate
Step status change
更新类型描述
StreamingUpdateReason.RunCreated
运行任务已启动
StreamingUpdateReason.RunInProgress
运行任务处理中
StreamingUpdateReason.RunCompleted
运行任务已完成
StreamingUpdateReason.RunFailed
运行任务出错
MessageContentUpdate
文本内容片段
RunStepUpdate
步骤状态变更

Key Types Reference

关键类型参考

TypePurpose
PersistentAgentsClient
Main entry point
PersistentAgent
Agent with model, instructions, tools
PersistentAgentThread
Conversation thread
PersistentThreadMessage
Message in thread
ThreadRun
Execution of agent against thread
RunStatus
Queued, InProgress, RequiresAction, Completed, Failed
ToolResources
Combined tool resources
ToolOutput
Function call response
类型用途
PersistentAgentsClient
主入口类
PersistentAgent
包含模型、指令、工具的Agent
PersistentAgentThread
对话线程
PersistentThreadMessage
线程中的消息
ThreadRun
Agent针对线程的执行任务
RunStatus
排队中、处理中、需要操作、已完成、失败
ToolResources
组合式工具资源
ToolOutput
函数调用响应

Best Practices

最佳实践

  1. Always dispose clients — Use
    using
    statements or explicit disposal
  2. Poll with appropriate delays — 500ms recommended between status checks
  3. Clean up resources — Delete threads and agents when done
  4. Handle all run statuses — Check for
    RequiresAction
    ,
    Failed
    ,
    Cancelled
  5. Use streaming for real-time UX — Better user experience than polling
  6. Store IDs not objects — Reference agents/threads by ID
  7. Use async methods — All operations should be async
  1. 始终释放客户端 — 使用
    using
    语句或显式释放资源
  2. 合理设置轮询延迟 — 状态检查间隔建议为500ms
  3. 清理资源 — 使用完成后删除线程和Agent
  4. 处理所有运行状态 — 检查
    RequiresAction
    Failed
    Cancelled
    状态
  5. 使用流式处理实现实时交互 — 比轮询方式的用户体验更好
  6. 存储ID而非对象 — 通过ID引用Agent/线程
  7. 使用异步方法 — 所有操作都应采用异步方式

Error Handling

错误处理

csharp
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}");
}
csharp
using Azure;

try
{
    var agent = await client.Administration.CreateAgentAsync(...);
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
    Console.WriteLine("资源未找到");
}
catch (RequestFailedException ex)
{
    Console.WriteLine($"错误: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
}

Related SDKs

相关SDK

SDKPurposeInstall
Azure.AI.Agents.Persistent
Low-level agents (this SDK)
dotnet add package Azure.AI.Agents.Persistent
Azure.AI.Projects
High-level project client
dotnet add package Azure.AI.Projects
SDK用途安装命令
Azure.AI.Agents.Persistent
底层Agent SDK(当前SDK)
dotnet add package Azure.AI.Agents.Persistent
Azure.AI.Projects
高层级项目客户端
dotnet add package Azure.AI.Projects

Reference Links

参考链接