Skip to main content
Graphify:先建 AST 與知識圖譜,再查詢 codebase,為什麼比純 LLM trace code 更省時省成本

Architecture Journal

Knowledge GraphCode AnalysisAI Agent

Graphify:先建 AST 與知識圖譜,再查詢 codebase,為什麼比純 LLM trace code 更省時省成本

我最近對一件事越來越有感。

不是模型又變強了,也不是又多了一個新的 agent framework。

而是很多公司開始發現,AI 這件事一旦真的進到日常工作流程,最先浮上來的問題常常不是 capability,而是帳單。

前幾個月你還會看到很多公司在鼓勵員工多用 AI,甚至把使用量做成 leaderboard,想辦法把 adoption 推上去。結果到了 2026 年 6 月,風向很明顯變了:

  • 2026-06-02,TechCrunch 引述 Uber 新規,提到 Uber 在年初鼓勵大量使用 AI coding tools 之後,因為很快燒完年度預算,開始對每位員工、每個 agentic coding tool 設每月 $1,500 上限
  • 2026-06-05,TechCrunch 把這股趨勢寫成 the token bill comes due,直接點出企業現在談的是 visibility、auditability、token controls 與 efficiency
  • 2026-06-17,Business Insider 也在寫 the next office power struggle: AI tokens,描述企業從鼓勵 tokenmaxxing,轉向開始設定 ceiling 與使用規則

這幾條新聞放在一起看,我覺得它們其實在講同一件事:

token 不再只是模型供應商的計價單位,
它開始變成企業內部要治理的工程資源。

一旦事情走到這一步,問題就不會只剩下:

哪個模型比較強?

更現實的問題會變成:

哪些工作流程,正在把大量 token 花在重複、機械、可前置處理的事情上?

我覺得這才是 Graphify 這類工具真正值得看的地方。

老實說,我一開始不是先看到 Graphify

比較早先注意到的其實是 jqassistant 這條線。它用圖的方式去理解 codebase、規則與架構關係,這個方向本身我一直覺得很合理。只是如果把場景換成今天的 AI workflow,我後來會開始在意另一個問題:

這套東西跟 agent 怎麼接?
要不要多養一套額外基礎設施?
對團隊來說,導入門檻到底重不重?

後來是單位裡一位資深學長注意到 Graphify,跟我提這個工具比較適合現在這種和 AI 一起工作的使用情境。原因很務實,不是因為它聽起來比較新,而是它剛好解掉幾個很現實的採用阻力:

  • 跟 AI / agent workflow 的整合比較直接
  • 不需要另外裝一套 Neo4j
  • 整體更輕量,比較像可以先拿來試、先拿來接進分析流程

這也讓我後來對它更有興趣。因為很多工具不是想法不好,而是太重,重到你還沒開始驗證價值,就先多背了一層維運成本。

真正讓我停下來想的是另一件事:

很多人第一次用 coding agent 分析 repo,直覺上都會這樣做:

把問題丟給 LLM,讓它自己去 trace code。

例如:

  • 這個 API 最後寫進哪張表?
  • 某個 controller 背後實際呼叫了哪些 service?
  • 權限檢查到底在哪一層做?

這種方式在小專案不是不能用,demo 也常常很好看。

但 codebase 一大,問題就會很快冒出來:

  1. agent 每次都要重新讀很多檔案
  2. multi-hop 關係很容易漏掉
  3. context window、latency 與 token cost 一起膨脹

所以我後來比較在意的,不是 Graphify 是不是又一個 AI coding tool,而是它把問題換了一個 framing:

不要每次都讓 LLM 從 raw code 重新理解一次 repo。
先把 codebase 編譯成可查詢的結構,再讓 agent 來查。

這個想法對我來說很有意思,因為它解的不是 prompt wording,而是 code understanding 的成本結構

很多舊專案真正花時間的,不是改 code,而是先把事故查清楚

如果你手上碰的是一個跑了很多年的舊專案,這個問題通常會更明顯。

我自己比較常想到的,不是 greenfield 開發,而是另一種很典型的場景。

半夜有人丟一個 incident 過來,現象是 POST /api/users 偶爾回 500。更麻煩的是,營運那邊已經先回報,有些使用者雖然看到失敗訊息,但資料後來又真的存在,甚至下游通知也發出去了。

這種時候你第一個問題通常不是「怎麼修」,而是:

  • 到底哪一層先出錯?
  • response 失敗前,哪些 side effect 已經發生?
  • transaction 有沒有真的 rollback?
  • event 是先發出去,還是 DB 先寫成功?

很多時候,我們找 agent 不是要它從零生一個新功能,而是要它幫忙做這些比較不討喜、但又很常見的事情:

  • incident 後的 root cause analysis
  • 某個 API 為什麼突然回 500
  • 某個 batch job 為什麼資料重複寫入
  • 某條查詢鏈在哪一層吞掉 exception
  • 某個權限判斷為什麼在某個 edge case 失效

這些工作的共同點是:

你不是只問一次。

因為真正的 RCA 很少是一問一答就結束。它通常會一路長出更多追問:

  • 這個錯誤是從哪個 entrypoint 進來的?
  • 中間經過哪些 service?
  • 哪裡有 retry、fallback、transaction 或 async handoff?
  • 最後是哪一層真的把錯誤吞掉?
  • 以前還有哪些類似路徑碰過同樣問題?

這裡最麻煩的地方是,如果每追一條新線索,agent 都要重新 trace 一遍舊 repo,那成本很快就會失控。

而且麻煩的不只是 token 帳單。整個調查流程也會一起慢下來:

  1. 每一輪都重新找 entrypoint
  2. 每一輪都重新讀相似的檔案
  3. 每一輪都重新建立局部 mental model
  4. 每一輪都可能在不同分支上漏掉關鍵一跳

所以在 RCA 場景裡,我越來越不覺得問題是「context window 再大一點就好」。

我後來越來越覺得,在這種場景裡,我們需要的比較像是一種能把重複結構理解前置掉的方法:

一種能減少重複 trace、降低 token 花費,同時縮短 investigation time 的方法。

而這正好把問題帶回 graph。

真正昂貴的,常常不是 token 單價,而是一直重建同一份 mental model

如果把話講白一點,純 LLM trace code 最痛的地方,不只是一次 call 很貴。

真正一直在漏水的是這件事:

同一份 repo 結構,被 agent 一次又一次重新理解。

如果每次問問題,agent 都要重新:

  • 找 controller 在哪
  • 找 route 綁到哪個 handler
  • 找 handler call 哪個 service
  • 找 service 又依賴哪個 repository
  • 找 repository 最後碰哪個 model 或 table

這時候你消耗掉的就不只是 input token,還包括:

  • 更多工具調用
  • 更多 grep / read file / search retries
  • 更長的 prefill 與推理時間
  • 更高的漏關係機率

所以很多 repo analysis 問題,表面上像是在問答,本質上更像:

repeated reconstruction of structure

而這件事,正是最適合被前置編譯掉的部分。

Graphify 吸引我的地方,是它比較像在做 knowledge compilation

Graphify 對我來說比較有意思的地方,在於它不是單純把 repo 切 chunk 丟去檢索。

它更接近:

先把 codebase 裡的符號、引用、依賴、檔案關係與結構訊號抽出來,整理成可查詢的知識圖譜。

一旦這個中間層先建立起來,後面的查詢就不必每次都從 raw code 開始。

它的價值也不是把 LLM 突然變成更厲害的架構師,而是讓 LLM 少做幾件很花錢、也很重複的事:

  1. 少重建一次 repo 結構
  2. 少重走一次跨檔案依賴
  3. 少把大量不變的 context 重新塞進 prompt

這讓 code query 比較像:

在已知關係圖上走訪

而不是:

在一堆原始文字裡重新拼湊架構

我覺得關鍵就在這裡。

當 query 從「重建結構」變成「利用結構」,時間、成本,甚至 agent 的失誤型態都會一起變。

為什麼 AST 很重要

這裡我想補一個我自己很在意、但很多文章會快速帶過的點:AST

很多人一談 code graph,很容易直接往「knowledge graph」或「agent memory」跳。但對 codebase 這件事來說,我反而覺得最穩的起點不是 LLM 自己猜,而是:

先從 deterministic structure 開始。

也就是 AST

AST 不是語意理解的全部,但它至少先提供了可靠的語法骨架:

  • 哪裡有 class、function、method
  • 哪裡有 import / export
  • 哪裡有 call expression
  • 哪裡有 decorator、annotation、route binding
  • 哪裡有欄位、型別、參數

像 Graphify 這類工具如果先用 parser 或 tree-sitter 去抽這一層,好處其實很務實:

  1. 成本低
  2. 結果穩
  3. 覆蓋率高
  4. 不需要每個檔案都先交給 LLM 做一次 expensive extraction

換句話說:

AST 不是讓 agent 更聰明。
AST 是讓 agent 不必一直重做基礎理解。

一個很實際的例子:從 API controller 一路追到資料庫

假設今天有一條很常見的呼叫鏈:

POST /api/users
  -> UserController.createUser()
  -> UserService.createUser()
  -> UserRepository.save()
  -> users table

如果用純 LLM trace code,agent 通常要自己逐步找:

  1. route 定義在哪裡
  2. controller method 是哪個
  3. controller call 了哪個 service
  4. service 又 call 了哪個 repository
  5. repository 最後寫到哪個 model / table

這在小 repo 當然還追得動,但專案一大,常見麻煩就來了:

  • routing 分散在別的檔案
  • DI / interface 把真實實作藏在另一層
  • repository 不是直接 SQL,而是 ORM 包裝
  • 中間夾了 validation、auth、transaction、domain event

如果前面已經有 graph,問題就會變得很不一樣。

我們可以把這條鏈拆成幾種 edge:

  • route -> controller method
  • controller method -> service method
  • service method -> repository method
  • repository method -> model / table
  • file -> import -> symbol

然後 agent 不需要「從頭推理這條鏈可能怎麼走」,而是可以先查:

entrypoint: POST /api/users

再沿著 graph 往下走。

這時候 agent 的角色比較像是在:

  • 驗證關係
  • 補語意說明
  • 產出人類可讀的 tracing 結果

而不是每次都重新當 parser、indexer、architect。

如果把這件事放回剛剛那種 RCA 現場,感覺會更明顯。

假設 production error 出現在 POST /api/users,你要追查的是:

  • request 是怎麼進來的
  • 哪一層開始出現異常
  • 資料最後有沒有真的寫進 users table
  • 哪裡有 side effect 已經發生、但 response 失敗

沒有 graph 的時候,你每追一次都很像在請 agent 再把整條 call chain 拼回來一次。

但如果 graph 已經在那裡,流程就比較像:

  1. 先定位 entrypoint
  2. 走過 controller -> service -> repository 關係
  3. 找出例外處理、transaction、event publish 這些關鍵分支
  4. 只在必要節點打開原始碼確認細節

這個差異會很直接地反映在 RCA 速度上,也會很直接地反映在 token 消耗上。

差別不是 agent 有沒有在工作,而是它到底把時間花在「重新理解 repo」,還是花在「沿著既有結構做 investigation」。

如果要驗證這個想法,可以把它當成一個小型實驗

如果想把這件事講得更工程一點,我覺得可以把它當成一個簡單的對照實驗。

給 agent 同樣一個問題:

追查 POST /api/users 的失敗路徑,確認錯誤在哪一層發生,是否已寫入資料庫,以及哪些 side effects 已經發生。

然後比較兩種 workflow:

Workflow A:純 LLM trace code

  • 直接讓 agent 搜檔、讀檔、grep、推理
  • 每次追新分支時,再打開更多原始碼
  • 讓 agent 自己在 raw code 中重建 call chain

Workflow B:先有 AST / graph,再讓 agent 查

  • 先用 parser / tree-sitter 抽出 symbols、imports、calls、routes
  • 先把關係建成 graph
  • agent 先查結構,再針對少數節點打開原始碼

如果這個想法是對的,你大概會看到這幾個差異:

  1. Workflow B 讀的檔案更少
  2. Workflow B 工具調用次數更少
  3. Workflow B 在 multi-hop tracing 上比較穩
  4. Workflow B 比較不容易把不相關檔案塞進 context
  5. Workflow B 在重複查詢與後續追問時更省 token

我自己現在比較在意的也是這一層。

不是某次 demo 到底快了幾倍,而是它在 workflow 上到底改變了什麼:

原本每次 query 都要重建結構,
變成先有結構,再沿結構追查。

這對 agents 真正有價值的地方,是減少 context 汙染

如果只把這件事理解成「省 token」,我覺得還是太窄了。

更重要的是,它會減少 agent 在大 repo 裡常見的 context pollution。

當 agent 每次都拿著很多原始檔案進 prompt,它很容易:

  1. 抓到不相關但表面相似的檔案
  2. 漏掉真正關鍵的中間一跳
  3. 在很長的 tracing 過程中狀態漂移
  4. 把一次查詢中看到的局部線索誤當全局架構

反過來,如果前面已經有 graph 或某種結構化中間層,agent 的工作上下文就會乾淨很多:

  • 先看關係,再決定要不要打開原始碼
  • 先縮小候選範圍,再投入昂貴推理
  • 先用結構定位,再做語意補全

這其實跟我前面幾篇一直在想的事情很接近:

agent 成本問題,常常不是模型太貴,
而是同一份 context 被反覆重送、重建、重查。

在 code tracing 這件事上,graph 就是在幫你把這種浪費前置消化掉。

Context window 變大,不代表 graph 這層就可以省掉

我猜很多人看到這裡,第一個反應會是:

但現在 model context window 已經很大了,直接丟更多 code 不就好了?

但我的看法是,window 變大 不等於 結構問題消失

原因很簡單。

第一,大 context 只是讓你可以塞更多東西,不代表模型會更穩地追多跳關係。

第二,能塞進去不代表值得每次都塞。

第三,當查詢是重複發生的,raw context 的重送本身就是浪費。

所以真正該問的不是:

模型能不能一次吞下整個 repo?

而是:

repo 裡哪些資訊值得被做成可重用的中間層,而不是每次重新丟進上下文?

這也是為什麼我會把 graph 理解成一種 context architecture

它不是在和 model 對抗,而是在幫 agent 做 context 分層:

  • 穩定的結構資訊,先編譯
  • 動態的任務問題,後查詢
  • 真正需要語意判斷時,再把少量原始碼打開

真正省下來的,也不只是一張 token 帳單

如果這套 workflow 真的有效,它省下來的通常不只是一筆 API 費。

它還可能同時省掉:

  1. 查詢 latency
  2. tool calling 次數
  3. 失敗後的重試成本
  4. 人類等待 agent 找路的時間
  5. 因 tracing 不完整導致的誤判成本

所以更準確的說法可能不是:

Graph 讓 LLM 更便宜。

而是:

Graph 把 code understanding 裡最重複、最機械、最適合預先整理的那一層,從每次 query 中抽離出來。

所以我覺得 Graphify 那張對比圖真正有價值的,也不是某個絕對 benchmark 數字,而是它提醒了一個更值得帶回團隊裡討論的 workflow insight:

對大型 repo 而言,先建圖再查詢,常常比每次直接 trace code 更符合成本結構。

這不是銀彈,但我覺得它很適合某幾種場景

我不會把這件事講成唯一正解。

如果 repo 很小、模組邊界很單純,或者你只是一次性回答一個很局部的問題,直接讓 agent 讀原始碼就可能夠用了。這時先建 graph,反而可能是額外流程。

而且 graph 也不是自動就會準。它還是有自己的維護成本,例如:

  • parser 支援哪些語言
  • framework-specific routing 能不能抽準
  • interface、reflection、dynamic dispatch 能不能補齊
  • code 變動後 graph 更新的頻率要怎麼設計

所以我比較願意把它看成一種很實用的中間層,而不是銀彈。

它特別適合的,通常是這幾種情境:

  • 舊專案 RCA,要反覆追很多條呼叫鏈
  • 大型 repo analysis,要跨檔案、跨模組追多跳關係
  • 同一類架構問題會被反覆問很多次
  • 團隊開始在意 agent token 花費、latency 與調查效率

對我來說,這類做法最有價值的地方,不是它看起來比較進階,而是它很貼近一個老問題:

當系統已經變大、問題已經變雜時,
我們到底要不要每次都為同一份結構理解重複付費?

這篇先停在 code understanding,下一步才是 repo wiki

如果沿著這條線繼續往前推,其實很自然就會接到另一個更大的問題:

那這個中間層,可不可以不只拿來 tracing code,還拿來維護 repo 知識?

這就會從 code graph 走向 repo wiki

也就是說,graph 可以先解:

  • 結構理解
  • 關係追蹤
  • 多跳查詢

再往上一層,wiki 可以開始解:

  • 架構摘要
  • 模組說明
  • 決策脈絡
  • 慣例、限制與 known issues
  • 隨 repo 演進而更新的知識維護

這兩件事當然有關,但我覺得不是同一篇硬講完會比較好。

所以這篇先聚焦在前者:

為什麼 code understanding 應該先被結構化。
為什麼 AST / graph 會讓 agent 在大 repo 上更省時、更省成本,也更穩。

下一篇再接著談:

如果 graph 是 repo 的結構層,
那 repo wiki 會不會是 agent 的持久化知識層?

參考資料