開發者跨工具搜尋:程式庫不是找決策理由的地方
多數開發決策不在程式碼裡。本文教你把 Slack、Linear、GitHub、Notion 串成跨工具搜尋,快速找回決策脈絡。
By Chris Calo · 2026-03-17
你的 codebase,其實是最不適合拿來找「為什麼做這個決策」的地方。
我知道這聽起來很反直覺。我們花了好幾年學 ripgrep 參數、調 IDE 搜尋、背 regex 模式 – 但當問題不是「這個 function 在哪」而是「為什麼我們選了這個方案,而不是當初討論的另外三個」時,這些技能完全派不上用場。第二種問題的答案幾乎不會在程式碼裡。它在四個月前的某個 Slack 討論串、一則被狀態更新洗掉的 Linear 留言、某人開了頭卻沒寫完的 Notion 文件,以及某個 PR review 裡一層回一層的留言裡。
這就是開發者面臨的跨工具搜尋問題 – 決策脈絡被切在多個工具裡,沒有統一的查詢路徑。每個工具的內建搜尋都不差 – Slack 搜尋還行、GitHub code search 很強、Linear 篩選器超多 – 但就是沒有東西能一次跨過去搜。真正塑造架構的那些決策散在五個不同地方,你只能靠自己記得該去哪找。 This is also the foundation of cross-tool project visibility: knowing where work is happening means knowing where decisions were made, not just where tickets sit.
好,那 – 以下就是用你手上現有工具做跨工具搜尋的方法。基本上不用加新工具(差不多啦 – 文末我會提一個,但沒有它也能跑)。
一個分散式決策的解剖
讓我講個具體例子。去年我們在決定 job queue 該選 BullMQ 還是 Temporal。這個決策實際上散落在:
- Slack(#engineering):兩天內三個獨立討論串。第一串是有人貼了一篇 Temporal 的部落格文章。第二串在吵到底需不需要 durable execution。第三串(一週後、不同頻道)是有人問「等等,queue 那件事我們有定案嗎?」
- Linear:一張叫「Evaluate job queue options」的 issue,有六則留言,包含一位工程師花了一個下午做的比較表。
- GitHub:BullMQ 實作的 PR 描述寫著「as discussed」,零連結,完全不知道討論在哪。
- Notion:一份寫到一半的架構決策紀錄,只涵蓋了 Temporal 的優點,但從未更新最終選擇。
- Google Docs:真正拍板的那場會議筆記,埋在兩個不相干 agenda 項目的項目符號之間。
五個工具。一個決策。如果你在任何單一工具搜尋,只會拿到碎片 – 永遠看不到全貌。PR 告訴你我們最後選了什麼。Slack 告訴你我們考慮過什麼。Linear issue 告訴你取捨。Notion 文件給你一半的推理。會議筆記才是定案的瞬間。
這不是特例。這差不多就是 2026 年工程團隊追蹤決策的常態。我們有能寫 code 的 AI,有能索引整個網路的搜尋引擎,但想知道團隊為什麼選了 BullMQ 不選 Temporal,還是得開五個 app 然後祈禱有人記憶力夠好。
為什麼開發者跨工具搜尋很難
問題不在 API – 我們每天用的工具幾乎都有不錯的搜尋 API。難點比較怪:
資料形狀各不相同。 Slack 回傳的是帶時間戳和 channel ID 的訊息。Linear 回傳的是帶狀態和標籤的 issue。GitHub 以完全不同的回應格式回傳 commit、PR 和 code match。要把這些合成一條可讀的時間線需要做 normalisation,但這種事沒人會排進工作(畢竟 sprint demo 看不到這種東西)。
脈絡被切碎。 Slack 上一句「那就選方案 B 吧」,如果沒有前面定義 A、B、C 的討論串,完全沒有意義。但 Slack 搜尋回的是單一訊息,不是整段對話弧線。你找到了結論,卻抓不到推理過程。
時間漂移。 決策過程常常橫跨數天到數週,中間會有大家埋頭做其他事的空窗期。關鍵字搜尋可能抓到一段對話的開頭和結尾,卻漏掉最關鍵的中段 – 只因為不同階段用了不同的詞。
開發者跨工具搜尋不是 API 問題 – 每個工具都有不錯的搜尋端點。真正的問題是脈絡:決策以不相容的形狀分散在各工具裡,被對話弧線切碎,再被時間漂移拉開。關鍵字搜尋只能抓碎片;只有把脈絡連起來才能看到全貌。
用現有工具做跨工具搜尋
來看實作。只做三到四個工具的唯讀搜尋,MVP 大概半天可以跑起來 – 大部分時間會花在授權設定和回應 normalisation,不是搜尋邏輯本身。
設定 API 存取
你會需要各工具的 token:
- Slack:有
search:read scope 的 user token(Slack 搜尋方法需要 user token,不是 bot token – 從 Slack API apps page 建立)
- Linear:Settings 裡 API 部分取得 personal API key
- GitHub:對你 repo 有 read 權限的 fine-grained PAT
- Notion:Settings 裡 Connections 部分取得 internal integration token
Fan-out 查詢腳本
基本模式簡單得令人有點尷尬 – 把同一個 query 丟到每個 API,再把結果收回來:
```typescript interface SearchResult { source: 'slack' | 'linear' | 'github' | 'notion'; title: string; snippet: string; url: string; timestamp: Date; }
async function crossToolSearch(query: string): Promise<SearchResult[]> { const results = await Promise.all([ searchSlack(query), searchLinear(query), searchGitHub(query), searchNotion(query), ]);
return results .flat() .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime()); } ```
每個 search* function 包一層對應 API。Slack 用 search.messages。Linear 用 GraphQL 查它的搜尋欄位。GitHub 用 REST search endpoint。Notion 用帶 query 參數的 search endpoint。
Normalise 與去重
真正的難點不在搜尋 – 而在讓結果好用。你需要做:
- 跨工具時間戳 normalise(Slack 用 Unix epoch,Linear 用 ISO 字串,GitHub 用帶時區 offset 的 ISO)
- 合併相關結果 – 同一個 Slack thread 若三則訊息都命中,應合成單筆結果並用 thread URL
- 按相關性排序 – 各家 API 有自己的 relevance score,但跨工具沒辦法直接比。簡單規則:標題精準命中 > 內文命中;同分時新資料 > 舊資料
包成 CLI
我自己用 Commander.js(純粹習慣,其他也行):
```bash $ cross-search "bullmq vs temporal"
Found 14 results across 4 tools:
[Slack] #engineering – 2025-11-14 "I've been comparing BullMQ and Temporal for the job queue..." https://myteam.slack.com/archives/C0X.../p17318...
[Linear] ENG-342 – 2025-11-15 "Evaluate job queue options – BullMQ vs Temporal" https://linear.app/myteam/issue/ENG-342
[GitHub] PR #289 – 2025-11-22 "feat: implement BullMQ job queue (as discussed)" https://github.com/myorg/myrepo/pull/289
[Notion] Architecture Decisions – 2025-11-13 "Job Queue Evaluation: Temporal vs BullMQ" https://notion.so/myteam/abc123... ```
14 筆結果、跨 4 個工具、按時間排序。你可以一次看到完整的決策弧線:先有 Notion 文件,接著 Slack 討論發生,然後開了 Linear issue 追蹤,最後一週後 PR 合併。
怎麼讓它真的好用
上面的基本版可以用,但有一些讓人挫折的邊緣情況。以下是改進方法:
Slack thread 展開。 找到命中訊息時,用 conversations.replies 把整串抓下來。命中訊息可能只是「好,就用 BullMQ」– 沒有前面 40 則討論幾乎沒價值。顯示 thread 摘要,不要只顯示命中的那則。
PR review 留言。 GitHub 搜尋 API 在搜 PR 時不會一起回傳 review comments – 你需要另外打 pull request reviews endpoint 來取得。真正的技術討論通常都在那裡。
反向連結。 找到 Linear issue 後,反查是否有 Slack 訊息包含該 issue 的 URL。Slack 搜尋支援 has:link 搭配關鍵字篩選。這能挖出圍繞正式追蹤項目發生的非正式討論。
快取。 如果團隊內容產出量大(哪個團隊不是呢),很快就會撞到 rate limit。建議本地快取並設 30 分鐘 TTL – 大多數歷史決策不會變那麼快。
文字搜尋會撞牆的地方
這裡我得直說限制。跨工具的關鍵字搜尋能帶你走得出乎意料地遠,然後就會撞上一堵牆。
牆是這樣的:決策會演化。那串討論「job queue」的 Slack thread 可能從頭到尾都沒提到「BullMQ」這個字 – 相反,有人貼了連結,另一個人說「我比較偏好 Redis-backed 那個」,第三個人回「同意,就那個吧」。你搜「BullMQ」會整串漏掉,因為關鍵字根本沒出現過。參與那串討論的人知道「Redis-backed 那個」是什麼意思,你的搜尋不知道。
這從根本上是個圖譜問題,不是文字問題。你真正想問的是:「把和 PR #289 這個決策相關的所有東西都給我看。」這意味著要理解:PR 引用了一張 Linear issue,那張 issue 是某串 Slack 討論之後才建的,而那串討論的起點是有人讀了一份 Notion 文件。這些連結是隱性的 – 人們靠貼 URL 和寫「as discussed」來建立 – 關鍵字搜尋重建不了它們。
你可以靠追連結部分解決。從 Slack 訊息、PR 描述和 Linear 留言中解析 URL。建一個簡單的 adjacency list:這個 Slack thread 連到這張 Linear issue,而這張 issue 被這個 PR 引用。之後使用者搜尋時,即使某些項目沒命中關鍵字,你也可以把關聯項目一起展開。
這種 adjacency-list 方法,本質上就是一個基礎版的知識圖譜 – 也正是開發者跨工具搜尋真正有價值的地方。重點不是找到單一訊息,而是沿著一個決策走過的每個工具把脈絡串起來。它比較不像「搜尋」,更像是開發者知識管理 – 理解資訊怎麼在你的工具間流動,讓你在需要時能還原完整脈絡。 That’s the same problem as the cross-tool decision trail from Slack through Linear to GitHub: you need the full chain, not just whichever fragment the right keyword happened to surface. And it’s inseparable from tracking work without losing context between platforms – decisions and tasks are two sides of the same cross-tool visibility coin.
維護問題(以及捷徑)
腳本方案前三個月通常很好用,然後某天 Slack workspace 改設定、Linear 更新 GraphQL schema,或你多接了一個工具但沒人記得更新搜尋腳本。這套東西我做過兩次、也放生過兩次(這大概更能說明我對維護的承諾,而不是方法本身的問題)。
如果你要的是不用 babysit、能跟上工具變動的開發者跨工具搜尋,像 Sugarbug 這類工具就是為這件事設計的 – 它會自動維護知識圖譜,工具變動時也能維持連結。不過如果你願意做維護,上面的 DIY 版本真的已經很好用。
不要再分別搜五個工具了。Sugarbug 建立知識圖譜,讓你在同一個地方找到任何決策、討論或 commit。
Q: 我要怎麼一次搜尋多個開發工具? A: 你可以把各工具 API 串成一個輕量跨工具搜尋腳本 – 例如 Slack 的 search.messages、Linear 的 issueSearch、GitHub 的程式碼搜尋端點 – 把查詢同時送出,再依時間戳合併結果。上面的程式碼範例,一個下午就可以做出能跑的版本。真正困難點不在搜尋本身,而在把各家不同回應格式 normalise 成同一條時間線。
Q: Sugarbug 有提供開發者跨工具搜尋嗎? A: 有。Sugarbug 會把來自 Linear、GitHub、Slack、Figma、Notion 等工具的訊號匯入知識圖譜,所以你搜尋某個決策或討論時,可以在同一個地方看到所有相關 thread、issue 和 commit。它會自動處理 normalisation、去重和連結追蹤 – 也就是 DIY 方案最容易隨時間壞掉的那些部分。
Q: 為什麼我在 codebase 找不到架構決策? A: 因為大多數決策發生在 Slack 討論串、Linear 留言、Notion 文件和 PR review – 不在程式碼本身。程式碼記錄的是決策結果(某個 function 存在了、某個 library 被採用了),但推理過程、取捨和替代方案散落在各種協作工具裡。git blame 可以告訴你某一行是誰、什麼時候改的,但不會告訴你為什麼他們選了那個方案而不是替代方案。
Q: Sugarbug 可以取代 ADR 來追蹤決策嗎? A: Sugarbug 不會取代 ADR,但它能補到那些從沒被寫進 ADR 的決策。多數團隊可能只替 10% 的架構選擇寫 ADR – 其餘的都散在 Slack 討論串和 PR 留言裡。Sugarbug 把對話和產生的程式碼變更連結起來,讓你不用改變任何人的工作流程,也能補齊另外 90% 的決策追蹤。