azure-ai-agents-persistent-dotnet
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAzure.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.IdentityCurrent 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 managementPersistentAgentsClient
├── 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
可用工具
| Tool | Class | Purpose |
|---|---|---|
| Code Interpreter | | Execute Python code, generate visualizations |
| File Search | | Search uploaded files via vector stores |
| Function Calling | | Call custom functions |
| Bing Grounding | | Web search via Bing |
| Azure AI Search | | Search Azure AI Search indexes |
| OpenAPI | | Call external APIs via OpenAPI spec |
| Azure Functions | | Invoke Azure Functions |
| MCP | | Model Context Protocol tools |
| SharePoint | | Access SharePoint content |
| Microsoft Fabric | | Access Fabric data |
| 工具 | 类 | 用途 |
|---|---|---|
| 代码解释器 | | 执行Python代码、生成可视化内容 |
| 文件搜索 | | 通过向量库搜索上传的文件 |
| 函数调用 | | 调用自定义函数 |
| Bing Grounding | | 通过Bing进行网页搜索 |
| Azure AI Search | | 搜索Azure AI Search索引 |
| OpenAPI | | 通过OpenAPI规范调用外部API |
| Azure Functions | | 调用Azure Functions |
| MCP | | 模型上下文协议工具 |
| SharePoint | | 访问SharePoint内容 |
| Microsoft Fabric | | 访问Fabric数据 |
Streaming Update Types
流式更新类型
| Update Type | Description |
|---|---|
| Run started |
| Run processing |
| Run finished |
| Run errored |
| Text content chunk |
| Step status change |
| 更新类型 | 描述 |
|---|---|
| 运行任务已启动 |
| 运行任务处理中 |
| 运行任务已完成 |
| 运行任务出错 |
| 文本内容片段 |
| 步骤状态变更 |
Key Types Reference
关键类型参考
| Type | Purpose |
|---|---|
| Main entry point |
| Agent with model, instructions, tools |
| Conversation thread |
| Message in thread |
| Execution of agent against thread |
| Queued, InProgress, RequiresAction, Completed, Failed |
| Combined tool resources |
| Function call response |
| 类型 | 用途 |
|---|---|
| 主入口类 |
| 包含模型、指令、工具的Agent |
| 对话线程 |
| 线程中的消息 |
| Agent针对线程的执行任务 |
| 排队中、处理中、需要操作、已完成、失败 |
| 组合式工具资源 |
| 函数调用响应 |
Best Practices
最佳实践
- Always dispose clients — Use statements or explicit disposal
using - Poll with appropriate delays — 500ms recommended between status checks
- Clean up resources — Delete threads and agents when done
- Handle all run statuses — Check for ,
RequiresAction,FailedCancelled - Use streaming for real-time UX — Better user experience than polling
- Store IDs not objects — Reference agents/threads by ID
- Use async methods — All operations should be async
- 始终释放客户端 — 使用语句或显式释放资源
using - 合理设置轮询延迟 — 状态检查间隔建议为500ms
- 清理资源 — 使用完成后删除线程和Agent
- 处理所有运行状态 — 检查、
RequiresAction、Failed状态Cancelled - 使用流式处理实现实时交互 — 比轮询方式的用户体验更好
- 存储ID而非对象 — 通过ID引用Agent/线程
- 使用异步方法 — 所有操作都应采用异步方式
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
| SDK | Purpose | Install |
|---|---|---|
| Low-level agents (this SDK) | |
| High-level project client | |
| SDK | 用途 | 安装命令 |
|---|---|---|
| 底层Agent SDK(当前SDK) | |
| 高层级项目客户端 | |