RAG 典範轉移:從向量檢索到結構化檢索
案例來源:LangChain 團隊重建自家 Chatbot 的真實經驗與架構演進
問題的起點:內部工程師不用自家產品
【Context】 LangChain 團隊營運著 chat.langchain.com,一個基於向量檢索的 AI chatbot,用於回答 LangChain 相關技術問題。然而他們發現一個尷尬的事實:內部工程師並不使用這個 chatbot。
【Real-World Observation】
LangChain 工程師面對技術問題時的實際工作流程:
Step 1: 查閱官方文檔 (docs.langchain.com)
↓
Step 2: 搜尋知識庫 (support.langchain.com)
↓
Step 3: 直接搜尋程式碼庫
這個三步驟流程是手動的,但非常有效。
【Core Insight】
工程師需要的不是「相似的文字片段」,而是:
- 完整的文檔頁面
- 結構化的知識內容
- 可驗證的程式碼
向量檢索的三大根本問題
【Context】 在分析為何內部工程師不使用 chatbot 後,LangChain 團隊識別出傳統向量檢索 RAG 系統的三個核心痛點。
【Core Problems】
Problem 1: Chunking 破壞文檔結構
問題本質:
- 為了生成 embeddings,文檔必須被切分成固定大小的片段(chunks)
- 切分過程會破壞文檔的原始結構:標題階層、步驟順序、上下文關聯
- 使用者收到的是「片段化的答案」,而非「完整的脈絡」
實際影響:
- 失去標題和階層關係
- 步驟順序被打散
- 上下文不完整
Problem 2: 持續的 Reindex 維護負擔
實際成本:
- LangChain 文檔每天更新多次
- 每次更新需要重新 chunking、重新 embedding、重新上傳到 vector database
- 這個流程既耗時又消耗運算資源
- 從文檔更新到 chatbot 能回答新內容之間存在明顯延遲
Problem 3: 引用來源模糊不清
使用者困擾:
- AI 回答可能正確,但使用者無法確認資訊來源
- 無法追溯到原始文檔的確切位置
- 難以理解答案的完整上下文
【Why This Matters】
這三個問題不只是技術細節,而是根本性的架構缺陷:向量檢索打破了內容原本就存在的結構。
典範轉移:從向量檢索到結構化檢索
【Context】 面對這些問題,LangChain 團隊決定自動化內部工程師的手動工作流程,這帶來了架構上的根本性轉變。
【Core Insight】
關鍵發現:
「文檔本身已經有良好的結構。知識庫已經有明確的分類。程式碼庫已經可以透過搜尋工具導航。我們不需要更聰明的檢索演算法——我們需要讓 AI Agent 直接存取這些既有的結構。」
【Architecture Shift】
舊架構:向量檢索
Document → Chunking → Embedding → Vector DB → Similarity Search → Chunks
核心特徵:
- 檢索單位:文字片段 (chunks)
- 檢索方式:語義相似度
- 結構:被破壞
新架構:結構化檢索
┌→ 文檔 API (完整頁面) →┐
│ │
User Query → Agent →├→ 知識庫 API (分類內容) →├→ 合成完整答案
│ │
└→ 程式碼搜尋工具 →┘
核心特徵:
- 檢索單位:完整頁面、完整文章、具體檔案
- 檢索方式:關鍵字搜尋 + API 查詢 + 工具呼叫
- 結構:完整保留
【Core Differences】
| 維度 | 向量檢索 | 結構化檢索 |
|---|---|---|
| 內容單位 | 文字片段 (chunks) | 完整頁面/文章 |
| 檢索方式 | 語義相似度搜尋 | 關鍵字 + API 存取 |
| 結構保留 | 被破壞 | 完整保留 |
| 引用精確度 | 模糊 | 精確到頁面/段落 |
| 維護成本 | 高(需持續 reindex) | 低(API 自動更新) |
| 回應時間 | 快(但品質不穩定) | 快且穩定 |
【Implementation Approach】
工具設計:
- 文檔搜尋工具:透過 Mintlify API 存取完整的文檔頁面
- 知識庫搜尋工具:透過 Pylon API 查詢結構化的支援內容
- 程式碼搜尋工具:使用 ripgrep 在 codebase 中搜尋
核心優勢:
- 完整上下文:Agent 獲得完整的文檔頁面,包含標題、子章節、程式碼範例
- 精確引用:直接連結到文檔頁面或知識庫文章
- 零維護成本:文檔透過 API 實時更新,無需 reindex
- Agent 推理能力:可以精煉搜尋關鍵字、在多個來源之間切換、驗證資訊的一致性
雙軌架構:快速與深度
【Context】 LangChain 團隊設計了兩種架構來處理不同複雜度的查詢:快速模式(createAgent) 和 深度模式(Deep Agent with subgraphs)。
架構一:快速模式(createAgent)
【Purpose】 處理大多數常見查詢,優先考慮回應速度。
【Execution Flow】
User Query → Agent 分析
↓
選擇適當工具(文檔/知識庫/程式碼)
↓
呼叫工具(3-6 次)
↓
合成完整答案
↓
Sub-15 秒回應
【Key Features】
- 工具呼叫次數:平均 3-6 次
- 回應時間:少於 15 秒
- 適用場景:單一領域的明確問題(如「如何配置 streaming?」)
- 模型選擇:使用較小的模型(Claude Haiku 4.5 / GPT-4o Mini)
架構二:深度模式(Deep Agent with Subgraphs)
【Purpose】 處理需要跨多個領域整合資訊的複雜查詢。
【Core Approach】
Subgraph 設計:
- 每個 subgraph 專注於特定領域(文檔、知識庫、程式碼)
- Subgraphs 可以獨立執行搜尋和分析
- 主 agent 整合所有 subgraph 的結果
【Execution Flow】
Complex Query → 主 Agent 分解問題
↓
┌─────────┼─────────┐
↓ ↓ ↓
Docs Knowledge Code
Subgraph Subgraph Subgraph
↓ ↓ ↓
└─────────┼─────────┘
↓
主 Agent 整合結果
↓
完整答案
【Key Features】
- 回應時間:1-3 分鐘
- 適用場景:需要綜合多個來源的複雜問題(如「比較 LangChain 和 LangGraph 的 state management」)
- 品質優勢:更深入、更全面的分析
【Tradeoff Analysis】
| 維度 | 快速模式 | 深度模式 |
|---|---|---|
| 速度 | 快 (< 15秒) | 慢 (1-3分鐘) |
| 深度 | 文檔 + 知識庫 | + 程式碼驗證 |
| 適用場景 | 一般問答 | 複雜除錯 |
| 成本 | 低 | 高 |
選擇策略:
- 預設使用快速模式
- 當初始回答無法完整解決問題時,升級到深度模式
Agent 推理:像人類一樣搜尋
【Context】 結構化檢索的核心不只是 API 存取,更重要的是教會 Agent 如何推理和精煉搜尋。
【Core Technique: Iterative Refinement】
傳統向量檢索:
Query → Embedding → Top-K Results → Done
結構化檢索:
Query → Search → Evaluate Results → Refine Query → Search Again
↓
Is this enough?
↓ ↓
Yes No → Ask follow-up
↓
Answer
【Real-World Example】
場景:用戶問「How do I add memory to my agent?」
Agent 推理過程:
Step 1: 初步搜尋
- 搜尋關鍵字:「memory」
- 結果:Checkpointing, Conversation History, Store API
Step 2: 評估與識別歧義
- 發現「memory」很模糊,可能指:
- Thread 內的對話歷史 (Checkpointing)
- 跨 Thread 的長期記憶 (Store API)
Step 3: 精煉搜尋
- 搜尋「checkpointing」→ 獲得 thread-level 持久化資訊
- 搜尋「store API」→ 獲得 cross-thread 記憶資訊
Step 4: 交叉驗證
- 閱讀知識庫文章:「How do I configure checkpointing in LangGraph?」
- 發現沒有涵蓋 cross-thread memory
Step 5: 填補缺口
- 搜尋「store API」文檔
- 獲得完整圖像
Step 6: 合成答案
- 涵蓋兩種使用場景:
- Checkpointing for conversation history
- Store API for long-term memory
- 為每個場景提供精確引用
【Why This Works】
Agent 具備推理能力:
- 識別歧義並主動釐清
- 評估初始結果的完整性
- 決定是否需要更多資訊
- 交叉驗證多個來源
結果品質提升:
- 回答更完整(涵蓋多個面向)
- 引用更精確(明確指出來源)
- 使用者滿意度更高(一次解決問題)
解決 Context Overload:Subgraph 過濾機制
【Context】 Deep Agent 最初的問題:main agent 會被大量原始搜尋結果淹沒。
【Problem】
最初設計的失敗:
- Main Agent 接收:5 個完整文檔頁面、12 篇知識庫文章、20 個程式碼片段
- 結果:Context Window 爆炸
- 影響:答案冗長或遺漏關鍵資訊
【Solution: Specialized Subgraphs】
重構後的架構:
┌─ Docs Subagent ────┐
│ • 搜尋 5 頁文檔 │
│ • 過濾關鍵段落 │
User Query │ • 提取精華內容 │
↓ └──────────┬─────────┘
Main Agent ←─────────── 2 key paragraphs
↓
├────────────┬─ KB Subagent ───────┐
│ │ • 掃描 20 篇標題 │
│ │ • 讀取 3 篇文章 │
│ │ • 提取相關摘要 │
│ └──────────┬──────────┘
←─────────────── 3 relevant summaries
↓
└────────────┬─ Code Subagent ─────┐
│ • 搜尋 50 個檔案 │
│ • 定位關鍵實作 │
│ • 提取程式碼片段 │
└──────────┬──────────┘
←─────────────── Implementation with line numbers
↓
合成完整答案
【Each Subagent’s Workflow】
Docs Subagent:
- 廣泛搜尋文檔頁面
- 評估段落相關性
- 提出後續問題(如果發現歧義)
- 提取黃金數據(只保留關鍵段落)
- 返回精煉結果給 main agent
KB Subagent:
- 掃描知識庫標題
- 過濾相關文章
- 讀取完整內容
- 提取關鍵資訊
- 返回摘要
Code Subagent:
- 搜尋程式碼模式
- 理解檔案結構
- 讀取關鍵實作
- 返回精確引用(檔案名 + 行號)
【Key Benefits】
Context 管理:
- Main agent 不會被原始結果淹沒
- 只接收經過過濾的「黃金數據」
- Context window 保持在可控範圍
品質提升:
- 每個 subagent 都是領域專家
- 可以深入挖掘而不影響其他領域
- 最終答案更全面且精確
可擴展性:
- 容易添加新的 subagent(如 GitHub Issues、StackOverflow)
- 每個 subagent 獨立演進
- Main agent 只需要處理合成邏輯
實戰效果:量化改善
【Context】 新系統上線後,LangChain 團隊觀察到顯著的改善。
【Quantitative Results】
Public Chat LangChain
回應速度:
- 平均回應時間:< 15 秒
- Tool calls:3-6 次
- Token 使用:降低 40%
引用品質對比:
向量檢索時期:
- 回答:「Set streaming=True」
- 來源:文檔片段 #127(無法點擊查看)
結構化檢索時期:
- 回答:「To enable streaming in LangGraph, set streaming=True in your StreamConfig. This allows real-time token updates.」
- 來源:LangGraph Streaming Documentation(完整頁面,可點擊)
- 連結:https://docs.langchain.com/…\#streaming
維護成本:
- Reindex 時間:從數小時 → 0(API 自動更新)
- 儲存成本:降低 60%(不需要 vector DB)
- 更新延遲:從數小時 → 即時
Internal Deep Agent
工程師效率提升:
- 每週節省:10-15 小時/人
- 解決複雜問題:從 30 分鐘 → 3 分鐘
- 首次解決率:提升 70%
【Real-World Case Studies】
Case 1: Streaming Token 問題
問題:「Production 環境 streaming tokens 卡住」
Deep Agent 調查流程:
- Docs Subagent: 找到 streaming configuration 文檔
- KB Subagent: 發現支援文章「升級後 token streaming 失效」
- Code Subagent: 定位到 callbacks/streaming.py 行 47-83,發現預設 buffer size 被硬編碼
結果:3 分鐘內找到根本原因,並提供修復方案
Case 2: Memory Configuration
問題:「How to add memory to my agent?」
Agent 推理過程:
- 識別歧義:memory 可能指 thread 內或 cross-thread
- 搜尋「checkpointing」:獲得 thread-level 資訊
- 搜尋「store API」:獲得 cross-thread 資訊
- 交叉驗證知識庫文章
- 合成完整答案,涵蓋兩種使用場景
結果:一次回答解決用戶的所有疑問
【Qualitative Feedback】
內部工程師:
「我們終於開始使用自己的 chatbot 了。它現在真的能幫我們解決問題,而不只是返回模糊的文檔片段。」
外部用戶:
「引用變得非常精確,我可以立即驗證答案並找到相關文檔。這就是我需要的 AI 助手。」
關鍵洞察與最佳實踐
【Context】 從向量檢索到結構化檢索的轉變,帶來了許多寶貴的經驗教訓。
【Key Takeaways】
Insight 1: 複製成功的工作流程
原則:
不要重新發明輪子;自動化你最優秀的用戶(或內部專家)已經在使用的成功工作流程。
實踐:
- 觀察內部工程師如何解決問題
- 識別重複的模式和步驟
- 直接複製這個流程,而不是猜測「理想」流程
LangChain 範例:
- 工程師的三步驟流程:查文檔 → 查知識庫 → 查程式碼
- 設計三個專門的 subagent 來複製這個流程
Insight 2: 評估 Vector Embeddings 的適用性
何時使用 Vector Embeddings:
- ✅ 非結構化內容(論文、書籍、PDF)
- ✅ 語義搜尋(概念匹配)
- ✅ 聚類和分類
- ✅ 內容推薦
何時避免 Vector Embeddings:
- ❌ 結構化文檔(產品文檔、API 文檔)
- ❌ 已經有良好組織的內容
- ❌ 需要精確引用來源
- ❌ 頻繁更新的內容
決策樹:
你的內容是?
├─ 結構化(文檔、知識庫、程式碼)
│ └─ 使用結構化檢索(API + Agent 推理)
│
├─ 非結構化(PDF、論文、書籍)
│ └─ 使用 Vector Embeddings + Semantic Search
│
└─ 混合
└─ 分層架構:結構化部分用 API,非結構化部分用 Vector
Insight 3: 給予 Agent 直接存取結構
原則:
讓 agent 直接存取內容的既有結構,而不是重新創建結構。
實作:
- 使用 API 獲取完整文檔頁面
- 提供目錄導航能力
- 支援階層式瀏覽
- 保留原始格式和脈絡
對比:
❌ 破壞結構再重建:
Document → Chunking → Embedding → Similarity → Reconstruct
✅ 直接存取結構:
Document API → Full Page with Structure → Agent Navigation
Insight 4: 優先推理而非檢索
原則:
Agent 的價值不在於檢索能力,而在於推理和精煉搜尋的能力。
設計工具來模仿人類工作流程:
人類的兩階段搜尋模式:
- 掃描標題 → 選擇相關文章 → 深入閱讀
- 搜尋模式 → 理解結構 → 定位實作
提供相應的工具讓 agent 執行相同流程。
Prompt 設計重點:
- 鼓勵 agent 提出後續問題
- 教導 agent 如何精煉搜尋
- 要求 agent 評估初始結果的完整性
- 設定「tool call 預算」來促進策略性思考
Insight 5: 使用 Subgraphs 管理 Context
原則:
對於複雜的多領域問題,使用專門的 subgraphs 來防止 main agent 被原始搜尋結果淹沒。
架構模式:
Main Orchestrator Agent
↓
只接收精煉後的洞察
↓
┌─────┴──────┬──────────┐
│ │ │
Docs Expert KB Expert Code Expert
│ │ │
搜尋 → 過濾 搜尋 → 過濾 搜尋 → 過濾
│ │ │
提取黃金數據 提取黃金數據 提取黃金數據
每個 Subagent 的責任:
- 在自己的領域內深入搜尋
- 提出後續問題以釐清歧義
- 過濾和精煉結果
- 只返回最相關的洞察
Insight 6: Production Middleware 是必需的
原則:
即使是優雅的 agent 設計也需要強大的基礎設施才能可靠運行。
必要的 Middleware 層:
- Guardrails:過濾無關問題
- Retry:處理 API 失敗
- Fallback:模型切換
- Caching:成本優化
好處:
- Agent 邏輯保持簡潔
- 關注點分離
- 容易測試和維護
- 生產級可靠性
總結:典範轉移的核心意義
【Context】 從向量檢索到結構化檢索,不只是技術細節的變更,而是思維方式的根本轉變。
【Paradigm Shift Summary】
從「檢索為中心」到「推理為中心」
舊典範(Vector-Centric):
問題 → 生成 Embedding → 相似度搜尋 → 返回片段 → 生成答案
- 核心:找到「相似」的內容
- Agent 是被動的接收者
- 品質取決於 embedding 品質
新典範(Reasoning-Centric):
問題 → Agent 推理 → 策略性搜尋 → 評估結果 → 精煉搜尋 → 合成答案
- 核心:理解「需求」並主動尋找
- Agent 是主動的推理者
- 品質取決於 agent 推理能力
從「片段重組」到「結構保留」
舊方法:
Complete Document
↓ Chunking
Fragments (失去結構)
↓ Embedding
Vector Space
↓ Retrieval
Scattered Pieces
↓ Reconstruction (困難)
Incomplete Context
新方法:
Structured Content
↓ Direct API Access
Full Pages (保留結構)
↓ Agent Navigation
Complete Context
↓ Synthesis
Comprehensive Answer
關鍵成功因素
1. 觀察真實工作流程
- 不要猜測「理想」流程
- 觀察專家如何工作
- 複製成功的模式
2. 善用既有結構
- 文檔已經有組織
- 不需要重新創建結構
- 直接存取並導航
3. 賦予 Agent 推理能力
- 不只是檢索
- 評估、精煉、交叉驗證
- 像人類一樣思考
4. 分層處理複雜度
- 簡單問題用簡單 agent
- 複雜問題用 subgraphs
- 避免過度設計
5. Production-Ready 思維
- Middleware 處理基礎設施
- 關注點分離
- 可靠性和成本優化
【Final Thoughts】
這個典範轉移告訴我們:
最好的 AI 系統不是那些使用最先進技術的,而是那些最理解用戶需求、最善用既有結構、最能模仿人類推理的系統。
Vector embeddings 依然有其價值,但不應該是預設選擇。評估你的內容類型、觀察用戶工作流程、選擇最適合的架構——這才是建構可靠 AI 系統的關鍵。
【Action Items】
如果你正在建構 RAG 系統:
- 評估你的內容:是結構化還是非結構化?
- 觀察用戶:他們如何手動找答案?
- 測試假設:先用結構化檢索做 POC
- 量化比較:對比兩種方法的效果
- 漸進演進:從簡單開始,逐步優化
這個典範轉移正在改變 RAG 系統的設計方式。你準備好了嗎?
延伸閱讀
相關文章:
官方資源:
- Chat LangChain 實際體驗
- LangChain Documentation
- LangGraph Documentation
- DeepAgents Documentation
- LangSmith Platform
原文連結:
Tags
#RAG #Vector Search #Structured Retrieval #LangChain #Agent Architecture #Information Retrieval #AI Systems #Paradigm Shift #Best Practices #Production AI