RAG實戰5-自定義prompt

一蓑烟雨度平生發表於2024-03-11

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] 

相關文章