上一篇談的是 Eval:當我們改了模型、提示詞或程式規則,要怎麼知道結果真的變好。再往前看,前面的文章其實已經把資料進入系統時會遇到的問題逐一拆開,只是還沒有用同一個案例把它們接起來。
今天我們就沿著一個品牌案例,把整條流程完整走一次。假設手上有品牌 A 的名稱與已知網站,希望把這個品牌,以及網站裡適合收錄的商品,整理成可以交給後續審核的資料,整條流程會怎麼走?
在開始執行之前,我想先把這個案例的起點和終點定清楚。輸入是品牌名稱,以及目前已知的官方網站或社群入口;輸出則是一份可以交給後續審核的資料,裡面同時包含品牌層資料、商品提案,以及需要人工確認的項目。
const input = {
brand: {
name: "品牌 A",
knownUrls: ["https://brand-a.example"],
},
};
type BrandReviewPacket = {
brand: {
canonicalName: string;
description: string | null;
channels: string[];
};
products: Array<{
name: string;
category: string | null;
subcategory: string | null;
description: string;
image: string | null;
sources: string[];
}>;
warnings: string[];
};
前面談過的 Structured Outputs、Tool Use、分類、內容整合、圖片判斷與 Eval,放回這個案例後,其實都只是這條資料路徑中的不同問題。

真正麻煩的是,品牌網站沒有共同的資料格式。首頁可能同時放品牌故事、商品入口、圖片與購買通路;資料可能藏在 HTML、meta 資訊或 JSON-LD,也可能要經過 JavaScript 渲染後才出現。真正有價值的資料甚至可能不在首頁,而是在更深的子頁面。

因此這裡不適合只靠一套固定解析器。能用規則處理的地方仍然交給程式;只有「接下來該看哪裡、要不要換取得方式」這類會隨目前資料改變的問題,才交給 Agent。
目前整條流程拆成六個階段:Gather → Detect → Acquire → Names → Editorial → Products。接下來就沿著品牌 A,看它們怎麼交接。
雖然我們已經有品牌 A 的官網,但品牌可能另外有 Instagram、Threads、Linktree、Pinkoi、Shopee 或其他購買通路,而且這些入口不一定會全部列在官網上。我們接下來要解決的,就是怎麼有效率地把這些來源補齊。
我們可以使用 Serper.dev 來程式化執行 Google Search,把品牌名稱和相關資訊組成搜尋詞,快速取得 Google SERP(搜尋引擎結果頁)。這讓我們有機會補到社群帳號、連結集中頁、購買通路,以及其他和品牌有關的來源。
Gather 在這裡負責的不是「理解完整品牌內容」,而是先把後續流程可能會用到的來源補齊。

跑完這一步後,我們會得到一組整理過的已知網址:除了 SERP 新找到的網址,也包含從既有入口、連結集中頁或社群簡介展開出的來源。 到這裡我們還沒有判斷這些內容是否真的符合收錄條件;這會是下一步 Detect 的主要任務。
Gather 把來源補齊之後,我們手上會多出不少網址和搜尋線索,但「找到很多相關結果」不代表這個品牌真的符合目前的收錄範圍。Detect 不是在評估品牌好不好,也不是在這裡判斷它是不是台灣品牌;它先處理一個更前面的問題:這個品牌到底是不是一個有自己設計或生產實體產品的品牌?
目前會直接排除的類型包括:
這裡的邊界也很重要:選物店只要有自己的產品線,仍然算品牌;插畫家或角色 IP 只要有自己設計的實體商品,也可以算品牌。Detect 會使用 Gather 的 SERP 摘要,再對少量已知網址做輕量的靜態檢查,讓模型同時看到外部搜尋脈絡,以及網站本身的標題與描述。

模型最後交出的不是完整品牌資料,而是一個給後續程式使用的判斷結果。沿用前面 Structured Outputs 的簡化格式,大致可以看成:
type DetectDecision = {
isNonBrand: boolean;
nonBrandReason: string | null;
brandName: string | null;
confidence: "high" | "medium" | "low";
};
到這裡,我們只回答了「這個品牌要不要繼續處理?」。如果答案是要,下一步 Acquire 才開始處理真正的資料取得問題:要去哪裡找到足夠的品牌與商品資訊?
通過 Detect 之後,才進到整條流程裡最需要動態決策的地方:我們要怎麼取得品牌資訊? 每個官方網站的架構都不盡相同,很難用一套固定程式判讀所有網站,因此需要一個能根據當下找到的內容調整下一步的 Agent 系統。
Acquire 可以理解成一個有工具、有預算、有停止條件的回饋迴圈:先看目前手上有哪些品牌資料,再據此產生抓取計畫,執行後檢查資料是否足夠,而當資料不足時會再重新進行一次回圈來抓取所需要的資料。

Acquire 會先對已知網址做輕量檢查,看看頁面文字量、是否可能需要渲染,以及有哪些連結值得繼續展開。接著模型進入一個開始針對不同的網站展開 Tool Use 迴圈,包含了以下幾種 Tool:
當第一次分析執行完畢後,Agent 會在檢查(Critique)階段做出以下三種判斷:
sufficient:目前資料已經足夠,進入 finalize 階段thin:有資料上不足夠,若允許時會進行補救(再一次的 Tool Use 迴圈)fail:目前結果不適合繼續,直接停止由於每個網站的設計不同,倘若沒有設計好迴圈的限制,Agent 可能會不斷重複迴圈。這邊我們會預先設定一個迴圈限制,在預算內可以選擇展開更多網址、搜尋或重新渲染,再做一次檢查;圖片太少時也可以另外補一次圖片搜尋。這個停止條件很重要,否則 Agent 很容易變成「資料不夠 → 再找一下」,讓成本和延遲一路增加。
const plan = await planWithTools({ knownUrls });
let evidence = await executePlan(plan);
let verdict = await critique({ plan, evidence });
if (verdict === "thin" && budgetRemaining()) {
evidence = await recoverOnce(evidence);
verdict = await critique({ plan, evidence });
}
return verdict === "fail"
? { status: "blocked" }
: finalize(evidence);
Acquire 最終結果不只是抓到的 HTML,而是整理過的文字資料、圖片候選、商品目錄線索與抓取計畫;系統也會留下執行步驟、動作、原因與耗時,供後續除錯與 Eval。到這裡「資料要去哪裡拿」已經解決,後面開始處理「資料要怎麼整理成穩定的輸出」。
Acquire 把資料拿回來之後,下一個問題不是立刻生成文案,而是先處理另一種常見情況:同一個概念,在不同來源裡可能有不同寫法。
品牌名稱是這裡最直接的例子:資料庫裡可能只有英文名,Detect 從搜尋結果看到中英文並列,官方網站標題又多了一段宣傳標語。這些字串看起來不同,但不一定真的代表不同品牌,有些只是格式不同,有些則是來源真的給了不同答案。當多個來源都在描述同一個概念時,先把候選值正規化與去重;如果去重後只剩一個答案,就直接沿用。只有真的還有兩個以上不同候選時,才需要進一步判斷,選出後續統一使用的值。

到這裡,我們先把同一個概念的多個候選值收斂成後續統一使用的結果。接下來的問題才是:我們要怎麼根據手上的來源,把品牌本身整理清楚?
在這個階段我們的主要目標是以下三種輸出:

如果 Descriptions、Stockists、FAQ 各自獨立生成,很容易出現「每個欄位單看都合理,合在一起卻不一致」的問題,因此我們這裡還設計了一層 Validation Layer 來確認彼此間的邏輯合理,倘若有問題則會進行至多一次的修正。這裡正好對應前面談過的「以證據為基礎的內容整合」:模型可以重新組織語句,但每個重要陳述還是要能回到來源;而且 AI 產生內容之後,仍然要讓程式規則負責它擅長的驗證。
Editorial 做完後,我們已經有相對完整的品牌層資料。最後剩下的是另一種更複雜的問題:網站上可能有很多商品,我們到底要留下哪些,又怎麼把它們整理成可以審核的商品提案?
至此,我們已經接近完成「品牌」這個階層的處理:我們從最一開始只有一個官方網站和品牌名稱,到現在我們已經擁有了圖文、品牌描述等,但若想變成一個線上的選物平台我們不能僅把資料停留在品牌層面,而是需要找到合適的商品並呈現在品牌的資訊欄位中,這便是 Products 這個流程的目標。
商品候選可能同時來自商品目錄探索、Acquire 的抓取計畫、Acquire 過程中發現的頁面,以及已經抓取的頁面。Agent 開始之前,程式先把這些來源合併、去重,只留下品牌自己的網站或已知購買通路,並排除列表頁、無法存取的 URL 與近似重複頁面。
來源之間也有優先順序:商品目錄探索取得的候選通常帶有較完整的標題與圖片,Acquire 的抓取計畫則可以補上目錄探索沒有走到的商品頁;其他已發現或已抓取頁面再補剩下的候選。

讀完資料後,我們需要近一步思考如何將這些資料轉換成可利用的形式,這裡同時碰到前面幾篇拆開談過的問題:
category、subcategory屬於封閉集合分類 (Day 9)到這裡,前面從 Structured Outputs、Tool Use、分類、內容生成、圖片判斷到 Eval,再加上這篇把 Gather、Detect、Acquire、Names、Editorial 和 Products 串成完整流程,我們已經把這個專案目前主要的 Agent 資料處理流程走過一輪:怎麼從網站上零散、不一致的資訊出發,最後整理成有明確資料契約、可以交給後續審核的品牌與商品資料。
但把資料整理好,只解決了一半的問題。好的資料如果沒有適合的方式被找到、排序與呈現,對使用者來說仍然很難產生價值。 如果使用者必須先知道品牌名稱才能使用這些資料,那我們做的其實還比較像一個資料庫,而不是一個真正能幫助人探索商品的平台。
所以接下來,重點會從「怎麼把資料放進系統」轉到 Search / Discovery:這些品牌與商品要怎麼被表示?使用者只有模糊需求時,系統怎麼理解?候選怎麼找、怎麼排,又要怎麼呈現,才能真的幫助人往下一個值得看的商品前進?
下一篇先從搜尋入口開始。假設使用者不知道品牌或商品名稱,只說「想找一份適合露營朋友的禮物」,這句自然語言需求要怎麼變成系統真的能執行的限制條件與候選商品?
我們明天見!