RAG实战5-自定义prompt
RAG实战5-自定义prompt
在阅读本文之前,先阅读RAG实战4。在RAG实战4中我们分析了LlamaIndex中RAG的执行过程,同时留下了一个尚待解决的问题:LlamaIndex中提供的prompt template都是英文的,该如何使用中文的prompt template呢?
直接看以下代码:
import logging
import sys
import torch
from llama_index.core import PromptTemplate, Settings, StorageContext, load_index_from_storage
from llama_index.core.callbacks import LlamaDebugHandler, CallbackManager
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.huggingface import HuggingFaceLLM
# 定义日志
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
# 定义system prompt
SYSTEM_PROMPT = """你是一个医疗人工智能助手。"""
query_wrapper_prompt = PromptTemplate(
"[INST]<<SYS>>\n" + SYSTEM_PROMPT + "<</SYS>>\n\n{query_str}[/INST] "
)
# 定义qa prompt
qa_prompt_tmpl_str = (
"上下文信息如下。\n"
"---------------------\n"
"{context_str}\n"
"---------------------\n"
"请根据上下文信息而不是先验知识来回答以下的查询。"
"作为一个医疗人工智能助手,你的回答要尽可能严谨。\n"
"Query: {query_str}\n"
"Answer: "
)
qa_prompt_tmpl = PromptTemplate(qa_prompt_tmpl_str)
# 定义refine prompt
refine_prompt_tmpl_str = (
"原始查询如下:{query_str}"
"我们提供了现有答案:{existing_answer}"
"我们有机会通过下面的更多上下文来完善现有答案(仅在需要时)。"
"------------"
"{context_msg}"
"------------"
"考虑到新的上下文,优化原始答案以更好地回答查询。 如果上下文没有用,请返回原始答案。"
"Refined Answer:"
)
refine_prompt_tmpl = PromptTemplate(refine_prompt_tmpl_str)
# 使用llama-index创建本地大模型
llm = HuggingFaceLLM(
context_window=4096,
max_new_tokens=2048,
generate_kwargs={"temperature": 0.0, "do_sample": False},
query_wrapper_prompt=query_wrapper_prompt,
tokenizer_name='/yldm0226/models/Qwen1.5-14B-Chat',
model_name='/yldm0226/models/Qwen1.5-14B-Chat',
device_map="auto",
model_kwargs={"torch_dtype": torch.float16},
)
Settings.llm = llm
# 使用LlamaDebugHandler构建事件回溯器,以追踪LlamaIndex执行过程中发生的事件
llama_debug = LlamaDebugHandler(print_trace_on_end=True)
callback_manager = CallbackManager([llama_debug])
Settings.callback_manager = callback_manager
# 使用llama-index-embeddings-huggingface构建本地embedding模型
Settings.embed_model = HuggingFaceEmbedding(
model_name="/yldm0226/RAG/BAAI/bge-base-zh-v1.5"
)
# 从存储文件中读取embedding向量和向量索引
storage_context = StorageContext.from_defaults(persist_dir="doc_emb")
index = load_index_from_storage(storage_context)
# 构建查询引擎
query_engine = index.as_query_engine(similarity_top_k=5)
# 输出查询引擎中所有的prompt类型
prompts_dict = query_engine.get_prompts()
print(list(prompts_dict.keys()))
# 更新查询引擎中的prompt template
query_engine.update_prompts(
{"response_synthesizer:text_qa_template": qa_prompt_tmpl,
"response_synthesizer:refine_template": refine_prompt_tmpl}
)
# 查询获得答案
response = query_engine.query("不耐疲劳,口燥、咽干可能是哪些证候?")
print(response)
# 输出formatted_prompt
event_pairs = llama_debug.get_llm_inputs_outputs()
print(event_pairs[0][1].payload["formatted_prompt"])
先看print(list(prompts_dict.keys()))
这行代码的输出:
['response_synthesizer:text_qa_template', 'response_synthesizer:refine_template']
这表明我们使用的查询引擎中包含了两种类型的prompt template,一种是问答模板(text_qa_template),一种是重写模板(refine_template)。需要哪些类型的template取决于我们使用什么样的响应合成器(response_synthesizer)。在RAG实战4我们曾提到过,默认的响应合成器是compact,其将文本集中在一起,简化了refine的步骤。因此这里我们只需要修改text_qa_template即可。在上面的代码中,为了演示,我们同样修改了refine_template,尽管这不是必要的。
query_engine.update_prompts(...)
将我们在前面定义的qa_prompt_tmpl和refine_prompt_tmpl更新到查询引擎中。
大模型经过RAG的响应如下:
从中医临床的角度来看,不耐疲劳、口燥、咽干的症状可能与津液亏耗证(津液亏耗证或液干热结证)相关。津液亏耗证表现为口干、唇裂、鼻燥、皮肤干燥,以及口渴、干咳等症状,而津液不足证或津亏热结证也包括这些特征。然而,具体诊断还需结合其他临床表现和脉象分析,因为中医强调四诊合参。如果伴有发热、无汗、头痛或肢体酸痛,可能指向燥干清窍证或者津伤燥热证。建议患者到中医诊所详细咨询。
同时,我们可以使用RAG实战4的追踪技术看一下实际形成的prompt(print(event_pairs[0][1].payload["formatted_prompt"])
):
[INST]<<SYS>>
你是一个医疗人工智能助手。<</SYS>>
上下文信息如下。
---------------------
file_path: document/中医临床诊疗术语证候.txt
4.6.1.1
津液不足证 syndrome/pattern of fluid and humor insufficiency
津亏证
因津液生成不足,或嗜食辛辣,蕴热化燥,邪热灼损津液所致。临床以口眼喉鼻及皮肤等干燥,大便干结,小便短少,舌质偏红而干,脉细数等为特征的证候。
4.6.1.
file_path: document/中医临床诊疗术语证候.txt
临床以口干、舌燥,频饮而不解其渴,食多、善饥,夜尿频多,逐渐消瘦,舌质红,舌苔薄黄或少,脉弦细或滑数,伴见皮肤干燥,四肢乏力,大便干结等为特征的证候。
4.6.3.2
津亏热结证 syndrome/pattern of fluid depletion and heat binding
液干热结证
因津液亏虚,热邪内结所致。
file_path: document/中医临床诊疗术语证候.txt
临床以口眼喉鼻及皮肤等干燥,大便干结,小便短少,舌质偏红而干,脉细数等为特征的证候。
4.6.1.2
津液亏涸证 syndrome/pattern of fluid and humor scantiness
津液亏耗证
津液干枯证
因津液亏损,形体官窍失养所致。临床以口干、唇裂,鼻燥无涕,皮肤干瘪,目陷、螺瘪,甚则肌肤甲错,舌质红而少津,舌中裂,脉细或数,可伴见口渴、欲饮,干咳,目涩,大便干,小便少等为特征的证候。
file_path: document/中医临床诊疗术语证候.txt
临床以鼻咽干涩或痛,口唇燥干,舌质红,舌苔白或燥,脉浮或微数,伴见发热、无汗,头痛或肢节酸痛等为特征的证候。
3.6.3.2
燥干清窍证 syndrome/pattern of dryness harassing the upper orifices
因气候或环境干燥,津液耗损,清窍失濡所致。临床以口鼻、咽喉干燥,两眼干涩,少泪、少涕、少津、甚则衄血,舌质瘦小、舌苔干而少津,脉细等为特征的证候。
file_path: document/中医临床诊疗术语证候.txt
6.3.1
津伤化燥证 syndrome/pattern of fluid damage transforming into dryness
津伤燥热证
因燥热内蕴,或内热化燥,伤津耗液所致。临床以口干、舌燥,频饮而不解其渴,食多、善饥,夜尿频多,逐渐消瘦,舌质红,舌苔薄黄或少,脉弦细或滑数,伴见皮肤干燥,四肢乏力,大便干结等为特征的证候。
4.6.3.
---------------------
请根据上下文信息而不是先验知识来回答以下的查询。作为一个医疗人工智能助手,你的回答要尽可能严谨。
Query: 不耐疲劳,口燥、咽干可能是哪些证候?
Answer: [/INST]