ultradoc——從源頭回答問題,而非記憶
ultradoc 透過擷取有根據的證據並進行推理,來回答關於開源專案的超精準問題。確定性引擎(scripts/ultradoc.mjs,零依賴 Node)用程式碼進行搜尋和索引;你的工作是閱讀擷取到的證據,並撰寫精確、附有引用的答案。每個聲明都必須指向真實來源。這一點是強制的:如果任何引用無法解析為擷取的證據,ultradoc check 將會失敗。
核心規則: 不要根據你對該函式庫自身的知識來回答。你的訓練資料已經過時,且會產生幻覺 API。僅根據
ultradoc從實際儲存庫、議題、PR、文檔和網路中擷取的證據來回答。如果證據未涵蓋,請說明並擷取更多——切勿猜測。
腳本
一個已提交、無依賴的套件:node scripts/ultradoc.mjs <command>。無需 npm install,無需 API 金鑰。執行 --help 查看完整功能。關鍵命令:
ask --repo <url|path> --q "<question>" [--sources ...] [--package <p>] [--semantic] [--docs-url <u>]複製(任何 git URL,快取於/tmp/ultradoc/<slug>)、索引、從所有選定來源擷取,並將證據檔案(EVIDENCE.md、evidence.json、meta.json)寫入一個執行資料夾——該資料夾會持久化儲存在複製檔案旁(<clone>/.ultradoc/runs/<id>),這是一個穩定的、提交固定的主目錄,可在多個問題間重複使用,除非你傳入--out。預設來源:code,issues,prs,docs(當僅靠儲存庫無法回答問題時,添加web,so;對於「X 何時被添加/更改」的問題,添加releases,history;對於社群問答,添加discussions——需要 gh CLI)。 在單一儲存庫中,--package <name|dir>將程式碼/文檔的擷取範圍限定於一個工作區套件。code|issues|prs|docs|releases|history|discussions|so --repo <...> --q "..."—— 鑽入一個來源,將證據輸出到 stdout(無檔案)。使用這些命令來擴展薄弱的領域。history在複製檔案上執行 git pickaxe(log -S/-G)——首次對遠端儲存庫呼叫時,會獲取完整的歷史記錄一次。web --repo <...> [--q "..."] [--url <u,...>]——無金鑰的網路發現(SearXNG → DuckDuckGo → 你的 WebSearch)+ 擷取/提取。傳入--url來驗證你透過自己的 WebSearch 找到的特定頁面。overview --repo <...> [--refresh]——生成(一次)儲存庫的快取 Markdown 摘要:它是什麼、其工作區套件、佈局、公開 API 和文檔地圖。快取在複製檔案旁,並在提交不變時重複使用——閱讀它以在多個問題間定位,而無需重新索引。這是一個導航地圖,不是可引用的證據。doc --repo <...> [--package <p>] [--sources ...]——搭建一個有根據的參考文檔:一個確定性的章節大綱(概述、安裝、公開 API/每個套件、配置、架構),每個章節一個擷取的檔案,合併為一個evidence.json,以及一個DOC.todo.md工作清單。你將附有引用的散文寫入DOC.md;check像驗證答案一樣驗證它。持久化儲存在<clone>/.ultradoc/doc/下。請參閱下面的「生成文檔」。check --run <dossier-dir>——驗證ANSWER.md(或doc執行的DOC.md)的引用是否對應於檔案的evidence.json。退出碼非零 ⇒ 無根據。--answer <file>驗證特定檔案。index --repo <...>——建構/列印結構索引(用於除錯/檢查);列出單一儲存庫中發現的工作區套件。semantic up|down|status——可選的本地向量後端(見下文)。
工作流程
你端到端負責此任務:返回一個有根據、附有引用的答案,絕不交回一個半完成的擷取檔案。但擷取和驗證工作是一組獨立、近乎免費的呼叫——當你的協調機制允許時,請並行化它們(將獨立的鑽取命令批次處理到同一條訊息中;如果可用,分派給子代理或工作流程),否則就內聯執行。迭代幾輪直到證據完整;在完成之前不要返回。請參閱 references/orchestration.md。
-
確定目標。 識別專案和精確的問題。如果你只有名稱,請找到規範的儲存庫 URL(使用你的 WebSearch,或者如果不明確,詢問使用者)。注意使用者關心的任何版本/分支(
--ref)。關於同一個儲存庫的多個問題? 執行一次
overview --repo <url>並閱讀它列印的快取OVERVIEW.md:它繪製了儲存庫地圖(套件、佈局、公開 API、文檔),因此後續問題可以重複使用同一個複製+索引,而無需從頭開始重新定位。切勿引用它——它是導航,不是證據。單一儲存庫? 如果
ask/index/overview報告了工作區套件(例如socialgouv/code-du-travail-numerique→@cdt/frontend、@socialgouv/modeles-social……),請選擇其名稱/目錄與問題所涉及的子系統相符的套件,並添加--package <name|dir>,這樣擷取就不會被其他套件淹沒。如果沒有套件名稱明顯匹配,先執行一次無範圍限定的ask,檢視頂部命中結果集中在哪個套件,然後重新執行帶有範圍限定的ask。未知的套件名稱會大聲失敗並列出存在的套件。 -
擷取。 首先,像開發者一樣思考,為問題推導出 2-3 個查詢變體——引擎會進行字面搜尋,因此措辭很重要:
- 自然語言措辭(「重試退避」),
- 程式碼庫可能使用的識別碼形式(
retryBackoff、retry_backoff、MAX_RETRIES), - 如果使用者引用了文字錯誤訊息、選項或標誌名稱,則使用該文字。
多部分問題? 現在將其拆分為子問題——每個子問題需要自己的證據,或者在最後明確標記為「未知」。追蹤每個子問題的覆蓋範圍。
引擎已經處理了複數和變音符號(「retries」/「retry」、「délai」/「delai」),將識別碼拆分為子 token,並提升以關鍵字命名的檔案——因此將你的變體集中在同義詞和識別碼上(「heartbeat」與
ping,「pool」與connectionLimit),而不是同一個詞的不同屈折形式。同時了解何時詞彙搜尋會很薄弱:它需要字面上出現在儲存庫中的詞。對於概念性或「為什麼這樣設計」的問題,應優先使用docs、discussions、web(或--semantic),而不是指望code能承載答案。使用最佳變體和合適的來源執行
ask:node scripts/ultradoc.mjs ask --repo <url> --q "<precise question>" --sources code,issues,prs,docsultradoc 會從專案自身的 README/清單中自動發現其官方文檔 URL(並優先考慮儲存庫內規範的
docs/樹),然後根據其進行驗證——僅在需要覆蓋時傳入--docs-url <url>。當問題是概念性或儲存庫內容稀疏時,添加web,so;當問題涉及某事物何時/為何/哪個版本發生變化時,添加releases,history。該命令會列印檔案路徑。然後將剩餘的變體 × 鑽取來源視為一個扇出——在一條訊息中將這些獨立的鑽取命令作為平行呼叫發出(或每個單元格一個子代理)。請參閱references/orchestration.md。 -
閱讀檔案。 開啟執行資料夾中的
EVIDENCE.md。每個項目都有一個 ID([E1]、[E2]……)、一個來源ref和一個片段。這是你的證據——閱讀實際的程式碼/議題/PR/文檔文字。 -
針對差距進行鑽取。 當一個子問題少於約 2 個相關項目,或者沒有項目實際包含所問及的符號/行為時,該子問題就是薄弱的。不要等到檔案看起來薄弱才鑽取變體——從一開始就平行執行變體鑽取(鑽取近乎免費:複製和索引都已快取)。將它們扇出到各個來源:
code --repo <...> --q "<symbol or behavior>"以拉取更多程式碼區域。issues/prs以閱讀相關討論和進行中的更改。- 當問題涉及某事物何時/為何/哪個版本發生變化時,使用
releases(變更日誌 + 發行說明)和history(git pickaxe)。 discussions用於社群問答和設計線程(需要 gh CLI)。web(或你的 WebSearch →web --url <u>)用於外部參考資料。 遵循references/retrieval-playbook.md了解如何迭代,以及references/orchestration.md了解如何平行執行鑽取命令。
撰寫前進行分類。 擷取是面向回憶的,因此檔案將包含僅共享關鍵字的無關項目。測試標準:僅當一個項目的片段提及了所問及的符號/行為或描述了相同的機制時,它才與問題相關——共享一個關鍵字是不夠的。列出通過該測試的證據 ID,並忽略其餘的——一個無關的項目不能僅僅因為存在就被引用。如果分類後少於約 2 個項目支持核心聲明,請回去擷取更多。
重新查詢,而不是重新閱讀。 如果前 3 個程式碼項目都是無關的,不要一直往下閱讀列表——使用步驟 2 中的下一個識別碼形式變體重新執行
code --q。連續兩個無關的檔案表示措辭有問題,而不是儲存庫缺少答案。循環直到枯竭。 以數輪的方式進行鑽取(最多約 3 輪)。當一輪沒有出現新的相關證據時停止,或者當每個子問題都有 ≥2 個支持項目時停止——然後進行分類並撰寫。在達到上限後仍未得到支持的子問題,是一個明確的未知項,永遠不要從記憶中填充。
-
撰寫答案。 在同一個執行資料夾中建立
ANSWER.md。要精確且簡潔。引用每個事實性陳述,並附上其依據的證據 ID,例如Retries use exponential backoff with jitter [E1], and PR #79 is rewriting this [E7].請參閱references/citation-format.md。當版本重要時,將答案固定到meta.json中顯示的提交。涵蓋步驟 2 中的每個子問題;將任何證據未能確定的內容標記為明確的未知項——不要從記憶中填充。 -
驗證(兩層)。
- 結構性:
node scripts/ultradoc.mjs check --run <dossier-dir>。任何無法解析為證據的引用,或沒有引用的答案,都會導致失敗。修正並重新執行直到通過。 - 語義性(對抗性支持檢查):
node scripts/ultradoc.mjs verify --run <dossier-dir>會寫入一個聲明↔證據工作清單(VERIFY.todo.json+VERIFY.md)。作為一個懷疑論者來判斷每一對:預設為unsupported/refuted,除非被引用的片段字面上支持該聲明,將 verdict 設定為 supported · partial · refuted · unsupported(+ 簡短說明)。每對執行一個懷疑論者——可用時扇出到子代理(每個返回其 verdict),否則內聯裁決每一對——並將所有 verdict 收集到一個單一的verdicts.json中(請參閱references/orchestration.md),然後:
node scripts/ultradoc.mjs verify --apply verdicts.json --run <dossier-dir> node scripts/ultradoc.mjs check --semantic --run <dossier-dir>這會失敗於懸空/無來源(結構性)以及任何被駁斥或不受支持的聲明——填補了引用解析但實際上不支持該聲明的差距。修正該聲明(重新引用、弱化、丟棄或擷取一個更好的項目)並重新驗證直到通過。同時根據
references/answer-rubric.md進行自我審查,以確保完整性/時效性/未知項。 - 結構性:
-
呈現。 向使用者提供有根據的答案及其引用和連結(檔案:行號、議題/PR 編號、來自證據的文檔/SO/網路 URL),以及驗證所依據的提交。
生成文檔
當使用者想要的是整個專案(或整個套件)的文檔,而不是一個答案時,請使用 doc——這是相同的有根據循環,但扇出到一個章節大綱:
- 搭建框架。
node scripts/ultradoc.mjs doc --repo <url> [--package <p>]。引擎建構一個確定性的大綱(概述、安裝/使用、公開 API 或每個工作區套件一個章節、配置、架構),為每個章節擷取一個檔案,將它們合併為一個帶有全局[E#]ID 的evidence.json,並寫入DOC.todo.md(每個章節的工作清單)+DOC.plan.json。添加--sources code,docs,issues,prs以將章節基於 code+docs 之外的更多來源。它會持久化儲存在<clone>/.ultradoc/doc/下。 - 撰寫每個章節。 閱讀
DOC.todo.md和EVIDENCE.md,然後在執行資料夾中撰寫DOC.md:每個大綱條目一個章節,每個聲明引用[E#]。證據薄弱的章節是一個扇出單元——對其進行鑽取(code|docs|issues …)或將差距標記為明確的未知項;切勿憑記憶撰寫。每個章節的工作可以並行化——請參閱references/orchestration.md。 - 驗證與呈現。
node scripts/ultradoc.mjs check --run <doc-dir>(以及用於支持門控的verify+check --semantic,與步驟 6 完全相同——兩者都會自動檢測DOC.md)。修正直到有根據,然後呈現固定到其提交的DOC.md。
可選的語義模式(完全本地,無 API 金鑰)
確定性 Tier-1 搜尋(ripgrep + 符號索引)是預設選項,無需任何設定。對於更模糊、概念性的問題,您可以啟用本地語義搜尋:
node scripts/ultradoc.mjs semantic up # docker compose: Qdrant + Ollama (+ SearXNG)
node scripts/ultradoc.mjs ask --repo <url> --q "..." --semantic
所有內容都在本地 Docker 容器中運行——無需金鑰,資料不會離開機器。如果堆疊未啟動,--semantic 會記錄一條通知並回退到 Tier 1。請參閱 references/semantic-setup.md。
參考資料
references/orchestration.md— 如何在呼叫/子代理之間並行化擷取鑽取和驗證,包括返回 + verdict 組裝合約以及順序回退。references/retrieval-playbook.md— 如何選擇來源並迭代以得到完整答案。references/citation-format.md—check強制執行的引用語法。references/answer-rubric.md— 呈現前的語義自我審查。references/provider-apis.md— 如何基於主機、無金鑰地擷取議題/PR。
…
[已截斷以進行翻譯]