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>
AZURE_TOKEN_CREDENTIALS=prod
驗證
using Azure.AI.Agents.Persistent;
using Azure.Identity;
var projectEndpoint = Environment.GetEnvironmentVariable("PROJECT_ENDPOINT");
var credential = new DefaultAzureCredential(
DefaultAzureCredential.DefaultEnvironmentVariableName
);
PersistentAgentsClient client = new(projectEndpoint, credential);
用戶端階層
PersistentAgentsClient
├── Administration → 代理 CRUD 操作
├── Threads → 對話串管理
├── Messages → 訊息操作
├── Runs → 執行與串流
├── Files → 檔案上傳/下載
└── VectorStores → 向量儲存管理
核心工作流程
1. 建立代理
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. 建立對話串與訊息
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. 執行代理(輪詢)
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. 串流回應
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. 函數呼叫
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 })
);
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. 使用向量儲存進行檔案搜尋
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);
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 基準化
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 搜尋
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 程式碼、產出視覺化圖表 |
| File Search | FileSearchToolDefinition | 透過向量儲存搜尋上傳的檔案 |
| Function Calling | FunctionToolDefinition | 呼叫自訂函數 |
| Bing Grounding | BingGroundingToolDefinition | 透過 Bing 進行網頁搜尋 |
| Azure AI Search | AzureAISearchToolDefinition | 搜尋 Azure AI 搜尋索引 |
| OpenAPI | OpenApiToolDefinition | 透過 OpenAPI 規格呼叫外部 API |
| Azure Functions | AzureFunctionToolDefinition | 叫用 Azure Functions |
| MCP | MCPToolDefinition | 模型內容協定工具 |
| SharePoint | SharepointToolDefinition | 存取 SharePoint 內容 |
| Microsoft Fabric | MicrosoftFabricToolDefinition | 存取 Fabric 資料 |
串流更新類型
| 更新類型 | 描述 |
|---|
StreamingUpdateReason.RunCreated | 執行已開始 |
StreamingUpdateReason.RunInProgress | 執行處理中 |
StreamingUpdateReason.RunCompleted | 執行已完成 |
StreamingUpdateReason.RunFailed | 執行發生錯誤 |
MessageContentUpdate | 文字內容片段 |
RunStepUpdate | 步驟狀態變更 |
關鍵類型參考
| 類型 | 目的 |
|---|
PersistentAgentsClient | 主要進入點 |
PersistentAgent | 具有模型、指令和工具的代理 |
PersistentAgentThread | 對話串 |
PersistentThreadMessage | 對話串中的訊息 |
ThreadRun | 代理對對話串的執行 |
RunStatus | 佇列中、處理中、需要操作、已完成、失敗 |
ToolResources | 組合的工具資源 |
ToolOutput | 函數呼叫回應 |
最佳實務
- 始終處置用戶端 — 使用
using 陳述式或明確處置
- 以適當間隔輪詢 — 建議在狀態檢查之間延遲 500 毫秒
- 清理資源 — 完成後刪除對話串和代理
- 處理所有執行狀態 — 檢查
RequiresAction、Failed、Cancelled
- 使用串流改善即時體驗 — 比輪詢提供更好的使用者體驗
- 儲存 ID 而非物件 — 透過 ID 引用代理/對話串
- 使用非同步方法 — 所有操作應為非同步
錯誤處理
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 | 低階代理(此 SDK) | dotnet add package Azure.AI.Agents.Persistent |
Azure.AI.Projects | 高階專案用戶端 | dotnet add package Azure.AI.Projects |
參考連結