iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
AI Engineering

從零打造 RAG 系統:檢索、生成與落地全紀錄系列 第 19 篇

[Day 19] 多輪對話中的檢索挑戰(Conversational RAG)

  • 分享至 

  • xImage
  •  

前言

到目前為止,我們討論的檢索場景都是「單輪問答」——使用者問一句,系統回一句。但實際應用中,使用者往往會延續前面的對話繼續追問,這對 RAG 系統的檢索階段帶來了新的挑戰。

問題:省略主詞的追問

真實對話常常長這樣:

使用者:「Postgres 的 pgvector 要怎麼安裝?」
系統:(回答安裝步驟...)
使用者:「那它支援哪些索引類型?」   ← 「它」指的是 pgvector,但這句話本身沒講清楚

如果直接拿「那它支援哪些索引類型?」去做向量搜尋,系統根本不知道「它」是什麼,檢索結果很可能牛頭不對馬嘴。

解法一:對話歷史 + Query Rewriting

延續 Day 18 提到的 Query Rewriting,在多輪對話情境下更加重要:把對話歷史一起交給 LLM,讓它把當前問題改寫成「獨立、完整」的問題,再拿去檢索。

def rewrite_with_history(chat_history, current_question):
    history_text = "\n".join(
        f"{'使用者' if m['role']=='user' else '系統'}:{m['content']}"
        for m in chat_history
    )
    prompt = f"""以下是一段對話歷史,請根據上下文,
將「目前問題」改寫成一個不需要依賴對話歷史、單獨也能被理解的完整問題:

對話歷史:
{history_text}

目前問題:{current_question}

改寫後的完整問題:"""
    return call_llm(prompt).strip()

範例輸出:

改寫後:「pgvector 支援哪些索引類型?」

解法二:保留對話中提到的關鍵實體

另一種思路是額外維護一個「目前對話中提到的關鍵實體」清單(例如產品名稱、技術名詞),在組裝檢索查詢時自動帶入,而不完全依賴 LLM 改寫。

class ConversationContext:
    def __init__(self):
        self.mentioned_entities = []

    def update(self, question, answer):
        entities = extract_entities(question + answer)  # 可用 NER 或 LLM 抽取
        self.mentioned_entities.extend(entities)

    def build_search_query(self, current_question):
        context_hint = "、".join(self.mentioned_entities[-3:])  # 取最近提到的幾個實體
        return f"{context_hint}{current_question}"

多輪對話下的 Prompt 設計

生成階段的 Prompt 也需要調整,通常會把「對話歷史」與「本輪檢索結果」一起放入:

System: 你是一個技術問答助手,請根據下方參考資料與對話歷史回答使用者的最新問題。

對話歷史:
{chat_history}

參考資料(本輪檢索結果):
{retrieved_chunks}

使用者最新問題:{current_question}

要注意:對話歷史一長,加上每輪都要放入檢索結果,很容易讓 Prompt 超過 context window 限制,通常需要做對話歷史的摘要或截斷(只保留最近 N 輪)。

每輪都要重新檢索嗎?

不一定。可以先判斷「這一輪問題是否需要查新的資料」:

  • 如果只是針對前一輪回答做澄清或延伸討論(例如「可以講更詳細一點嗎?」),可能不需要重新檢索,直接根據已有的上下文回答即可
  • 如果話題明顯轉移到新主題,才需要觸發新一輪檢索

這個判斷可以用一個簡單的分類 Prompt 讓 LLM 先做決定,避免每輪都做不必要的檢索,增加延遲與成本。

小結

多輪對話為 RAG 系統帶來的最大挑戰,是「使用者的問題不再是獨立完整的」,需要額外處理指代消解與上下文延續的問題。透過 Query Rewriting、實體追蹤等技巧,可以讓系統在對話情境下依然檢索到正確的內容。明天是檢索優化系列的最後一天,我們要處理長文件與多文件交叉引用的挑戰。


上一篇
[Day 18] Query 改寫與擴展(Query Rewriting / HyDE)
下一篇
[Day 20] 處理長文件與多文件交叉引用
系列文
從零打造 RAG 系統:檢索、生成與落地全紀錄 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言