# 🚀 Day 2 學習總結：從原型到可維護的 RAG 系統

## 📅 學習日期
2025-11-04

## 🎯 學習目標達成情況

### ✅ 技術目標
- [x] 將 CLI 程式改造成 RESTful API
- [x] 加入系統監控與 logging 機制
- [x] 深入理解向量資料庫的運作原理
- [x] 建立評估 RAG 效果的方法

### ✅ 思維目標
- [x] 從「能跑」到「可維護」的工程思維
- [x] 學會「如何知道系統好不好」（可觀測性）
- [x] 理解「debug RAG 系統」的系統化方法

## 💡 核心技術突破

### 1. LangChain 架構演進的深度理解

**重要發現：**
- **舊架構已淘汰**：`RetrievalQA.from_chain_type()` → `create_react_agent()`
- **新的工具模式**：從 Chain 思維轉向 Agent + Tools 思維
- **模組化升級**：套件拆分更細緻（`langchain-huggingface`, `langchain-chroma`, `langgraph`）

```python
# Day 1 舊方法
qa = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)

# Day 2 新方法
@tool(response_format="content_and_artifact")
def retrieve_context(query: str):
    # 自定義檢索邏輯
    return serialized, retrieved_docs

agent = create_react_agent(llm, [retrieve_context])
```

**啟發：**
> LLM 框架發展極快，保持學習新架構比深度優化舊架構更重要。Agent 思維比 Chain 思維更靈活。

### 2. 向量資料庫運作原理的實戰洞察

**距離分數的現實意義：**
```
軟體開發 (中文)    : 10.9  ← 高度相關
software development : 22.6  ← 中等相關  
遇到熊怎麼辦        : 22.2  ← 低度相關
```

**關鍵發現：**
- **距離越小越相似**（與直覺相反）
- **多語言效果差異大**：同概念的中英文距離差距達 2 倍
- **相關性閾值是必需的**：避免系統回答無關問題

**啟發：**
> 向量搜尋不是魔法，需要大量實驗來找到合適的閾值。多語言支援需要專門的模型調校。

### 3. System Prompt 的決定性影響

**實驗對比：**

**模糊 Prompt（失敗）：**
```
"你是一個專業的助手，請根據提供的資料回答問題。"
結果：LLM 自己編造答案，忽略檢索資料
```

**具體 Prompt（成功）：**
```
你正在回答關於一位軟體工程師的問題。你手上有這位工程師的完整履歷資料。

重要規則：
1. 只能根據提供的資料回答
2. 如果資料中沒有相關資訊，請明確說「資料中沒有相關資訊」
3. 不要自己編造或推測任何資訊
4. 「這個人」指的就是履歷中的軟體工程師
```

**啟發：**
> System Prompt 是 RAG 系統的「憲法」，必須明確、具體、強制性。模糊的指令會導致 LLM 忽略檢索資料。

## 🔍 RAG 系統的核心挑戰與解決方案

### 挑戰 1：幻覺問題（Hallucination）
**現象：** LLM 明明有正確資料，卻編造不存在的資訊
**解決方案：**
- 強制性 System Prompt
- 相關性閾值過濾
- 明確的拒絕回答機制

### 挑戰 2：檢索失效
**現象：** 明明知識庫有資訊，卻檢索不到
**解決方案：**
- 調整 chunk_size 和 overlap
- 實驗不同的 top_k 值
- 使用 `similarity_search_with_score` 分析距離

### 挑戰 3：系統可觀測性
**現象：** 系統出問題時無法快速定位原因
**解決方案：**
- 結構化 Logging（JSONL 格式）
- 請求追蹤（unique request_id）
- 詳細的效能監控

## 📊 量化評估的威力

### 評估前 vs 評估後

**評估前的盲目狀態：**
- "感覺系統還可以"
- "回答好像有點問題"
- "不知道哪裡需要改進"

**評估後的清晰認知：**
- **通過率：28.6%** ← 明確的基準線
- **平均回應時間：19.99 秒** ← 效能瓶頸
- **失敗模式分析**：技能查詢 0%，工具查詢 0%

**啟發：**
> 沒有測量就沒有改進。RAG 系統必須建立量化評估機制，才能系統性地提升效能。

## 🛠️ 工程思維的轉變

### 從「實驗」到「產品」

**Day 1 思維：**
- 能跑就好
- 單次測試
- 手動驗證

**Day 2 思維：**
- 系統化監控
- 批量評估
- 自動化分析

### 從「代碼」到「系統」

**技術棧演進：**
```
Python Script → FastAPI → 完整 Web 服務
print() → Logging → 結構化監控
手動測試 → 評估腳本 → 持續改進循環
```

## 🚨 踩坑經驗與解決

### 1. Import 地獄
**問題：** LangChain 套件結構變化快，import 路徑經常失效
**解決：** 使用 Context7 查詢最新文檔，保持套件版本一致性

### 2. Agent 回應格式變化
**問題：** `response["messages"][-1].content` 從字串變成 list
**解決：** 建立彈性的解析邏輯，處理多種格式

### 3. 相關性過濾實作錯誤
**問題：** `any()` 函數參數類型錯誤
**解決：** 深度理解 Python 語法，使用生成器表達式

## 🎓 最重要的學習洞察

### 1. RAG 不是檢索 + 生成的簡單組合
RAG 是一個複雜的系統工程，涉及：
- 資料預處理（chunking strategy）
- 檢索策略（similarity threshold）
- 生成控制（system prompt engineering）
- 品質保證（evaluation framework）

### 2. LLM 的「智能」有邊界
LLM 很聰明，但：
- 會忽略明確的指令
- 會編造不存在的資訊
- 需要非常具體的約束條件

### 3. 可觀測性是 AI 系統的生命線
傳統軟體 bug 容易重現，AI 系統的問題：
- 難以重現
- 受多重因素影響
- 需要統計性分析

### 4. 評估驅動開發是必須的
AI 系統的改進必須：
- 建立基準線
- 量化每次變更的影響
- 系統性地迭代改進

## 🚀 下一步行動計畫

### 立即改進（技術債）
1. **優化 System Prompt** - 提高指令遵循度
2. **調整相關性閾值** - 減少無關回答
3. **改進錯誤處理** - 更好的降級機制

### 中期目標（系統升級）
1. **實作 Hybrid Search** - 結合關鍵字和語意搜尋
2. **加入 Re-ranking** - 二階段精確檢索
3. **建立 A/B Testing** - 對比不同配置效果

### 長期願景（產品化）
1. **多輪對話支援** - 記憶上下文
2. **多文件來源** - 處理複雜知識庫
3. **個性化調優** - 針對特定領域優化

## 💭 個人成長反思

這一天的學習讓我深刻體會到：

1. **技術框架變化很快**，但底層原理相對穩定
2. **實際部署和實驗階段**有巨大差異
3. **量化評估**是 AI 系統開發的核心技能
4. **系統思維**比算法優化更重要
5. **工程實踐**決定了 AI 項目的成敗

## 📈 關鍵指標總結

- **開發時間：** 8 小時
- **程式碼行數：** ~500 行（API + 評估）
- **系統通過率：** 28.6%（基準線）
- **踩坑次數：** 6 次（全部解決）
- **核心洞察：** 5 個重大發現

---

> **Day 2 最大收穫：** 學會了如何把一個「能跑的原型」轉變成「可持續改進的系統」。這不只是技術升級，更是思維模式的根本轉變。