1422 字
7 分鐘

DeepSeek Search/Fetch API:搜尋後何時需要再抓正文?

Agent 搜尋到五個網址後,要不要全部再呼叫一次 Fetch?先看 Search 是否已回傳可用正文,再依任務需要補抓。 DeepSeek 的 Search 負責找來源,Fetch 負責取得單頁 Markdown;它們是獨立的 JSON API,不是把問句送給聊天模型就一定會執行的步驟。

本文處理「搜尋結果如何進入資料蒐集流程」。Workers AI 的 DeepSeek 模型呼叫是另一個入口,不能直接套用本文端點、金鑰或計費規則。以下依 2026-10-19 官方文件整理,沒有呼叫真實 DeepSeek API;程式測試使用人工 fixture。

先讓 Search 回傳你需要的資料#

Search API reference列出的端點是 POST https://api.deepseek.com/v1/tools/search。下列為 shell 請求示意,需在自己的受控環境設定 DEEPSEEK_API_KEY;金鑰應留在後端,不能放入瀏覽器前端程式或公開儲存庫。

Terminal window
curl --fail-with-body https://api.deepseek.com/v1/tools/search \
-H "Authorization: Bearer ${DEEPSEEK_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{"query":"Astro content collections site:docs.astro.build","count":3,"need_content":true}'

need_content 預設為 false,因此只收到空的 content 不等於 API 壞了。開啟後也不保證每一頁都有正文;snippet、summary 與 content 是不同欄位,摘要不能替代你需要核對的原文。成功但沒有匹配來源時,results 可以是空陣列。

count 控制結果數量,不是「一定能讀到幾篇完整文件」。先用小結果集確認搜尋意圖,再逐篇決定是否有必要取正文,比先把所有網址都排入抓取佇列更容易查核。

缺正文才補抓,先保留來源再決定取捨#

若問題只需要尋找文件入口,標題、網址與摘要可能已足夠;若需要查核限制或引用正文,就要有可讀取的 content。Fetch API reference提供以下獨立請求,回傳 title 與 Markdown content:

Terminal window
curl --fail-with-body https://api.deepseek.com/v1/tools/fetch \
-H "Authorization: Bearer ${DEEPSEEK_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{"url":"https://docs.astro.build/en/guides/content-collections/"}'

以下補抓規則是本文自行定義的應用層契約:只接受 HTTPS、只處理明確允許的 hostname、拒絕含帳密的 URL,並以去掉 fragment 後的完整 URL 去重。不同 query 可能代表不同頁面,所以保留 query,也不擅自合併尾斜線或子網域。

這個函式只產生計畫,不發出請求。ready 表示已有非空正文,仍需人工或後續流程確認內容與問題相關;不代表資料已可信。對同一 URL 的重複結果,優先保留有正文的一筆,避免前一筆空結果造成不必要補抓。

function planSources(results, allowedHosts) {
const sources = new Map();
for (const row of results) {
if (!row || typeof row.url !== 'string') continue;
let url;
try { url = new URL(row.url); } catch { continue; }
if (url.protocol !== 'https:' || url.username || url.password ||
!allowedHosts.has(url.hostname)) continue;
url.hash = '';
const key = url.href;
const content = typeof row.content === 'string' ? row.content : '';
const previous = sources.get(key);
if (!previous || (!previous.content.trim() && content.trim())) {
sources.set(key, { url: key, content });
}
}
const rows = [...sources.values()];
return {
ready: rows.filter(row => row.content.trim()),
needsFetch: rows.filter(row => !row.content.trim()).map(row => row.url),
};
}

把函式與下面測試存成 source-plan-check.mjs,執行 node source-plan-check.mjs。這些資料刻意使用官方文件網址作為字串,並未真的抓取那些頁面:

import assert from 'node:assert/strict';
const hosts = new Set(['docs.astro.build']);
const first = 'https://docs.astro.build/en/guides/content-collections/';
const second = 'https://docs.astro.build/en/guides/routing/';
const plan = planSources([
{ url: first + '#intro', content: '' },
{ url: first + '#schema', content: '人工測試正文' },
{ url: second, content: ' ' },
{ url: second, content: '' },
{ url: 'https://docs.astro.build.example.com/', content: '不接受' },
{ url: 'https://user:pass@docs.astro.build/', content: '不接受' },
{ url: 'http://docs.astro.build/', content: '不接受' },
{ url: 'invalid' },
], hosts);
assert.deepEqual(plan.ready, [{ url: first, content: '人工測試正文' }]);
assert.deepEqual(plan.needsFetch, [second]);
assert.deepEqual(planSources([], hosts), { ready: [], needsFetch: [] });
assert.equal(planSources([
{ url: first + '?lang=zh' }, { url: first + '?lang=en' },
], hosts).needsFetch.length, 2);
console.log('source planning checks passed');

補抓完成後,仍要把內容配回原始 URL,記錄抓取時間與失敗原因。不要把失敗頁面直接刪掉,否則下游會誤以為蒐集已完整。多頁允許部分失敗時,可沿用 Promise.allSettled 的具名結果處理;並行上限與每秒請求配額仍需分別管理。

這個 allowlist 只篩選候選網址,沒有處理重新導向、DNS 或完整的伺服器請求安全防護。網站也可能拒絕抓取或無法抽取 Markdown;不能把 Fetch 當成能讀取已登入頁面或繞過網站存取政策的工具。取得的網頁內容應視為資料,不能直接當成 Agent 的執行指令。

計費與失敗,要按每次請求記錄#

官方指南的 billing 與 errors 說明目前將 Search、Fetch 各列為每千次成功請求 US$0.75;可計費成功另要求搜尋結果非空或抓到正文。因此 Search 後再 Fetch 是兩次操作,不能把 count=3 當成三次搜尋費,也不能把空結果當成已取得證據。

指南另將透過 DeepSeek Harness、Claude Code 或 Codex 使用 DeepSeek API 時的伺服器端工具呼叫列為暫免,預定北京時間 2026-11-01 00<00> 開始按次計費。這項暫免不能套用到本文直接呼叫 JSON 端點的範例;接入前應重新查核帳單條件。

重試也要分類:408、429、5xx 可等待後有限次重試;402 要先處理餘額,其他 4xx 不應原樣重送。Fetch 的 404 可以代表無可用正文,不只是網址不存在。保留 HTTP status 與原始 error,才知道要改搜尋詞、換來源,還是稍後再試。

本文已執行離線去重與補抓規則測試;curl 僅檢查 shell 語法,沒有驗證金鑰、實際扣款、QPS、重新導向或搜尋品質。導入時先以少量公開文件驗收「有正文、缺正文、空結果與抓取失敗」四條路徑,再接到正式 Agent。

參考資料:

DeepSeek:Search & Fetch 指南

DeepSeek:Search API

DeepSeek:Fetch API

DeepSeek Search/Fetch API:搜尋後何時需要再抓正文?
https://laplusda.com/posts/deepseek-search-fetch-api-workflow/
作者
Zero
發佈於
2026-10-19
許可協議
CC BY-NC-SA 4.0