
GOAP 可以先不要想得太抽象,把它想成一張流程地圖。
目前有哪些事實,就是 current state;想達到的結果,就是 goal;中間每個 action 則像一條路。planner 的工作,是從目前狀態找出一條能抵達 goal 的路。

每個 action 都要說清楚兩件事:執行前需要什麼,執行後會產生什麼。這樣流程就不是硬寫死的 pipeline,而是一組可被推導、可被重組的能力。
GOAP 可以想成一張地圖。world state 是目前所在城市,action 是可走的道路,preconditions 是上路前必須滿足的條件,postconditions 是走完後世界狀態的改變,goal 則是想抵達的目的地。
以客服摘要為例,使用者輸入 CustomerQuery 後,系統可能先 fetchActivity 取得 TravellerActivity,再 summarize 產生 ActivitySummary,接著 proposeOffer 產生 OfferDraft,最後 reviewOffer 取得 ReviewedOffer。每個 action 都只承諾自己能從哪些事實產生哪些新事實。
可以先把 CustomerQuery、TravellerActivity、ActivitySummary 想成幾個「名字明確的資料盒子」。這些型別通常用 Java record 宣告,裡面只放這一步真的要傳遞的欄位,不先塞 service、流程控制或一大包 Map<String, Object>。
這種描述方式的好處是擴充時不必重寫整條流程。你新增一個 action,planner 只要看到它的條件與效果,就能判斷是否可以放進路徑裡。流程從命令式 pipeline 變成可推導的能力網路。
Day 02 到 Day 04 先建立觀念:為什麼要把 AI 放進工程邊界、Spring AI / agent-utils / Embabel 的差異,以及 Loop Engineering 和 GOAP 的取捨。到今天把工作拆成 action、state 與 goal 之後,才適合第一次看程式碼。
@Agent 表示這是一組可被 Embabel 管理的能力@Action 表示 planner 可以選擇這個步驟@AchievesGoal 表示這個 action 能達成最後目標@Agent(description = "Find news based on a person's star sign")
public class HoroscopeAgent {
@Action
public StarSign findStarSign(UserInput input) {
return new StarSign(input.text());
}
@Action
public NewsArticle fetchNews(StarSign sign) {
return newsService.findByStarSign(sign);
}
@AchievesGoal(description = "Write an amusing writeup based on horoscope and news")
@Action
public Writeup write(StarSign sign, NewsArticle article) {
return new Writeup(sign.value(), article.headline());
}
}
這段程式碼對應到今天的概念:UserInput 是目前已知事實,findStarSign 與 fetchNews 是可被規劃的 action,write 是達成 goal 的終點。重點不是 annotation 長什麼樣,而是方法簽章已經把「需要什麼」與「產生什麼」說清楚。
把 Antechinus Travel 的客服流程畫成 5 個 action,寫出每個 action 的輸入型別、輸出型別與失敗情境。
如果你也想進一步學習如何透過 AI 開發 Spring Framework 應用,讓 AI 協助理解框架、撰寫程式、除錯與驗>證,歡迎到 Hahow 看凱文大叔的最新課程【駕馭 AI 的全端實戰養成班:從零打造企業級智慧應用系統】。一起>學習如何駕馭 AI,提升 Spring 應用的開發效率與品質。
課程連結