# 為什麼你的 AI 編碼代理會產生檔案路徑幻覺

Canonical source: https://maguyva.ai/zh-hant/blog/why-ai-coding-agents-hallucinate-file-paths

License: text under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/); code samples under [MIT-0](https://opensource.org/license/mit-0); the Maguyva name, logos, brand assets and other code are not covered. Details: [maguyva.ai/license](https://maguyva.ai/license).

Date: 2026-08-14 · Author: Maguyva Team

> 當 AI 編碼代理沒有儲存庫的真實地圖時，就會編造檔案路徑。本文說明這為何發生，以及紮根依據如何帶來更少的幻覺編輯。

破綻不是一個寫錯的函式體。而是一次自信滿滿的編輯，針對一個不存在的檔案，或者一個存在但並非實作該行為的檔案。

你要求修復工作階段過期問題。代理開啟了 `src/auth/session.ts`。這條路徑看起來合理。但它也是錯的。真正的處理函式在 `apps/api/src/middleware/expiry.ts` 裡，兩次重構之前被重新命名過。代理沒有對你撒謊。它是用訓練先驗加上上下文視窗裡已經有的內容，補全了一個路徑形狀的字串。

這是真實儲存庫中常見的失敗模式。模型會寫程式碼。失誤在於選錯了寫程式碼的地方。

## 為什麼代理會編造路徑

編碼代理是一個帶工具的下一個 token 預測模型。當你說「修一下工作階段過期」時，它必須先指定一個檔案，才能讀取或修補任何東西。如果它還沒有一張有依據的地圖，它就會從以下來源拼湊出一條路徑：

1. 它在其他儲存庫裡見過的命名慣例。`src/auth/session.ts` 是一種常見形態。
2. 已經出現在對話裡的檔案，那可能是你上週貼上過的檔案，而不是現在真正重要的檔案。
3. 它碰巧執行過的目錄清單，在大型程式碼樹上是不完整的。
4. 指令檔案。`CLAUDE.md` 和 `AGENTS.md` 告訴代理該如何表現。它們不是符號、呼叫端或當前路徑的活索引。

這些來源沒有一個是今天這個儲存庫的地圖。模型填補空白的方式，和它填補任何空白的方式一樣：用一個高機率的延續。這個延續常常看起來像一條真實的路徑。有時那個檔案確實存在，而且就在正確檔案旁邊。有時它曾經存在於上個月已合併的一個分支上。有時它從來就不存在。

如果代理從未搜尋過正確的字串，grep 在這裡救不了你。代理猜了一條路徑，然後讀了那條路徑傳回的內容，然後編輯了它。第一個錯誤的步驟是路徑，不是補丁。

讀檔案也不等於找到正確的檔案。Claude Code、Cursor、Codex 以及類似的工具，可以開啟你指向的任何東西。問題在於，它們能否在編輯之前，可靠地找到正確的檔案、重要的符號、依賴關係、測試，以及影響範圍。沒有地圖的檔案存取，依然是從猜測開始的。

## 錯誤檔案的編輯是一個檢索問題

把編造出來的路徑當作一次檢索失敗來處理，而不是當作性格缺陷。

如果代理在被允許編輯之前必須傳回 `path/file.ext:line`，會發生兩件事。第一，你可以開啟這條引用，在十秒內拒絕這次工作。第二，代理必須去查詢某個真正瞭解這棵程式碼樹的東西。

這就是程式碼庫上下文層的工作。僅靠語意搜尋是不夠的。一個「聽起來像工作階段過期」的片段，依然可能落在一個已廢棄的套件裡。當你知道字串時，你還需要精確文字；當你知道名字時，你需要符號查詢；當你知道形狀時，你需要結構化搜尋；當你需要呼叫端和影響範圍時，你需要依賴圖。

Maguyva 就是為相容 MCP 的編碼代理提供的這一層。它不是編輯器。Claude Code、Cursor、Codex CLI、VS Code、Windsurf 以及其他 MCP 用戶端，都留在它們原本的位置。代理在觸碰任何一行程式碼之前，先查詢一張排序過的地圖。

這個主張刻意保持謙遜：更少的幻覺編輯。Maguyva 並不會剝奪模型猜測的能力。它改變的是預設的第一步，從「編造一條看似合理的路徑」變成「請求排序過、帶引用的位置」。

## 一份有依據的答案是什麼樣子

對「工作階段過期在哪裡處理」這個問題，一個有用的答案不是一段話。而是一份簡短的位置清單：

- `apps/api/src/middleware/expiry.ts:48` - 處理函式
- `apps/web/src/lib/auth-client.ts:112` - 呼叫端
- `apps/api/tests/expiry.test.ts:20` - 如果這次改動出錯就會失敗的測試

你可以開啟這些行。如果錯了，你就停下。如果對了，代理就可以編輯。重點在於驗證，而不是一句口號。

Maguyva 提供 11 個面向客戶的 MCP 工具，涵蓋搜尋、符號、依賴分析、檔案檢索、儲存庫上下文和確定性實用工作流程。四種檢索模式（語意、結構、圖／依賴和文字）融合成排序結果；符號查詢是一個獨立的 MCP 工具（`find_symbol`）。有依據的答案會附上檔案路徑和行號傳回，方便你對照眼前的程式碼樹來評判。

[文件](/zh-hant/docs) 描述了最短路徑：先免費開始，索引一個你已經瞭解的儲存庫，連接用戶端，然後問一個你能核實的問題。

## 一個改變第一次編輯的迴圈

你不需要一套新的工作流程信條。你需要的是在第一次落筆之前多加一步。

1. 問一個你已經能評判的問題。「哪段程式碼處理登入和工作階段過期」比「修一下認證」更好。
2. 要求引用。檔案路徑和行號，而不是「認證模組」的一段摘要。
3. 開啟被引用的檔案。跟著符號走。確認你即將觸碰的依賴關係。
4. 只有到那時，才讓代理去打補丁。

如果第二步沒有傳回任何有用的東西，代理就沒有資格臨時編造一條路徑。它要麼再搜尋一次，要麼由你來指路。正是這一道關卡，產生了更少的幻覺編輯。模型還是同一個模型。變了的是地圖。

指令檔案依然重要。保留它們。用它們來記錄慣例、審查規則，以及不該觸碰的東西。不要要求它們充當索引。一個列出三個重要目錄的 `CLAUDE.md`，在一次套件拆分之後的那一週就會過時。而一張可查詢的地圖，會隨著儲存庫的更新而更新。

一個相關的失敗是「幾乎對」的檔案：當行為其實在 `auth-client.ts` 裡時，代理卻開啟了 `auth.ts`；或者補丁打在了一個生成的檔案上，而不是原始檔；或者因為名字匹配，編輯了 `packages/legacy` 裡的那份複製。引用不會讓這些錯誤變得不可能發生。它們只是讓這些錯誤在 diff 落地之前變得可見。

## 一張地圖不會為你修復的東西

對自己得到的東西保持清醒。一張有依據的地圖不會讓每一次編輯都變得正確——你的代理依然可能在完全正確的檔案裡寫出一個糟糕的補丁。如果你的程式碼庫依賴動態派發、反射或猴子補丁，一些符號查詢傳回的結果會比你希望的更單薄，因為執行時的間接性對任何靜態索引都會造成這種效果。而如果你在期待一個百分比——「幻覺路徑減少了 X%」——你在這裡找不到，因為除了你自己，沒有人能為你的儲存庫誠實地測出這個數字。

你可以期待的東西範圍更窄，也更有用：代理不再用一條猜測出來的路徑來開始它的編輯。這第一步會紮根於一張真實的地圖，而更少的幻覺編輯正是由此而來。引用之後的一切——閱讀 diff、判斷補丁——依然是你的工作，和以往一樣。

這個測試幾乎不花你什麼成本：索引一個你已經瞭解的儲存庫，問一個你能核實的問題。從一條曾經讓你吃過虧的路徑開始。如果引用錯了，你會立刻看出來。如果對了，你代理的下一次編輯就有了一個更好的落腳點。

`// it doesn't know the file. it knows how to find it.`
