--- name: iterative-retrieval description: 逐步優化內容擷取的模式,旨在解決子 Agent (Subagent) 的上下文 (Context) 缺失問題。 --- # 疊代擷取模式 (Iterative Retrieval Pattern) 用於解決多 Agent 工作流中的「上下文問題」— 即子 Agent 在開始工作前,往往不知道自己具體需要哪些上下文資訊。 ## 何時啟用 - 當啟動子 Agent 時,它們需要事前無法預知的程式碼庫上下文。 - 建構需要逐步優化上下文的廣泛多 Agent 工作流。 - Agent 任務中遇到「內容過載 (Context too large)」或「缺少上下文 (Missing context)」的失敗情況。 - 為程式碼探索設計類 RAG (檢索增強生成) 的擷取流水線。 - 在 Agent 編排中優化 Token 使用量。 ## 問題所在 子 Agent 啟動時僅具備有限的上下文。它們通常不知道: - 哪些檔案包含相關程式碼。 - 程式碼庫中存在哪些既定模式。 - 專案使用了哪些特定術語。 標準做法通常會失敗: - **發送全部內容**:超出上下文限制。 - **什麼都不發送**:Agent 缺少關鍵資訊。 - **猜測需求**:往往猜錯。 ## 解決方案:疊代擷取 (Iterative Retrieval) 一個分為 4 階段的迴圈,用於逐步精煉上下文: ``` ┌─────────────────────────────────────────────┐ │ │ │ ┌──────────┐ ┌──────────┐ │ │ │ 派發 │─────▶│ 評估 │ │ │ └──────────┘ └──────────┘ │ │ ▲ │ │ │ │ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │ 迴圈 │◀─────│ 精煉 │ │ │ └──────────┘ └──────────┘ │ │ │ │ 最多 3 個週期,隨後繼續執行 │ └─────────────────────────────────────────────┘ ``` ### 階段 1:派發 (DISPATCH) 初始階段:執行廣泛查詢以蒐集候選檔案。 ```javascript // 從高階意圖開始 const initialQuery = { patterns: ['src/**/*.ts', 'lib/**/*.ts'], keywords: ['authentication', 'user', 'session'], excludes: ['*.test.ts', '*.spec.ts'] }; // 派發給擷取 Agent const candidates = await retrieveFiles(initialQuery); ``` ### 階段 2:評估 (EVALUATE) 評估所擷取內容的相關性: ```javascript function evaluateRelevance(files, task) { return files.map(file => ({ path: file.path, relevance: scoreRelevance(file.content, task), reason: explainRelevance(file.content, task), missingContext: identifyGaps(file.content, task) })); } ``` 評分標準: - **高 (0.8-1.0)**:直接實作了目標功能。 - **中 (0.5-0.7)**:包含相關的模式或型別定義。 - **低 (0.2-0.4)**:僅有些微關聯。 - **無 (0-0.2)**:不相關,應排除。 ### 階段 3:精煉 (REFINE) 根據評估結果更新搜尋準則: ```javascript function refineQuery(evaluation, previousQuery) { return { // 加入在高度相關檔案中發現的新模式 patterns: [...previousQuery.patterns, ...extractPatterns(evaluation)], // 加入程式碼庫中使用的術語 keywords: [...previousQuery.keywords, ...extractKeywords(evaluation)], // 排除已確認不相關的路徑 excludes: [...previousQuery.excludes, ...evaluation .filter(e => e.relevance < 0.2) .map(e => e.path) ], // 針對特定的資訊缺口 focusAreas: evaluation .flatMap(e => e.missingContext) .filter(unique) }; } ``` ### 階段 4:迴圈 (LOOP) 使用精煉後的準則重複執行(最多 3 次週期): ```javascript async function iterativeRetrieve(task, maxCycles = 3) { let query = createInitialQuery(task); let bestContext = []; for (let cycle = 0; cycle < maxCycles; cycle++) { const candidates = await retrieveFiles(query); const evaluation = evaluateRelevance(candidates, task); // 檢查是否有足夠的上下文 const highRelevance = evaluation.filter(e => e.relevance >= 0.7); if (highRelevance.length >= 3 && !hasCriticalGaps(evaluation)) { return highRelevance; } // 精煉並繼續 query = refineQuery(evaluation, query); bestContext = mergeContext(bestContext, highRelevance); } return bestContext; } ``` ## 實戰範例 ### 範例 1:除錯任務的上下文 任務:「修復身份驗證權杖 (Auth Token) 過期的錯誤」 週期 1: - **派發**:在 `src/**` 中搜尋 "token", "auth", "expiry"。 - **評估**:發現 `auth.ts` (0.9), `tokens.ts` (0.8), `user.ts` (0.3)。 - **精煉**:加入關鍵字 "refresh", "jwt";排除 `user.ts`。 週期 2: - **派發**:搜尋精煉後的詞彙。 - **評估**:發現 `session-manager.ts` (0.95), `jwt-utils.ts` (0.85)。 - **精煉**:上下文已足夠。 結果:`auth.ts`, `tokens.ts`, `session-manager.ts`, `jwt-utils.ts` ### 範例 2:功能實作 任務:「為 API 端點加入速率限制 (Rate Limiting)」 週期 1: - **派發**:在 `routes/**` 中搜尋 "rate", "limit", "api"。 - **評估**:無相符結果 — 程式碼庫使用的是 "throttle" 術語。 - **精煉**:加入關鍵字 "throttle", "middleware"。 週期 2: - **派發**:搜尋精煉後的詞彙。 - **評估**:發現 `throttle.ts` (0.9), `middleware/index.ts` (0.7)。 - **精煉**:還需要路由模式。 週期 3: - **派發**:搜尋 "router", "express" 相關模式。 - **評估**:發現 `router-setup.ts` (0.8)。 - **精煉**:上下文已足夠。 結果:`throttle.ts`, `middleware/index.ts`, `router-setup.ts` ## 整合至 Agent 可以在 Agent 提示詞中使用此邏輯: ```markdown 在為此任務擷取上下文時: 1. 從廣泛的關鍵字搜尋開始。 2. 評估每個檔案的相關性 (0-1 評分)。 3. 識別仍缺失的上下文內容。 4. 精煉搜尋準則並重複執行 (最多 3 次週期)。 5. 回傳相關性評分 >= 0.7 的檔案內容。 ``` ## 最佳實踐 1. **先廣後窄** — 初次查詢不要過於具體。 2. **學習程式碼庫術語** — 第一個週期通常會揭示專案的命名慣例。 3. **追蹤缺失內容** — 明確識別資訊缺口是驅動精煉的關鍵。 4. **「夠好」即停** — 3 個高度相關的檔案優於 10 個平庸的檔案。 5. **果斷排除** — 相關性低的檔案通常在後續週期也不會變為相關。