Notebook 多轮聊天

第一步,部署一个模型,开源私有或者Saas API 都可以。

具体部署代码如下:


!byzerllm setup single;

run command as LLM.`` where 
action="infer"
and pretrainedModelType="llama"
and localModelDir="/home/winubuntu/projects/llama-7b-cn"
and udfName="chat"
and modelTable="command";

这里我们部署了一个 llama7b 模型,并且将该函数映射成 chat 函数。 这个名字可以随意。

接着通过注释和该模型对话:

--%chat
--%model=chat
--%system_msg=You are a helpful assistant. Think it over and answer the user question correctly.
--%user_role=User
--%assistant_role=Assistant
--%output=q0

你好,请记住我的名字,祝威廉。

上面注释其实就是一些配置,这些配置的含义如下:

namedescription
chat这个参数是个标记参数,表示这个 Notebook Cell 是一个聊天输入框
model我们前面部署的函数名称,这里是chat
system_msg第一次聊天,可以设置的一个系统消息。You are a helpful assistant. Think it over and answer the user question correctly.
user_role比如上面设置成User,那么在产生的消息对话中,用户消息使用 User: 进行标记
assistant_role比如上面设置成Assistant,那么在产生的消息对话中,模型的输出消息使用 Assistant: 进行标记
output该会话的引用
input基于那个对话继续往后聊
--%chat
--%model=chat
--%user_role=User
--%assistant_role=Assistant
--%input=q0
--%output=q1

请问我的名字是什么

这个是我们第二段对话,其中我们把 input设置为 q0, 这个时候会接着 q0 聊,所以系统能够顺利的说出我的名字。 此时也不需要在设置 system_msg, 因为我们在对话 q0 已经设置过了。

后续对话只要不断变化 input/output,形成对话链路就可以。

我们也可以跳过一些对话,比如现在有 q0, q1... q9 十段对话,如果希望跳过 q1-q6 这六个对话,那么可以将q7 的input设置为 q0, 此时 对话内容为 q0 q7 q8 q9。

 

SQL 多轮聊天

我们也可以直接使用 SQL 进行多轮聊天。

比如在 Notebook 的多轮多话用纯SQL实现,如下:

第一段对话:

select chat(llm_param(map(
    "system_msg",'You are a helpful assistant. Think it over and answer the user question correctly.',
    "instruction",'你好,请记住我的名字,我叫祝威廉。如果记住了,请说记住。',
    "temperature","0.1",
    "user_role","User",
    "assistant_role","Assistant"
))) as q as q1;

这里,我们使用 llm_param 函数组装chat 函数需要的请求数据格式,并且我们给 对话通过表名来标记, 起名为 q1。

接着我们进行第二段对话:

select  chat(llm_stack(q,llm_param(map(
    
    "instruction",'请问我叫什么名字?',
    "temperature","0.1",
    "user_role","User",
    "assistant_role","Assistant"
)))) as q from q1 as q2;

这里我们基于 q1 进行进行对话,这里是通过 llm_stack 函数来配合的。 llm_stack 函数接受两个参数:

  1. 上一轮对话的结果 q
  2. 这次对话的参数,也就是通过 llm_param 函数来进行拼接。

llm_stack 会自动从从 q1 表的 q 字段抽取历史对话信息,并且和当前的新构建的对话信心进行组合,然后转化成模型可以接受的格式, 从而实现多轮对话。

此外,我们可能经常需要模板的功能,Byzer-LLM 提供了 llm_prompt 函数,该函数可以使用SQL 表中的字段进行prompt 进行渲染。

比如下面的例子:

select id,
chat(llm_param(map(
              "system_msg",'You are a helpful assistant. Think it over and answer the user question correctly.',
              "instruction",llm_prompt('
Use the following Contents and Rules answer the question at the end. If you do not know the answer, just say that you do not know, do not try to make up an answer.

The Contents:

{0}


Please summary the Contents.
',array(Contents))

)))

 as q,Rules from it_table as q1;
 

我们使用 {0} 作为占位符,然后使用 it_table 表中的 Contents 对该占位符进行替换,之后把渲染的新内容再通过 llm_param 函数进行组装, 最后交给 chat 函数进行应答。 注意这里,你可以使用多个占位符,从而传递多个参数,只要按序号传递即可。

比如下面的例子,

select llm_prompt('
Use the following Contents and Rules answer the question at the end. If you do not know the answer, just say that you do not know, do not try to make up an answer.

The Contents:

{0}


{1}

{0}

Please summary the Contents.
',array(Contents,"YES")))

as template as output;

{0} 会被 Contents 字段替换, {1} 会被 "YES" 字符串替换。用户可以在Notebook 自行体验。

优化 Tips

因为和大模型交互是昂贵的,为了防止反复请求,我们可以讲每一轮对话进行持久化。

创建一个命令persist_table:

set persist_table='''
 save overwrite {0} as parquet.`/tmp/test/{0}`;
 load parquet.`/tmp/test/{0}` as {0}
''' where scope="session";

之后就可以在后续cell中这么用:

select chat(llm_param(map(
    "system_msg",'You are a helpful assistant. Think it over and answer the user question correctly.',
    "instruction",'你好,请记住我的名字,我叫祝威廉。如果记住了,请说记住。',
    "temperature","0.1",
    "user_role","User",
    "assistant_role","Assistant"
))) as q as q1;

!persist_table q1;

后续Cell 引用该 q1的时候,就不会触发对话的重复执行。

Logo

更多推荐