Agent 最容易失控的時候,往往是功能開始「順便」變多:會找 code 以後想讓它順便跑測試,能跑測試後想讓它順手修 bug,最後還想叫它自動 commit。
這一篇我們先立下專案最核心的鐵律:我們做的是一個徹底「唯讀」的 Codebase 分析工具。
在寫下任何檢索邏輯前,必須先把系統邊界畫死。這套系統只負責探勘與梳理事實,不負責對你的程式碼產生任何副作用。
我們將「建立索引」與「查詢推論」明確切開,讓資料流向單純可控:
【索引期:離線建置】
目標 Repo (唯讀) ──► AST Scanner ──► SQLite Index
【查詢期:唯讀推論】
CLI / LLM Agent
│
▼ (唯讀呼叫)
受限工具層 (tools.py) ──► 查詢 SQLite / Git Diff ──► 產出 Evidence
為了避免 Agent 在本機「放飛自我」,系統的邊界矩陣定義如下:
| 能做(確定性唯讀分析) | 不能做(主動性副作用) |
|---|---|
| 靜態掃描目標 Python 原始碼 | 修改、建立任何檔案,或執行 commit/push |
| 提取 symbol 定位、import 關聯與行號 | 執行任意 shell 指令或背景 process |
| 讀取已索引檔案的指定區間程式碼 | 讀取專案目錄以外的路徑(防止 Path Traversal) |
| 解析受限的 Git diff 候選影響範圍 | 讀取或向模型洩漏 .env、憑證與私鑰 |
重要原則:安全防護不依賴模型自律
「不能讀取專案外路徑」或「不可外洩敏感檔」不是寫在 System Prompt 裡拜託 LLM 遵守,而是寫死在底層 Python 程式碼的硬限制。工具層會強制進行路徑正規化(os.path.realpath),只要存取超出專案根目錄,或是命中 .gitignore 與敏感檔案清單,底層函式直接拋出例外中斷。
至於跑測試?那是開發者的責任。工具只負責指出「候選受影響的測試檔案路徑」,絕不主動調用終端機執行腳本。
架構切分成三個獨立層次:
codebase.py(核心引擎):純粹的本機靜態分析器,負責 AST 遍歷、提取結構並存入 SQLite。tools.py(受限工具層):將分析功能封裝為無副作用、輸入輸出結構嚴謹的唯讀函式。cli.py(控制介面):讓工程師能直接在終端機操作所有工具。未來加入的 Ollama 或本機 LLM,本質上只是最外層的「意圖解析與對話入口」,它完全不決定資料如何被分析與保存。
這種拆法的好處非常務實:
今天確立的核心規矩只有一條:沒有 Evidence,就不下結論。
之後每推進一個功能,我們都會回頭檢驗:它是否維持唯讀?每一條回覆是否都有明確的行號與檔案依據?
下一篇,我們正式開始用 Python AST 萃取專案的第一批符號與依據。