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] 
posted @ 2024-03-11 09:56  一蓑烟雨度平生  阅读(529)  评论(0编辑  收藏  举报