关于 azure-ai-agents-persistent-dotnet
面向 .NET 开发者的低层 SDK,用于创建和管理持久化 AI Agent、对话线程、消息、运行和工具。它提供异步执行与流式响应,并支持多种内置及自定义工具。
主要功能
- 01创建和管理 Agent 与线程
- 02发送消息并执行运行任务
- 03流式接收运行状态与文本
- 04配置文件搜索和向量存储
- 05接入函数及多种工具
适用场景
- 01构建持久化 AI Agent 应用
- 02为 Agent 添加文件搜索
- 03处理自定义函数调用
- 04通过流式更新呈现运行进度
MCP 相关
SDK 提供 MCPToolDefinition,可将 MCP 工具配置为 Agent 可用的工具。README 未说明 MCP 服务的连接或管理细节。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill azure-ai-agents-persistent-dotnet安装后在 Claude Code 中输入/azure-ai-agents-persistent-dotnet确认已加载。
详细介绍
Azure.AI.Agents.Persistent(.NET)
用于创建和管理持久化 AI Agent 的底层 SDK,支持线程、消息、运行和工具。
安装
dotnet add package Azure.AI.Agents.Persistent --prerelease
dotnet add package Azure.Identity
当前版本:稳定版 v1.1.0,预览版 v1.2.0-beta.8
环境变量
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>
身份验证
using Azure.AI.Agents.Persistent;
using Azure.Identity;
var projectEndpoint = Environment.GetEnvironmentVariable("PROJECT_ENDPOINT");
PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());
客户端层级
PersistentAgentsClient
├── Administration → Agent CRUD operations
├── Threads → Thread management
├── Messages → Message operations
├── Runs → Run execution and streaming
├── Files → File upload/download
└── VectorStores → Vector store management
核心工作流
固定兼容的包版本,并验证链接中的 SDK 签名;代码片段使用项目定义的辅助函数,并非完整应用。运行前,请确认终结点/部署、已授权的工具操作、上传范围和预算。轮询/流式传输时请设置有限的取消期限,并在读取最终答案前区分已完成、失败、已取消、已过期和需要执行操作等状态。执行前,请验证/允许列表中的每个函数名称和类型化参数集;切勿将模型的原始参数作为代码或 SQL 执行。仅在 finally 块中删除当前运行创建的资源,并保留所需的证据。
1. 创建 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. 创建线程和消息
// 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?"
);
3. 运行 Agent(轮询)
// 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);
}
}
4. 流式响应
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. 函数调用
// 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);
6. 使用向量存储进行文件搜索
// 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 }
);
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. 清理
await client.Threads.DeleteThreadAsync(thread.Id);
await client.Administration.DeleteAgentAsync(agent.Id);
await client.VectorStores.DeleteVectorStoreAsync(vectorStore.Id);
await client.Files.DeleteFileAsync(file.Id);
可用工具
| 工具 | 类 | 用途 |
|---|---|---|
| Code Interpreter | 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 | Model Context Protocol 工具 |
| SharePoint | SharepointToolDefinition | 访问 SharePoint 内容 |
| Microsoft Fabric | MicrosoftFabricToolDefinition | 访问 Fabric 数据 |
流式更新类型
| 更新类型 | 描述 |
|---|---|
StreamingUpdateReason.RunCreated | 运行已启动 |
StreamingUpdateReason.RunInProgress | 运行处理中 |
StreamingUpdateReason.RunCompleted | 运行已完成 |
StreamingUpdateReason.RunFailed | 运行出错 |
MessageContentUpdate | 文本内容片段 |
RunStepUpdate | 步骤状态变更 |
关键类型参考
| 类型 | 用途 |
|---|---|
PersistentAgentsClient | 主要入口点 |
PersistentAgent | 包含模型、指令和工具的 Agent |
PersistentAgentThread | 对话线程 |
PersistentThreadMessage | 线程中的消息 |
ThreadRun | Agent 在线程上的执行 |
RunStatus | 已排队、进行中、需要执行操作、已完成、失败 |
ToolResources | 组合工具资源 |
ToolOutput | 函数调用响应 |
最佳实践
- 根据已安装 SDK 的生命周期指南重复使用 SDK 客户端;不要假设每个客户端都实现了 IDisposable
- 采用适当的延迟进行轮询——建议在状态检查之间间隔 500ms
- 清理资源——完成后删除线程和 Agent
- 处理所有运行状态——检查
RequiresAction、Failed、Cancelled - 使用流式传输实现实时 UX——比轮询能提供更好的用户体验
- 存储 ID 而非对象——通过 ID 引用 Agent/线程
- 使用异步方法——所有操作都应为异步
错误处理
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}");
}
相关 SDK
| SDK | 用途 | 安装 |
|---|---|---|
Azure.AI.Agents.Persistent | 底层 Agent(此 SDK) | dotnet add package Azure.AI.Agents.Persistent |
Azure.AI.Projects | 高层项目客户端 | dotnet add package Azure.AI.Projects |
参考链接
适用场景
此技能适用于执行概述中描述的工作流或操作。
限制
- 仅当任务明确符合上述范围时,才使用此技能。
- 不要将输出视为环境特定验证、测试或专家审查的替代品。
- 如果缺少必要的输入、权限、安全边界或成功标准,请暂停并请求澄清。
评论
支持 Markdown