Microsoft Agent Framework がリリースされたため、少しずつ検証しています。
まずはチュートリアルを試していますが、「人間の介入を含む承認プロセスで関数ツールを使用する」というサンプルで少し悩んだので、メモを残しておきます。
ドキュメントにあるサンプルコードをまとめると以下のようになります。
using Azure.AI.OpenAI; using Azure.Identity; using Microsoft.Agents.AI; using Microsoft.Extensions.AI; using OpenAI; using System.ComponentModel; namespace MicrosoftAgentFrameworkTutorialAgentApp; internal class ApprovalToolSample { internal static async Task RunAsync() { // https://learn.microsoft.com/ja-jp/agent-framework/tutorials/agents/function-tools-approvals Console.WriteLine("*** Function tools with approval ***"); AIFunction weatherFunction = AIFunctionFactory.Create(GetWeather); AIFunction approvalRequiredWeatherFunction = new ApprovalRequiredAIFunction(weatherFunction); AIAgent agent = new AzureOpenAIClient( new Uri("https://<myresource>.openai.azure.com"), new AzureCliCredential()) .GetChatClient("gpt-4o") .CreateAIAgent(instructions: "You are a helpful assistant", tools: [approvalRequiredWeatherFunction]); AgentThread thread = agent.GetNewThread(); AgentRunResponse response = await agent.RunAsync("What is the weather like in Fukuoka?", thread); var functionApprovalRequests = response.Messages .SelectMany(x => x.Contents) .OfType<FunctionApprovalRequestContent>() .ToList(); FunctionApprovalRequestContent requestContent = functionApprovalRequests.First(); Console.WriteLine($"We require approval to execute '{requestContent.FunctionCall.Name}'"); ChatMessage approvalMessage = new(ChatRole.User, [requestContent.CreateResponse(true)]); Console.WriteLine(await agent.RunAsync(approvalMessage, thread)); Console.WriteLine(); } [Description("Get the weather for a given location.")] static string GetWeather([Description("The location to get the weather for.")] string location) => $"The weather in {location} is cloudy with a high of 15°C."; }
上記コードを実行すると、承認が要求されることなくエージェントからの応答が返ってきてしまいます。
*** Function tools with approval *** We require approval to execute 'GetWeather' The current weather in Fukuoka is cloudy, with a high temperature of 15°C.
なぜかと思いコードを読んでいると、この部分で「承認している」ことになっていることが分かりました。
ChatMessage approvalMessage = new(ChatRole.User, [requestContent.CreateResponse(true)]);
CreateResponse メソッドの定義を見ると、引数に承認の状態をbool値で渡すようになっています。
サンプルコードでは true を渡しているため、承認されたことになってしまうわけです。
そこで、承認するかどうかを標準入力によって決定するように変更しました。
Console.Write("Approval(y/n): "); string approval = Console.ReadLine() ?? ""; ChatMessage approvalMessage = new(ChatRole.User, [requestContent.CreateResponse(approval == "y")]);
承認したとき:
*** Function tools with approval *** We require approval to execute 'GetWeather' Approval(y/n): y The weather in Fukuoka is currently cloudy, with a high temperature of 15°C.
承認しなかったとき:
*** Function tools with approval *** We require approval to execute 'GetWeather' Approval(y/n): n I couldn't fetch the weather for Fukuoka. Would you like me to try again?
やっぱりサンプルコードもちゃんと読まんといけませんね。