Data Payload & Schema Inspection · Litmeb/RAW-RAG

Raw-RAG 把哪些資料丟給 RAG?

深入解析 rag_adapter.py 的資料轉換管線:從原始對話到向量庫索引(chunks + embeddings + turn_context),以及在檢索時分別送給 Embedding 模型、Reranker 模型與 Reader LLM 的精確資料格式。

1 全局資料流總覽:從原始對話到三個模型的輸入負載

Raw-RAG 的關鍵設計是「檢索時用 256-token 緊湊切片算分數,但在送給 Reader LLM 前,會透過 turn_context 將切片還原為完整的對話回合」。

1. 原始對話格式化 _format_conversation() Header (對話標頭): Conversation ID: locomo_0 Speaker A: Caroline Speaker B: Melanie Turn Lines (逐句對白): [2023-05-08] Caroline: ... [2023-05-08] Melanie: ... [2023-05-25] Caroline: ... 保留真實日期 + 說話者 + 原文 2. 存進 RAG 索引的 3 大結構 rag_index.json / pgvector A. chunks (256-tok 切片陣列) • content (256 tokens 原始文字切片) • start_token, end_token, start_turn, end_turn B. embeddings (向量陣列) • 對每個 chunk["content"] 編碼的浮點向量 C. turn_context (回合映射表) • turn_spans: 每回合 [tok_start, tok_end] • turn_session_dates & turn_lines 3A. 丟給 Embedding / Reranker Qwen3-Embedding-4B & Reranker-4B 僅丟「256-tok 原始文字切片」: • Query: 使用者問題原文 • Doc: chunk["content"] (緊湊切片) 3B. 呈現期動態展開 (Top-15) _expand_chunk_to_turns() 查 turn_spans 將 Top-15 切片 還原為「完整未截斷的對話回合」 並透過 seen_turns 自動去除重疊行 4. 丟給 Reader LLM _format_context() Memory 1 (chunk=12, similarity=0.68, rerank=0.94): [2023-05-08] Caroline: ... [2023-05-08] Melanie: ... Memory 2 (chunk=45, ...): [2023-05-25] Caroline: ... + Question: 使用者問題 + CoT 回答指令 Prompt

2 存進 RAG 索引(rag_index.json)的真實資料結構

在 rag_adapter.py 中,每個對話索引只存以下 3 個欄位的 JSON 物件,完全沒有 LLM 生成的摘要或知識圖譜三元組:

1. chunks (切片與座標) 檢索基本單位

以 cl100k_base 切成 256 tokens(重疊 32 tokens)。注意除了文字外,還記錄了該切片橫跨哪些 Token 與哪些對話回合(start_turn ~ end_turn)。

{
  "chunk_id": "locomo_0_chunk_0",
  "chunk_index": 0,
  "content": "Conversation ID: locomo_0\nSpeaker A: Caroline\nSpeaker B: Melanie\n\n[2023-05-08] Caroline: I went to a LGBTQ support group...",
  "start_token": 0,
  "end_token": 256,
  "start_turn": 0,
  "end_turn": 7
}
2. embeddings (稠密向量) 粗排相似度計算

直接將左方 chunk["content"] 原文送進 Qwen3-Embedding-4B 所得到的浮點向量,一對一對應每個區塊。

// 與 chunks 陣列一對一對齊
[
  [
    -0.018432,
    0.042911,
    0.009184,
    // ... 2560 維浮點數 (Qwen3-Embedding-4B)
  ],
  // chunk_1, chunk_2 ...
]
3. turn_context (回合映射表) 時序過濾 + 無損展開

記錄每一輪對話(Turn)在整份文件中的 Token 起訖位置與日期,讓系統能在檢索前按日期過濾,並在檢索後把 256-token 切片還原成完整對話回合。

{
  "header": "Conversation ID: locomo_0...",
  "turn_spans": [
    [18, 42],  // Turn 0 的 token 區間
    [43, 79]   // Turn 1 的 token 區間
  ],
  "turn_timestamps": [
    "2023-05-08T13:14:00", ...
  ],
  "turn_session_dates": [
    "2023-05-08", ...
  ],
  "turn_lines": [
    "[2023-05-08] Caroline: ...", ...
  ]
}

3 關鍵差異:「丟給檢索模型的切片」vs.「丟給 Reader LLM 的展開記憶」

固定 256 tokens 切塊常會把一句長話從中間切斷。Raw-RAG 為什麼不怕切斷句子?因為檢索模型看的是 256-token 切片,但 Reader LLM 看到的是展開後的完整回合(expand_turns_on_display: true):

階段 A:丟給 Embedding 與 Reranker 的文字 256-Token 緊湊切片 (可能首尾截斷)

chunk["content"] 嚴格限制在 256 tokens,確保向量語意集中、不被長篇大論稀釋,但頭尾的句子可能剛好被切在一半:

// chunk_12["content"] (剛好在 token 邊界被切斷)
...really helped me feel seen.
[2023-05-08] Melanie: That sounds amazing, Caroline! What made it so impactful for you?
[2023-05-08] Caroline: Hearing other trans women share their stories inspired me to [← 在第 256 token 處截斷]
階段 B:最終丟給 Reader LLM 的文字 (_format_context) 動態展開為完整對話回合 + 自動去重

當 chunk_12 進入 Top-15 後,_expand_chunk_to_turns 會查 turn_spans 找出它觸及的所有回合,把頭尾被切斷的句子完整補齊,並標上檢索分數送給 Reader:

Memory 1 (chunk=12, similarity=0.684210, rerank=0.9412):
[2023-05-08] Caroline: I went to a LGBTQ support group yesterday and it really helped me feel seen.
[2023-05-08] Melanie: That sounds amazing, Caroline! What made it so impactful for you?
[2023-05-08] Caroline: Hearing other trans women share their stories inspired me to pursue counseling!

4 總結對照表:Raw-RAG 丟了什麼 vs. 刻意不丟什麼?

對比 Mem0、Zep、MemOS 等複雜記憶系統,Raw-RAG 拒絕把任何 LLM 二次改寫的產物放進索引。

✓ Raw-RAG 實際丟進 RAG 的資料

  • 對話標頭 (Header):Conversation ID、Speaker A、Speaker B。
  • 帶日期與說話者的原始對白:[YYYY-MM-DD] Speaker: Content。
  • 256-Token 滑動切片 (Overlap 32):供 Embedding 與 Cross-Encoder 計算語意匹配。
  • Token 與回合位置座標 (turn_spans):供呈現期無損還原完整對話回合並跨區塊去重。
  • 回合時間戳記 (turn_session_dates):供檢索前過濾時間範圍,以及在狀態演進任務依時間先後重排。

✗ Raw-RAG 刻意「不丟」進 RAG 的衍生資料

  • 不丟 LLM 萃取的「原子事實 (Atomic Facts)」:實測會讓索引物件膨脹 5.38× 且切斷跨回合因果鏈。
  • 不丟 LLM 生成的「滾動摘要 (Rolling Summaries)」:實測在寫入期直接造成 21.9% 的永久表徵損失。
  • 不丟「知識圖譜三元組 (KG Triples)」或「實體屬性表」:省去每輪對話高達數百倍的 LLM 寫入延遲。
  • 不丟 LLM 主觀判斷的「記憶重要性分數 / 覆寫標記」:避免寫入期誤刪未來多跳推理所需的背景線索。