有些时候将 Agent 当成一个工具分发源,期望 Agent 在完成调用工具之后就退出对话,不需要将工具结果再次返回给到模型
本文采用的 Microsoft Agent Framework 为 1.0.0-rc4 版本
现在很多时候都采用模型编排的方式,支持 Agent As Tool 的模式,即将模型当成工具给到另一个模型使用的方式
此时的上级模型可能只是一个调度分发的功能,工具执行的结果不期望返回给到上级模型,希望调用完工具就自动退出对话
在 Microsoft Agent Framework 的函数工具调用是通过 Microsoft.Extensions.AI 的 FunctionInvokingChatClient 提供的
可以通过 UseFunctionInvocation 扩展方法进行配置,配置时可设置 FunctionInvokingChatClient 的 FunctionInvoker 委托属性。通过此 FunctionInvoker 委托属性,可以在每次函数工具被调用的时候触发。在此委托里的 FunctionInvocationContext 参数里面,通过设置 Terminate 属性,即可控制是否在调用完成工具之后立刻退出对话
示例内容如下:
OpenAI.Chat.ChatClient chatClient = ...;
var agent = chatClient.AsIChatClient()
.AsBuilder()
// 在 ChatClientExtensions.cs 的 WithDefaultAgentMiddleware 会判断是否有 FunctionInvokingChatClient 从而来决定是否注册
//.Use((innerClient, services) =>
//{
// var functionInvokingChatClient = innerClient.GetService<FunctionInvokingChatClient>();
// var invokingChatClient = services.GetService<FunctionInvokingChatClient>();
// return innerClient;
//})
.UseFunctionInvocation(configure: functionInvokingChatClient =>
{
functionInvokingChatClient.FunctionInvoker = (context, token) =>
{
// 写入属性,即可在调用函数之后退出
context.Terminate = true;
return context.Function.InvokeAsync(context.Arguments, token);
};
})
.BuildAIAgent(options: new ChatClientAgentOptions()
{
ChatOptions = new ChatOptions()
{
Tools =
[
AIFunctionFactory.Create(GetWeather)
]
}
});
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location,
[Description("查询天气的日期")] string date)
{
Console.WriteLine($"调用函数");
return $"查询不到 {location} 城市信息";
}
此时的代码里面,无论调用的函数是什么,都会设置 Terminate 属性,这就意味着一旦模型尝试调用工具,则会在工具完成之后立刻退出对话
await foreach (var reasoningAgentResponseUpdate in agent.RunReasoningStreamingAsync(new ChatMessage(ChatRole.User,
"今天北京的天气咋样.")))
{
if (reasoningAgentResponseUpdate.IsFirstThinking)
{
Console.WriteLine($"思考:");
}
if (reasoningAgentResponseUpdate.IsThinkingEnd && reasoningAgentResponseUpdate.IsFirstOutputContent)
{
Console.WriteLine();
Console.WriteLine("----------");
}
Console.Write(reasoningAgentResponseUpdate.Reasoning);
Console.Write(reasoningAgentResponseUpdate.Text);
}
Console.WriteLine($"结束");
Console.WriteLine();
Console.Read();
尝试运行代码,可以看到模型在对话过程中,尝试调用 GetWeather 方法。方法执行完成之后,对话也就结束了
如此可见工具的结果不会返回到模型里,如此也就可以很方便地被设计为让模型只负责工具的调用分发,而不让模型对工具返回结果感兴趣
本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码。我整个代码仓库比较庞大,使用以下命令行可以进行部分拉取,拉取速度比较快
先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 743fb8a7885af20c265dbd323dd703c912e41774
以上使用的是国内的 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码。如果依然拉取不到代码,可以发邮件向我要代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 743fb8a7885af20c265dbd323dd703c912e41774
获取代码之后,进入 SemanticKernelSamples/BejalljeawakihereKearyojileelai 文件夹,即可获取到源代码
更多技术博客,请参阅 博客导航
本文会经常更新,请阅读原文: https://blog.lindexi.com/post/dotnet-Microsoft-Agent-Framework-%E9%85%8D%E7%BD%AE%E8%B0%83%E7%94%A8%E5%B7%A5%E5%85%B7%E5%90%8E%E9%80%80%E5%87%BA%E5%AF%B9%E8%AF%9D.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航
本作品采用
知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议
进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:
https://blog.lindexi.com
),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请
与我联系
。
无盈利,不卖课,做纯粹的技术博客
以下是广告时间
推荐关注 Edi.Wang 的公众号
欢迎进入 Eleven 老师组建的 .NET 社区
以上广告全是友情推广,无盈利