iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
AI 自動化

《從心出發:30 天打造一套具 RAG、心理支持決策、安全治理與 ARCI 自適應能力的 AI 心理支持平台》系列 第 21

#Day 21|Retrieval:找到最像的資料,不代表找到最該使用的資料

  • 分享至 

  • xImage
  •  

上一篇談 Context Assembly 時,我把「資料還在」與「這一輪可以使用」分開處理。即使一筆資訊仍然有效,也不能因此直接放進模型的上下文。

但這個流程還有一個前提:等待檢查的候選資料,已經被找出來了。

今天我想再往前追一步。在「從心出發」裡,這些候選資訊從哪裡來?如果檢索器交回的資料不合適,後面的組裝流程又會面對什麼問題?

這讓我開始區分兩件容易被混在一起的事:找到一份資料,與決定採用這份資料。

找到最像的資料,為什麼還不夠?

先用一個假想情境說明。以下不是使用者紀錄,也不是本日實際模型生成的結果。

使用者說:「最近每天晚上都很難睡,腦袋一直停不下來。」

假設檢索結果裡,候選 A 出現很多相近的字詞,因此排名第一,卻缺少可追溯的來源;候選 B 排名稍後,但來源完整,也符合這次流程允許使用的資料類型。

只看排名,A 似乎最值得採用。但它排在前面,回答的是搜尋方法衡量下的接近程度,不是來源是否可靠,更不是它有沒有資格進入這次回答。

這裡需要分清楚三個概念:

Similarity 是相似度,描述資料與查詢在檢索方法下有多接近。Relevance 是相關性,問的是這份資料是否有助於當前問題。Eligibility 是准入資格,則要檢查來源、有效性及使用政策是否允許它進入後續流程。

三者不能互相代替。資料可以很像,卻不適合拿來回應;也可以確實相關,卻因為缺少來源資訊而不能通過准入。

因此,Top-K 在這篇裡只是候選範圍,不是答案清單。拿到排名最高的幾筆資料,不代表已經完成了證據選擇。

Retriever 負責找候選,不負責裁決

本日實作集中在 src/psychological_support/conversation/retrieval.py。我把查詢、候選資料與准入判斷分開,使用 QueryRepresentation、QueryBuilder、RetrievalCandidate、CandidateProvenance、OfflineCandidateRetriever 與 RetrievalEligibilityGate 表達不同責任。

其中最重要的界線是:候選資料產生時,只能是 CANDIDATE_ONLY。

RetrievalCandidate 可以帶有 similarity_score,但不能因為分數高,就自行宣告已取得准入資格。相似度欄位也不能被當成真實性、權威性或臨床相關性的認證。

以下是這個責任分離的概念圖。最後接往 Context Assembly 的虛線表示設計上的後續位置,不表示這份交付已證明整條即時生成流程接通。

flowchart TD
U[使用者原始訊息] --> Q[查詢建構與不確定性保留]
Q --> R[離線候選檢索]
R --> C[候選集合:CANDIDATE_ONLY]
C --> G[來源、有效性與准入檢查]
G -->|有合格候選| E[通過本階段檢查的候選]
G -->|沒有合格候選| N[保留空結果,不捏造證據]
E -.-> A[後續 Context Assembly]

檢索器負責提供值得檢查的資料,准入檢查決定它能不能進入下一階段。即使通過這一關,也不代表資料已被證明為真,更不代表可以直接照著它生成回答。

問題也可能出在搜尋之前

檢索結果不合適,不一定是資料庫的問題。查詢本身也可能先被改寫偏了。

例如,使用者只說:「我最近不太想說話。」如果系統把查詢改寫成 depression social withdrawal,就已經加入原句沒有提供的診斷方向。後面的搜尋即使忠實地依照查詢找資料,也是在回答一個被系統改過的問題。

這又回到 Day 18:不知道的事情,不能在資料轉換時被偷偷補成已知。

依本日交付紀錄,QueryBuilder 對沒有依據的診斷用詞設有限制,會移除不合理加入的臨床詞彙。這裡想守住的,不只是避免某幾個字,而是避免查詢建構替使用者新增沒有表達過的判斷。

不過,指定案例通過,不等於所有自然語言改寫都已被涵蓋。我能依本日紀錄描述這條規則與測試結果,不能把它擴大成任意輸入都不會被誤解的保證。

同一份資料,不能因為切成三段就變成三份證據

另一個容易忽略的問題,是候選數量不等於獨立來源數量。

假設同一份文件被切成三個片段,而三段都出現在搜尋結果裡。它們可以是三個候選片段,卻不能因此被算成三份互相支持的獨立資料。

本日實作加入共享來源辨識與去重,將來自同一來源文件的片段視為具有共同的 provenance,避免下游把重複內容誤認成多個獨立支持。

這個處理也有範圍:辨識同一文件的片段,不等於已經完成所有來源之間的獨立性分析。它先處理的是本日交付所描述的共同來源與重複候選問題。

另外,缺少來源、資料過期或沒有合格結果時,流程採取保守處理,而不是為了交出內容就降低准入條件。沒有找到合格候選,本身就是需要保留下來的結果。

從 Retrieval Pollution 回看上下文污染

Day 20 討論的是:不合適的資料進入上下文之後,可能影響回答。

今天則把問題往前推。如果查詢先被加入沒有根據的解釋,搜尋結果就可能跟著偏向那些解釋。後面的組裝器即使有篩選規則,面對的候選集合仍可能一開始就不平衡。

我在本文用 Retrieval Pollution(檢索污染)描述這種工程風險。它不是臨床術語,也不是本日已經量測出的模型行為,而是一個提醒:檢查不能只從 Prompt 開始,還要回頭看查詢如何形成、候選如何取得。

所以,檢索邊界與上下文邊界不是互相取代的功能。前者限制候選如何產生及進入下一階段,後者再處理這一輪究竟需要使用哪些資訊。

今天真正驗證了什麼

本日 Walkthrough 記載,新增的測試套件是 tests/conversation/test_retrieval_candidate.py,涵蓋任務要求的十項邊界案例。執行結果如下:

測試範圍

交付紀錄記載的結果

執行時間

Retrieval 專屬單元測試

10 項通過,結束碼 0

0.001 秒

Conversation 回歸測試

716 項通過,結束碼 0

3.015 秒

Repository 全測試探索

927 項通過,結束碼 0

15.640 秒

這些數字來自不同執行範圍,不應直接相加成互不重複的測試總數。

交付摘要列出的重點包括:候選不能自行宣告准入、查詢不能無據加入診斷詞、共同來源需要辨識,以及缺少來源、過期資料與空結果的處理。這些結果支持本日設定的檢索邊界,不代表模型回答已因此變得更好。

交付也包含 Evidence Map、來源與主張清單,以及測試輸出與收據,讓文章中的工程敘述可以回到相應紀錄檢查。

我還不能從這份結果推出什麼

目前提供的紀錄沒有交代真實向量資料庫、ARCI 心理學資料庫查詢、即時模型生成或前端整合的端到端證據。因此,不能把這次離線候選流程的結果,寫成完整 RAG 或心理學知識庫已經接通的證明。

這也不代表其他功能一定不存在;只是本日這份紀錄不足以建立那些主張。

同樣地,單元測試與回歸測試通過,不構成臨床有效性或心理支持安全性的證明。今天處理的是檢索流程的責任邊界,不是讓系統獲得心理診斷能力。

回看這四篇,Day 18 問的是「不知道,能不能自行補完」;Day 19 問「保存過,是否永遠有效」;Day 20 問「目前存在,這一輪是否可以使用」;Day 21 則問「搜尋得到,是否就值得相信」。

下一篇,我想接著處理准入之後仍然留下的問題:即使一份資料有來源,也通過了這一階段的檢查,系統憑什麼認為它足以支持某個說法?

這會把我們帶到 Day 22 的 Evidence Gate:有來源,不代表有證據。

而今天先守住一句話:檢索器負責找到候選資料,不負責替系統決定什麼是真的。


上一篇
# Day 20|Context Assembly:不是記得越多越好,而是只拿這一輪真正需要的資訊
下一篇
# Day 22|Evidence Gate:有來源,不代表有證據
系列文
《從心出發:30 天打造一套具 RAG、心理支持決策、安全治理與 ARCI 自適應能力的 AI 心理支持平台》26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言