logo
7
话题头图

【千帆SDK+Semantic-Kernel】多轮对话ChatBot

💡学习前小提示
请大家点击链接并加🌟:https://github.com/baidubce/bce-qianfan-sdk

Semantic Kernel

Semantic-Kernel(以下简称SK),是微软开源的一个大模型轻量开发框架,它抽象出了大语言模型应用中主要的几大概念:
  • Plugins/Skills:Function集合
  • Planner: 根据任务goal,skills等信息,生成任务计划
  • Memory: 保存历史任务状态数据
  • connectors:与数据库、LLM等组件交互组件
在实现上,SK主要围绕Plugin/Skill(Function集合)进行串联,把每一个功能函数/prompt配置等抽象成一个NativeFunction/SemanticFunction,以此实现更中度的功能集合,再将这些功能集合通过与LLM、数据库等组件进行交互,以实现LLM原生应用。
接下来我们以一个实际的案例来说明如何使用SK+千帆SDK以实现一个基于SK Plugin的多轮对话ChatBot.

前置准备

安装依赖:

本文基于semantic-kernel0.4.5dev0版本,由于 SK持续迭代的原因,原来的Skill正在迁移成Plugin,如碰到不兼容问题请检查依赖版本。 使用以下命令可以安装我们所需要的qianfan以及semantic-kernel
  
  
! pip install "qianfan>=0.3.0" -U
! pip install semantic-kernel=='0.4.5.dev0'
与直接调用千帆SDK类似,我们需要先初始化鉴权(以下以使用IAM鉴权为例):
  
  
import os
os.environ["QIANFAN_ACCESS_KEY"] = "your_ak"
os.environ["QIANFAN_SECRET_KEY"] = "your_sk"
初始化一个SKkernel, kernel是 SK中的一个重要类型,通过Kernel,我们可以把众多Plugin,LLM,以及Memory等进行注册组合,最终实现一键式的规划调用。
  
  
import semantic_kernel as sk
kernel = sk.Kernel()
初始化兼容SK的千帆ChatCompletion service对象,并注册到kernel中: 对于续写场景,QianfanChatCompletion也实现了对应的抽象类方法,所以可以统一使用。
  
  
from qianfan.extensions.semantic_kernel.connectors.qianfan_chat_completion import QianfanChatCompletion
qfchat = QianfanChatCompletion(ai_model_id="ERNIE-Bot")
# 注册service_id 以及对应的service对象
kernel.add_chat_service(
"qianfan", qfchat
)
# kernel.add_text_completion_service(
# "qianfan_text", qfchat
# )
定义一个PromptTemplate,以及调用大模型时候会用到的PromptTemplateConfig,基于prompt config我们可以构造出一个semantic function用于调用,并注册到kernel中:
  
  
sk_prompt = """
你是一个ChatBot,可以跟用户产生多轮对话,并根据用户输入和历史对话进行输出
{{$chat_history}}
用户:> {{$user_input}}
输出:>
"""
prompt_config = sk.PromptTemplateConfig.from_completion_parameters(temperature=0.7, top_p=0.4)
prompt_template = sk.PromptTemplate(sk_prompt, kernel.prompt_template_engine, prompt_config)
function_config = sk.SemanticFunctionConfig(prompt_config, prompt_template)
chat_function = kernel.register_semantic_function("ChatBot", "Chat", function_config)
在以下代码中我们构造了了一个读取用户输入,并使用sk.ContextVariables来处理历史对话消息。
  
  
async def chat(context_vars: sk.ContextVariables) -> bool:
try:
user_input = input("用户:> ")
context_vars["user_input"] = user_input
except KeyboardInterrupt:
print("\n\nExiting chat...")
return False
except EOFError:
print("\n\nExiting chat...")
return False
if user_input == "exit":
print("\n\nExiting chat...")
return False
# 在context中不断填充历史聊天记录
answer = await kernel.run_async(chat_function, input_vars=context_vars)
context_vars["chat_history"] += f"\用户:> {user_input}\nChatBot:> {answer}\n"
print(f"ChatBot:> {answer}")
return True
context = sk.ContextVariables()
context["chat_history"] = ""
构造循环实现多轮对话:
  
  
async def main():
chatting = True
while chatting:
chatting = await chat(context)
await main()
  
  
用户:>hi
ChatBot:> 你好,有什么我可以帮助你的吗?
用户:>你是谁
ChatBot:> 你好,我是一个ChatBot,我可以跟用户产生多轮对话,并根据用户输入和历史对话进行输出。
请问你有什么需要帮助的吗?
用户:>你知道baidu吗
ChatBot:> 当然知道,Baidu是中国最大的搜索引擎之一。你想了解它的什么信息呢?
用户:>它的历史
ChatBot:> Baidu是由李彦宏在2000年创立的,是一家专注于搜索引擎技术的公司。它在中国拥有广泛的用户群体,并且提供各种搜索服务,如网页搜索、图片搜索、视频搜索等。如果你需要更多关于Baidu的信息,我很乐意为你提供帮助。
Exiting chat...
评论
用户头像