AIModelRouter
AI模型路由,模型的能力有大小之分,有些簡(jiǎn)單任務(wù),能力小一點(diǎn)的模型也能很好地完成,而有些比較難的或者希望模型做得更好的,則可以選擇能力強(qiáng)的模型。為什么要這樣做呢?可以降低AI模型的使用成本,畢竟能力強(qiáng)的模型會(huì)更貴一點(diǎn),省著用挺好的。
Semantic Kernel中可以很簡(jiǎn)便地使用一個(gè)AIModelRouter。
實(shí)踐
先來(lái)一個(gè)簡(jiǎn)單的例子
來(lái)自https://github.com/microsoft/semantic-kernel/tree/main/dotnet/samples/Demos/AIModelRouter
新建一個(gè)CustomRouter類,如下所示:
internal sealed class CustomRouter()
{
internal string GetService(string lookupPrompt, List<string> serviceIds)
{
foreach (var serviceId in serviceIds)
{
if (Contains(lookupPrompt, serviceId))
{
return serviceId;
}
}
return serviceIds[0];
}
private static bool Contains(string prompt, string pattern)
=> prompt.IndexOf(pattern, StringComparison.CurrentCultureIgnoreCase) >= 0;
}
新建一個(gè)SelectedServiceFilter類用于打印一些信息:
internal sealed class SelectedServiceFilter : IPromptRenderFilter
{
public Task OnPromptRenderAsync(PromptRenderContext context, Func<PromptRenderContext, Task> next)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Selected service id: '{context.Arguments.ExecutionSettings?.FirstOrDefault().Key}'");
Console.ForegroundColor = ConsoleColor.White;
Console.Write("Assistant > ");
return next(context);
}
}
使用多個(gè)模型:
![](/files/attmgn/2025/1/freeflydom20250109093344476_0.jpg)
為捕獲路由器選擇的服務(wù) ID 添加自定義過(guò)濾器:
![](/files/attmgn/2025/1/freeflydom20250109093344613_1.jpg)
開(kāi)啟一個(gè)聊天循環(huán):
Console.ForegroundColor = ConsoleColor.White;
ChatHistory history = [];
string history1 = string.Empty;
bool isComplete = false;
do
{
Console.WriteLine();
Console.Write("> ");
string? input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
continue;
}
if (input.Trim().Equals("EXIT", StringComparison.OrdinalIgnoreCase))
{
isComplete = true;
break;
}
if (input.Trim().Equals("Clear", StringComparison.OrdinalIgnoreCase))
{
history.Clear();
history1 = " ";
Console.WriteLine("已清除聊天記錄");
continue;
}
history.Add(new ChatMessageContent(AuthorRole.User, input));
history1 += $"User:{input}\n";
Console.WriteLine();
KernelArguments arguments = new(new PromptExecutionSettings()
{
ServiceId = router.GetService(input, serviceIds).Result,
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
});
var result = await kernel.InvokePromptAsync(history1, arguments).ConfigureAwait(false);
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(result);
Console.WriteLine();
history.AddMessage(AuthorRole.Assistant, result.ToString());
history1 += $"Assistant:{result}\n";
} while (!isComplete);
}
}
來(lái)看看現(xiàn)在這個(gè)簡(jiǎn)單的路由規(guī)則:
![](/files/attmgn/2025/1/freeflydom20250109093344636_2.jpg)
當(dāng)你的提問(wèn)中包含一個(gè)ServiceId的時(shí)候,就會(huì)選擇那個(gè)服務(wù)ID對(duì)應(yīng)的模型進(jìn)行回復(fù),如果不包含就選擇第一個(gè)服務(wù)ID對(duì)應(yīng)的模型進(jìn)行回復(fù)。
實(shí)際上這樣使用,很容易讓AI迷惑,因?yàn)槲覀兛偸且獛弦粋€(gè)ServiceId,如果讓AI根據(jù)用戶的提問(wèn),自己決定用哪個(gè)模型是更好的。
進(jìn)階使用,用AI自己來(lái)決定
![](/files/attmgn/2025/1/freeflydom20250109093344805_3.jpg)
使用一個(gè)靠譜的AI模型來(lái)做這個(gè)事情比較好。
我們輸入你好,那么Prompt就會(huì)變成這樣:
![](/files/attmgn/2025/1/freeflydom20250109093344883_4.jpg)
AI返回的結(jié)果如下:
![](/files/attmgn/2025/1/freeflydom20250109093344928_5.jpg)
![](/files/attmgn/2025/1/freeflydom20250109093344946_6.jpg)
再試試其他幾個(gè)怎么觸發(fā):
![](/files/attmgn/2025/1/freeflydom20250109093345014_7.jpg)
而工具調(diào)用與其他比較容易混淆,因?yàn)榫退闶俏覀冏约海埠茈y分辨有什么區(qū)別:
![](/files/attmgn/2025/1/freeflydom20250109093345040_8.jpg)
這時(shí)候或許修改Prompt可以奏效。
修改后的Prompt如下:
string skPrompt = """
根據(jù)用戶的輸入,返回最佳服務(wù)ID。
如果用戶需要獲取當(dāng)前時(shí)間與寫(xiě)郵件,則選擇工具調(diào)用相關(guān)的服務(wù)ID。
用戶輸入:
{{$input}}
服務(wù)ID列表:
{{$serviceIds}}
無(wú)需返回任何其他內(nèi)容,只需返回服務(wù)ID。
""";
效果如下所示:
![](/files/attmgn/2025/1/freeflydom20250109093345064_9.jpg)
以上就是本次分享的全部?jī)?nèi)容,希望對(duì)你有所幫助。
?轉(zhuǎn)自https://www.cnblogs.com/mingupupu/p/18654982
該文章在 2025/1/9 9:34:20 編輯過(guò)