【Semantic Kernel】Chat聊天服务
生成式AI之所以火爆,是通过ChatGPT引起的,因为这种智能对话(chat)式交互,颠覆人们对人机对话的认识和理解,它可以真人一样把上下文串起来,进行整体的理解和回复。当然,SK会在早期的版中就进行了适配,SK让聊天上下文留存是通过ChatHistory实现的,并且这些内存会区分角色,当前1.15.0的包中角色有四种:System,Assistant,User,Tool,下面说明一下四种角色的功能和作用:
- System (系统): 这个角色指示或设置助理的行为。在系统中,它可能是管理权限、控制流程或执行系统级任务的角色。
- Assistant (助理): 这个角色提供对系统指令和用户提示输入的响应。在对话中,助理角色是向用户提供帮助、回答问题或执行任务的角色。
- User (用户): 这个角色提供聊天完成所需的输入。在对话中,用户角色代表与系统交互的实际人类用户,他们提出问题或请求信息。
- Tool (工具): 这个角色提供聊天完成所需的额外信息和参考资料。在对话中,工具角色可能是提供支持功能、数据查询或其他辅助性任务的角色。
代码:
public static class OpenAiChatSample
{
public static async Task Exec()
{
//chatgpt
var builder = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(modelId: Config.OpenAiChatModel, Config.OpenAiKey);
var kernel = builder.Build();
await ChatStream(kernel);// Chat(kernel);
}
public static async Task Chat(Kernel kernel)
{
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
var history = new ChatHistory();
string? userInput;
do
{
Console.ResetColor();
Console.Write("User > ");
userInput = Console.ReadLine();
history.AddUserMessage(userInput);
var result = await chatCompletionService.GetChatMessageContentAsync(history, kernel: kernel);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"{result.Role.Label} > " + result);
// Add the message from the agent to the chat history
history.AddMessage(result.Role, result.Content ?? string.Empty);
} while (userInput is not null);
}
/// <summary>
/// 流式响应(如果回复内容过多,需要等待,用户体验不好,建议使用流式响应)
/// </summary>
/// <param name="kernel"></param>
/// <returns></returns>
public static async Task ChatStream(Kernel kernel)
{
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
var history = new ChatHistory();
string? userInput;
do
{
Console.ResetColor();
Console.Write("User > ");
userInput = Console.ReadLine();
history.AddUserMessage(userInput);
AuthorRole? role = AuthorRole.Assistant;
var contentBuilder = new StringBuilder();
Console.ForegroundColor = ConsoleColor.Green;
await foreach (var reply in chatCompletionService.GetStreamingChatMessageContentsAsync(history, kernel: kernel))
{
if (reply.Role.HasValue)
{
Console.Write(role.Value.Label + " > ");
if (role != reply.Role)
{
role = reply.Role;
}
}
Console.Write(reply.Content);
}
history.AddMessage(role.Value, contentBuilder.ToString());
Console.WriteLine();
} while (userInput is not null);
}
}