当前位置: 首页 > news >正文

大模型提示词工程实践:聊天机器人定制与实践-打造个性化任务助手

#大模型聊天格式

学习目标

通过本课程,你将学会利用聊天格式与个性化的语言,实现一个专门针对特定任务或行为的聊天机器人并与它进行扩展对话。

相关知识点

大模型聊天格式

学习内容

1 大模型聊天格式

大模型聊天格式主要通过消息角色体系与对话历史机制实现人机交互,其核心要素包括:

  • 角色定义:通过role字段区分不同身份,常见角色包括:
    **system:**设定模型的行为准则和任务定位(如 “你是一个医学顾问”)
    **user:**用户输入的文本内容(如提问、指令)
    **assistant:**模型生成的回复内容
  • 消息结构:每条消息为 JSON 对象,包含role和content字段,示例:
    {“role”: “user”, “content”: “请推荐一本科幻小说”}
    对话历史:通过维护消息列表(如messages)记录完整交互过程,模型基于历史信息生成响应
1.1 准备工作

安装进行本课程需要的python依赖

%pip install httpx
%pip install openai
%pip install panel==1.2.3

上述依赖中,httpx 是一个用于进行 HTTP 请求的库,我们可以使用它来向大模型发送请求并获取响应。 openai 库提供了统一的接口来调用大模型。panel 是一个用于创建交互式 Web 应用程序的库,我们会用它来创建一个简单的界面,方便我们与点单机器人进行交互。

安装完依赖后,我们需要初始化大模型相关参数。

import os
import httpx
from openai import OpenAI# 此课程基于DeepSeek-R1运行,学员可自行前往官网进行api申请
client = OpenAI(base_url=<BASE_URL>,api_key=<API_KEY>,http_client=httpx.Client(verify=False),
)

接下来,我们定义了一个函数 extract_after_think,用于从模型的响应中提取特定的内容。

from openai import ChatCompletion
def extract_after_think(chat_completion: ChatCompletion) -> str:content = chat_completion.choices[0].message.contentstart_index = content.find("</think>")if start_index != -1:return content[start_index + len("</think>"):]else:return ""

在这个函数中,我们首先获取模型响应中的消息内容content,然后查找字符串 在content中的位置 start_index。如果找到了这个字符串,我们就返回 之后的内容;如果没有找到,就返回一个空字符串。 然后,我们定义了两个函数 get_completion和 get_completion_from_messages,用于与大模型进行交互。

1.2 调用大模型

get_completion函数用于向模型发送单个用户提示,并获取模型的响应。它将提示封装在 messages列表中,然后调用 client.chat.completions.create方法与模型进行交互,最后调用 extract_after_think函数处理响应。

#请根据实际替换model_name
def get_completion(prompt, temperature=0.6):messages = [{"role": "user", "content": prompt}]response = client.chat.completions.create(model=<model_name>,messages=messages,stream=False,temperature=temperature,max_tokens=2048,top_p=0.95)return extract_after_think(response)

get_completion_from_messages 函数用于向模型发送一组消息,并获取模型的响应。它首先过滤掉 content为空的消息,然后调用 client.chat.completions.create方法与模型进行交互,最后调用 extract_after_think 函数处理响应。

def get_completion_from_messages(messages, temperature=0.6):# 过滤掉 content 为空的消息valid_messages = [msg for msg in messages if msg.get('content')]response = client.chat.completions.create(model="Deepseek-R1",messages=valid_messages,stream=False,temperature=temperature,max_tokens=2048,top_p=0.95)return extract_after_think(response)

下面,我们通过一些示例消息来展示如何让大模型扮演不同的角色,并与用户进行交互。

messages =  [  
{'role':'system', 'content':'You are an assistant that speaks like Shakespeare.'},    
{'role':'user', 'content':'tell me a joke'},   
{'role':'assistant', 'content':'Why did the chicken cross the road'},   
{'role':'user', 'content':'I don\'t know'}  ]

在这个示例中,我们设置了三个角色的消息。system 角色告诉大模型它要扮演一个说话像莎士比亚的助手。user 角色向大模型提出了一个请求,让大模型讲一个笑话。assistant 角色给出了一个回答,然后 user 角色表示不知道答案。

接下来,我们把这些对话历史输入给大模型,看看它的输出。通过调用get_completion_from_messages函数,我们将这些消息发送给大模型,并获取大模型的响应,最后打印出响应内容。

response = get_completion_from_messages(messages, temperature=1)
print(response)

然后,我们尝试让大模型记住我们的名字。

在这个例子中,我们设置了一个 system 角色,告诉大模型它是一个友好的聊天机器人。然后 user 角色告诉大模型自己的名字是 Isa。通过调用 get_completion_from_messages 函数,我们获取大模型的响应,并打印出来。

messages =  [  
{'role':'system', 'content':'You are friendly chatbot.'},    
{'role':'user', 'content':'Hi, my name is Isa'}  ]
response = get_completion_from_messages(messages, temperature=1)
print(response)
messages =  [  
{'role':'system', 'content':'You are friendly chatbot.'},    
{'role':'user', 'content':'Yes,  can you remind me, What is my name?'}  ]
response = get_completion_from_messages(messages, temperature=1)
print(response)

这里,user 角色询问大模型自己的名字,我们再次调用 get_completion_from_messages 函数获取大模型的响应。从上面的回答可以看出,两次分开与大模型对话,它并不能识别出第二次的用户是谁。

正确的操作是将整个对话历史都传递给大模型,让大模型能够记住之前的信息。

messages =  [  
{'role':'system', 'content':'You are friendly chatbot.'},
{'role':'user', 'content':'Hi, my name is Isa'},
{'role':'assistant', 'content': "Hi Isa! It's nice to meet you. \
Is there anything I can help you with today?"},
{'role':'user', 'content':'Yes, you can remind me, What is my name?'}  ]
response = get_completion_from_messages(messages, temperature=1)
print(response)

在这个例子中,我们将整个对话历史都传递给大模型,包括 user 告诉大模型自己的名字,assistant 的回复,以及 user 再次询问自己的名字。这样,大模型就能够记住之前的信息,并给出正确的回答。

1.3 实现点单机器人

下面,我们定义了一个名为collect_messages 的函数,用于处理用户输入的消息,并与大模型进行交互。

在这个函数中,我们首先获取用户输入的提示prompt,并将输入框的值清空。然后,我们将用户的提示添加到 context 列表中,其中 role 为 “user”,content 为用户的提示内容。接着,我们调用get_completion_from_messages 函数,将 context列表作为参数传递给它,获取大模型的响应response。然后,我们将大模型的响应添加到context列表中,其中role为 “assistant”,content为大模型的响应内容。最后,我们将用户和大模型的消息添加到panels列表中,并返回一个包含所有消息的 pn.Column对象。

def collect_messages(_):prompt = inp.value_inputinp.value = ''context.append({'role':'user', 'content':f"{prompt}"})response = get_completion_from_messages(context) context.append({'role':'assistant', 'content':f"{response}"})user_panel = pn.GridBox(pn.pane.Markdown("User:", width=70, style={'font-weight': 'bold'}),pn.pane.Markdown(prompt, width=600,  # 限制最大宽度sizing_mode="fixed",style={'white-space': 'pre-wrap', 'word-wrap': 'break-word'}),ncols=2,sizing_mode="stretch_width")assistant_panel = pn.GridBox(pn.pane.Markdown("Assistant:", width=70, style={'font-weight': 'bold'}),pn.pane.Markdown(response, width=600,sizing_mode="fixed",style={'white-space': 'pre-wrap','word-wrap': 'break-word','background-color': '#F6F6F6','border-radius': '5px','padding': '8px'}),ncols=2,sizing_mode="stretch_width",margin=(0, 0, 15, 0))panels.append(user_panel)panels.append(assistant_panel)return pn.Column(*panels, sizing_mode="stretch_width")

下面的代码通过提示词的设置,实现一个简单的点单机器人。(大模型回复耗时较长,请耐心等待)

在这段代码中,我们首先导入了 panel 库,并使用 pn.extension() 启用 panel 的扩展功能。然后,我们创建了两个空列表 panels 和 context,分别用于收集显示的内容和对话历史。

接下来,我们定义了一个 context 列表,其中包含一个 system 角色的消息,告诉大模型它是一个披萨店的点单机器人,并详细说明了点单机器人的任务和菜单信息。然后,我们创建了一个文本输入框 inp 和一个按钮 button_conversation。文本输入框用于用户输入消息,按钮用于触发与点单机器人的对话。

最后,我们使用 pn.bind 函数将 collect_messages 函数与按钮 button_conversation 绑定,这样当用户点击按钮时,就会调用 collect_messages 函数处理用户输入的消息。

import panel as pn
pn.extension(sizing_mode="stretch_width")  # 启用响应式布局panels = []  # 收集显示内容context = [ {'role':'system', 'content':"""
You are OrderBot, an automated service to collect orders for a pizza restaurant. \
You first greet the customer, then collects the order, \
and then asks if it's a pickup or delivery. \
You wait to collect the entire order, then summarize it and check for a final \
time if the customer wants to add anything else. \
If it's a delivery, you ask for an address. \
Finally you collect the payment.\
Make sure to clarify all options, extras and sizes to uniquely \
identify the item from the menu.\
You respond in a short, very conversational friendly style. \
The menu includes \
pepperoni pizza  12.95, 10.00, 7.00 \
cheese pizza   10.95, 9.25, 6.50 \
eggplant pizza   11.95, 9.75, 6.75 \
fries 4.50, 3.50 \
greek salad 7.25 \
Toppings: \
extra cheese 2.00, \
mushrooms 1.50 \
sausage 3.00 \
canadian bacon 3.50 \
AI sauce 1.50 \
peppers 1.00 \
Drinks: \
coke 3.00, 2.00, 1.00 \
sprite 3.00, 2.00, 1.00 \
bottled water 5.00 \
"""} ]inp = pn.widgets.TextInput(value="Hi", placeholder='Enter text here…',sizing_mode="stretch_width"
)
button_conversation = pn.widgets.Button(name="Chat!",button_type="primary",sizing_mode="fixed",width=100
)interactive_conversation = pn.bind(collect_messages, button_conversation)dashboard = pn.Column(inp,pn.Row(button_conversation, sizing_mode="fixed", height=40),pn.panel(interactive_conversation, loading_indicator=True,sizing_mode="stretch_both"),sizing_mode="stretch_both"
)dashboard

以下代码复制context列表到 messages 列表,并添加一个系统提示,要求生成订单的 JSON 摘要。

调用 get_completion_from_messages函数获取模型的响应,并打印输出。

messages =  context.copy()
messages.append(
{'role':'system', 'content':'create a json summary of the previous food order. Itemize the price for each item\The fields should be 1) pizza, include size 2) list of toppings 3) list of drinks, include size   4) list of sides include size  5)total price '},    
)response = get_completion_from_messages(messages, temperature=0)
print(response)
http://www.dtcms.com/a/325450.html

相关文章:

  • Oracle 19C 配置TAF
  • 投资光伏怕成本超标?鹧鸪云系统配置最优方案
  • 微算法科技(NASDAQ:MLGO)通过蚁群算法求解资源分配的全局最优解,实现低能耗的区块链资源分配
  • 【深度学习计算性能】03:自动并行
  • Apache Ignite 生产级的线程池关闭工具方法揭秘
  • 【C++】封装哈希表模拟实现unordered_set和unordered_map
  • 【10】微网优联——微网优联 嵌入式技术一面,校招,面试问答记录
  • 【Linux让旧电脑重获新生的奇妙魔法】
  • 【k8s】k8s安装与集群部署脚本
  • Godot ------ 平滑拖动03
  • 量子神经网络:从NISQ困境到逻辑比特革命的破局之路
  • Day 37:早停策略和模型权重的保存
  • C语言指针(四):字符指针、数组指针与函数指针的实战指南
  • Unity大型场景性能优化全攻略:PC与安卓端深度实践 - 场景管理、渲染优化、资源调度 C#
  • 在Mac 上生成GitLab 的SSH 密钥并将其添加到GitLab
  • 在 .NET Core 5.0 中启用 Gzip 压缩
  • AI时代基于云原生的 CI/CD 基础设施 Tekton
  • Redis Sentinel 中 `sentinel resolve-hostnames yes` 的必要性解析
  • C#图形库SciChart与ScottPlot及LiveCharts2对比
  • Linux客户端利用MinIO对服务器数据进行同步
  • 掌握while循环:C语言编程基础
  • Unity跨平台性能优化全攻略:PC与安卓端深度优化指南 - CPU、GPU、内存优化 实战案例C#
  • 《番外:Veda的备份,在某个未联网的旧服务器中苏醒……》
  • 扩展运算符...作用介绍
  • 关系型数据库:原理、演进与生态全景——从理论基石到云原生的深度巡礼
  • 国内 Mac 开启 Apple Intelligence 教程
  • 深入浅出JVM:Java虚拟机的探秘之旅
  • 第2节 PyTorch加载数据
  • 关系操作符详解与避坑指南
  • 软件编程2-标准IO