Legwork
用途
這是決策研究。不是學術研究。問題永遠是某種形式的「我們應該對 X 做什麼」。成果的評判標準在於它是否可用,而非是否詳盡。
這一點決定了以下所有內容。一個聲明的判斷標準是其來源是否為該聲明正確的類型,而非其領域是否值得尊敬。三個來源達成一致只有在它們可能意見分歧時才有意義。而一串無法回答問題的執行應當明確說出,而不是產出含糊其辭的長篇大論。
自主原則。 根據上下文推斷你需要的資訊,選擇一個層級,然後開始。用一句話宣告層級並繼續進行;不要要求使用者選擇。使用者可以在執行過程中重新導向,這比每次請求都遇到阻礙性問題的成本低得多。僅在遇到嚴重錯誤或無法理解的查詢時才停止。
層級
深度會提高嚴謹度。它絕不會提高篇幅。
| 快速 | 標準 | 深入 | |
|---|---|---|---|
| 框架 | 決策加上 2-3 個子問題 | 加上命名反駁論點 | 加上二階角度 |
| 蒐集 | SERP 摘要;僅在確定數字時才擷取 | 直接擷取每個發現的頂級來源 | 每個發現都有一個主要來源 |
| 挑戰 | 僅獨立性分組 | 每個發現進行一次反駁搜索 | 每個發現進行反駁搜索加上來源審計 |
| 格式 | 簡報 | 簡報或報告 | 報告 |
| 關卡層級 | --level quick | --level standard | --level deep |
| 預估時間 | 3-5 分鐘 | 8-12 分鐘 | 20-40 分鐘 |
預設為標準。使用使用者命名的層級(quick、standard、deep,或等效詞如「快速掃描」或「深入探究」),否則使用 $LEGWORK_DEFAULT_MODE,否則使用標準。單獨的「深度研究」本身是此技能的調用短語,而不是對深入層級的請求 - 應回退到預設值。
如果範圍界定顯示問題的利害關係顯著高於請求所暗示的,則靜默提升一個層級,並在同一開場白中說明。
開場白,然後直接進入第一階段:
執行標準(約 8-12 分鐘)。說「深入」以獲取主要來源和反駁查證。
流程
四個階段。完整說明請參閱 methodology.md。
- 框架 - 命名決策、能夠解決該決策的子問題,以及哪些證據會改變答案。
- 蒐集 - 針對每個子問題進行檢索,記錄每一次擷取。
- 挑戰 - 尋找反駁案例;根據獨立性對來源進行分組。
- 撰寫 - 組合交付物,然後進行關卡檢查。
第 2 和第 3 階段會根據每個發現交錯進行,而不是作為嚴格的關卡執行。
開始之前
錨定日期。 執行 date -u +%Y-%m-%d 並使用該字串作為執行、輸出資料夾名稱以及每個可能返回過時材料的搜索查詢中的日期。絕不要依賴你自己對當前年份的感知,也絕不要讓子代理自行處理。
檢查此執行是否已經完成。 首先讀取索引。它是一個調度器:每一行對應一次過去的執行,而一行摘要欄的存在是為了讓你可以決定是否打開報告,而無需為此付出代價。
python3 ${CLAUDE_SKILL_DIR}/scripts/index.py list --base "$OUTPUT_BASE"
然後選擇四個路徑之一,並在你的開場白中說明:
| 索引顯示的內容 | 你該做的事 |
|---|---|
| 某次執行涵蓋此問題且未過時 | 從中回答。閱讀那份報告,而不是網路。 |
| 某次執行涵蓋此問題但被標記為過時 | 更新它 |
| 某次執行接近但回答了不同的問題 | 新執行,並相互參照 |
| 沒有匹配項 | 新執行 |
從先前的執行中回答是一種成功,而不是捷徑。 打開報告,閱讀與問題相關的發現,並完整保留其信心區間來回答。明確說明這來自於某個日期的執行。重新進行已經完成且仍然有效的研究,正是這個索引旨在防止的浪費。
更新而非重新執行
更新就地更新現有報告 - 相同的資料夾,相同的檔案。不要創建第二個資料夾:用兩個資料夾描述一個問題,只會導致讀者根據他們碰巧打開的那個來行動。
-
恢復擷取日誌,而不是開始一個新的。其中的一切都是已經付出的成本。
python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py resume --tsv "$OUT/$BASE.tsv"這會顯示已經處理過的角度、已經擷取的頁面,以及哪些頁面仍未包含引用。處理未涵蓋的角度並重新驗證決定答案的聲明;不要重新擷取已經記錄且最新的內容。
-
將現在錯誤的每個聲明移動到
## Superseded區段,並附上日期和原因。絕不要默默刪除一個聲明。 可能有人已經據此行動,而將來的執行需要知道這個領域已經被處理過。如果同一答案現在已經被推翻兩次,請大聲說出來 - 這是文件中關於該問題不穩定性最強烈的信號。 -
附加一行
## Timeline說明變更內容。 -
更新索引行。
歸檔執行
每次執行都會進入索引,包括那些無法回答的 - 「我們查過了,什麼也沒找到」正是未來的工作階段不再重複查詢所需的信息。
python3 ${CLAUDE_SKILL_DIR}/scripts/index.py add --base "$OUTPUT_BASE" \
--folder "$BASE" --topic "小型診所的 Outlook 分流" --level deep \
--one-liner "在 E5 以下沒有原生分流功能;差距是真實存在但範圍狹窄的"
一行摘要說明的是該次執行得出的結論,而不是它的主題是什麼。六個月後「關於插件庫的筆記」毫無用處;而「不存在提交途徑,只能透過 URL 安裝或根本無法安裝」則能獨立回答問題。當存在索引時,關卡檢查會對缺失的執行發出警告。
檢索政策
兩個階梯,優先使用免費階梯。僅爬到你需要的程度。
搜索:
| 階梯 | 調用 | 時機 |
|---|---|---|
| 1 | WebSearch | 始終。每個角度使用三個查詢變體。 |
| 2 | platforms.py search --on ... | 答案是一個平台持有的記錄:一個討論串、一個套件、一個儲存庫、一則有日期的新聞、一個供應商的更新日誌。免費、無需金鑰,且返回記錄而非關於該記錄的頁面。 |
| 3 | bd_search.py -m general --engine bing --country XX --language yy | 三個變體後仍然稀少,或者問題是地理特定的。第二個引擎是付費的理由。 |
| 4 | bd_search.py -m discover --intent "..." | 兩個引擎仍然稀少。 |
打開頁面:
| 階梯 | 調用 | 時機 |
|---|---|---|
| 1 | fetch.py "<url>" --find "term" | 始終優先。免費,且是唯一一個能取得頁面文字的免費傳輸方式,因此可以追踪數字並檢查引用。 |
| 2 | WebFetch | fetch.py 返回退出碼 3,且該頁面不值得付費。 |
| 3 | bd_search.py "<url>" -m scrape | 被封鎖:機器人防護、付費牆、403。 |
| 4 | bd_search.py "<url>" -m render | 客戶端渲染的殼。 |
| 5 | bd_search.py "<url>" -m pipeline --pipeline NAME | 一個封鎖了以上所有方式的平台。按記錄計費;-m reddit 是唯一當它成為唯一途徑而非最後手段時使用的情況。 |
執行 platforms.py list 查看十個免費平台,以及 bd_search.py --help 查看付費模式。若返回退出碼 2(認證或配額問題),告訴使用者執行 brightdata login。不要重試。
搜索結果是線索,而不是你可以閱讀的頁面。 在標準和深入層級,打開你所引用的內容:關卡檢查會將僅依賴於 websearch 行的引用視為未打開,在標準層級是警告,在深入層級是錯誤。快速層級本質上以摘要為優先,不做此要求。
在回退之前記錄失敗。 無法打開的頁面是關於該執行的證據 - --status blocked - 而收據會計入它。
限制你拉回的內容。 在抓取調用中使用 --max-chars 8000,並偏好使用 --find 而非盲目限制:在長頁面上,前八千個字符通常是導航。
你可以使用誰的來源
研究是指一個局外人能夠建立的東西。這個邊界在兩個方向都很重要。
絕不要將使用者自己的記錄作為一個發現呈現。 如果問題涉及使用者自己的公司、產品或市場定位,不要進入他們的私人帳戶 - 他們的域名註冊商、他們的帳單、他們的收件箱、他們的內部文件 - 然後報告你在那裡發現的內容,彷彿它是被發現的一樣。他們已經知道這些。這是循環論證,它膨脹了表面證據,並掩蓋了局外人實際上能看到的東西有多少。搜索公開的等效物,並報告一個局外人會找到的內容,包括什麼也沒找到。
對於第三方,可以使用使用者已經授予你的獨佔權限。 使用者明確提供的付費訂閱、私有資料集或內部數據庫,在研究競爭對手、供應商或市場時是真正的優勢。使用它,像對待任何其他來源一樣記錄它,並在限制部分說明該發現依賴於讀者可能沒有的權限。
當一個實體最終被發現完全沒有公開足跡時,那就是答案。列出你檢查過的內容,說明其存在性或其規模無法從外部驗證,並且不要用特權存取來填補這個空白。這是針對單一實體而非整個問題的「無法回答」的形狀。
擷取日誌
每一次檢索,在任何層級,都會附加一行:
python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log \
--tsv "$OUT/$BASE.tsv" \
--url "https://acme.example/pricing" \
--kind vendor_pricing \
--angle "競爭對手收費多少" \
--via webfetch \
--date 2026-07-01 \
--title "定價" \
--quote "團隊方案:每位使用者每月 30 美元,按年計費。" \
--text-file /tmp/page.txt
有兩個欄位承擔重任,而下游的任何東西都無法檢查它們。
--angle 是此次檢索正在回答的子問題。驗證是根據角度而非來源來計算的,因為 Legwork 自身的擴散會誇大來源計數。誠實地記錄角度 - 在一次執行中重複使用同一個字串會默默地破壞檢查,而任何腳本都無法分辨你這麼做了。
--quote 是使該來源值得引用的逐字句子。在你閱讀時,為你打算引用的每個來源記錄一個。 大約一半的發現不包含數字,因此對於這些發現,引用是唯一存在的證據,並且是頁面變更後唯一倖存的部分。當頁面文字儲存在磁碟上時 - 任何使用 fetch.py 打開的頁面,或帶有 --out 的 -m scrape - 引用會與之核對,而 quote_verified: false 意味著你錯誤引用了該頁面。
--from-fetch 會從這兩個東西寫入的 sidecar 檔案填充 url、標題、日期和頁面文字,因此無需重新輸入任何內容:
python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log --tsv "$OUT/$BASE.tsv" \
--from-fetch /tmp/legwork/ab12cd34ef56.json \
--angle "競爭對手收費多少" --kind vendor_pricing \
--query "site:acme.example pricing" --quote "團隊方案:每位使用者每月 30 美元 ..."
sources.py log --help 涵蓋了其餘部分:--via 傳輸方式(包括 api、local 和 mcp)、--text-file 數字提取、--kind。記錄你實際使用的傳輸方式 - 透過不同的傳輸方式重新擷取頁面以使其可記錄,只會扭曲跟踪記錄,而不是記錄它。sources.py kinds 會列印哪些來源類型適合哪些聲明。
子代理
檢索是唯一值得並行化的階段,每個角度一個子代理。使用 subagent-brief.md 向他們簡報,該文件包含逐字的模板、要求的回傳格式以及每一行存在的理由。子代理沒有上下文,因此它需要的一切都必須放在簡報中。
有三件事留在你身邊,而不是簡報中:
- 將模型與角度的形狀相匹配。 摘要收集和固定已知數字在廉價模型上運行良好 - 明確傳遞覆蓋參數,絕不要讓它意外地繼承會話模型。但是深入層級的主要來源工作,以及任何重建列舉的工作,都應保持在協調器模型上執行。實測結果:在一次比較中,協調器在從廉價到功能強大的範圍內打開了 3、8 和 32 個供應商頁面,只有最弱的模型在報告成功的同時,從單一聚合器填充了網格中的每個儲存格。
- 絕不要將子代理的對話記錄貼上到你的綜合分析中。 獲取結構化的回傳,檢查角度字串是否原樣返回,記錄每一行,並基於日誌進行工作。
- 範圍界定、挑戰和綜合分析是判斷性工作。 它們保留在主模型上。
腳本
全部僅依賴標準庫。無需虛擬環境。任何 python3 >= 3.9。
| 腳本 | 用途 |
|---|---|
fetch.py "<url>" --find TERM | 免費打開頁面並保留其文字;在封鎖或殼層返回時以退出碼 3 退出 |
platforms.py list | search --on X | 十個免費的平台原生來源,返回記錄而非頁面 |
sources.py kinds | log | score | 來源類型詞彙表、擷取日誌、按聲明類型計算的適合度評分 |
sources.py receipt | 收據行的檢索計數,取自日誌 |
sources.py stale --claim-kind K | 哪些已記錄的來源根據該聲明類型的半衰期已失效 |
sources.py resume | 先前執行已擷取了什麼,以便重新執行時跳過 |
independence.py groups | check | 將來源合併為獨立的意見;計算考慮角度的驗證 |
independence.py portfolio | 整個執行中的來源集中度,而非單個發現內 |
index.py add | list | 研究索引 - 歸檔執行、查找過去的執行、發現過時的執行 |
matrix.py check --report PATH | 比較矩陣的完整性 |
check.py --report PATH --level LEVEL | 可交付性關卡檢查 |
finish.py --report PATH --level LEVEL | 一次調用完成關卡檢查、過時掃描和歸檔 |
bd_search.py "<query|url>" -m MODE --json | Bright Data 檢索回退 |
輸出
在執行開始時解析輸出基礎路徑一次:
OUTPUT_BASE="${LEGWORK_OUTPUT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)/docs/research}"
BASE="[Topic]_Research_$(date +%Y%m%d)"
OUT="$OUTPUT_BASE/$BASE"; mkdir -p "$OUT"
…
[因翻譯需要截斷]