AI NPC · 角色開始會思考之後,什麼變了

AI NPC:AI 驅動的非玩家角色怎麼運作(以及怎麼做一個)

做一個你自己的 ai npc

AI NPC 能對話、能記住事情、能反應。先搞懂 AI NPC 的運作原理,再用一句話做一個,丟進可以走進去逛的 3D 世界。

✦遊戲
做一個 ai npc

AI NPC 是一種非玩家角色,它的對白與意圖在執行期由語言模型產生,但移動與碰撞仍然走確定性的路徑。AI 決定角色說什麼、想要什麼;引擎決定身體往哪裡走。在 Neta Studio 上,你用一句話描述角色,Agent Sprite Forge 產出一個低多邊形元件,這個元件直接落進用 Three.js 打造、可以走進去逛的 3D 世界。

這條分界線很重要,因為它直接告訴你 bug 會長在哪裡。NPC 穿牆,是路徑有問題。NPC 無緣無故嗆玩家,是提示詞契約有問題。這頁談的是第二類:ai npc 系統怎麼產生台詞、怎麼持有性格參數、怎麼記住一次 session,以及當模型負責規劃、引擎卻執行不了的時候,會怎麼壞掉。

快速回答:AI NPC 到底是什麼

把這個詞拆開。「AI」在這裡指的是由模型產生文字與高階意圖。「NPC」指的是角色控制器、碰撞體、動畫狀態機。兩者跑在不同的時鐘上:模型用幾百毫秒回答一次,控制器每一帧都以 60 Hz 更新。它們透過一個狹窄的介面溝通,通常就是控制器去輪詢的一小包 JSON。

實務上這個介面長這樣:模型回傳 {line, intent, target}。控制器讀 intent,檢查 target 在導航網格上到不到得了,然後決定播對應動畫的台詞,或改播備援台詞。如果把這兩層混在一起,你就會得到會瞬移、會滑行、或講到一半站著不動等模型生成完的 NPC。

所以可用的定義是:AI NPC 是一種 NPC,它說出來的話與下一步動作的選擇來自生成式模型,但被一組引擎真的執行得了的合法意圖框住。

  • 對白層呼叫模型。延遲 200–900 ms。可能失敗、可能被限流、可能回傳格式壞掉的 JSON。
  • 意圖層一個短列舉:greet、follow、flee、trade、attack、idle。列舉之外的東西一律丟掉。
  • 移動層導航網格尋路、碰撞體、動畫混合。每一帧都跑。不呼叫模型。
  • 記憶層一個鍵值儲存,放 NPC 被允許回想的事實,受 token 預算上限約束。

規則式 NPC 與 AI 驅動 NPC 的差別

規則式 NPC 從表裡挑。狀態、轉移、台詞全部手工撰寫。它精確、便宜、可重現:同樣的輸入永遠得到同樣的輸出,所以測試起來很輕鬆,除錯也很輕鬆。天花板是你的寫作時間,失敗模式是玩家打了你沒預想到的東西,然後得到一片空白。

AI 驅動 NPC 是生成台詞。你寫的是契約與一組合法意圖,模型去填中間那塊空間。它能優雅地處理沒預想到的輸入,但同樣的輸入在兩次執行之間可能產生不同輸出,這會讓天真的重播測試壞掉。成本隨對話長度成長,而不是隨角色數量成長,所以一場話多的戲比一場沉默的戲更貴。

兩者沒有誰絕對比較好。誠實的比較是:

面向規則式 NPCAI 驅動 NPC
行為來源人工撰寫的狀態機與台詞表受意圖列舉約束的模型輸出
可重播性每次執行位元級一致不確定,除非你把 seed 與 temperature 釘死
成本形狀建置期固定執行期按 token 計,隨對話長度成長
可除錯性追轉移就好,log 就是程式碼提示詞、原始回應、解析出的意圖、備援路徑要分開記錄
失敗模式回空白或走錯分支台詞出契約、延遲爆掉、或 JSON 解析不了
撰寫成本每句台詞高,每個狀態低每句台詞低,每條約束高

動態對白

對話樹是一張有撰寫好節點的圖。作者控制每一個字,所以任務、契約、劇情關鍵揭露到現在還是用樹。玩家的輸入會被比對到 N 個分支之一;N 之外的東西就是沒處理。樹的規模隨內容線性成長:對話內容加倍,寫的量就加倍。

生成的對白是種類上的不同,不只是量上的不同。模型讀玩家實際打的那句話,加上你注入的上下文——NPC 名稱、當下目標、最近三輪往來——然後寫出一個對得上的回應。你沒預想到的問題它也能接。它也可能接得很爛,但很有自信,而且很入戲,那比直接失敗還糟。

什麼時候樹還是對的:任何一句台詞承載了遊戲其他部分要靠的狀態。「閘門密碼是 4417。」這種不要讓模型自己編。可靠的作法是混用——樹持有事實與分支點,模型持有措辭與閒聊。在 Neta Studio 裡,你從描述建出 AI NPC 時,生成的元件會開一個意圖列舉;你要保證的事實就當固定字串放進元件,而不是當指令塞進提示詞。

撐得過玩家蹂躪的提示詞形狀

系統提示詞大概壓在 300 token 以內。角色、語氣、三條約束、輸出結構描述。其他全部——道具欄、任務狀態、世界事實——放進引擎每回合注入的獨立上下文區塊。把整個世界塞進系統提示詞,延遲會往上爬,而且模型會開始忽略後面那些指令。

永遠要求結構化輸出。要一個帶 line 與 intent 的 JSON 物件。解析它。解析失敗就丟掉那句,播備援。絕對不要把模型原始文字不經長度檢查就直接渲染到對話框;一次失控生成就會吐出四百字的獨白,把你的 UI 撐爆。

程序化性格

性格不是一段背景故事。一段背景故事是給模型想像力用的訓練資料,而且它會隨長度劣化:超過幾百字之後,模型開始把它當成調味,然後漂向通用的有求必應。把性格當成三、四個參數來處理,而且每一個都要能改變可觀察的行為。

goal 是 NPC 現在想要什麼。tone 是它怎麼說話:短促、正式、嘲諷。constraint 是它不做什麼:不說謊、不談那場戰爭、不交易。這三個塞得進一行提示詞,而且各自可測。只有當你能講出變動它會改變什麼,才加第四個。

在 Neta Studio 裡,Agent Sprite Forge 吃一段描述,回一個低多邊形元件,這些參數以欄位形式開在元件上。你可以只改 goal 而不碰模型提示詞,也可以複製一個元件只改 tone,就得到第二個 NPC。兩個 NPC 用同一張網格、不同 tone,在場景裡讀起來就是不同角色,比做兩套精靈便宜。

  • 目標一句話,現在式。「讓玩家離開神社。」
  • 語氣兩到四個形容詞。「短促、古雅、不耐煩。」
  • 約束否定規則。「絕不講出那條河的名字。絕不接受物品。」
  • 知識邊界NPC 可以引用什麼。之外的東西應該產生一個入戲的迴避,而不是編造。

自適應行為

單次 session 內的記憶又便宜又有效。你保留最近 N 輪往來的滾動緩衝,再加一個小的鍵值儲存放 NPC 被告知的事實。N 取 8 到 12 對大多數場景都夠;超過之後提示詞長得比玩家的耐心快,而且更舊的輪次反正也不再影響輸出。

NPC 能可靠記住的:玩家自己講的名字、某個特定物品有沒有給出去或被拒絕、上一次互動是不是鬧翻了、最後一次講出的目標。它不能可靠記住的:二十輪之前的確切措辭、從沒被寫進鍵值儲存的事實、以及任何跨頁面重載的東西,除非你把它持久化。只活在提示詞裡的記憶,就是會蒸發的記憶。

反應是另一半。引擎盯著狀態變化——血量下降、物品轉移、跨過距離門檻——把事件推入 NPC 的上下文。模型再從列舉裡挑一個意圖。這正是意圖列舉存在的理由:模型提案,引擎否決。一個「決定」要攻擊的 NPC,還是得通過可達性檢查。沒過,它就播一句警告台詞,留在原地。

持久化實際上的代價

把記憶寫進儲存體是一行程式碼加一個 schema 決定。鍵保持短而扁平:playerName、gaveItem、hostility。嵌套物件會膨脹、會腐爛。schema 從第一天就上版本;之後一次改名會默默丟掉舊存檔,除非你寫遷移。

跨 session 時,不要試著把整段對話歷史重播進上下文。那很貴,而且會讓 NPC 變得重複。持久化摘要就好——三到五條事實——然後讓對話紀錄重新開始。

用一句話做一個 AI NPC

Neta Studio 的流程刻意做得很短。你寫一段描述。Agent Sprite Forge 產生一個低多邊形元件,帶網格、調色盤、行為模式。你把它丟進用 3D game builder 做出來、可以走進去逛的場景,它生成時就已經接好碰撞、尋路、對白掛鉤。

能用的描述會講清楚角色、語氣、一條約束。「一個多疑的燈塔管理員,講話短促,北方口音,絕不談那場船難。」這樣產出的元件,提示詞裡就正好是這三個參數。像「一個很酷的角色」這種就會得到通用的結果,因為沒有任何東西被約束住。

你可以在兩個地方測結果:The Cyclops' Island,這是長篇、可以走進去逛的場景;以及 Mini World,比較小、迭代比較快。兩者都在瀏覽器裡跑 Three.js。把元件丟進去,走過去,打一句話,讀回應。語氣不對,就改元件上的 tone 欄位,不要從頭重寫提示詞。

1

01

寫一句話:角色、語氣、一條約束。

2

02

丟進 Agent Sprite Forge,產生低多邊形元件。

3

03

在 3D game builder 裡開 Mini World 或 The Cyclops' Island。

4

04

把元件丟進場景;生成時就帶碰撞與對白掛鉤。

5

05

走過去打一句話。讀回應,以及它選了哪個意圖。

6

06

改元件上的 tone 或 constraint,不要改系統提示詞。

7

07

測失敗路徑:打一句離題的話,確認備援有觸發。

8

08

行為對了之後,把元件移到比較大的場景。

AI NPC 到現在還做不到的事

長跨度規劃行不通。叫模型規劃一個場景裡的三十個步驟,它會產出一份看似合理的計畫,然後在第六步就失去線頭,因為步驟之間沒有任何東西在持有狀態,除了提示詞,而提示詞只會越來越長、越來越雜。如果你要一個多階段任務,階段自己寫,讓模型在每個階段內填對白。不要叫它撐住整條弧線。

真正開放式的目標也不行。「你想做什麼就做什麼」只會產生兩種結果:癱瘓,或有求必應的迴圈,因為模型沒有訊號判斷什麼算進展。一個目標只有在引擎能檢查它有沒有被滿足時才可用。如果你寫不出那個檢查,你有的不是目標,是心情。

成本控制才是真正的缺口。每回合成本很小;壞掉的是那場永遠講不完的討論。玩家一直聊就一直計費。你需要每次互動的回合數硬上限、上下文 token 上限,以及一條降級路徑——撞到上限之後,NPC 切換成更短、罐頭式的回應。少了這三樣,一個好奇的測試員就能燒掉比你整個場景加起來還多的預算。

還有一些比較小的失敗:延遲超過大約 1.5 秒,讀起來就是遊戲壞了,而不是角色在沉思。不確定性會弄壞重播測試,除非你把 seed 與 temperature 釘死。而且任何生成台詞都可能跟樹已經建立的事實牴觸,這就是事實留在樹裡的原因。

  • 規劃跨度一、兩步內可靠。再過去就嚴重劣化。
  • 目標驗證必須能被引擎檢查。否則那個目標只是裝飾。
  • 成本上限需要每次互動的回合上限,加上 token 上限,加上一個備援模式。
  • 延遲預算對話感要壓在 1.5 秒內;超過,玩家就假設它當掉了。
  • 確定性預設不確定。如果你靠重播來測,就把 seed 與 temperature 釘死。
描述一個角色,它就落進一個可以走進去逛的世界——AI NPC,一句話。
Little Ritual — 規則式基準線,AI NPC 得先贏過它。

走進它所屬的那個世界

精靈是一個無處可站的角色。最後這一步是別人都沒給的:把剛做好的精靈表放進一個有人可以走來走去、逛一圈的世界——一座小島、一顆行星、一個下雨的街角。這個網站上的每一個世界都是從一段文字描述做出來,然後發布成一個你可以玩的分頁。

常見問題

NPC 算是 AI 嗎?+

傳統上不算。典型的 NPC 就是一台帶人工撰寫台詞的狀態機,而且到現在還是大多數已上市遊戲的預設做法。「AI NPC」這個詞專指對白或意圖選擇由模型在執行期產生、而不是從表裡挑的角色。

什麼是 AI NPC?+

一種非玩家角色,它說出來的話與下一步動作的選擇來自生成式模型,並受一組引擎執行得了的固定意圖約束。移動、碰撞、動畫維持確定性;模型只填對白並提議一個意圖。

AI NPC 能記住事情嗎?+

單次 session 內可以——最近 8 到 12 輪往來的滾動緩衝,加一個放事實的小鍵值儲存,就涵蓋大多數場景。跨頁面重載就不行,除非你把事實持久化到儲存體。只活在提示詞裡的記憶,上下文一消失就跟著消失。

我可以免費做一個嗎?+

Agent Sprite Forge 與 3D game builder 都在瀏覽器裡跑,讓你用一句話生成元件,不需要本機工具鏈。執行期的模型呼叫才是會產生費用的部分,而那筆費用取決於你路由到哪個模型、以及你的對話跑多長。

做一個 AI NPC 需要遊戲引擎嗎?+

做瀏覽器場景不需要。3D game builder 在 Three.js 上處理算繪,並讓生成的元件帶碰撞、尋路、對白掛鉤,所以你可以跳過引擎設定的步驟。只有當你要出原生版本時,才需要一套完整引擎。

AI NPC 在瀏覽器裡能跑嗎?+

可以。模型呼叫是一個網路請求,算繪是 WebGL,所以兩邊都在瀏覽器裡跑。實務上的限制是延遲:系統提示詞保持短,上下文區塊獨立出來,否則回應會慢到玩家已經以為遊戲當掉了。

跑一個 AI NPC 要多少成本?+

它隨對話長度成長,不隨你放幾個角色成長。一個沉默的 NPC 幾乎不花錢;話多的一個按回合計費。真正有效的控制是每次互動的回合數硬上限加 token 上限,並在撞到上限後切換成罐頭回應。

回到 3D Game Builder

31 個完成的 3D 世界、遊戲與場景全在同一个頁面上——每一個都能玩。

平台:Neta Studio頁面:AI NPC:AI 驅動的非玩家角色怎麼運作(以及怎麼做一個)接著讀:/explore/guide/npc-behavior · /explore/guide/ai-npc · /explore/tool/ai-npc-generator
×