前言
经常网购的朋友肯定知道,有时候总有些沟通不了的神奇客服,只会一直发亲亲和道歉能把你气个半死,甚至想让我们来上一句"转人工",正好我最近正在学习吴恩达的Prompt Engineering课程,今天已经学习完毕了,掌握了Prompt的基本规则,不得不说这是一项很有魅力的技术,我们今天就来设计一个通过分析顾客评论的AI客服来取代某些"非人工客服"。
Prompt设计
Prompt设计是学习AI编程中非常重要的一环,它是我们与大模型间沟通的桥梁 ,如果你想在今后的学习和工作中能更好的利用大模型来帮助你,那么prompt设计的学习是必不可少的。有人可能会觉得Prompt就是一两句话的事情,但其实不是,其设计就是为了能让大模型更清晰,更准确的完成我们所希望它完成的任务,做到想你所想,做你所做,让它学会思考,所以我们需要不断完善我们的prompt设计风格,把一段简单的prompt细分再细分,一步一步引导大模型思考,从而达到我们预期的效果,话不多说,直接开始。
AI客服
js
npm init -y // 初始化后端项目
npm i openai
npm i dotenv
首先,还是熟悉的老三样,先初始化一个后端项目后再导入openai
依赖包,这是我们将要运用到的大模型,以及dotenv
依赖包,用来管理我们的环境变量,在这里的作用是用来保护我们的apikey和url
上传到远程仓库时避免被他人盗用。
如果成功的话,打开package.json
文件下可以看到依赖中有这两个的名字和版本信息:
接下来我们在入口文件中导入这两个包,做好大模型调用前的准备工作:
js
import dotenv from 'dotenv';
import OpenAI from 'openai'; // 模块引入放在头部, 不会重复
// .env 本项目 环境变量配置文件
dotenv.config();
const {
OPENAI_API_KEY,
OPENAI_BASE_URL
} = process.env
// 实例化openai对象
const client = new OpenAI({
apiKey: OPENAI_API_KEY,
baseURL: OPENAI_BASE_URL,
});
这里我们将apikey和url
存放在创建的.env
文件下,再通过dotenv.config()
的引入,它会找到.env文件中的配置信息,添加到process.env
对象上,我们再通过此对象就能进行访问。
接下来我们封装一个函数来完成大模型的功能,这个函数可以说是调用ai的模板:
js
// get_completion 函数封装
/**
* 异步函数,用于从 OpenAI 的 GPT-3.5-turbo 模型获取完成文本
* @param {string} prompt - 用户提供的提示文本
* @param {string} model - 要使用的 OpenAI 模型,默认为 'gpt-3.5-turbo'
* @returns {Promise<string>} - 解析后的模型响应内容
*/
const get_completion =
async (prompt, model= 'gpt-3.5-turbo') => {
// 创建一个包含用户角色和提示内容的消息数组
const messages = [
{ role: 'user', content: prompt }
]
// 使用 OpenAI API 创建一个聊天完成请求
const response = await client.chat.completions.create({
model,
messages,
temperature: 0,
});
// 返回解析后的模型响应内容
return response.choices[0].message.content;
}
这乍一看很复杂,其实就是封装了一个异步函数,函数中通过传入我们后面会输入的prompt
和规定好的大模型gpt3.5
然后调用了openai
包中的api
完成了一个聊天请求,其中的temperature
代表了大模型给你答复的随机性,它的取值是0~1,比如0.2,0.5这种,越趋近于1,大模型给你的答复将会更有随机性,愈趋进于0,答复将会更严谨,由于我们这里的任务是通过分析用户评论从而发送答复所以回答当然要非常严谨为0。
ok接下来就到了我们最重要的prompt设计环节,我将输入几段评论和prompt开启我们今天的质变之旅:
js
const main = async () => {
const lamp_review =`
`
const prompt = `
`
const response = await get_completion(prompt);
console.log(response);
}
main()
在这里我们运用到了es6新增的模板字符串,将用户的评论review
和我们需要规定的prompt
输入进去,它具有强大的可读性和便利性,你可以创建跨越多行的字符串而不用使用换行符或者连接符 ,在其中插入变量或者表达式只需要使用${expression}
语法即可。
js
const sentiment = "negative" // 消极
const review = `
因此,他们仍然以 70-10 左右的价格在季节性销售,价格也比之前的 29 美元低。
所以它看起来还不错,但如果你看看底座,刀片锁定到位的部分看起来不如几年前的版本那么好,但我打算非常温柔地使用它(例如,我先在搅拌机中粉碎非常硬的物品,如豆子、冰、米饭等。然后在搅拌机中将它们粉碎成我想要的份量,然后切换到搅拌刀片以获得更细的面粉,并在制作冰沙时先使用十字切割刀片,然后如果我需要它们更细/更少的浆状,则使用平刀片)。制作冰沙的特别提示:将水果和蔬菜切碎并冷冻(如果使用菠菜,请稍微炖一下,然后冷冻直至可以使用;如果制作冰糕,请使用小型或中型食品加工机),这样就可以避免在制作冰沙时添加太多冰块。
大约一年后,电机发出奇怪的声音。
我打电话给客服,但保修期已过,所以我不得不再买一个。仅供参考:这类产品的整体质量已经下降,因此他们有点指望品牌认知度和消费者忠诚度来维持销售。大约两天后就收到了。
`
const prompt = `
你是一名客服AI助理。
你的任务是向尊贵的客户发送电子邮件回复。
给定以'''分隔的评论的客户发送电子邮件,
生成回复以感谢客户的评论。
如果情绪是正面或中性的,感谢他们的评论。
如果情绪是负面的,道歉并建议他们可以联系客服。
确保使用评论中的具体细节。
用简洁专业的语气写作。
在电子邮件中签名为"AI客户代理"
客户评论: '''${review}'''
评论情绪: ${sentiment}
`
在这里我们传入了一段用户的评论,首先给他一个角色,这是极为重要的,因为它会根据自己的角色进行思考需要做什么,就好比我说你是一个厨师,那你就知道了你的任务是做菜,并且告诉它情绪为消极的,然后根据prompt设计规则,将需要传入的参数用6个反引号包裹起来,最后告诉它根据用户的心情来做具体回复以及其他限制,并且署名:
可以看到它很好的完成了我们交给它的所有指定任务,如果你输出时,它缺少了某一项你附加的限定,除开prompt的问题外,也可能是大模型性能的问题,如果我们将此时的大模型切换到gpt4o
,它会产生截然不同且跟人性化的回复,不像此时一样呆板模板。感兴趣的朋友可以去试试。接下来我们继续换一个评论以及prompt:
js
const lamp_review = `
需要一盏漂亮的灯放在我的卧室,这盏灯有额外的存储空间,而且价格也不太高。
很快就收到了。我们灯的灯串在运输过程中断了,公司很乐意给我们寄来一根新的。
几天之内就到了。组装起来很容易。
我缺少一个零件,所以我联系了他们的支持人员,他们很快就给我找到了缺失的零件!
在我看来,Lumina 是一家关心客户和产品的好公司!!
`
const prompt = `
以下产品评论的情绪是什么
以三个反引号分隔
确定以下评论作者表达的感情列表。
列表中最多包含5项。将你的答案格式化为逗号分隔的单词列表。
评论内容:'''${lamp_review}'''
`
它返回了5个心情,并且使用了我们规定的格式化逗号格式返回。
js
const prompt = `
从评论文本中识别以下项目:
- 情绪(正面或负面)
- 评论者是否表达愤怒?(真或假)
- 评论者购买的商品
- 制造商品的公司
评论以三个反引号分隔。
将您的回复格式化为 JSON 对象,其中
"情绪"、"愤怒"、"商品"和"品牌"作为键。
如果信息不存在,请使用"未知"
作为值。
让您的回复尽可能简短。
将愤怒值格式化为布尔值。
// 评论文本: '''${lamp_review}'''
`
在这里我们给他添加了更多限制,通过符号,让他一步一步细化完成我们的任务,并让他将回复转化为json对象。
简直完美有没有,这就是prompt设计的魅力所在,只要你能熟练的掌握它的设计规则并且规范的写出,它就能完成你预期的任务。
总结
通过上面的AI客服,我们知道了大模型可以完成我们许多想不到的功能,我们需要了解大模型到底能做什么,而我们仅仅需要给它一段准确的prompt,比如给它一个角色,细化它的任务步骤,回复的风格,或者给它一个案例,也可以给返回内容约定一个格式,其中我们需要运用到反引号的字符串模板,并将变量通过6个反引号包裹,这就是规范的设计模式,我们需要通过一些练习和思考就能很快掌握,如果感兴趣的可以去看看原课程吴恩达prompt设计,ok今天的学习就到这里了,说不定在不久的将来网购网站上的客服将会被AI取代了。