如果 AI 產生的結果最後只能停留在一張卡片裡,使用者看完之後還是要自己重新操作,這個功能其實還沒有真正融入散步流程,有點不太實用。
所以今天想處理的不是再增加一個 AI 分析,而是把前兩天產生的結果接回原本的產品功能。
簡單來說就是 AI 負責提供建議,原本的產品功能負責執行。
昨天 AI 散步分析最後會得到一個下一次散步的目標,例如:
{
goal: 'reduce_difficulty',
target: {
durationMinutes: 25,
distanceMeters: 2000,
preferSimplerRecommendedRoute: true,
routeComplexity: 'simple',
},
}
這些資料其實已經可以拿來做很多事情。
例如:下一次可以先走 25 分鐘、2 公里。
但這裡有一個很重要的問題:
AI 知道下一次適合走多久,不代表 AI 就應該負責產生下一次的路線。
推薦路線本身已經有完整的流程,包括起點、距離、時間、是否回到起點、地點偏好,以及 Places / Routes API 和候選路線評分。
如果因為加入 AI,就另外做一套「AI 產生路線」的流程,反而會讓原本的架構變得更複雜。
所以這次的方向很簡單:
AI 不需要一路參與到最後。
昨天的 target 已經是結構化資料,所以這次不需要從 AI 產生的文字裡解析數字。
例如:下一次可以先走 25 分鐘、2 公里。
這句文字只是給使用者看的。
真正拿來串接推薦路線的,是:
{
durationMinutes: 25,
distanceMeters: 2000,
}
因此我另外做了一個純轉換函式:
coachingTargetToRouteIntent(target);
它的工作只有一件事就是把這次分析產生的 Target 轉成推薦路線可以理解的輸入。
例如:
durationMinutes
↓
targetDurationSeconds
distanceMeters
↓
targetDistanceMeters
這裡我特別避免直接把整個分析結果當成 Navigation Params 傳過去。
例如不會直接傳:
{
title,
reason,
suggestion,
goal,
target,
}
因為推薦路線根本不需要這些資訊。
它真正需要的只有:
{
targetDurationSeconds,
targetDistanceMeters,
}
所以 Mobile 端會先把 Target 轉成推薦頁需要的預填資料,再透過 Navigation Params 帶過去。
這樣兩個功能之間的依賴就會比較小。
未來就算 AI 分析的文案格式改了,只要 Target 沒有改變,推薦路線也不需要跟著修改。
使用者在 AI 建議卡片上看到「依照建議找路線」
點下去之後,不會直接呼叫 Routes API,而是先進入原本的推薦路線頁。
例如分析建議是:
25 分鐘
2 公里
推薦頁就會先預填:
目標時間:25 分鐘
目標距離:2 公里
使用者還是可以修改。
例如今天只有 15 分鐘,就可以改成:
15 分鐘
如果今天想多走一點,也可以改成:
30 分鐘
3 公里
修改之後,後面完全走原本的推薦路線流程。
所以 AI 的角色比較像幫使用者把下一步先準備好,而不是替使用者做最後決定。
乍看之下,點一下就直接出現路線似乎更方便。
但推薦路線除了時間和距離之外,還需要其他條件。
例如:
這些資訊 AI 分析其實沒有必要知道。
使用者今天可能在公司,明天可能在家;今天可能想去公園,明天可能只是想在附近走走。
如果 AI 自己補上這些資訊,就會開始出現一個問題:
AI 到底是根據什麼決定這些條件?
與其讓 AI 猜,不如直接讓使用者在原本的推薦頁確認。
這樣也剛好可以重用已經存在的 UI 和驗證邏輯。
推薦路線原本已經有自己的輸入限制與 validation。
所以分析結果帶過來的時間和距離,也會直接走同一套流程。
不另外建立:
這樣可以避免兩邊的規則慢慢產生差異。
不管這個數字是使用者手動輸入,還是 AI 建議後自動預填,最後都必須經過同一套推薦路線流程。
這其實也是這次串接比較重要的一個原則:
AI 不應該複製原本的產品邏輯,而應該使用原本已經存在的產品邏輯。
routeComplexity 暫時不直接使用Target 裡還有:
routeComplexity
preferSimplerRecommendedRoute
例如最近幾次推薦路線完成率比較低時,分析結果可能會得到:
routeComplexity: 'simple'
但目前推薦路線 API 還沒有真正代表「路線難度」的欄位。
如果現在硬把 simple 映射成「少一個 waypoint」或「少找一個地點」,其實不一定真的代表路線比較簡單。
因此這次沒有為了把這個欄位用掉,就強行修改推薦路線邏輯。目前先讓它保留在分析結果裡。
等未來推薦路線本身真的支援路線難度,再把兩邊正式接起來。
這樣會比現在先做一個語意不準確的轉換更合理。
把資料傳進推薦頁並不難,真正容易出問題的是:這個預填值會不會一直留著?
例如使用者第一次從分析建議進入推薦頁:
25 分鐘
2 公里
如果這些資料直接寫進推薦頁的 state,之後使用者自己從 Tab 重新進入推薦頁時,就可能還看到:
25 分鐘
2 公里
但這其實已經不是這次分析建議的操作了。
所以這類預填資料會被當成一次性的 Navigation Params。
流程是:
收到 coachPrefill
↓
套用到表單
↓
標記已使用
↓
清除 coachPrefill
這樣它只會影響「從分析建議進入的這一次」。
使用者之後正常打開推薦路線頁,仍然使用原本的預設值。
這次只是多了一條新的入口:
首頁
↓
AI 散步分析
↓
推薦路線
原本的入口仍然存在:
首頁
↓
推薦路線
兩者最後都進同一個 RecommendedScreen。
差別只有:
一般入口
→ 使用原本的預設值
分析建議入口
→ 額外套用一次預填值
後面的路線產生、候選路線、評分和顯示方式全部不變。
因此不需要再建立一個新的:
AIRecommendedScreen
也不需要為 AI 分析維護另一份推薦路線 state。
當使用者確認條件之後,後面完全不需要 AI 參與,仍然是原本的流程,AI 只負責前面的「建議」。
真正的路線產生仍然交給原本的推薦路線系統。
這樣做的好處是,AI 不會變成整個散步功能的核心依賴。
即使 AI 暫時無法使用,原本的推薦路線仍然可以正常運作。
做到這裡,整個流程會變成:
完成散步
↓
分析這一次發生了什麼
↓
累積可靠散步紀錄
↓
決定下一次適合怎麼調整
↓
產生 Target
↓
預填推薦路線
↓
使用者確認 / 修改
↓
原本的推薦路線流程
↓
開始下一次散步
整個 App 的功能到現在就差不多結束了,明後天會分享的是省電策略以及無障礙的部分。