AI探索实践11 - 实现 Prompt Template (提示语模版) 功能

大家好,我是feng,感谢你阅读我的博文,如果你也关注AI应用开发,欢迎关注公众号和我一起​探索。如果文章对你有所启发,请为我点赞!

在博文《AI探索实践9 - 不用Python!用前端也能开发一个本地运行的"ChatGPT"!》,实现了仅依靠前端程序,就可以和本地大模型通信,实现了类似ChatGPT聊天的效果。但是在运行程序后,我发现本地模型的响应是一次性显示的,并没有像ChatGPT那样实现打字机的效果。本文就来研究如何实现流式输出的效果。

在博文《AI探索实践10 - 前端实现本地模型流式响应输出》,了解到前端程序如何将模型的响应以流式方式呈现在页面上。

本篇文章将介绍一个比较重要的概念 Prompt Template - 提示语模板,以及如何在前端实现。

一、重点回顾

在前端程序中,使用LangChain框架来实现大模型应用的开发。基本逻辑是:

  1. 声明一个 ChatOllama 对象,配置本地大模型参数:ip、模型名称、temperature等。
  2. 使用模型的invoke、batch或stream等方法,实现向模型发送请求和收到响应。
  3. 根据请求的方法不同,处理不同的响应数据对象,同步更新到模板。

二、问题

上面的代码逻辑,实现了类似ChatGPT聊天的效果。但是在使用过程中发现,我们在连续提出问题时,如果发的提示语比较简单、没有把相关的上下文也一起发送,那么模型回答会显得莫名其妙:

可以看出,模型的回答仅仅针对的是你这一次的提问。现有的代码逻辑,并没有将你这次提问的上下文一起发送给模型,所以在模型看来有些问题可能就会莫名奇妙,答案自然也很离谱。

人与人之间的交流过程中,如果你想得到期望的回答,你就需要说出让对方 听得懂的话,这很重要。话中的歧义越少,对方理解偏差就越小,给你的响应回答也就越符合你的期望。和大模型的通信也是一样的道理。提示语,就是我们发给模型的内容、说的话。好的提示语能够让模型更好的理解你的问题,从而给你更好的答案。

因此,提示语 Prompt很重要。

三、实现提示语模版功能

实际上,说提示语 prompt很重要,但这是针对现阶段大模型的处理能力来说的。理想情况下,大模型应该有能力充分的理解你想要表达的意思,我相信这在未来是会实现的。现实是大模型还不具备这样的能力,所以我们在实现大模型应用时,要充分的考虑到这一点。应该通过技术来提供一种机制,来优化和补充用户发出的提示语,帮助大模型更好的理解用户意图。

我们可以通过模型对象的方法(invoke/batch/stream),来获取模型的响应。我们也可以通过使用提示语模版对象(Prompt Template)来获得响应。提示语模版,常用于将用户的输入内容,转换为对于大语言模型更易于理解的内容。

创建一个提示语模板 Prompt Template,可以有2种不同的方法创建:

3.1 从字符串提示语模板中创建

第一种方法,是从字符串模版中创建。它需要以单个字符串作为输入,该字符串代表了系统消息,指示模型以某种方式运行。

新建一个 prompt-template.js 文件:

TypeScript 复制代码
import { ChatOllama } from '@langchain/community/chat_models/ollama';
import { ChatPromptTemplate } from '@langchain/core/prompts';

// 创建一个模型
const chatModel = new ChatOllama({
  baseUrl: 'http://localhost:11434', // Default value
  model: 'qwen:4b',
  temperature: 0.7,
});

const prompt = ChatPromptTemplate.fromTemplate(
  '你是一个喜剧演员,使用接下来的词创作一个笑话: {input}',
);

ChatPromptTemplate 类,可以帮助我们创建一个提示语模版对象。fromTemplate 函数中 {input} 代表用户输入的变量,使用大括号 {} 作为占位符。

在LangChain中,可以以某种方式组合模型和提示语,这被称之为:chain。接下来,我们创建一个chain,通过pipe方法将模型和提示语链接起来。当然也可以链接其他对象:

TypeScript 复制代码
const chain = prompt.pipe(chatModel);

接下来,我们不再是调用模型的方法来获取响应,而是调用 chain对象来做同样的事情:

TypeScript 复制代码
const response = await chain.invoke({
  input: '小狗',
});

// 在控制台中
console.log(response);

我们执行一下这个js,来看看控制台输出的内容:

可以看到,通过chain将模型与提示语模版对象链接起来,并调用chain的方法同样实现了对模型的请求与响应。我们再来梳理和说明一下逻辑:

模板字符串内容是:

你是一个喜剧演员,使用接下来的词创作一个笑话: {input}

这个提示语起到3个作用:

  1. 告诉了模型的定位:喜剧演员。模型将重点使用这个定位的知识来做响应。
  2. 创作笑话:任务指令,告诉模型要做什么
  3. {input}:告诉模型,要根据用户的数据,并且输入的变量名为:input

当我们调用链时:

input: '小狗',

这个小狗,实际上代表的是用户在页面文本框中输入的内容。也是告诉大模型,变量名为input的值是:小狗

3.2 从消息数组中创建

另一种创建提示语模板的方法是,从消息数组中创建。这个可以更好的控制模型的输出。在这个消息数组中,你可以指定角色以及角色要执行的任务。数组中,每一个元素是一个键值数组:

TypeScript 复制代码
const prompt2 = ChatPromptTemplate.fromMessages([
  ['system', '根据用户提供的词语,来创作一首四言绝句'],
  ['human', '{input}'],
]);

在代码中,定义了2个角色:system和human。system代表了系统角色,human代表了用户。

TypeScript 复制代码
const chain2 = prompt2.pipe(chatModel);
const response2 = await chain2.invoke({
  input: '大海',
});
console.log(response2);

执行代码,看看返回的结果:

四、总结

通过提示语模板功能,我们可以为用户发送的提示语,补充更多的上下文信息,从而得到更好的答案。

我们可以在提示语中间指定模型的角色、明确模型要做的任务,以及说明需要识别用户的输入占位符等。

很明显,质量更高的提示语内容能够帮助大模型给我们回答更准确的结果。如何编写高质量的提示语不在本文的讨论范围,网络也有很多资料可以学习。

相关推荐
好喜欢吃红柚子6 分钟前
万字长文解读空间、通道注意力机制机制和超详细代码逐行分析(SE,CBAM,SGE,CA,ECA,TA)
人工智能·pytorch·python·计算机视觉·cnn
小馒头学python11 分钟前
机器学习是什么?AIGC又是什么?机器学习与AIGC未来科技的双引擎
人工智能·python·机器学习
神奇夜光杯20 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
正义的彬彬侠23 分钟前
《XGBoost算法的原理推导》12-14决策树复杂度的正则化项 公式解析
人工智能·决策树·机器学习·集成学习·boosting·xgboost
Debroon32 分钟前
RuleAlign 规则对齐框架:将医生的诊断规则形式化并注入模型,无需额外人工标注的自动对齐方法
人工智能
羊小猪~~39 分钟前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
AI小杨40 分钟前
【车道线检测】一、传统车道线检测:基于霍夫变换的车道线检测史诗级详细教程
人工智能·opencv·计算机视觉·霍夫变换·车道线检测
晨曦_子画1 小时前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
道可云1 小时前
道可云人工智能&元宇宙每日资讯|2024国际虚拟现实创新大会将在青岛举办
大数据·人工智能·3d·机器人·ar·vr
人工智能培训咨询叶梓1 小时前
探索开放资源上指令微调语言模型的现状
人工智能·语言模型·自然语言处理·性能优化·调优·大模型微调·指令微调