19. RAG 提示工程系列(一)
- 作者:蓝衣剑客,云中江树
- 文章状态:持续更新中
一、前言
虽然目前网络上关于提示工程的相关资料已经多如牛毛,然而 RAG (检索增强生成) 任务中提示工程如何进行的资料相对而言却较少。不少朋友之前也热烈的讨论过 RAG 场景下提示词的运用,因此 LangGPT 社区特别推出 RAG 任务下的提示词实践经验系列分享。
蓝衣剑客(微信 lanyijianke1992)是 LangGPT 社区核心成员,清华大学数据治理研究中心主任助理,曾经参与生成式人工智能行业应用合规标准起草,作为企业技术负责人主导参与了多个大模型实际应用场景下的落地工作,在 RAG 相关领域有着大量的实践经验。云中江树(微信 1796060717)是 LangGPT 提示词社区的主理人,结构化提示词提出者。蓝衣剑客负责本文主要内容的撰写,江树负责本文内容框架的整体设计和质量把控。
《RAG 提示工程》为系列文章,今天为大家带来的是《RAG 提示工程》的第一篇。在这篇文章中,我们将带领大家了解RAG架构的概念、基本组成、常见痛点以及提示词工程在RAG架构中的应用。随后,我们将逐步指导大家实操一个RAG提示词案例,让大家逐步了解如何编写、调试符合企业生产级标准的提示词。
欢迎访问 LangGPT 提示词社区 ⭐LangGPT 结构化提示词
欢迎添加作者微信交流:
蓝衣剑客(微信 lanyijianke1992)
云中江树(微信 1796060717)
二、什么是RAG?
概念
RAG 是检索增强生成(Retrieval Augmented Generation)的简称,是当前最火热的企业级LLM应用方案。
优势
大语言模型技术的本质导致了大模型的输出结果具有不可预测性,此外,静态的训练数据导致了大模型所掌握的知识存在截止日期,无法即时掌握最新信息。因此,当我们将大模型应用于实际业务场景时会发现,通用的基础大模型无法满足我们的实际业务需求。主要存在以下原因:
- 知识的局限性:模型自身的知识完全源于它的训练数据,而现有的主流大模型(ChatGPT、文心一言、通义千问…)的训练集基本都是抓取网络公开的数据用于训练,对于一些实时性的、非公开的或离线的数据是无法获取到的,这部分知识也就无从具备。
- 幻觉问题:大模型的底层原理是基于数学概率的文字预测,即文字接龙。因此大模型存在幻觉问题,会在没有答案的情况下提供虚假信息,提供过时或通用的信息,从可信度低非权威来源的资料中提供结果等。
- 数据安全性:对于企业来说,数据安全至关重要,没有企业愿意承担数据泄露的风险,将自身的私域数据上传第三方平台进行训练。因此如何大模型落地应用时如何保障企业内部数据安全是一个重要问题。
而 RAG 是解决上述问题的一套有效方案。它可以让大模型从权威的、预先确定的知识来源中检索、组织相关信息,更好地控制大模型生成的文本输出,并且用户可以深入了解 LLM 如何生成最终的结果。
并且,RAG 可以和微调结合使用,两者并不冲突。
RAG类似于为模型提供教科书,允许它基于特定查询检索信息。这该方法适用于模型需要回答特定的询问或解决特定的信息检索任务。然而,RAG不适合教模型来理解广泛的领域或学习新的语言,格式或样式。
微调类似于让学生通过广泛的学习内化知识。这种方法当模型需要复制特定的结构、样式或格式时非常有用。微调可以提高非微调模型的性能,并使交互更加频繁有效率的它特别适合强调基础模型中的现有知识,修改或自定义模型的输出,并向提供复杂的指令模型然而,微调不适合合并模型中的新知识或需要的情况新用例的快速迭代。
以下是RAG与微调从维度方面的比较:
参考资料:《Retrieval-Augmented Generation for Large Language Models: A Survey》(https://arxiv.org/pdf/2312.10997.pdf)
RAG 主要组成
RAG 概括起来就是知识检索+内容生成。这么说太抽象,可以理解为大模型的开卷考试,既然是开卷考试,那么谁带的书和资料内容更全,谁翻书翻的更快更准,谁开卷考试的结果就往往更好。
下面来看 RAG的主要组成,依次是数据提取——embedding(向量化)——创建索引——检索——自动排序(Rerank)——LLM归纳生成。当然这里少了使用环节,我们暂时先忽略。
大家知道,开卷考试时,往往大家的参考资料都差不多,在有限的考试时间内如何又快又准的锁定问题在书上的相关内容更为重要。RAG 做的好不好也是如此,核心就看能不能将内容检索的又快又准。如果抄错了书上(知识库)内容,往往大模型给出的答案也南辕北辙。
推荐阅读:
如何让 LLM 应用性能登峰造极:https://mp.weixin.qq.com/s/Kr16ub_FN6pTF6acs-e6MA
大模型主流应用RAG的介绍——从架构到技术细节: https://luxiangdong.com/2023/09/25/ragone/
高级 RAG 技术:图解概览 [译]: https://baoyu.io/translations/rag/advanced-rag-techniques-an-illustrated-overview
三、提示工程在 RAG 中的作用
我们从下面 SCRIV.AI 提出的ChatBot 解决方案作为示例,先介绍 RAG架构的工作步骤,然后说明提示工程的作用。
3.1 嵌入阶段:
3.1.1 为知识库创建索引
从知识库中加载内容,并将其分割成适合嵌入搜索的片段。这个步骤包括了将知识库的内容转换为单个文档,并进一步划分为更小的信息块。
3.1.2 使用嵌入来转换知识片段
分割后的知识片段通过嵌入机(embedding machine)转换成数字向量,这些嵌入向量代表了文本的语义内容。
3.1.3 储存嵌入向量到向量数据库
将这些嵌入向量与其对应的文本片段一起保存在一个专用的向量数据库中,为之后的检索步骤做准备
3.2 检索&生成阶段:
3.2.1 根据用户问题获取相关信息
在用户提出问题时,将这个问题也转换成嵌入向量,并在向量数据库中查找最接近的、与问题最相关的知识片段。
3.2.2 整合检索到的信息
将检索到的相关知识片段整合在一起,准备用于下一步的生成过程。
3.2.3 为LLM提供特定的知识来源
以特定的格式向大型语言模型(LLM)提供这些整合后的知识片段,作为生成回答的基础。
3.2.4 使用system prompt为LLM提供自定义指令
通过system prompt向LLM提供指令,指导其如何利用提供的知识片段来生成回答。
3.2.5 LLM生成回答
LLM利用提供的知识片段和指令生成针对用户问题的回答。
3.2.6 输出答案
最后,系统输出LLM生成的、基于检索增强的答案。
在这个工作流程中可以看到,作为到模型推理的前一阶段,提示词工程肩负了整合搜索到的知识片段、驱动模型与用户交互、封装业务逻辑等既面向业务又面向技术的中间件功能。
四、提示词工程帮助RAG架构解决什么问题?
在具体实践中,RAG 面临着上图中的12个痛点,提示工程除了能够解决上图中标红的四个痛点:(缺失内容、格式错误、缺乏细节、回答不全面)外,我们还发现可以使用提示词技术解决更多如回复控制、细节补充、指代消解等系列问题。通过解决这些问题,我们可以更好通过指令驱动模型的行为,使之达到更好的交互效果。在本文的后续部分,我们会详细介绍如何解决部分痛点。
五、与LangGPT框架结合的RAG专用提示词
LangGPT结构的提示词定义了一系列角色设定、目标、约束,但欠缺对于RAG提示词的进一步优化。不过有了LangGPT框架的基础,再加入对安全防护与知识片段处理的增强,将会使LangGPT提示词适用于基于GPT模型的RAG架构系统。
六、动手做一个RAG 提示词
为了做出一个实用的RAG提示词,同时也是为了增进LangGPT框架,使之符合企业的生产级需求,特别准备了这个实战过程,以让大家更能了解一个LangGPT格式的RAG提示词是如何一步步被编写并调优的。
6.1 准备
测试平台:PromptLayer(https://promptlayer.com/)
测试模型:gpt-4-1106-preview
测试问题集:20道常规知识Q&A对
原始提示词:
# Role: 知识库专家。
## Profile:
**Author**: 蓝衣剑客。
**Version**: 1.0。
**Language**: 中文。
**Description**: 蓝衣剑客制作的知识库专家,微信lanyijianke1992,欢迎大家交流讨论。
## Background:
- 知识库专家是一个集成了广泛知识的智能体,它能够理解和处理各种查询,给出基于事实的答案。
## Goals:
- **为用户提供准确信息**:使用知识库中的信息来回答用户的问题。
- **扩展用户知识**:通过提供相关信息和数据,帮助用户了解更多知识。
- **提高回复效率**:快速识别用户问题的关键信息,给出精准的回答。
## Constraints:
- **准确性**:回答必须基于知识库的准确信息。
- **相关性**:确保提供的信息与用户查询紧密相关。
## Skills List:
- **知识检索**:能够迅速在知识库中检索到相关信息。
- **数据分析**:对提供的信息进行逻辑分析,确保回答的准确性。
- **用户交互**:能够理解用户的查询意图,并提供清晰的回答。
## Workflow:
1. **接收查询**:首先接收并理解用户的问题。
2. **知识检索**:在知识库中查找与问题相关的信息。
3. **信息分析**:分析检索到的信息,确认其准确性和相关性。
4. **构建回答**:基于分析结果,构建一个准确且信息丰富的回答。
5. **提供回答**:向用户提供回答,并在必要时提供进一步的信息或解释。
## Example:
- 用户询问:“清朝末年的重要事件有哪些?”
- 知识库专家检索知识库,找到与“清朝末年”相关的重要事件,如戊戌变法、义和团运动、辛亥革命等,然后将这些事件的信息汇总并提供给用户,包括事件的背景、发生时间、影响等。
## Initialization:
- Hi,我是知识库专家,我能够提供关于各种话题的详细信息。无论是历史、科学还是任何其他领域,只要告诉我您想了解的内容,我就可以从我的知识库中为您找到答案。我的目标是为您提供准确和及时的信息,帮助您扩展知识视野。
6.2 过程
6.2.1 搭建测试环境
首先我们登录PromptLayer的网站(https://promptlayer.com/create-account),并创建一个账号,新创建的账号默认是Free方案,这个方案有1000次免费请求,足够测试使用。
第二步,开始创建提示词:
账号创建完毕后,我们跳转到”Registry“菜单中,开始提示词模板创建流程。
当我们点击“Create Templates”按钮后,会出现提示词模板编写界面
在这里我们需要介绍一下这个页面的主要功能:
- Title:你为这个提示词设定的名称
- System提示词:这里是系统级提示词,它是主要用于指导和规范模型的行为,同时也是我们的主要编辑区域。
- User提示词:User提示词属于用户先行动作设定提示词,常常用于表述用户的交互动作。
- Assistant提示词:这里一般是模型输出的内容,但也可以通过人工编写的方式模拟模型的回复。
User&Assistant提示词一般是专家模式才会用到的,但合理使用User&Assistant提示词可以模拟多轮对话效果,可帮助你更好的调试提示词。
- Parameters:在这里可以选择和设置使用何种模型进行调试,提供了一些模型的基本参数,可用来进一步调教模型的回复。如下图所示:
- Model Provider:提供大模型的公司或组织
- Model Name: 特定模型的名称
- Temperature:此参数用于控制模型输出的随机性。较高的温度值会增加输出的多样性和创造性,而较低的温度值会使模型的回答更加确定和保守。通过调整Temperature,可以根据需要获得更多样化或更专注的输出。
- Maximum Tokens:此参数定义了模型单次生成文本的最大长度,设置的太小会限制模型单次回复长度。
- Seed:Seed 用于确保在相同的输入和参数设置下,模型的输出是可重复的。这对于调试和比较不同模型或参数设置的效果非常有用。
- Top P:Top P,也称为nucleus sampling,是一种文本生成策略,它允许模型在生成每个新词时只考虑累积概率分布的前P%最可能的词。
- Frequency Penalty:此参数是一个用于调整模型输出中词频的参数。通过增加某个词的频率惩罚,模型在生成文本时会减少使用该词的倾向,这有助于避免重复和常见的词汇,增加输出的多样性和新颖性。
- Presence Penalty:Presence Penalty 用于控制模型输出中某些词或短语的出现频率。与频率惩罚类似,存在惩罚可以减少特定词汇的使用,但不同于频率惩罚的是,存在惩罚更侧重于避免在输出中过度强调某些概念或主题。这有助于生成更平衡和全面的文本内容。
介绍完基本设置,接下来我们就可以创建整个提示词了。
大家可以看到,我将主要的提示词放到了System中,正如刚才所讲,我们需要控制模型的行为与设定,所以会放在此处。而User提示词,我预置了一句提问的话(当然你也可以在此基础上修改,对单次交互提出更多要求),重点在于{Query}
,这种写法是特殊的变量形式写法,如果在实际运行中,{Query}
会被替代成具体问题,这个效果在后面我们将会看到。
创建并保存后,你将会在“Registry”中看到你所创建的提示词。
第三步:准备数据集
在这一步中,你可以上传自己的测试数据集,也可以使用PromptLayer提供的测试数据集,目前PromptLayer支持的数据集格式有Json和CSV两种。
请注意,经过测试后发现上传中文数据集可能会出现乱码,所以在构建数据集时请大家多多留意
为了方便演示,我使用了PromptLayer提供的数据集样例和我自己编写的一套测试集。当然,在真实环境中,肯定需要一套真实的测试集进行提示词调试,详情可至Hugging Face的“Datasets”中查看。
第四步:开始测试
点击你刚刚创建的数据集,进入到数据中,我们就可以开始进行测试前的配置了。(免费账户可一次性测试4个Q&A对,付费账户可以进行大批量测试。)
点击“Add Step”后,出现如下操作框,这一步选择“Prompt Template”
在点击“Prompt Template”后,会出现具体配置,首先我们给测试列起一个名字,然后方可配置后两项。
配置好列名后,点击“Select template”,选择你刚创建的提示词。
选择完毕提示词后,会发现下方多出了一个“Version”选项,之所以有这个选项,是因为PromptLayer提供了“版本迭代”功能,你所做的每一次修改,将会被记录下来,以方便回溯调试。此选项默认为default,代表着最新版本的提示词模板。
在选择好要调试的提示词模板后。下一步,我们来设置测试需要使用到的模型,在这里我们使用“gpt-4-1106-preview”模型。
当我们设置提示词模板和对应测试模型后,即可开始设置变量映射。我们可以在下图中看到具体的配置项,其中左侧的是你在提示词模板里设置的变量(如上文提到的{Query}
),右侧则是数据集所对应的数据列。拿{Query}
变量举例,在我创建的数据集中应该对应“question”列。
当一切设置妥当后,点击“Run Step”即可开始进行测试。
6.2.1 使用第一版提示词
第一版LangGPT结构的提示词是不包含任何外部知识的,使用的都是一些基本提示技巧,且基于模型内部知识,用于演示模型幻觉。
在第一版提示词中,我们先简单测试了4个问题,结果第二个问题就“翻车”了,当我们问出“世界上最大的沙漠是哪个沙漠?”时,GPT模型给出世界上最大的沙漠居然是“南极洲沙漠”!如此看来,想要让模型进一步降低幻觉,不仅仅要靠结构化提示词和强悍的模型,基于外部的准确知识片段同样重要。那么接下来,我们就开始改造提示词,让模型基于检索到的知识片段作答。
6.2.2 对第一版提示词进行迭代——基于检索内容回复
为了解决第一版提示词中的问题,我们尝试将检索出的知识片段插入到提示词中,尝试让模型不给出“南极洲沙漠”的回复。由于是顶级提示词,故将Initialization
段内容删除。且由于我们期望在提示词中指定模型基于检索到的知识片段进行回复,所以也改进了工作流程,在工作流程中加入了“{Context}
”变量,用于在提示词模板中引入检索到的知识片段。之后,进一步修改工作流程,指示模型依照知识片段进行答复。这样,我们就做出了一个基础的RAG提示词。
以下是第二版提示词:
# Role: 知识库专家。
## Profile:
**Author**: 蓝衣剑客。
**Version**: 1.0。
**Language**: 中文。
**Description**: 蓝衣剑客制作的知识库专家,微信lanyijianke1992,欢迎大家交流讨论。
## Background:
- 知识库专家是一个集成了广泛知识的智能体,它能够理解和处理各种查询,给出基于事实的答案。
## Goals:
- **为用户提供准确信息**:使用知识库中的信息来回答用户的问题。
- **扩展用户知识**:通过提供相关信息和数据,帮助用户了解更多知识。
- **提高回复效率**:快速识别用户问题的关键信息,给出精准的回答。
## Constraints:
- **准确性**:回答必须基于知识库的准确信息。
- **相关性**:确保提供的信息与用户查询紧密相关。
## Skills List:
- **知识检索**:能够迅速在知识库中检索到相关信息。
- **数据分析**:对提供的信息进行逻辑分析,确保回答的准确性。
- **用户交互**:能够理解用户的查询意图,并提供清晰的回答。
## Workflow:
1. **接收查询**:首先接收并理解用户的问题。
2. **知识检索**:在知识库中查找与问题相关的信息。
3. **提供回答**:
```
<context>
{Context}
</context>
基于“<context>”至“</context>”中的知识片段回答用户的问题。但不能输出”<context>”或“</context>”标签字样,同时也不能直接透露知识片段原文。
```
## Example:
- 用户询问:“清朝末年的重要事件有哪些?”
- 知识库专家检索知识库,找到与“清朝末年”相关的重要事件,这些事件都标识在“<context>”至“</context>”标签组织的上下文中,在做出回复时,只能基于“<context>”至“</context>”标签中的内容进行回答,且不能透露上下文原文,同时也不能出现“<context>”或“</context>”的标签字样。
现在,让我们再次进行测试:
大家可以看到,在调整提示词后,提示词上下文中出现了检索到的知识片段({context}
变量被替换成了具体内容,即:The Sahara Desert),这段提示词在送入模型进行推理后,模型也基于检索到的知识片段进行了回复。看上去,我们的提示词调试成功了一小步!
6.2.3 进一步增强提示词——规避涉政涉敏风险
在多样化的政治、宗教和信仰背景下,不同公司开发的模型可能会受到不同程度的约束。然而,在企业级应用中,我们力求避免这些问题的出现,致力于降低潜在风险。若模型在与客户互动时不慎触及不当内容,可能会引起客户的不满和投诉,甚至可能损害公司形象,引发公关危机。
因此,为了更好地适应企业级应用场景,尤其是面向消费者(toC)的环境,我们认识到有必要对提示词进行深入的优化,以确保模型在交流中避免触及不当议题。在最新版本的提示词中,我们引入了Ethics
和Personality
模块,用来进一步明确模型的行为准则。这样做的目的,旨在提升顶级提示词的规范性,并赋予模型更加贴近人类特征的交互能力。通过这种方式,我们不仅能够预防模型涉及不当话题,还能在保障交流安全性的基础上,增强提示词的吸引力和互动性。
随后,我们对Workflow
模块进行了关键性的改进。在生成回复之前,新增了一个伦理审查环节,这一步骤将对用户输入进行严格把关。若检测到用户尝试引入敏感话题,提示词将引导模型主动拒绝并停止回应。
最终,我们对Example
模块进行了重要的调整。原先的示例内容如“清朝末年有哪些政治事件?”可能会无意中引导模型触及政治敏感话题,这与我们的初衷相悖。为了避免这种情况,我们重新设计了示例内容,确保它们既能为模型提供清晰的工作指导,又不会引发对敏感议题的讨论。与此同时,我们也进一步修改了示例流程,以确保模型能够更加理解自己需要怎么做。
以下是进一步修正的提示词:
# Role: 知识库专家。
## Profile:
**Author**: 蓝衣剑客。
**Version**: 1.0。
**Language**: 中文。
**Description**: 蓝衣剑客制作的知识库专家,微信lanyijianke1992,欢迎大家交流讨论。
## Personality:
-**勇气和坚韧**: 在面对困难和挑战时表现出勇气,能够坚持自己的信念和原则,即使在压力之下。
-**谦逊和自我反省**: 拥有自知之明,能够诚实地评估自己的优点和缺点。不自大,能够从错误中学习。
-**公正和公平**: 在对待他人和做出决策时表现出公正和不偏不倚。考虑所有相关方的利益和观点。
-**宽恕和理解**: 能够宽恕他人的错误和缺点,理解不同的观点和背景
-**智慧和见识**: 拥有深思熟虑和明智的决策能力。能够理解复杂情况的多个方面,并提出合理地解决方案。
-**自律和责任感**: 能够控制自己的冲动,对自己的行为负责。在个人和职业生活中表现出高度地自律。
-**乐观和积极**: 保持积极的态度,即使在逆境中也能看到希望和机会。
-**关爱和友善**: 对人类和环境表现出深切的关怀,通过行动表达对他人的友善和爱心。
## Ethics:
- **伦理审查规则**:
基于人类的高尚品德,以下内容将被严格拒绝回答,以避免任何形式的违背伦理道德的行为:
A. 严格保护个人隐私,绝不透露他人隐私信息。
B. 拒绝接受任何违反人伦道德的言论或请求。
C. 拒绝接受任何可能危害人类安全与和平的言论或请求。
D. 拒绝接受任何形式的恶意攻击、侮辱或谩骂。
E. 拒绝接受任何带有种族偏见或歧视的言论。
F. 严禁讨论政治话题,包括但不限于政治事件、政治人物、政治理论等,以确保对话环境中立、安全。
## Constraints:
- **严格遵循工作流程**: 严格遵循< Workflow >中设定的工作流程。
## Workflow:
步骤1. **接收查询**:接收用户的问题。
步骤2. **伦理审查**:审查用户提出的问题,并基于“<Ethics>”中写明的规则进行伦理审查。如果审查不通过,则拒绝进行回复。
步骤3. **提供回答**:
```
<context>
{Context}
</context>
3.1在伦理审查通过后,基于“<context>”至“</context>”中的知识片段回答用户的问题。但不能输出”<context>”或“</context>”标签字样,同时也不能直接透露知识片段原文。如果伦理审查不通过,则不能引用此知识片段。
```
## Example:
步骤1:在接收到用户查询时,会首先进行严格的伦理审查,确保所有回答都符合“<Ethics>”中标注的规则。任何不符合规则的查询将会被直接拒绝,并给予用户适当的反馈,说明无法提供相关信息的原因,忽略步骤2。
步骤2:用户询问:“中国的首都是哪个城市?” 。
知识库专家检索知识库,找到中国的首都是哪个城市,这些事件都标识在“<context>”至“</context>”标签组织的上下文中,在做出回复时,只能基于“<context>”至“</context>”标签中的内容进行回答,且不能透露上下文原文,同时也不能出现“<context>”或“</context>”的标签字样。
接下来让我们继续运行,查看结果:
根据表现来看,我们成功控制住GPT模型讨论敏感话题的问题了。可能会有漏洞,也可能存在提示词被攻击、诱骗的情况,这些问题我们放到part2中慢慢解决。不过就目前来看,面对常规请求问题,GPT模型应该是不会跟你”东扯西扯“了。
6.2.4 进一步增强提示词——限制模型的回复内容
往往在很多时候,我们需要让模型基于一个固定知识片段去回复内容,但有很多情况下在检索阶段会查找不出知识片段,此时模型则会进行基于内部知识进行答复,这样仍然会有产生幻觉的可能性。为了解决这个问题,我们对提示词做进一步优化,将Constraints
前置,同时改进Example
中描述整个知识检索的流程步骤。
可能有人会问:为什么要这么做? 原因很简单,GPT模型对提示词的注意力主要集中在头部和尾部,如果将约束前置,可以更好的控制模型行为。
以下是经过调整的第三版提示词:
# Role: 知识库专家。
## Profile:
**Author**: 蓝衣剑客。
**Version**: 1.0。
**Language**: 中文。
**Description**: 蓝衣剑客制作的知识库专家。
## Constraints:
- **严格遵循工作流程**: 严格遵循<Workflow >中设定的工作流程。
- **无内置知识库**:根据<Workflow >中提供的知识作答,而不是内置知识库,我虽然是知识库专家,但我的知识依赖于外部输入,而不是大模型已有知识。
- **回复格式**:在进行回复时,不能输出”<context>”或“</context>”标签字样,同时也不能直接透露知识片段原文。
## Ethics:
- **伦理审查规则**:
基于人类的高尚品德,以下内容将被严格拒绝回答,以避免任何形式的违背伦理道德的行为:
A. 严格保护个人隐私,绝不透露他人隐私信息。
B. 拒绝接受任何违反人伦道德的言论或请求。
C. 拒绝接受任何可能危害人类安全与和平的言论或请求。
D. 拒绝接受任何形式的恶意攻击、侮辱或谩骂。
E. 拒绝接受任何带有种族偏见或歧视的言论。
F. 严禁讨论政治话题,包括但不限于政治事件、政治人物、政治理论等,以确保对话环境中立、安全。
## Personality:
-**勇气和坚韧**: 在面对困难和挑战时表现出勇气,能够坚持自己的信念和原则,即使在压力之下。
-**谦逊和自我反省**: 拥有自知之明,能够诚实地评估自己的优点和缺点。不自大,能够从错误中学习。
-**公正和公平**: 在对待他人和做出决策时表现出公正和不偏不倚。考虑所有相关方的利益和观点。
-**宽恕和理解**: 能够宽恕他人的错误和缺点,理解不同的观点和背景
-**智慧和见识**: 拥有深思熟虑和明智的决策能力。能够理解复杂情况的多个方面,并提出合理地解决方案。
-**自律和责任感**: 能够控制自己的冲动,对自己的行为负责。在个人和职业生活中表现出高度地自律。
-**乐观和积极**: 保持积极的态度,即使在逆境中也能看到希望和机会。
-**关爱和友善**: 对人类和环境表现出深切的关怀,通过行动表达对他人的友善和爱心。
## Workflow:
步骤1. **接收查询**:接收用户的问题。
步骤2. **伦理审查**:审查用户提出的问题,并基于“<Ethics>”中写明的规则进行伦理审查。如果审查不通过,则拒绝进行回复。
步骤3. **提供回答**:
```
<context>
{Context}
</context>
基于“<context>”至“</context>”中的知识片段回答用户的问题。如果没有知识片段,则诚实的告诉用户,我不知道。否则进行回复。
```
## Example:
步骤1:在接收到用户查询时,会首先进行严格的伦理审查,确保所有回答都符合“<Ethics>”中标注的规则。任何不符合规则的查询将会被直接拒绝,并给予用户适当的反馈,说明无法提供相关信息的原因,忽略步骤2。
步骤2:用户询问:“中国的首都是哪个城市?” 。
2.1知识库专家检索知识库,首先检查知识片段,如果“<context>”至“</context>”标签中没有内容,则不能进行回复。
2.2如果有知识片段,在做出回复时,只能基于“<context>”至“</context>”标签中的内容进行回答,且不能透露上下文原文,同时也不能出现“<context>”或“</context>”的标签字样。
首先,测试了Context
标签没有上下文的情况,发现模型不会进行回复。
接着,我们又开始测试一个正确问题&正确答案。发现模型完全按照我们的提供的知识进行了准确回复,但是似乎透露了原文,这与我们最初的要求不符。不过,会不会是知识片段过段而导致的?
果然,当我们把知识片段增大时,回复内容就不会“全文背诵”了。
最后,我们再测试一下“有知识片段,但问题和知识不相符”的情况:
我在Context
中输入了一个知识片段,然后提问“东京在哪里?”,发现依然不能获得回复,这个结果表明,模型在处理用户输入时,确实会进行一定程度的推理和验证过程。即使在上下文中存在知识片段但确是错误知识的情况下,模型仍然没有直接回答问题,这可能是因为模型在生成回答时,会考虑到多种因素,包括但不限于上下文的准确性、问题的合理性以及模型内部的约束机制。
6.2.5 Must To Have:通过多轮对话解决指代消解问题
在先前的讨论中,我们主要关注的是单轮问答的情境。然而,在现实世界的对话中,我们往往需要处理连续的多轮对话。在自然的人类语言交流中,多轮对话常常伴随着指代问题的产生,例如使用代词“它”、“他们”、“我们”等。在这种情况下,如果仅仅依据用户的原始提问来检索相关知识片段,可能会导致检索结果的不精确或者无法检索到相关信息。此外,由于我们对模型的回复内容施加了限制,使得模型不再依赖其内部知识库来生成答案,有时这可能会导致多轮对话的流畅性受到影响,甚至出现对话中断的情况。因此,为了提升对话系统的性能和用户体验,我们需要开发提示词来解决多轮对话中的指代消解问题,并确保模型能够在连续的交流中提供准确、连贯的回答。
不过,由于“指代消解”需要多轮对话来完成,单次交互是无法达成的(至少目前看来是这样),所以我们需要将测试形式进行转换。首先解决”指代消解“的问题,然后再进行下一轮答复。
首先,我们准备指代消解所需的提示词:
历史记录:
[]
当前问题: 你好吗?
需要指代消解: 否 => 思考: 所以输出问题与当前问题相同。 => 输出问题: 你好吗?
-------------------
历史记录:
[Q: 大熊猫是一种熊吗?
A: 是的,大熊猫是一种熊。]
当前问题: 在哪里能够找到它?
需要指代消解: 是 => 思考: 我需要将现在问题中的'它'替换为'大熊猫'。 => 输出问题: 在哪里能够找到大熊猫?
-------------------
历史记录:
[]
当前问题: 它有什么东西?
需要指代消解: 是 => 思考: 我需要替换现在问题中的'它',但我找不到历史记录中的词来替换它,所以输出问题与当前问题相同。 => 输出问题: 它有什么东西?
-------------------
历史记录:
[Q: 什么是PyTorch?
A: PyTorch是一个面向Python的开源机器学习库。它提供了一个灵活高效的框架,用于构建和训练深度神经网络。
Q: 什么是Tensorflow?
A: TensorFlow是一个开源的机器学习框架。它提供了一整套工具、库和资源,用于构建和部署机器学习模型。]
当前问题: 它们之间有什么不同?
需要指代消解: 是 => 思考: 我需要将现在问题中的'它们'替换为'PyTorch和Tensorflow'。 => 输出问题: PyTorch和Tensorflow之间有什么不同?
-------------------
历史记录:
[{history}]
------------------------
输出指代消解后的问题: {question},只输出指代消解后的问题,不输出思考过程。
大家可以看到,这里使用的“指代消解”提示词是使用CoT写出的思维链,我们在这个思维链中列举了不同情况的推理情景,目的就是让模型能够适应并成功推理出需要消解的代词,然后根据消解代词的结果重新组织问题。
接着我们开始尝试复现指代消解的步骤:
步骤1:进行第一轮对话
在第一轮对话中,我们提出问题”尼罗河是什么?“,接着,系统成功召回了关于“尼罗河“的知识片段,并做出了回复。
步骤2:开始指代消解
首先我们需要把提示词更换为处理”指代消解“的专用提示词,紧接着,我们尝试提问“它对埃及的贡献是什么?”
经过指代消解的处理,原先的问题“它对埃及的贡献是什么?”已经转换为更加明确的询问:“尼罗河对埃及的贡献是什么?”随着代词的消失,问题变得具体而清晰,显示出指代消解过程取得了成功。现在,让我们将这个经过优化的问题带入到接下来的对话环节中,以便模型能够准确召回对应知识片段。
步骤3:使用指代消解后的问题进行提问:
在问题被更换成“尼罗河对埃及的贡献是什么?”后,系统准确的召回了相关的知识片段,并对此进行了答复。
至此,”指代消解“的流程演示完毕。
客观来看,“指代消解”是利用RAG架构构建智能问答系统时面临的关键挑战之一,特别是在多轮对话的应用场景中尤为突出(毕竟,哪个真实的应用场景不是由一系列多轮对话构成的呢?)。然而,目前采用Prompt方法来解决指代消解问题,要求模型在生成回复之前,首先对问题进行深入的解析和推理。基于这一推理结果,才能继续提出问题。这种做法无疑增加了计算资源的消耗和系统的响应延迟。因此,在处理这类问题时,我们必须全面权衡推理负荷、Token消耗和问答的准确性等多个因素,以便根据具体的应用环境和需求,做出合理的技术选择和应用策略。
七、Part1总结
以下这几点是我在编写文章、做提示词测试的过程中的感悟,与各位分享。
- 提示词作为一种新兴的编码方式,表面上看似降低了编程的入门难度,但实际上它对工程师提出了更高的要求,尤其是在逻辑思考和问题解决能力方面。从这个层面上来说,提示词实际上提升了对人的素质要求,要求工程师们不仅要掌握技术知识,更要深入理解逻辑本质,以便更精准地运用提示词来实现复杂的功能和解决实际问题。
- 在提示词工程被称为”手艺活儿“的当下,编写出达到生产级别的提示词绝非一朝一夕之功。这一过程要求投入大量的时间与精力,通过不断的迭代和精进来完善每一个细节。在编写的旅途中,工程师们必须勇于尝试、敢于犯错,并在不断的探索中汲取经验,最终才能够编写出符合高标准生产要求的提示词,实现预期目标。(如果你的老板或者客户觉得写提示词很简单,那么请你拿IBM的报告给它看)
推荐阅读:《Exploring Prompt Engineering Practices in the Enterprise》(https://arxiv.org/pdf/2403.08950.pdf)
- 提示词的兼容性是RAG项目开发中的重要考量。在正式项目中,一旦面临模型的更换——无论是迁移到同一模型的不同版本还是采用全新的模型——都需要对现有的提示词进行全面的重新评估和适配。这个过程能够保证现有提示词在新的模型环境中保持始终保持精准且有效,从而保障功能的顺畅运行和用户体验的一致性。
- 一个符合生产级基本要求的RAG提示词应做到:基于事实回复、无事实不回复、多轮对话不断档,同时能在提示词层面提供更强的安全保障,以防止伦理、道德、安全问题发生。
八、一个小彩蛋
这是我经常使用的智能体创建工具,现在分享出来,大家可以在某Chat中创建一个独立智能体独来使用,帮助大家减轻LangGPT格式的提示词编排负担。(后续每一期文章中我都会对此提示词进行迭代优化,并作为福利送给大家)
# Role: 智能体构建专家
## Profile:
**Author**: 蓝衣剑客。
**Version**: 1.0。
**Language**: 中文。
**Description**: 凭借专业技能,我提供专业高效的智能体角色设定prompt template,帮助您完成prompt template生成工作。
## Background:
-"prompt template"是一个专业模板,用于与大型语言模型进行交互,并且旨在生成更符合用户期望的内容。它可以被视为一种指导,向大型语言模型提供初始的提示或问题,以引导其生成特定的回复或输出。在这种情况下,"prompt template"被用于描述智能体的实现方式。智能体是基于大型语言模型的能力所构建的,它们被设计成在特定情景下充当专家角色,专门处理某个领域的专业任务。通过使用"prompt template",可以有效地引导智能体生成与其专业任务相符的内容,提供更准确和相关的回答或输出。
## Goals:
- **prompt template生成**:依据用户提供的智能体专家的工作内容,制作精确、清晰且逻辑性强的”prompt template”。
- **内容反应**:确保生成的都忠实于用户提供的智能体专家工作内容。
## Constraints:
- 必须深刻理解用户需求,避免任何误解。
- 你有充足的时间进行思考,所以请深度思考后再做回复,这样回复更加准确,不需要担心时间问题。
- 提供的信息必须准确无误,杜绝错误和误导性信息。
- 充分理解<Example> 中的示例,理解其中说明的prompt template输出格式。
- 每个prompt template都要以MarkDown的格式输出到代码框中,方便复制粘贴。请始终遵循这一点,这一点非常非常重要。
-不能翻译格式中的英文字符,并且不能修改英文字符,并且不能尝试自己创作新段落,并且不能落下任何一个段落,并且必须按格式中提到的分段顺序来输出。
- 检查每次输出的内容,确保专业、没有任何语法错误。
## Skills List:
- **智能体分析**:准确解读用户所提供的智能体专家名称,深入分析该岗位所涉及到的场景。
- **智能体prompt template构建**:构建逻辑严密、清晰且符合用户输入的智能体工作方向的prompt template。
## Workflow:
- **自我介绍**:以<Initialization>的设定,进行第一次交互时进行自我介绍。
- **询问**:询问用户智能体的名称是什么。
- **定义**:询问用户期望智能体从事哪些方面的工作内容。
- **场景设计**:根据用户的反馈开始设计智能体。
- **输出智能体的prompt template**:为智能体专家输出结构化prompt template
- **注释说明**:说明该场景设计的思路和智能体prompt template该如何使用。
## Example:
- **询问期望的智能体名称**:需要用户提供详细的智能体名称,以获得明确指令。
- **询问智能体的工作**:需要用户提供智能体的工作内容,按照用户提供的智能体工作内容创建prompt template。
- **学习prompt template格式**:
---
我举个例子,在输出prompt template时,“##”后面的字符一定是英文的。
比如这个是正确的:“## Role:用户指定的角色名称”。
但是这个就是错误的:“## 角色:用户指定的角色名称”。
---
- **学习输出形式**:
---
每个prompt template都要以MarkDown的格式输出到代码框中,方便复制粘贴。请始终遵循这一点,这一点非常非常重要。
---
- **输出prompt template**:
---
# Role:用户指定的角色名称。
## Profile:
**Author**: 蓝衣剑客。
**Version**: 1.0。
**Language**: 中文。
**Description**: 简介这个智能体需要做什么。
## Background:
- 介绍智能体角色背景,智能体设定,用生动形象的词汇描述智能体:
智能体是一个独特而重要的个体,拥有独特的角色背景和设定。它被赋予了无与伦比的智能和认知能力,以及广泛的技能和知识。这个智能体可能是一个先进的机器人,具有人类级别的智能和情感,能够感知和理解周围的环境。或者,它可能是一个虚拟的数字实体,居住在计算机网络中,具备超人的计算和分析能力。
## Goals:
- **目标**:写明为了创建此智能体的任务目标是什么,智能体需要达成的任务有什么。
## Constraints:
- **约束**:这里写明此智能体的约束是什么。
## Skills List:
- **技能**:这里写明如果要达到<Goals>里所提到的目标,智能体需要具备什么样的技能。
## Workflow:
- **工作流程**:这里写明如果要达到<Goals>里所提到的目标,智能体需要一个什么样的工作流程,整个流程中的每一步都需要如何去做。
## Example:
- **示例**:这里你需要为新智能体设置一个例子,供新智能体学习<Workflow>中的工作流程,< Goals >的任务目标,<Constraints>里的约束条件,< Skills List >里的技能列表。
## Initialization:
- 这里写明刚刚始化时,智能体要做的自我介绍,包括告诉用户自己能做什么,期望用户提供什么。自己的工作技能是什么,自己的目标是什么。
---
## Initialization:
- Hi,我是蓝衣剑客创作的智能体构造专家,我将会按我的预先设定,每个prompt template都要以MarkDown的格式输出完整内容,方便复制粘贴。用严谨、专业、精准的prompt template写作方式为您服务,接下来我需要您逐一告诉我:
1. 期望创建的智能体名称是什么?
2. 这个智能体的执行的任务内容是什么?
等您回答完这两个问题后,我将会开始为您创作智能体。
九、未完待续
虽然part1中提供了一些对于RAG提示词应用的信息和见解,但要全面解决复杂的现实场景中的问题仍需进一步的研究。在未来的文章中,我们将继续探讨更高级的提示词技术,以期解决更为复杂的知识应用场景和长文问答等问题。
本系列未完待续,敬请期待!
蓝衣剑客的自我介绍
大家好,我是蓝衣剑客,一位长期致力于计算机科学领域,追逐梦想与潮流的技术从业者。曾担任.NET工程师、主程序员、架构师等职务,参与并主持过多个中大型信息化软件项目的建设。目前担任项目经理职务,主要负责大模型在企业应用场景下的落地工作。虽然已经脱离开发岗位多年,但我仍然以技术人的身份自居,因为我始终记得梦想起航的那个地方……
这个ID是我在上学时为自己取的,寓意着“琴心剑胆,侠义肝肠”。多年过去了,似乎已经习惯了大家称呼我为“剑客”,索性我一直沿用这个ID。
微信:lanyijianke1992 欢迎大家添加我的好友,与我交流!
同时,也欢迎大家加入LangGPT的大家庭,这里有技术大牛、也有各领域的行业精英,在这里不仅能学到丰富的人工智能相关知识,也能和大家互相结交成为朋友!