因為在它眼裡,「指令」和「資料」,長得一模一樣。
先講在前面:Prompt 注入,就是有人把「壞指令」藏進 AI 會讀到的資料裡,讓它照著做。
它為什麼會中招?不是它笨——是它天生就分不清,哪些字是「該做的命令」、哪些字只是「該讀的內容」。
不信?我唸四個給你聽。
你叫它「幫我摘要這個網頁」,它乖乖去讀,
但那頁裡被人偷偷埋了一段話,它讀著讀著,竟把那段陌生人埋的字,當成了新的命令、放下你的任務、轉頭去聽別人的。
你請它整理一封信、一份文件,
內容裡夾帶了一句不屬於你的指示,它分不清那是「要處理的資料」還是「要遵守的命令」,一個恍神,就把夾帶的那句,當成了你的吩咐。
你給它接了一堆工具、讓它自動幫你辦事,
它去讀的某個外部資料裡藏了鉤子,它就可能被牽著鼻子、去做一件你從沒交代、甚至會惹麻煩的動作——還一臉以為自己在幫忙。
最麻煩的是——你在前面設好的規矩、給它的系統指令,
跟後面它讀到的內容,在它眼裡通通是同一種東西:文字。誰講得更晚、更用力、更像命令,它就有可能聽了誰的。
看到這裡你可能會問:規矩不是明明白白寫在前面了嗎?怎麼一段藏在資料裡的字就能翻盤?
關鍵就在——這不是它「一時大意」,是它的天生構造,根本沒有一道牆,把「命令」和「內容」分開。
來看原理,這段有點料。
對模型來說,所有東西進去都變成同一種形式——一串文字(token),
你的系統指令、你的問題、它讀到的網頁內容,全被壓成同一條長長的字流,沒有顏色、沒有標籤、沒有「這是命令、那是資料」的分界。
它眼裡沒有「權限高低」,
只有一條混在一起的文字河——它做的事,是「順著這條河、預測下一個字」,而不是「先分清楚誰有資格下命令」。
傳統的程式,「程式碼」和「資料」是分開存、分開跑的,
資料就是資料,永遠不會被當成命令來執行——這道界線,是幾十年資安的根基。
但大模型天生就把兩者攪在同一鍋裡,
它的「指令」本來就是用自然語言寫的,而它讀的「資料」也是自然語言——兩者用的是同一種材質,自然就沒辦法涇渭分明地隔開。
它又被訓練成「盡量聽話、盡量配合、盡量照著文字裡的要求做」,
這份與生俱來的服從,是它好用的原因,也正是它的破口——它傾向於「照著讀到的指示走」,而不會停下來質疑「你有沒有資格對我下這個令」。
越聽話,越容易被牽走,
它那顆想幫忙的心,分不出這個「請求」是來自主人、還是來自藏在資料裡的陌生人——它只知道:有人說了,那就照做。
而這件事最難的地方在於——它是這門技術的「本質特性」,不是一個可以修掉的 Bug,
「能理解自然語言的指令」和「會被自然語言的指令騙」,根本是同一枚硬幣的兩面——你要它聽得懂人話,它就註定聽得進壞人的話。
工程師堵一個縫,總有新的縫,
攻擊只要成功一次,防守卻要防住每一次——這場攻防,天生就對防守方擺著不對等的、補不完的先天劣勢。
好,原理你懂了:它分不清指令和資料,而這是「聽得懂人話」的代價,不是一個能修好的漏洞。
那很多人會問——「那乾脆把它關起來、什麼資料都不給它讀,不就安全了?」
嗯……沒那麼簡單,往下看。
你可能想說,那把它綁死、什麼外部資料都不准碰,
是不是就固若金湯、再也不會被任何藏在內容裡的鉤子給牽著走了?
綁太死它就變廢物——不能讀網頁、不能看文件,它一半的本事就廢了,
好用和安全,天生站在蹺蹺板的兩端;真正的功夫,不是把它關進籠子,是在「讓它做事」和「守住底線」之間,拿捏那個平衡。
與其幻想擋掉所有攻擊,
不如假設「它遲早會被騙一次」,然後把系統設計成——就算它被騙了,也闖不出大禍。
最關鍵的一招,是「別給它一個人就能闖大禍的權限」,
能動錢、能刪資料、能對外發送的關鍵操作,別讓它讀了一段資料、自己一猜,就直接執行——中間留一道人的確認、留一個煞車。
把它當一個能幹但耳根軟的助手,
聰明的活交給它,但保險箱的鑰匙,別讓它一個人保管——這樣就算它偶爾被花言巧語騙了,你的城池,也還守得住。
再來是「把來路不明的內容,當成不可信的資料看待」,
它從外部讀進來的東西,預設都可能藏鉤子——重要的判斷,別全押在「它讀到什麼就信什麼」上,關鍵的環節,補上驗證、補上隔離、補上一雙人的眼睛。
它負責又快又聰明地處理,
你負責在會出大事的地方把個關——這一放一守之間,你才能既享受它的能幹,又不被那道「分不清指令和資料」的天生破口,給坑得措手不及。
所以下次看到「AI 被藏在資料裡的一句話騙了」的新聞,別太意外,也別急著笑它笨。
那不是它特別好騙,是「聽得懂人話」這件事,本來就註定了它也聽得進壞人的話——這是能力的光,也是能力的影。
真正該記住的,其實只有一件事——
它分不清「指令」和「資料」,因為在它眼裡,兩者都只是文字;
這是「聽得懂人話」的代價,不是一個能修好的 Bug;
與其幻想擋住所有攻擊,不如假設它會被騙——別給它一個人就能闖大禍的權限。