我們用AI豐富了28,840筆記錄:大批量資料處理的經驗教訓
上一季度,我們承接了一個在紙面上聽起來很簡單的專案:用AI生成的描述、分類和元數據豐富28,840條產品記錄。客戶有一個龐大的電子商務目錄正在遷移到無頭CMS,每一條記錄都需要更好的內容。隨後發生的事情是當您將數以萬計的記錄投入AI API時,一切可能出錯和正確的方面的大師級教學。
這不是理論指南。我將帶您詳細了解我們構建的實際架構、我們支付的確切成本、我們遇到的失敗模式,以及拯救我們的模式。如果您正在考慮為自己的專案進行AI批量內容豐富,這應該可以讓您節省幾週的痛苦探索。
目錄
- 為什麼我們選擇AI豐富而不是手動工作
- 架構:我們如何構建管道
- 選擇Claude API進行批量處理
- 大規模提示工程
- 速率限制、重試和不被禁的藝術
- 品質控制:人在環路中的現實
- 真實成本分解
- 我們做錯的事
- 我們下次會做什麼不同的事
- 常見問題
為什麼我們選擇AI豐富而不是手動工作
數學非常簡單。我們的客戶有28,840條產品記錄——每一條都需要改寫描述(150-300字)、三個SEO友好的分類標籤、元描述和從非結構化文本中提取的結構化屬性。以一位人工文案寫手每條記錄保守估計8分鐘計算,這需要3,845小時的工作。以$35/小時計,您需要支付$134,575,加上一個小團隊大約6個月的工期。
我們在11天內完成了AI豐富,API成本不到$3,200,加上大約80小時的工程和品質保證時間。即使計入我們的開發時間,總成本大約是手動方法的十分之一。
但這裡有一個沒有人告訴您的事情:困難的部分不是調用API。而是它周圍的一切。數據清潔、提示調整、品質驗證、錯誤處理,以及不可避免的邊界情況,讓人質疑職業選擇。
架構:我們如何構建管道
我們構建了豐富管道作為Node.js應用程式,這對我們在Next.js開發和TypeScript中的專業知識很有意義。以下是高階架構:
Source CSV → Parser → Batch Queue → Claude API → Response Validator → Output Store → QA Dashboard
數據層
我們使用SQLite作為本地處理數據庫。聽起來不性感,對嗎?但對於這樣的批量處理,它是完美的。無需管理伺服器,交易速度快,您可以輕鬆查詢結果。每條記錄都有一個狀態欄追蹤其歷程:
interface EnrichmentRecord {
id: string;
original_title: string;
original_description: string;
raw_attributes: string;
status: 'pending' | 'processing' | 'completed' | 'failed' | 'needs_review';
enriched_description: string | null;
enriched_categories: string[] | null;
enriched_meta: string | null;
structured_attributes: Record<string, string> | null;
attempts: number;
last_error: string | null;
token_usage: number;
created_at: string;
updated_at: string;
}
佇列系統
我們使用由Redis支持的BullMQ實現了一個簡單的工作佇列。每個工作都代表單個記錄豐富。我們配置了:
- 並發:5個並行工作線程(稍後詳細說明為什麼是這個數字)
- 最大重試次數:每條記錄3次
- 退避:指數級,起始30秒
- 工作逾時:60秒
const enrichmentQueue = new Queue('enrichment', {
connection: redisConnection,
defaultJobOptions: {
attempts: 3,
backoff: {
type: 'exponential',
delay: 30000,
},
timeout: 60000,
removeOnComplete: false, // Keep for auditing
},
});
處理工作線程
每個工作線程拉取一條記錄,構建提示,調用Claude的API,驗證響應結構,並將結果寫回。如果響應與我們預期的JSON架構不匹配,它會進入needs_review桶中,而不是無聲地破壞我們的數據集。
選擇Claude API進行批量處理
在決定使用Claude(特別是Claude 3.5 Sonnet,之後對於更簡單的任務使用Claude 3.5 Haiku)之前,我們評估了三個選項:
| 功能 | Claude 3.5 Sonnet | GPT-4o | Gemini 1.5 Pro |
|---|---|---|---|
| 輸入成本(每1M令牌) | $3.00 | $2.50 | $1.25 |
| 輸出成本(每1M令牌) | $15.00 | $10.00 | $5.00 |
| 速率限制(RPM,第2層) | 1,000 | 500 | 360 |
| JSON模式可靠性 | 優秀 | 優秀 | 不一致 |
| 結構化輸出品質 | 最佳級別 | 非常好 | 好 |
| 批量API折扣 | 50% | 50% | N/A |
Q1 2025年的價格。檢查當前定價——這些經常變化。
我們選擇Claude有幾個原因。首先,它在我們的500條記錄測試運行中對結構化輸出的指令遵循明顯優於替代品。當您處理近29K條記錄時,即使是2%的格式合規性改進也會節省您數百次手動修正。其次,Anthropic的批量API為非時間敏感的工作提供了50%的折扣,這使得經濟效益更加有利。
老實說,GPT-4o也會沒問題。這種規模的差異更多是關於速率限制和定價,而不是原始品質。但Claude與JSON輸出的一致性是決定因素。
為什麼我們同時使用Sonnet和Haiku
這是一個為我們節省了大約40%API成本的技巧:我們沒有對所有內容使用相同的模型。產品描述需要Sonnet的品質。但分類和屬性提取?Haiku以極低的成本處理得很好。
我們將豐富分為兩個階段:
- 階段1(Haiku):分類分類、屬性提取、基本元數據——$0.25/1M輸入、$1.25/1M輸出
- 階段2(Sonnet):描述改寫、元描述、SEO內容——$3.00/1M輸入、$15.00/1M輸出
大規模提示工程
這是大多數教程讓您失望的地方。他們展示您一個單一提示並完成。當您通過相同的提示範本運行28,840條記錄時,細微的缺陷被放大為巨大的問題。
提示範本
經過大約15次迭代(是的,我們在git中追蹤了它們),以下是有效的粗略結構:
const buildPrompt = (record: SourceRecord): string => `
You are enriching product data for an e-commerce catalog. Generate the following for the product below:
1. A product description (150-300 words, second person, benefit-focused)
2. Exactly 3 category tags from this allowed list: ${CATEGORY_LIST}
3. A meta description (120-155 characters)
4. Structured attributes as key-value pairs
Rules:
- Do NOT invent features not present in the source data
- If information is ambiguous, use the "uncertain" flag
- Match the brand's tone: professional but approachable
- Description must be unique -- do not repeat the title verbatim in the first sentence
Respond ONLY with valid JSON matching this schema:
${JSON_SCHEMA}
Source product data:
Title: ${record.title}
Existing description: ${record.description}
Raw attributes: ${record.attributes}
Price: ${record.price}
Brand: ${record.brand}
`;
大規模提示課程
對輸出格式極其具體。 我們在每個請求中包含了完整的JSON架構。是的,它增加了令牌。不,不要跳過它。唯一一次我們嘗試僅依賴系統指令時,我們的格式合規性從97%下降到81%。
限制輸出詞彙。 對於分類標籤,我們提供了一個明確的允許列表。開放式分類在我們的測試批次中產生了847個唯一分類。受限的版本?正好是我們想要的42個。
為幻覺添加護欄。 產品偶爾會長出他們沒有的功能。添加「不要發明源數據中不存在的功能」減少了大約70%的幻覺屬性。添加uncertain標誌捕獲了大多數剩餘情況。
溫度比您想像的更重要。 我們確定了0.3。低於這個值,描述在類似產品中變得重複。更高,我們開始得到創意寫作,不符合品牌聲音。
速率限制、重試和不被禁的藝術
這一部分真的應該被稱為「花費最多工程時間的部分」。Anthropic的速率限制得到了很好的記錄,但在持續負載下的行為方式與您從閱讀文件中預期的不同。
我們的速率限制策略
在第2層(您花費$40+後獲得),Claude為您提供1,000個請求/分鐘和80,000個令牌/分鐘。聽起來很慷慨,直到您意識到我們的平均請求約為1,200個輸入令牌和800個輸出令牌。這意味著我們在達到令牌限制之前的實際限制約為40個並發請求。
我們運行5個並發工作線程,每個處理一條記錄,請求之間延遲200毫秒。這給了我們大約15-20個請求/分鐘——遠低於RPM限制,舒適地在令牌預算內。
const rateLimiter = new Bottleneck({
maxConcurrent: 5,
minTime: 200, // ms between requests
reservoir: 900, // requests per minute (leaving buffer)
reservoirRefreshAmount: 900,
reservoirRefreshInterval: 60 * 1000,
});
為什麼這麼保守? 因為達到速率限制會導致級聯故障。一個429響應觸發重試,這增加到佇列,增加並發壓力。我們在第一次真實運行的第3小時時以困難的方式學到了這一點,當時激進的設置導致重試風暴,有效地使管道停頓了45分鐘。
批量API替代方案
在項目的中途,我們部分轉向了Anthropic的批量API。與其發出個別請求,您上傳一個請求的JSONL文件,並在24小時內取得結果。權衡:50%的成本降低,但您失去實時反饋。
我們對階段1(Haiku分類)使用了批量API,對階段2(Sonnet描述)使用了實時API。這種混合方法對我們來說是最佳點——對昂貴創意工作的快速反饋,對商品分類的批量經濟。
品質控制:人在環路中的現實
任何告訴您AI豐富完全自動化的人要麼在撒謊,要麼還沒有大規模進行過。我們構建了一個品質保證流程,可以及早捕獲問題並防止垃圾進入生產環境。
自動化驗證
每個API響應在被接受前都要進行驗證:
const validateEnrichment = (result: EnrichmentResult): ValidationOutcome => {
const issues: string[] = [];
// Length checks
if (result.description.length < 400 || result.description.length > 2000) {
issues.push('description_length');
}
// Category validation
const invalidCats = result.categories.filter(c => !ALLOWED_CATEGORIES.includes(c));
if (invalidCats.length > 0) issues.push('invalid_categories');
// Meta description length
if (result.meta.length > 160) issues.push('meta_too_long');
// Hallucination signals
const hallucination_phrases = ['I think', 'probably', 'might be', 'as an AI'];
if (hallucination_phrases.some(p => result.description.includes(p))) {
issues.push('possible_hallucination');
}
// Duplicate detection (fuzzy match against already-processed records)
if (isDuplicateDescription(result.description)) {
issues.push('duplicate_content');
}
return {
valid: issues.length === 0,
issues,
needsReview: issues.length > 0 && issues.length < 3,
rejected: issues.length >= 3,
};
};
手動審查取樣
我們對所有已處理記錄的5%(約1,440條)進行了手動審查取樣。我們的品質保證團隊根據準確性、品牌聲音和完整性對每一項進行了評分。以下是我們實際審查的數字:
| 指標 | 分數 |
|---|---|
| 事實準確性 | 94.2% |
| 品牌聲音匹配 | 87.6% |
| 格式合規性 | 97.1% |
| 分類準確性 | 91.8% |
| 需要修訂的記錄 | 8.3% |
| 完全拒絕的記錄 | 1.9% |
那8.3%需要修訂是重要的背景。這意味著約2,400條記錄需要人工編輯。仍然遠少於手動編寫全部28,840——但它不是零。為此做預算。
真實成本分解
透明時間。以下是我們實際支出:
| 成本類別 | 金額 |
|---|---|
| Claude 3.5 Haiku(階段1 - 批量API) | $312 |
| Claude 3.5 Sonnet(階段2 - 實時) | $2,147 |
| 失敗/重試請求(~6%開銷) | $189 |
| Redis託管(2週) | $15 |
| 工程時間(80小時× $150) | $12,000 |
| 品質保證審查時間(40小時× $45) | $1,800 |
| 總計 | $16,463 |
| 僅API成本 | $2,648 |
與完全手動工作的$134,575估計相比。即使包括所有工程和品質保證時間,我們也在手動成本的約12%。每條記錄的API成本計算為約$0.092。每條記錄不到一毛錢用於AI豐富。這是讓高管坐起來的數字。
我們做錯的事
低估數據清潔
在向Claude發送數據之前,我們花費了3天時間清潔源數據。記錄有HTML實體、Unicode垃圾、截斷描述和列中的錯誤字段。垃圾進,垃圾出不只是一個陳詞濫調——它是批量AI處理的基本法則。
沒有從第一天開始使用批量API
通過實時API運行階段1時,我們燃燒了大約$400額外的API成本,然後才發現批量API會將成本降低一半。開始之前閱讀完整文件。全部的。
重複檢測不足
我們最初的重複檢測太天真了——簡單的字符串匹配。Claude會為類似產品生成結構上相同但使用稍微不同措辭的描述。我們必須實現語義相似性檢查(使用嵌入)來捕獲這些,這增加了一天的工作。
JSON解析失敗
大約2.4%的響應返回格式不正確的JSON。有時是尾隨逗號,有時是產品描述中未轉義的引號。我們應該從一開始就實現更寬鬆的JSON解析器,而不是將這些視為硬性失敗。
// What we should have done from day one
const parseResponse = (raw: string): EnrichmentResult | null => {
try {
return JSON.parse(raw);
} catch {
// Try to extract JSON from markdown code blocks
const jsonMatch = raw.match(/```json?\n?([\s\S]*?)\n?```/);
if (jsonMatch) {
try { return JSON.parse(jsonMatch[1]); } catch { /* fall through */ }
}
// Try jsonrepair library as last resort
try { return JSON.parse(jsonrepair(raw)); } catch { return null; }
}
};
我們下次會做什麼不同的事
從1,000條記錄試點開始,然後再提交完整運行。我們做了500條,但還不足以涵蓋所有邊界情況。
從一開始就使用結構化輸出。 Anthropic現在支持帶有定義架構的工具使用,這消除了大多數JSON解析問題。我們在中途遷移到了這一點,並希望我們從一開始就開始了。
首先構建品質保證儀表板。 我們在反應性地構建它後出現問題。從第一天開始使用它會在前100條記錄而不是前2,000條記錄中捕獲問題。
投資更好的嵌入以進行去重。 我們從一開始就使用專用嵌入模型(如
text-embedding-3-small)進行語義重複檢測。考慮混合模型路由。 一些記錄很簡單(帶有基本屬性的T恤),有些很複雜(帶有數十個規格的電子產品)。將簡單記錄路由到Haiku,複雜記錄路由到Sonnet——即使對於描述——也會為API成本再節省20-30%。
如果您正在計劃類似項目並希望跳過困難部分,我們已將此類工作的可重複使用管道構建為我們無頭CMS開發實踐的一部分。很樂意分享更多細節。
常見問題
用AI豐富28,000多條記錄需要多長時間? 我們的實際處理時間約為11天,包括管道開發、測試、處理和品質保證審查。API處理本身(發送請求和取得響應)花費了大約48小時的連續運行。如果您專門使用批量API,預期API處理需24-48小時,加上3-5天的工程和品質保證。
AI內容豐富的每條記錄成本是多少? 使用Claude 3.5 Sonnet和Haiku的組合,我們的API成本約為每條記錄$0.092,用於生成產品描述、分類、元描述和結構化屬性。您的實際成本將根據輸入/輸出長度和您選擇的模型而有所不同。批量API處理會將此大致減半。
Claude還是GPT-4更適合批量數據豐富? 兩者都效果很好。我們選擇Claude 3.5 Sonnet是因為在我們的測試中它優越的JSON格式合規性(97.1%對GPT-4o的~94%)。但是,GPT-4o在輸出令牌方面稍便宜。如果您的豐富主要是分類而不是內容生成,差異不大。提交前先用500條記錄測試兩者。
在進行數千個API調用時,您如何處理速率限制? 使用速率限制程式庫,如Bottleneck,設置保守的並發(5-10個並行請求),為重試實現指數退避,並在發佈的速率限制下留下10-15%的緩衝。對於非時間敏感的工作,Anthropic的批量API避免了速率限制問題,成本降低50%。
AI豐富的記錄中有多少百分比需要人工審查? 在我們的項目中,8.3%的記錄需要某種形式的人工編輯,1.9%完全被拒絕並手動改寫。您的數字將取決於數據品質、提示工程和可接受的品質閾值。計劃人工干預為5-15%作為現實基線。
AI批量豐富能處理多種語言嗎? 是的,但品質因語言而異。Claude和GPT-4很好地處理主要歐洲語言,但對於較少見語言的準確性下降。我們建議每種語言運行單獨的提示範本,並在品質保證取樣中具有母語使用者。預期非英文內容的人工審查百分比大致翻倍。
您如何防止AI在產品數據中出現幻覺? 三層:明確禁止發明功能的提示指令、用於不明確數據的「不確定」標誌,以及自動化驗證將豐富屬性與源數據進行比較。我們還使用語義相似性評分來標記偏離原始產品信息的描述。這減少了大約70%的幻覺屬性。
值得構建自訂管道還是應該使用現有工具? 對於少於1,000條記錄,像Clay、Bardeen或精心構建的Google Sheets + Apps Script之類的工具可以工作。超過這個數字,自訂管道會很快為自己付費。自訂解決方案提供的對重試邏輯、品質驗證和成本優化的控制在大規模時是必不可少的。我們的管道約為2,000行TypeScript——不是平凡的,但也不是一個大項目。如果您想讓我們為您的用例構建一個,請查看我們的定價頁面。