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]