1 of 21

旅遊推薦系統各部位功能建置

五個部位 :

  1. line 端 ( 澎澎 )
  2. LLM 端 (澎澎)
  3. 向量搜尋 (石頭)
  4. 結構搜 (瑜庭)
  5. 旅遊演算法 (啓舜)

主程式 -> 各部位連接:

  1. main.py ( 啓瞬 )

注意事項:

  1. 每個方框都是一個 function
  2. 內部內容、順序、type不可更動,必須符合規範
  3. 各部位務必再確認接收參數的部位是否符合要求

2 of 21

  1. line 端 ( 澎澎 )

Line 端

type : str�(使用者問題 字串)

type : str�位置 : 本機記憶體(使用者問題 字串)

Line 端

flex message x3�(泡泡訊息)

注意事項:

  1. n 非定值,要是可彈性的泡泡
  2. 1-2 的交通時間 會放在 2

1

4

-

-

type : List [ Dict ]�(旅遊演算)�

= [

{

"name": “unknown",

"start_time": "00:00",

"end_time": "00:00",

"duration": int, # 停留時間

"hours": {'end': '23:59', 'start': '00:00'}, # 營業時間

"label": "起點|終點|資料庫其餘label",

"route_info":{...}, # 導航

"route_url" :"url", # 導航url

"step": int, # 第幾個點位

"transport": {

"mode": "大眾運輸" | "開車" | "騎自行車" | "步行",

"time": 0,

"period": "00:00-00:00"

"travel_distance": float

},

{ ... },

…,

{ ... }

]

3 of 21

2. LLM 端 ( 澎澎 )

LLM 端

type : str�(使用者問題 字串)

type : List [ Dict ] =

[ {上午 : "形容客戶行程的一句話" },

{ 中餐 : "形容客戶行程的一句話"},

{ 下午 : "形容客戶行程的一句話"},

{ 晚餐 : "形容客戶行程的一句話"},

{ 晚上 : "形容客戶行程的一句話" }]

(旅遊各時段形容詞)�

type : List [ Dict : int | str | none ] =

[{ 出發時間 : “00:00” | ”none”,

結束時間 : “00:00” | ”none”,

出發地點 : str | “none”,

結束地點 : str | “none”,

交通方式 : "大眾運輸" | "開車" | "騎車" | "步行",

可接受距離門檻(KM) : int|”none”,

早餐時間 : "00:00" | “none”,� 午餐時間 : "00:00" | “none”,

晚餐時間 : "00:00" | “none”,

預算 : int | “none”,

出發日 : “mm-dd” | "none”}]

(客戶基本要求,若沒給則給none)�

1

b

c

a

type : List [ Dict ]

= [{'內用座位' : true|false , � '洗手間' : true|false , � '適合兒童' : true|false , � '適合團體' : true|false , � '現金' : true|false , � '其他支付' : true|false , � '收費停車' : true|false , � '免費停車' : true|false , � 'wi-fi' : true|false , � '無障礙' : true|false }]

(確認是否具有特殊要求)�

4 of 21

3. 向量搜尋端 ( 石頭 )

向量搜尋

type : Dict

= { "上午" : "形容客戶行程的一句話"}

type :

= { period : [“PlaceID”, “PlaceID", …, "PlaceID"]} � � # period = lunch|dinner|morning|afternoon|night

會有五包

a

2

5 of 21

4. 結構搜尋端 ( 瑜庭 )

結構搜尋

type : List [ Dict ]

= [{'內用座位' : true|false , � '洗手間' : true|false , � '適合兒童' : true|false , � '適合團體' : true|false , � '現金' : true|false , � '其他支付' : true|false , � '收費停車' : true|false , � '免費停車' : true|false , � 'wi-fi' : true|false , � '無障礙' : true|false }]

(確認是否具有特殊要求)�

type : List [ Dict ]

= [{

place_id : "str",

name : “店名1”,

rating : float,

lat : float,

lon : float,

label_type : str # 大分類

label : str # 小分類,

hours : { 1: [{'start': '14:30', 'end': '21:00'}],

2: [{'start': '14:30', 'end': '21:00'}],

3: 'none',

4: [{'start': '14:30', 'end': '21:00'}],

5: [{'start': '14:30', 'end': '21:00'}],

6: [{'start': '14:30', 'end': '21:00'}],

7: [{'start': '14:30', 'end': '21:00'}] },

period: lunch|dinner|morning|afternoon|night

url : “ ” # googlemap url },

{placeID : "str", name : “店名2”,…, url : “ “ },

….,

{placeID : "str", name : “店名N”,…, url : “ “ }

}]

( 輸出各店鋪基本資訊 ) 加入餐廳與景點篩選

b

2

3

type :

= { morning: [“PlaceID”, “PlaceID", …, "PlaceID"],

lunch: [“PlaceID”, “PlaceID", …, "PlaceID"],

afternoon: [“PlaceID”, “PlaceID", …, "PlaceID"],

dinner: [“PlaceID”, “PlaceID", …, "PlaceID"],

night: [“PlaceID”, “PlaceID", …, "PlaceID"],}

會有五包

6 of 21

5. 旅遊演算法 ( 啓舜 )

Trip

type : List [ Dict : int | str | none ]

= [{ 出發時間 : “00:00” | ”none”,

結束時間 : “00:00” | ”none”,

出發地點 : str | “none”,

結束地點 : str | “none”,

交通方式 : "大眾運輸" | "開車" | "騎自行車" | "步行",

可接受距離門檻(KM) : int| “none”,

早餐時間 : "00:00" | “none”,� 午餐時間 : "00:00" | “none”,

晚餐時間 : "00:00" | “none”,

預算 : int | “none”,

出發日 : “mm-dd” | "none”}]

(客戶基本要求,若沒給則給none)�

type : List [ Dict ]�(旅遊演算)�

= [

{

"name": “unknown",

"start_time": "00:00",

"end_time": "00:00",

"duration": int, # 停留時間

"hours": {'end': '23:59', 'start': '00:00'}, # 營業時間

"label": "起點|終點|資料庫其餘label",

"route_info":{...}, # 導航

"route_url" :"url", # 導航url

"step": int, # 第幾個點位

"transport": {

"mode": "大眾運輸" | "開車" | "騎自行車" | "步行",

"time": 0,

"period": "00:00-00:00"

"travel_distance": float

},

{ ... },

…,

{ ... }

]

c

3

4

EXAMPLE :DEFAULT_REQUIREMENT = {

"start_time": None,

"end_time": "21:00",

"start_point": "中壢火車站",

"end_point": None,

"transport_mode": "driving",

"distance_threshold": 30,

"breakfast_time": None,

"lunch_time": None,

"dinner_time": "18:00",

"budget": None,

"date": None

}

type : List [ Dict ]

= [{

place_id : "str",

name : “店名1”,

rating : float,

lat : float,

lon : float,

label_type : str # 大分類

label : str # 小分類,

hours : { 1: [{'start': '14:30', 'end': '21:00'}],

2: [{'start': '14:30', 'end': '21:00'}],

3: 'none',

4: [{'start': '14:30', 'end': '21:00'}],

5: [{'start': '14:30', 'end': '21:00'}],

6: [{'start': '14:30', 'end': '21:00'}],

7: [{'start': '14:30', 'end': '21:00'}] },

period: lunch|dinner|morning|afternoon|night

url : “ ” # googlemap url },

{placeID : "str", name : “店名2”,…, url : “ “ },

….,

{placeID : "str", name : “店名N”,…, url : “ “ }

}]

( 輸出各店鋪基本資訊 ) 加入餐廳與景點篩選

7 of 21

主程式端. main.py( 啓舜 )

Line 端

LLM 端

向量搜尋

結構搜尋

Trip

Line 端

(旅遊各時段形容詞)

(確認是否具有特殊要求)

(客戶基本要求,若沒給則給none)

1

a

b

c

2

3

4

(使用者問題 字串)

(店名集合)

( 輸出各店鋪基本資訊 )

(旅遊演算)

8 of 21

情境搜索系統各部位建置

五個部位 :

  • line 端 ( 澎澎 )
  • LLM 端 (澎澎)
  • 向量搜尋 (石頭)
  • 結構搜 (瑜庭)
  • 情境搜尋演算法 ( 瑜庭 )

主程式 -> 各部位連接:

  • main.py ( 家瑋 )

9 of 21

  • line 端 ( 澎澎 )

Line 端

type : str�(使用者問題 字串)

type : str�位置 : 本機記憶體�(使用者問題 字串)

Line 端

flex message x3�(泡泡訊息)

type : List [ Dict ]�(情境檢索)

= [{

placeID : { name : "店名1",

rating : float,

address: str,

url : " "} ,

placeID : { name : "店名2",

rating : float,

address: str,

url : " "} ,

placeID : { name : "店名3",

rating : float,

address: str,

url : " "}

}]

-

-

1

5

10 of 21

2. LLM 端 (澎澎)

LLM 端

type : str�(使用者問題 字串)

type: List

= ["形容客戶行程的一句話"]

格式轉換

type : List [ Dict ] = X 10

[{

placeID : { name : "店名1",

rating : float,

address: str,

url : " "} ,

placeID : { name : "店名2",

rating : float,

address: str,

url : " "} ,

placeID : { name : "店名3",

rating : float,

address: str,

url : " "}

}]

1

b

c

a

4

5

type : List [ Dict ]

= [{'內用座位' : true|false , � '洗手間' : true|false , � '適合兒童' : true|false , � '適合團體' : true|false , � '現金' : true|false , � '其他支付' : true|false , � '收費停車' : true|false , � '免費停車' : true|false , � 'wi-fi' : true|false , � '無障礙' : true|false }]

(確認是否具有特殊要求)�

type: List [ Dict : int | str | none ]

= [{

星期別: int | "none" # 1-7

時間: "hh:mm" | "none",

類別: 餐廳 | 咖啡廳 | 小吃 | 景點

預算: int | "none",

出發地 : str | “none” # 台北車站|自己的經緯度

可接受距離門檻(KM) : int| “none”

交通方式 : "大眾運輸" | "開車" | "騎自行車" | "步行"

}]

(客戶基本要求資料)

type : List [ Dict ] = X 10

[{ placeID : "str"

name : "店名1",

rating : float,

num_comments: int,

total_commets: str

hours : { 1: [{'start': '14:30', 'end': '21:00'}],

2: [{'start': '14:30', 'end': '21:00'}],

3: 'none',

4: [{'start': '14:30', 'end': '21:00'}],

5: [{'start': '14:30', 'end': '21:00'}],

6: [{'start': '14:30', 'end': '21:00'}],

7: [{'start': '14:30', 'end': '21:00'}] },

avg_cost: int, },

{placeID : "str", name : "店名2",…},

….,

{placeID : "str", name : "店名N",…},

]

11 of 21

3. 向量搜尋端 ( 石頭 )

向量搜尋

type : List[Dict]

= [{

"Place ID 1":{"分數":"int"} , # 相似分數

"Place ID 2":{"分數":"int"} ,

…,

"Place ID n":{"分數":"int"}

}]

a

2

type: List

= ["形容客戶行程的一句話"]

前置作業 : 輸出成CSV檔

篩選整理評論放進結構資料庫

分數 :

環境 : 9

食物 : 7

服務 : 6

總分 : 7.5

12 of 21

4. 結構搜尋端 ( 瑜庭 )

結構搜尋

type : List [ Dict ] =

[{

placeID : { name : "店名1",

rating : float,

num_comments: int,

lat : float,

lon : float,

label : str,

price: int,

address: str,

url : " "} ,

placeID : { name : "店名2",…, price: url},

….,

placeID : { name : "店名N",…, price: url}

}]

b

2

3

type : List[Dict]

= [{

"Place ID 1":{"分數":"int"} , #相似分數

"Place ID 2":{"分數":"int"} ,

…,

"Place ID n":{"分數":"int"}

}]

type : List [ Dict ]

= [{'內用座位' : true|false , � '洗手間' : true|false , � '適合兒童' : true|false , � '適合團體' : true|false , � '現金' : true|false , � '其他支付' : true|false , � '收費停車' : true|false , � '免費停車' : true|false , � 'wi-fi' : true|false , � '無障礙' : true|false }]

(確認是否具有特殊要求)�

type : List [ Dict ]

=[

{ 'placeID' : str,

'place_name' : '店名1',

'rating' : 1-5, # googlemap 星數

'retrival_score' : float, # 向量分數

'comments' : int # 評論數

'lat' : float,

'lon' : float,

'new_label_type' : str # 大分類

'hours' : {

1: [{'start': '14:30', 'end': '21:00'}],

2: [{'start': '14:30', 'end': '21:00'}],

3: 'none',

4: [{'start': '14:30', 'end': '21:00'}],

5: [{'start': '14:30', 'end': '21:00'}],

6: [{'start': '14:30', 'end': '21:00'}],

7: [{'start': '14:30', 'end': '21:00'}]

},

'new_avg_cost' : int, # 新價格(清理過)

location_url : https://example.com # googlemap url

image_url : https://example.com

},

{'placeID' : 'str', 'place_name' : '店名2',…},

….,

{'placeID' : 'str', 'place_name' : '店名N',…} }

]( 輸出各店鋪基本資訊 )�

13 of 21

5. 情境搜尋演算法 ( 瑜庭 )

plan

type : List [ Dict ] = X 10

[{ placeID : "str"

name : "店名1",

rating : float,

num_comments: int,

total_commets: str,

adress: str,

hours : { 1: [{'start': '14:30', 'end': '21:00'}],

2: [{'start': '14:30', 'end': '21:00'}],

3: 'none',

4: [{'start': '14:30', 'end': '21:00'}],

5: [{'start': '14:30', 'end': '21:00'}],

6: [{'start': '14:30', 'end': '21:00'}],

7: [{'start': '14:30', 'end': '21:00'}] },

avg_cost: int, },

{placeID : "str", name : "店名2",…},

….,

{placeID : "str", name : "店名N",…},

]

c

3

4

type: List [ Dict : int | str | none ]

= [{

星期別: int | "none" # 1-7

時間: "hh:mm" | "none",

類別: 餐廳 | 咖啡廳 | 小吃 | 景點| 'none'

預算: int | "none",

出發地點 : (lon, lat) # 台北車站|自己的經緯度(一定要經緯度 or “none”)

可接受距離門檻(KM) : int| “none”

交通類別 : "大眾運輸" | "開車" | "騎自行車" | "步行"

}]

(客戶基本要求資料)

要額外加入 total comments 傳遞

type : List [ Dict ]

=[

{ 'placeID' : str,

'place_name' : '店名1',

'rating' : 1-5, # googlemap 星數

'retrival_score' : float, # 向量分數

'comments' : int # 評論數

'lat' : float,

'lon' : float,

'new_label_type' : str # 大分類

'hours' : {

1: [{'start': '14:30', 'end': '21:00'}],

2: [{'start': '14:30', 'end': '21:00'}],

3: 'none',

4: [{'start': '14:30', 'end': '21:00'}],

5: [{'start': '14:30', 'end': '21:00'}],

6: [{'start': '14:30', 'end': '21:00'}],

7: [{'start': '14:30', 'end': '21:00'}]

},

'new_avg_cost' : int, # 新價格(清理過)

location_url : https://example.com # googlemap url

image_url : https://example.com

},

{'placeID' : 'str', 'place_name' : '店名2',…},

….,

{'placeID' : 'str', 'place_name' : '店名N',…} }

]( 輸出各店鋪基本資訊 )�

14 of 21

主程式端. recommendation_service.py( 家瑋 )

Line 端

LLM 端

向量搜尋

結構搜尋

Plan

Line 端

X 100

-

1

b

c

a

2

3

Plan

MongoDB

a

b

c

1

格式轉換

X 10

X 10

4

5

格式轉換變數

query_info

6

: Line_user_id跟place_id

6

6

15 of 21

主程式端 recommendation_service_rerun.py追加function( 家瑋 )

MongoDB

(recommend_unsatisfied)

向量搜尋

結構搜尋

Plan

Line 端

格式轉換

X 100

X 10

X 10

b

c

a

BL

3

4

5

"black_list": {place1, place2, place3} // 用戶不滿意的推薦地點結果

2

BL

MongoDB

格式轉換變數

6

a

b

c

1

重跑必備資料

6

16 of 21

git 分支

master

integration

develop

feature/function_name 分支開發

1. 澎澎

* `feature/line` : Line 端各功能開發

2. 澎澎

* `feature/LLM` : LLM 端各功能開發

3. 石頭

* `feature/retrival` : 向量搜尋功能開發

4. 瑜庭

* `feature/SQL` : 關聯式搜尋功能開發

* `feature/plan` : 情境搜尋演算法開發

5. 家偉

* `feature/main_plan` : 情境搜尋演算法 main 建置

6. 啓舜

* `feature/trip` : 旅遊演算法功能開發

* `feature/main_trip` : 旅遊演算法 main 建置

17 of 21

master

integration

develop

feature/function_name

功能開發

hotfix

release

master & develop :

Branch rules:

  1. Restrict creations
  2. Restrict updates
  3. Restrict deletions
  4. Block force pushes

Bypass list

  1. Repository admin

18 of 21

feature/function_name 分支開發

1. 澎澎

* `feature/line` : Line 端各功能開發

2. 澎澎

* `feature/LLM` : LLM 端各功能開發

3. 石頭

* `feature/retrival` : 向量搜尋功能開發

4. 瑜庭

* `feature/SQL` : 關聯式搜尋功能開發

* `feature/plan` : 情境搜尋演算法開發

5. 家瑋

* `feature/main_plan` : 情境搜尋演算法 main 建置

6. 啓舜

* `feature/trip` : 旅遊演算法功能開發

* `feature/main_trip` : 旅遊演算法 main 建置

main_plan.py

main_trip.py

app.py 澎澎

19 of 21

情境搜索按鈕觸發邏輯(新增的3個按鈕)

按下此按鈕會將該用戶的line_user_id跟該地點的place id書出來給mongoDB

按下此按鈕會加該用戶收藏過的Location顯示出來(最多10個)

1

2

20 of 21

情境搜索按鈕觸發邏輯(新增的3個按鈕)

按下此按鈕會將相關資訊儲存起來,對於用戶那一句搜索語句去做重新演算

3

21 of 21

前端呈現 : Line

爬蟲

資料清整

前處理

應用服務

評論向量化

向量資料庫

提示工程

一日旅程規劃

用戶歷史紀錄

問答系統

情境搜索

用戶歷史紀錄

問答系統

打包部署

封裝

部屬