azure-ai-agents-persistent-dotnet について
永続的なAIエージェント、スレッド、メッセージ、実行、ツールを作成・管理する低レベルの.NET SDKです。非同期実行とストリーミングに対応し、組み込みツールとカスタムツールを利用できます。
主な機能
- 01エージェントとスレッドの作成・管理
- 02メッセージ送信と実行処理
- 03実行状態とテキストのストリーミング
- 04ファイル検索とベクトルストアの設定
- 05関数や各種ツールの接続
活用シーン
- 01永続型AIエージェントアプリの構築
- 02エージェントへのファイル検索追加
- 03カスタム関数呼び出しの処理
- 04ストリーミング更新による実行進捗の表示
MCP 対応
SDKは、エージェントが利用するMCPツールを設定するMCPToolDefinitionを提供します。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 エージェントを作成、管理するための低レベル 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. エージェントの作成
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. エージェントの実行(ポーリング)
// 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 グラウンディング
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);
利用可能なツール
| ツール | クラス | 目的 |
|---|---|---|
| コードインタープリター | CodeInterpreterToolDefinition | Python コードを実行し、可視化を生成します |
| ファイル検索 | FileSearchToolDefinition | ベクトルストア経由でアップロード済みファイルを検索します |
| 関数呼び出し | FunctionToolDefinition | カスタム関数を呼び出します |
| Bing グラウンディング | 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 | モデル、指示、ツールを備えたエージェント |
PersistentAgentThread | 会話スレッド |
PersistentThreadMessage | スレッド内のメッセージ |
ThreadRun | スレッドに対するエージェントの実行 |
RunStatus | キュー登録済み、実行中、アクションが必要、完了、失敗 |
ToolResources | 統合されたツールリソース |
ToolOutput | 関数呼び出しの応答 |
ベストプラクティス
- SDK クライアントを再利用する — インストールした SDK のライフタイムに関するガイダンスに従ってください。すべてのクライアントが IDisposable を実装しているとは限りません
- 適切な間隔でポーリングする — ステータス確認の間隔は 500ms が推奨です
- リソースをクリーンアップする — 使用後はスレッドとエージェントを削除してください
- すべての実行ステータスを処理する —
RequiresAction、Failed、Cancelledを確認してください - リアルタイムの UX にはストリーミングを使用する — ポーリングより優れたユーザーエクスペリエンスを提供します
- オブジェクトではなく 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 |
参考リンク
使用する場面
このスキルは、概要で説明されているワークフローまたはアクションを実行する場合に適用できます。
制限事項
- このスキルは、タスクが上記の説明範囲に明確に当てはまる場合にのみ使用してください。
- 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
- 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認を求めてください。