Azure AI Agents 持久化 .NET
Azure.AI.Agents.Persistent (.NET)
用于创建和管理具有线程、消息、运行和工具的持久化 AI 代理的低级 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 操作
├── Threads → 线程管理
├── Messages → 消息操作
├── Runs → 运行执行与流式传输
├── Files → 文件上传/下载
└── VectorStores → 向量存储管理核心工作流
1. 创建代理 (Agent)
var modelDeploymentName = Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME");
PersistentAgent agent = await client.Administration.CreateAgentAsync(
model: modelDeploymentName,
name: "Math Tutor",
instructions: "你是一位私人数学导师。请编写并运行代码来回答数学问题。",
tools: [new CodeInterpreterToolDefinition()]
);
2. 创建线程和消息
// 创建线程
PersistentAgentThread thread = await client.Threads.CreateThreadAsync();
// 创建消息
await client.Messages.CreateMessageAsync(
thread.Id,
MessageRole.User,
"我需要解方程 3x + 11 = 14。你能帮我吗?"
);
3. 运行代理 (轮询)
// 创建运行
ThreadRun run = await client.Runs.CreateRunAsync(
thread.Id,
agent.Id,
additionalInstructions: "请称呼用户为 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. 流式响应
AsyncCollectionResult<StreamingUpdate> stream = client.Runs.CreateRunStreamingAsync(
thread.Id,
agent.Id
);
await foreach (StreamingUpdate update in stream)
{
if (update.UpdateKind == StreamingUpdateReason.RunCreated)
{
Console.WriteLine("--- 运行已开始! ---");
}
else if (update is MessageContentUpdate contentUpdate)
{
Console.Write(contentUpdate.Text);
}
else if (update.UpdateKind == StreamingUpdateReason.RunCompleted)
{
Console.Wr
iteLine("\n--- 运行完成! ---");
}
}
### 5. 函数调用 (Function Calling)// 定义函数工具
FunctionToolDefinition weatherTool = new(
name: "getCurrentWeather",
description: "获取指定地点的当前天气。",
parameters: BinaryData.FromObjectAsJson(new
{
Type = "object",
Properties = new
{
Location = new { Type = "string", Description = "城市和州,例如 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: "你是一个天气机器人。",
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)// 上传文件
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: "你帮助用户在文档中查找信息。",
tools: [new FileSearchToolDefinition()],
toolResources: new ToolResources { FileSearch = fileSearchResource }
);
### 7. Bing 实时数据检索 (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: "使用 Bing 来回答关于当前事件的问题。",
tools: [bingTool]
);
### 8. Azure AI SearchAzureAISearchToolResource searchResource = new(
connectionId: searchConnectionId,
indexName: "my_index",
topK: 5,
filter: "category eq 'documentation'",
queryType: AzureAISearchQueryType.Simple
);
PersistentAgent agent = await client.Administration.CreateAgentAsync(
model: modelDep
loymentName,
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 代码,生成可视化图表 |
| File Search | FileSearchToolDefinition | 通过向量存储搜索上传的文件 |
| Function Calling | 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 | Run 已启动 |
| StreamingUpdateReason.RunInProgress | Run 处理中 |
| StreamingUpdateReason.RunCompleted | Run 已完成 |
| StreamingUpdateReason.RunFailed | Run 出错 |
| MessageContentUpdate | 文本内容分片 |
| RunStepUpdate | 步骤状态变更 |
关键类型参考
| 类型 | 用途 |
|------|---------|
| PersistentAgentsClient | 主入口点 |
| PersistentAgent | 包含模型、指令和工具的 Agent |
| PersistentAgentThread | 会话线程 |
| PersistentThreadMessage | 线程中的消息 |
| ThreadRun | Agent 在线程上的执行实例 |
| RunStatus | 状态:Queued, InProgress, RequiresAction, Completed, Failed |
| ToolResources | 组合工具资源 |
| ToolOutput | 函数调用响应 |
最佳实践
1. 始终释放客户端 — 使用 using 语句或显式调用释放方法
2. 使用适当的延迟进行轮询 — 建议状态检查间隔为 500ms
3. 清理资源 — 完成后删除线程和 Agent
4. 处理所有 Run 状态 — 检查 RequiresAction、Failed 和 Cancelled
5. 使用流式传输提升实时 UX — 比轮询提供更好的用户体验
6. 存储 ID 而非对象 — 通过 ID 引用 Agent/线程
7. 使用异步方法 — 所有操作均应为异步
错误处理
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 |
参考链接
| 资源 | URL |
|----------|-----|
| NuGet 包 | https://www.nuget.org/packages/Azure.AI.Agents.Persiste
| API 参考 | https://learn.microsoft.com/dotnet/api/azure.ai.agents.persistent |
| GitHub 源码 | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.Agents.Persistent |
| 示例 | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.Agents.Persistent/samples |
使用场景
此技能适用于执行概览中所描述的工作流或操作。局限性
- 仅在任务明确符合上述范围时使用此技能。
- 不要将输出结果视为针对特定环境的验证、测试或专家评审的替代方案。
- 如果缺少必要的输入、权限、安全边界或成功标准,请停止操作并寻求澄清。