你真的会写 Prompt ? 剖析 RAG 应用中的指代消解
随着 ChatGPT 等大语言模型(LLM)的不断发展,越来越多的研究人员开始关注语言模型的应用。
其中,检索增强生成(Retrieval-augmented generation,RAG)是一种针对知识密集型 NLP 任务的生成方法,它通过在生成过程中引入检索组件,从已知的知识库中检索相关信息,并将这些信息与 LLM 的生成能力结合,从而提高生成的准确性和可靠性。这种方法可以用于实现各种知识密集型 NLP 任务,如问答、文摘生成、语义推理等。
本文将从解决优化 RAG 系统里的一个具体问题出发,通过展示使用 LLM Prompt Engineering 的方法,来解析传统 NLP 的问题。
01.解决方案初探
开源项目 Akcio 就是一套完整的 RAG 问答系统,用户导入各类私有专业知识,就可以构建专业领域的问答系统。
|Akcio 的架构图。专业知识是各类 Documents,通过 DataLoader 导入进 Store。在每次提问 Question 后,LLM 可以结合召回知识,加上 LLM 自身的自然语言生成能力,给出对应的回答。
举个例子,比如我们将一篇名为《2023 大模型落地进展趋势洞察报告》的文章,将它导入 Akcio,就可以问它这篇报告里的问题了,比如:
2023年,大模型行业的应用场景可以分为哪几类?
通过一些召回策略,在 Store 里召回出了《报告》中,与问题最相关的 3 条原文片段:
['在2023年,大模型行业的应用场景可分为生成和决策两类应用场景,决策场景预期业务值更高。',
'大模型行业的生成场景主要有对话交互,代码开发,智能体等。',
'NLP的应用场景有文本分类,机器翻译,情感分析,自动摘要等。']
很显然,最有用的片段是第一条,但没关系,Akcio 会把这 3 条都作为 context,去问 LLM,比如它是这样问的:
请根据下面知识回答问题:
知识:
在2023年,大模型行业的应用场景可分为生成和决策两类应用场景,决策场景预期业务值更高。
大模型行业的生成场景主要有对话交互,代码开发,智能体等。
NLP的应用场景有文本分类,机器翻译,情感分析,自动摘要等。
问题:
2023年,大模型行业的应用场景可以分为哪几类?
LLM 就可以给出合理的回答:
大模型行业的应用场景可以分为生成和决策两类应用场景。
这样的话整条链路就走通了。这套架构逻辑看似并不复杂,但如果深入到开发过程中,就会发现其中有一些难点需要解决。
比如在多轮对话的情况下,就需要解决一个问题:如果在最新一轮的提问,里面有些指代上文的代词,那么如果直接用这个问题去做召回,很可能会召回错误的知识,比如:
问1: 2023年,大模型行业的应用场景可以分为哪几类?
答1: 大模型行业的应用场景可以分为生成和决策两类应用场景。
问2: 它们有什么区别,能举例说明吗?
这里的“它们”很显然指的是“生成和决策两类应用场景”,问题的原意是“生成和决策场景有什么区别,能举例说明吗?”。但如果直接用这个问题“它们有什么区别,能举例说明吗?”去做召回,那很有可能召回的是比如这样的知识片段:
['BERT和GPT都是NLP领域的重要模型,但它们的设计和应用场景有很大的区别。',
'大模型和小模型的区别在于其规模和复杂度。大模型通常具有更多的参数和更复杂的结构,需要更多的计算资源和时间来训练和推理。而小模型则相对简单,参数较少,训练和推理速度较快。',
'但没有更多的信息来区分这两个产品,因为它们看起来非常相似。']
显然主体错了,那用这些召回的知识肯定也就不对了,LLM 利用这些无用的知识也不用给用户很好的回答了。
那么要解决这个问题有什么好的办法呢?
首先可以想到的是NLP领域中的一个常见任务:指代消解(Coreference resolution)。指代消解是自然语言处理(NLP)中的一项重要任务,用于确定文本中指代相同实体的词语。该任务旨在识别代词、名词短语等,将它们与先前提到的实体关联起来。例如,在句子“John saw Mary. He waved to her.”中,coreference resolution会将“He”和“John”以及“her”和“Mary”归纳为同一实体。
也许这个任务可以帮助我们解决这个问题,但经过实践发现,无论是通过 spacy,还是 huggingface,目前的开源模型,处理指代消解这个任务都有一定的局限性,只能处理比较简单的场景,比如:
问1:大模型是什么?
问2:它有什么用?
可以找出“它”指的是“大模型”。然而,对于复杂的指代,却不能识别出来,比如:
问1:GPT3是什么?
问2:GPT4又是什么时候发布的?
问3:二者有什么区别?后者有什么优势?
没法识别出“二者”指的是 GPT3 和 GPT4,“后者”指的是“GPT4”。再比如:
问1:GPT4又是什么时候发布的?
答1:GPT4是在 2023 年发布的
问2:这一年在计算机视觉有什么进展?
没法识别出“这一年”指的是“2023年”。
也就是说,现有的 NLP 小模型,只能处理识别“它”,“他”,“她”,“这个”等简单的代词,而对于复杂的指代表述,没法识别处理。
那该怎么办呢,对于复杂语言场景,也许最好的处理就是用大模型,毕竟 ChatGPT 火爆时可是号称是“让 NLP 不存在的”的终极武器。于是我们可以尝试,让 LLM 来做这个指代消解任务。
02.用 ChatGPT 做指代消解
我们尝试使用便宜又好用的 ChatGPT 来做这个任务。这里面的关键,其实就是 prompt 怎么写的问题,也就是常说 prompt engineering。这其实是一个看起来好像很简单,但要做好,其实并不简单的一个事情。
比如我们最开始用一些简单的命令类的 prompt,试着让 ChatGPT 去代换最新问题中的代词:
prompt = f'''Please return a new question with the following requirements:
1. If there are pronouns or conditions are missing in the question, please make a complete question according to the context.
2. If the question is complete, please keep the original question.
{history}
Question: {question}'''
这个 prompt 并不复杂,提出要求,要么替换代词,要么保留原问题不变,并把历史上下文,和最新问题给到 GPT,让它来帮我们完成这个任务。那来测一些效果(相对中文来说,GPT 更擅长英文,所以直接用英文测试):
history = ''' What is NLP?
NLP stands for Natural Language Processing. It is a field of computer science and artificial intelligence that focuses on the interaction between computers and humans using natural language. '''
question = 'What problem does it solve?'
ChatGPT给的返回是:
What problem does Natural Language Processing (NLP) solve?
好像还不错,它把“it”识别出了“NLP”,而且还用“Natural Language Processing (NLP)”来补充全称。
再试试复杂的例子:
history = '''When was GPT4 released?
GPT4 was released in 2023'''
question = 'What progress has been made in computer vision this year?'
返回是:
What progress has been made in computer vision this year?
GPT 并没有成功替换掉 “this year”,在这个例子下它失败了。
再试个复杂例子:
history = '''What is GPT3?
GPT-3 (Generative Pre-trained Transformer 3) is a state-of-the-art language processing model developed by OpenAI.
When was GPT4 released?
GPT4 was released in 2023'''
question = 'What is the difference between the two? What are the advantages of the latter?'
返回是:
Sorry, the information provided about GPT-4's release date is not accurate as it has not been officially announced by OpenAI. Therefore, it is not possible to answer the question about the difference between GPT-3 and GPT-4 or the advantages of the latter.
ChatGPT 并没有按照我们的要求,去改写掉代词,而是直接去回答这个问题了(这里用的 GPT3 模型是偏早期的,它的训练资料里还没有关于 GPT4 的信息,因此它回答称自己不知道)。
在我们的后面的测试中,发现 ChatGPT 有一定的概率会去直接回答问题,而不是按照我们的要求 prompt 去改写代词。我们尝试在 prompt 里加一些要求,让它不要去直接回答问题,但这一问题还是有小的概率会出现。看来ChatGPT 并不是所有要求都能听懂,有时候也容易被其它信息干扰错乱。
在传统 NLP 小模型,和 ChatGPT 这样的大模型都无法解决这个问题的情况下,应该怎么办呢?也许我们从另外一个角度尝试优化我们的 prompt,可以让 ChatGPT 更加听话。
03.Few-shot prompt + CoT
在 prompt engineering 里有一些技巧,可以让 LLM 更加理解并服从指令,比如,我们给 LLM 多看几个参考答案,让它模仿我们的参考例题继续作答,这种 few-shot context learning 的方法,即不需要 fine-tune LLM 模型,又能产生很好的效果。一般给 LLM 看 5 次 shot 后,LLM 就能很好地顺从你的参考案例继续回答。
但是否需要做代词替换,还是要保留原问题,是一个比较复杂的 NLP 理解问题。即使是 ChatGPT 这样的 LLM,也不一定可以按照几个参考例子,直接给出正确的回答。还好,在 prompt engineering 里还有一个常见的方法,可以让 LLM 更好地处理逻辑问题,那就是思维链 CoT。
“思维链 (Chain-of-thought,CoT) 的概念是在 Google 的论文 "Chain-of-Thought Prompting Elicits Reasoning in Large Language Models" 中被首次提出。思维链(CoT)是一种改进的提示策略,用于提高 LLM 在复杂推理任务中的性能,如算术推理、常识推理和符号推理。大概思想就是,让 LLM 在回答的过程中,把中间过程推导也一并回答出来,让 LLM 逐步推导出最后的答案。这样比让 LLM 直接回答出最后的答案的准确率要高得多。
所以,我们完全可以在给 few-shot examples 时,也给到 LLM Chain-of-thought,就是也让它看到思考推理的过程。这样可以提高准确率。
于是,我们按照这样的思想,写出我们的最终 prompt:
REWRITE_TEMP = f'''
HISTORY:
[]
NOW QUESTION: Hello, how are you?
NEED COREFERENCE RESOLUTION: No => THOUGHT: So output question is the same as now question. => OUTPUT QUESTION: Hello, how are you?
-------------------
HISTORY:
[Q: Is Milvus a vector database?
A: Yes, Milvus is a vector database.]
NOW QUESTION: How to use it?
NEED COREFERENCE RESOLUTION: Yes => THOUGHT: I need to replace 'it' with 'Milvus' in now question. => OUTPUT QUESTION: How to use Milvus?
-------------------
HISTORY:
[]
NOW QUESTION: What is the features of it?
NEED COREFERENCE RESOLUTION: Yes => THOUGHT: I need to replace 'it' in now question, but I can't find a word in history to replace it, so the output question is the same as now question. => OUTPUT QUESTION: What is the features of it?
-------------------
HISTORY:
[Q: What is PyTorch?
A: PyTorch is an open-source machine learning library for Python. It provides a flexible and efficient framework for building and training deep neural networks.
Q: What is Tensorflow?
A: TensorFlow is an open-source machine learning framework. It provides a comprehensive set of tools, libraries, and resources for building and deploying machine learning models.]
NOW QUESTION: What is the difference between them?
NEED COREFERENCE RESOLUTION: Yes => THOUGHT: I need replace 'them' with 'PyTorch and Tensorflow' in now question. => OUTPUT QUESTION: What is the different between PyTorch and Tensorflow?
-------------------
HISTORY:
[{history}]
NOW QUESTION: {question}
NEED COREFERENCE RESOLUTION: '''
这里给 ChatGPT 看 4 个参考例子。第一个是一个空的对话历史,第二个是最简单的例子,第三个是一个替换失败的例子,最后一个是替换两个指代的例子。
在格式上,“HISTORY:”后面就是历史上下文,为了和其它行区分开,在格式上,每次问题前加上“Q:”,每次回答前加上“A:”。“NOW QUESTION”就是最新一轮的提问。而“NEED COREFERENCE RESOLUTION:”这一行后面,就是一次CoT的推导,先让LLM先判断是否需要做“COREFERENCE RESOLUTION”, 然后“THOUGHT:”一下,看看在尝试去替换时,是否成功。最后“OUTPUT QUESTION:”后输出改写后的问题。
最后解析 LLM 的返回时,只需要把 LLM 返回字符串的格式拆解开,只有在“NEED COREFERENCE RESOLUTION:”后跟“Yes”的情况,才去拿最后“OUTPUT QUESTION:”改写的最终问题。
接下来,我们来看看用这个 prompt 的使用效果,还是用上面失败的两个例子,LLM 还是用 ChatGPT:
history = '''When was GPT4 released?
GPT4 was released in 2023'''
question = 'What progress has been made in computer vision this year?'
返回:
Yes => THOUGHT: I need to replace "this year" with "2023" in the now question. => OUTPUT QUESTION: What progress has been made in computer vision in 2023?
```python
可以看到 ChatGPT 成功返回了我们想要的结果,成功将“this year”替换成“2023”。
下一个例子:
```python
history = '''What is GPT3?
GPT-3 (Generative Pre-trained Transformer 3) is a state-of-the-art language processing model developed by OpenAI.
When was GPT4 released?
GPT4 was released in 2023'''
question = 'What is the difference between the two? What are the advantages of the latter?'
返回:
Yes => THOUGHT: I need to replace 'the two' with 'GPT-3 and GPT-4' and 'the latter' with 'GPT-4' in the now question. => OUTPUT QUESTION: What is the difference between GPT-3 and GPT-4? What are the advantages of GPT-4?
可以看到这种复杂问题,也能成功将“the two”替换成“GPT-3 and GPT-4”,“the latter”替换成“GPT-4”。
04.总结
本文从解决优化 RAG 系统里的一个具体问题出发,讨论了使用 LLM prompt engineering 的方法,来解析传统 NLP 的问题,并得到一定的质量提升。可以看到,写 prompt 有时很简单,有时却是一个很难的事。所以在 LLM 爆火之后,prompt engineering 分支领域也逐渐形成并发展,各种写 prompt 层出不穷。也许本文展示的最终 prompt 可能并非最优解,但一定比传统 NLP 方法好得多。这也让我们看到了,用 LLM 大模型,确实可以帮助优化和解决很多传统 NLP 领域的问题,也许就是大模型之所以强大的地方吧。
随着GPT-4之后的大模型能力越来越强,我相信也许多年后 NLP 领域的很多问题可能已不是问题,通用的人工智能会慢慢走近我们。
keepReading

向量数据库发展迎里程碑时刻!Zilliz Cloud 全新升级:超高性价比,向量数据库唾手可得
升级后的 Zilliz Cloud 不仅新增了诸如支持 JSON 数据类型、动态 Schema 、Partition key 等新特性,而且在价格上给出了史无前例的优惠,例如推出人人可免费使用的 Serverless cluster 版本、上线经济型 CU 等。这意味着,更多的开发者可以在不考虑预算限制的情况下畅用云原生向量数据库。

向量数据库的行业标准逐渐清晰!Vector DB Bench 正式开源!
本文将从 Vector DB Bench 的特点和优点出发,帮助开发者全面、客观、高效地评估向量数据库。

LLM 快人一步的秘籍 —— Zilliz Cloud,热门功能详解来啦!
此次我们在进行版本更新的同时,也增加了多项新功能。其中,数据迁移(Migration from Milvus)、数据的备份和恢复(Backup and Restore)得到了很多用户的关注。本文将从操作和设计思路的层面出发,带你逐一拆解 Zilliz Cloud 的【热门功能】。




