用AI+高德地圖MCP,3小時做出杭州美食地圖

阿里妹導讀
本文記錄了一次從靈光一現到快速落地的 AI + 地圖服務實踐,透過結合 Cursor 與高德 MCP 地圖服務平臺,作者僅用幾個小時就實現了一個可互動、可篩選、可推薦的杭州美食地圖應用。
最近刷到一篇熱帖,一位在阿里五年的同學總結了一份她這五年(吃的每一口記錄)收集的杭州美食排行榜,為“美食荒漠”正名。也讓我回憶起自己初到杭州進入團隊時也曾想整理一份“美食地圖”,卻因種種原因而作罷。逢最近團隊準備選團建的餐廳,於是立馬把這篇帖子分享給投食官。投食官仔細調研後感慨道,“這篇文章真是太好了,如果能在地圖上看到它們的位置就更好了。”
這讓我萌生了為這個美食排行榜做一個杭州美食地圖的想法,以便能快速地看到餐廳的位置並進行選擇。實現方法上 AI coding 加高德 MCP 有沒有搞頭?
文末附原始碼和專案地址供大家參考和取用。
安裝高德MCP server
過程參考 :Cursor快速接入高德MCP server
https://lbs.amap.com/api/mcp-server/gettingstarted
只需準備好你的高德 key,在 cursor 上設定裡如下配置即可。
{"mcpServers":{"amap-amap-sse":{"url":"https://mcp.amap.com/sse?key=您在高德官網上申請的key"}}}
配置好後檢查 mcpserver 的狀態,如下圖則是正常可用的。
給 AI 提需求-構建工程提示詞
1. 在當前資料夾下進行編寫專案,儘量少的建立檔案,只建立必要檔案。2. 根據給定的杭州推薦的美食店,製作一份可以預覽的美食地圖。最終的產物使用便捷的方式呈現,如使用html進行展示。3. 地圖上標註下面每個店鋪精確的位置,為每個型別的餐廳用不同的合適的圖標表示。4. 地圖採用真實的杭州市地圖。5. 點選圖示可顯示餐廳更多資訊,餐廳優勢,預約電話,推薦指數等。6. 過程中可以藉助任何工具和能力實現這一目標,如 高德MCP工具。7. 展示的店鋪已給定的為準,最終給出的資料要真實可靠。8.將下列資料,透過amp-amp-sse 的 mcpserver,製作成適配高德地圖的 json 格式資料。若沒有找到餐廳,不要編造資料,座標欄位設為空值即可。餐廳資料如下:*:主廚團隊對傳統杭幫菜的解構能力堪稱藝術,招牌魚圓彈潤如凝脂,黃酒鵝肝配牛小排的組合既有東方韻味又有西式巧思。景觀位雖為日式下沉設計,但私密性極佳,適合重要紀念日。唯一提醒:訂位時建議直接對接主理人確認細節,米其林加身後服務響應速度有提升空間。金*廳:四季酒店的鎮店之寶,時令選單每月更新,清明前的香椿嫩芽配河蝦仁、霜降後的桂花糖藕都是必嘗限定。脆皮雞的表皮酥脆度堪比藝術品,和牛炒飯的鑊氣十足,適合帶海外友人感受中式烹飪的精細度。*杯:裡園的孿生品牌,早期的黃魚鍋貼仍是教科書級別,但近年創新菜式如松茸釀飯口感層次稍顯單薄。建議避開週末午市,工作日晚間用餐能更好體會主廚團隊的匠心。集*樓:庭院裡的江南美學展,青梅鵝肝配茉莉花茶凍的創意值得點贊。近期推出的「盲盒套餐」價效比突出,適合想體驗高階杭菜又怕踩雷的新客。*溪:宋宴主題套餐需提前三天預訂,茶點與菜餚的搭配暗合二十四節氣,但每道菜量控制在2-3口剛好嚐鮮。特別推薦茶藝師現場點茶,宋代七湯點茶法視覺效果震撼。桂*房:滿覺隴店的露臺夜景是最大賣點,桂花釀醉蝦的甜度把控精準。若多人聚餐可嘗試「山房九宮格」拼盤,冷熱葷素搭配考究,但需注意部分創意菜式如黑松露貓耳朵口味較重。【浙菜】*湖:原乾朧匯班底升級之作,龍翔橋店的脆皮雞改良自港式燒味,外皮的焦糖層厚度比EFC店更均勻。推薦搭配店家自釀的青梅酒,解膩效果出眾。算*擋:濱江園區的寶藏食堂,人均150可吃到現拆的蟹粉豆腐和炭烤鰻魚。建議4人以上拼單,把招牌菜湊齊分著吃更划算。【創意菜】*:西溪溼地內的隱秘據點,荷葉包蒸東山羊是夏季限定,肉質軟爛入味。划船至碼頭需提前預約接駁船,整體體驗像私人會所。【融合菜】喬*:阿里園區周邊的老牌宴請場所,最近推出的「數字化點餐系統」可即時檢視後廚烹飪進度。推薦黑椒牛排配龍井茶湯,西式主菜與杭幫調味的結合恰到好處。略...
輸入“需求文件”後,cursor 會進入 Plan 模式進行規劃整體設計方案。
已開始為你的美食地圖收集真實的高德地圖資料。以下是實現方案和進度說明:實現方案資料收集:為每個餐廳透過高德地圖API檢索真實的地理位置(經緯度)、地址、照片等資訊。若未找到則座標為空。資料格式:整理為適配高德地圖MCPJSON格式,包含必要的欄位(如名稱、型別、座標、推薦指數、電話、優勢等)。地圖展示:最終生成一個HTML檔案,使用高德地圖JSAPI進行視覺化。不同型別餐廳用不同圖示,點選可彈窗顯示詳細資訊。檔案結構:只建立必要的檔案(如index.html和資料JSON),保證專案簡潔。進度說明已完成“如*”“金*廳”真實資料檢索,獲取了精確座標和相關資訊。正在依次為所有餐廳檢索真實資料,確保資料可靠。檢索不到的餐廳將座標設為空,不會編造資訊。請確認:是否需要為每家餐廳都補充“推薦指數、預約電話、優勢”等欄位?如無公開資料,是否允許留空或用描述性文字?是否需要將所有資料單獨匯出為JSON檔案,還是直接嵌入HTML中?如無異議,將繼續批次檢索並整理資料,隨後生成地圖預覽HTML。你可隨時檢視進度或指定展示細節。
十幾分鍾寫完“需求文件”,晚飯時間到,提給 AI 讓它先寫著,我們去吃飯~
AI coding-開始尋找杭州美食之旅
呼叫高德 MCP Server-獲取餐廳準確位置和資訊

第一輪-模糊查詢找到候選餐廳

AI 會先呼叫高德 MCP Server 的 maps_text_search 方法透過模糊查詢,查到候選餐廳資訊。
輸入
{"keywords":"如院餐廳 杭州","city":"杭州","citylimit":true}
輸出
可以看到,查出了一系列餐廳,其中有如*餐廳的基本資訊,取出 id,作為下一輪的輸入。
{"pois": [    ...    {"id""B0JA5UF6R*","name""如*餐廳","address""玉泉路1*號","typecode""0501**","photo""http://store.is.autonavi.com/showpic/b08795ab6adeba25a0115d74130862**"    },     {"id""B023B019A*","name""群*飯店(信*路店)","address""濱安路119*號(近信*路)","typecode""0501**","photo""http://store.is.autonavi.com/showpic/2ac9e95efffe6e27a8eda43ef82711**"    },    ...  ],"suggestion": {"keywords""","ciytes": {"suggestion": []    }  }}

第二輪-透過 id 獲取餐廳詳情

可以看到緊接著 AI 會呼叫高德 MCP Server 的maps_search_detail能力,透過 id 來獲取餐廳詳情。
輸入
{"id":"B0JA5UF6R*"}
輸出
可以看到這裡獲取到了餐廳的詳情資訊,包含名稱、經緯度、地址、照片、營業時間、評分等。
{"id":"B0JA5UF6R*","name":"如*餐廳","location":"120.122175,30.253356","address":"玉泉路1*號","business_area":"西湖旅遊區中心片區","city":"杭州市","type":"餐飲服務;中餐廳;中餐廳","alias":"","photo":"http://store.is.autonavi.com/showpic/b08795ab6adeba25a0115d74130862a*","cost":"","opentime2":"週一至週日 11:30-14:00,17:30-21:00","rating":"4.7","open_time":"11:30-14:00 17:30-21:00","meal_ordering":"0"}
AI 會將高德 MCP Server 中獲取的資料格式化,整理到 json 檔案中,作為資料來源。
編寫頁面
資料收集完後,就開始根據需求,編寫程式碼了,透過引入高德 API 展示杭州地圖,然後將上一步整理的資料引入進來,標出餐廳的位置。並且支援點選餐廳的名稱,彈框展示餐廳的詳情,餐廳的推薦理由。
雖然沒有關注程式碼具體怎麼實現的,但是它就這樣水靈靈的工作起來了~
但我認為我們還是需要理解 AI 寫的每一行程式碼,對程式碼質量有一個評估,一方面自己能有所進步,一方面不能讓 AI 自由發揮的太過,到後面一行也看不懂,改也改不動的時候,專案就崩了。自己不理解的程式碼,可以讓 AI 為程式碼都加上註釋,方便理解。
除錯頁面
AI 寫完了主體頁面和功能點後,預覽一下,還是有挺多細節需要修改的,如名稱大小、背景框樣式、彈框點選關閉邏輯等,這些和 AI 溝通,說明需要修改的位置和要求即可,如果說不清的時候,可以直接截圖給 AI,告訴它要改什麼,理解意圖上還是十分強大的。
找素材
但是 AI 有一點不足的是不太方便從外部直接獲取資源,比如試圖讓 AI 自己去網上找合適的素材圖示,但是失敗了,它會讓我去給它下載,不然它會自己畫一個醜陋抽象的 SVG 圖示。
實在忍不了,只能去網上找素材,可以說整個過程中,花的最多的時間就是這裡了。找合適的素材,嘗試下載,要收費?換一個地方找,終於是免費的了,下載下來,傳到圖床上,變成公網可訪問的連結。
整個找素材的過程十分痛苦,如果 AI 可以自己找就好了,也許是使用的姿勢不太對,還需要繼續研究。
好在最終找到了一個非常棒的平臺,那就是阿里巴巴圖示向量庫,還是自家兄弟好,素材非常的全且好用,大力推薦。
地址:https://www.iconfont.cn/?spm=a313x.search_index.i3.d4d0a486a.2dff3a81XH4Q3q
餐廳分類與篩選
對於之前的收集的餐廳的資料,沒有一個很好的分類進行表達,於是讓AI 重新分析一下整個餐廳資料,結合餐廳的資訊,進行分類,然後將餐廳型別與圖示素材再進行一個匹配。得到一個分類好的餐廳列表,與圖示的對映關係。
然後就可以愉快的讓 AI 結合這個分類資料,改寫一下餐廳的圖示啦,並且基於分類,再加上了圖例列表,和篩選項的功能,方便展示,不然 100個餐廳全部展示在地圖上,也不太方便小夥伴們看。
然後頁面的效果如下:
AI 推薦餐廳
看了地圖上標註的餐廳後,才發現,離自己園區的距離都比較遠,於是含淚再寫一份自己團隊的聚餐選點指南,讓 AI 幫助推薦餐廳。
1. 在當前專案中進行改進,刪去圖例、篩選項功能。2. 使用給出的餐廳資料,在地圖上進行標註。3. 我們的出發位置是杭州市阿里巴巴濱江園區,標註出發點位置,用星星圖標表示。4. 圖示素材在 resource/icon.txt中.5. 計算出發點到各個餐廳的位置,在地圖上用線連起來進行展示。6. 分析一下各個餐廳的優劣,離出發點的距離,交通方式,和所需時間,周邊配套,列在餐廳詳情裡。7. 最後進行一個智慧總結,推薦一個餐廳8.9. 過程中可以藉助任何工具和能力實現這一目標,如 高德MCP工具。10. 展示的店鋪已給定的為準,最終給出的資料要真實可靠。將下列資料,透過amp-amp-sse 的 mcpserver,製作成適配高德地圖的 json 格式資料。若沒有找到餐廳,不要編造資料,座標欄位設為空值即可。1. 海*撈中南樂遊城店2. 黃*海鮮大排檔(長河地鐵站旁)3. 群*飯店4. 龍*·濱江烤全羊(杭州總店)dong'da5. 東*方保利時光裡店
有了前面的基礎,這次 20 分鐘就搞定了,主要在寫需求文件和微調頁面樣式上,可以分析一下各個餐廳的優劣,離出發點的距離,交通方式,和所需時間,周邊配套等。 最後進行一個智慧總結,推薦一個餐廳,效果如下:
小夥伴們就可以愉快的進行決策,到底選哪個餐廳了~
新的功能正在和我們投食官持續最佳化中,比如先選擇團建地方,再選擇聚餐地方,多個地點讓 AI 分析推薦等~
釋出與部署
公網部署方法挺多的,比如 GitHub、Gitee上提供了靜態頁面部署的能力,或者可以租一個阿里雲伺服器申請域名,搭建自己的網站。
在 GitHub 部署靜態頁面的簡要指南
以下為 GitHub Pages 靜態部署的核心步驟,基於官方文件和工具鏈實現:

1.建立倉庫

  • 新建公共倉庫,命名格式為username.github.iousername為你的 GitHub 使用者名稱)
  • 克隆倉庫到本地,新增靜態檔案(如index.html),並推送至main分支

2. 配置釋出源

  • 進入倉庫Settings > Pages,選擇釋出分支(如maingh-pages)或docs資料夾作為源
  • 若使用自定義構建工具(如 Hugo、Vue 等),需停用預設 Jekyll 構建:在源目錄根路徑建立空檔案.nojekyll

3. 使用 GitHub Actions 自動部署

  • 在工作流配置檔案(如.github/workflows/deploy.yml)中新增以下步驟:
- name: Deploy to GitHub Pages    uses: peaceiris/actions-gh-pages@v3    with:      github_token: ${{ secrets.GITHUB_TOKEN }}      publish_dir: ./public  # 替換為你的構建輸出目錄
此 Action 會將指定目錄內容部署到gh-pages分支

4.訪問頁面

  • 頁面地址為https://username.github.io,更新後通常需等待 1-10 分鐘生效。

5. 注意事項

  • 許可權問題:若使用 GitHub Actions 推送,需確保管理員已驗證郵箱並推送過程式碼
  • 符號連結:倉庫含符號連結時,需透過 GitHub Actions 部署。
最後
這次的實踐我認為還是非常的有趣的,整個開發過程大概 3-4 小時,而且主要花在了找素材和調整樣式上了。放在以前,有了一個好的點子,但是可能會因為麻煩,跨技術棧,生產週期長、拖延症等各種因素導致“創業未半而中道崩殂”。
不得不感嘆,AI 真的能幫助人們提高效率,並且使之前不可能或者很難完成的事情變得可行。在 AI 時代,可能需要從之前傳統的“關注技術棧和專業,關注如何實現”的思維轉向聚焦到“擴充套件思維的寬度和認知,尋找事物的可達路徑”上。
另外,高德的小夥伴是否考慮一下,增加一個餐廳、團建的地點投票功能~
可以在高德上發起投票,錄入幾個候選位置,邀請小夥伴們一起投票。可以很方便的檢視當前位置(或者出發地點)距離候選地點的距離、交通方式和用時、候選地點周邊配套等。 也可以讓 AI 結合需求背景,總結一下各候選地點的優勢。然後小夥伴們就可以愉快地投票了!

附錄

原始碼如下,需要的小夥伴可自取,在這個基礎上改改就能用了。
杭州美食地圖
<!DOCTYPE html><htmllang="zh-CN"><head><metacharset="UTF-8"><title>杭州美食地圖</title><metaname="viewport"content="width=device-width, initial-scale=1.0"><style>htmlbody#map { height100%margin0padding0; }.amap-info-content { font-size14px; }.legend {position: absolute;top10px;left10px;backgroundrgba(255,255,255,0.9);border-radius6px;padding10px;box-shadow02px8pxrgba(0,0,0,0.15);z-index1000;    }.legend-item { display: flex; align-items: center; margin-bottom6px; }.legend-icon { width20pxheight20pxmargin-right6px; }.marker-label {font-size16px;color#fff;backgroundrgba(34,34,34,0.75);border-radius6px;padding2px10px;box-shadow02px8pxrgba(0,0,0,0.15);white-space: nowrap;transition: background 0.2s;border: none;    }.marker-label-hover {backgroundrgba(34,34,34,0.95);color#ffe58f;border: none;    }/* 強制覆蓋高德地圖label的藍色邊框和背景 */.amap-marker-label {border: none !important;box-shadow: none !important;background: none !important;padding0!important;    }.filter-panel {position: absolute;top40px;right20px;width220px;backgroundrgba(255,255,255,0.97);border-radius10px;box-shadow02px16pxrgba(0,0,0,0.13);padding18px18px12px18px;z-index1200;font-family'PingFang SC''Microsoft YaHei', Arial, sans-serif;font-size15px;color#222;transition: box-shadow 0.2s;max-height600px;overflow-y: auto;    }.filter-title {font-size18px;font-weight: bold;margin-bottom12px;letter-spacing2px;    }.filter-section { margin-bottom14px; }.filter-label { font-size14pxmargin-bottom6pxcolor#666; }.filter-recommendlabel.filter-categorylabel {display: inline-block;margin-right10px;margin-bottom6px;cursor: pointer;font-size14px;    }.filter-category {max-height280px;overflow-y: auto;border-radius6px;background#f7f7f7;padding6px4px4px8px;border1px solid #eee;    }.filter-categorylabel { width120px; }.filter-panelinput[type="checkbox"] {      accent-color#1890ff;margin-right3px;vertical-align: middle;    }</style><!-- 高德地圖 JS API --><scriptsrc="https://webapi.amap.com/maps?v=2.0&key=「你的高德 apikey」"></script></head><body><divid="map"></div><divclass="legend"id="legend"></div><divid="filter-panel"class="filter-panel"><divclass="filter-title">杭州美食指南</div><divclass="filter-section"><divclass="filter-label">推薦指數</div><divclass="filter-recommend"><label><inputtype="checkbox"name="recommend"value="5"> 5星</label><label><inputtype="checkbox"name="recommend"value="4"> 4星</label><label><inputtype="checkbox"name="recommend"value="3"> 3星</label><label><inputtype="checkbox"name="recommend"value="2"> 2星</label><label><inputtype="checkbox"name="recommend"value="1"> 1星</label></div></div><divclass="filter-section"><divclass="filter-label">餐廳類別</div><divclass="filter-category"id="filter-category-list"></div></div></div><script>// 餐廳資料直接嵌入或讀取同級目錄下檔案都可const data =  [  {"name""如*餐廳","type""中餐廳","location""120.122175,30.253356","address""玉泉路1*號","photo""http://store.is.autonavi.com/showpic/b08795ab6adeba25a0115d74130862aa","cost""","open_time""11:30-14:00 17:30-21:00","rating""4.7","phone""","advantage""推薦理由 xxxx","recommend_index""5","category""中餐"  },  {"name""杭州**湖四季酒店金沙廳","type""浙江菜","location""120.129637,30.251887","address""靈隱路5號杭州**湖四季酒店1層(近麴院風荷)","photo""http://store.is.autonavi.com/showpic/03f435393b04359460529d3cc484e826","cost""533.00","open_time""11:30-14:00 17:30-21:00","rating""4.8","phone""","advantage""推薦理由 xxxx","recommend_index""5","category""杭幫菜/浙江菜"  },  {"name""門沒鎖咖啡館","type""咖啡館","location""120.099355,30.297518","address""政紫弄23幢**號沿街(**地鐵站F口步行210米)","photo""https://aos-comment.amap.com/B0KUPD8084/comment/A241830B_F0B4_4496_A253_95A1F5385C51_L0_001_1500_2000_1735672012627_76019873.jpg","cost""","open_time""10:00-17:00","rating""4.3","phone""","advantage""推薦理由 xxxx","recommend_index""4","category""咖啡館"  }  {"name""helloworld","type""咖啡館","location""120.005480,30.280547","address""歐美金融城西溪麗晶居*幢底商1-13號","photo""http://store.is.autonavi.com/showpic/72efe174477c732d4264f7373dfaf768","cost""30.00","open_time""08:00-18:00","rating""4.3","phone""","advantage""推薦理由 xxxx","recommend_index""4","category""咖啡館"  }];// 圖示對映表,按最新icon.txtconst typeIcons = {'辣椒''「需要自己準備」','甜點''「需要自己準備」','咖啡''「需要自己準備」','中餐''「需要自己準備」','日料''「需要自己準備」','快餐''「需要自己準備」','烤肉''「需要自己準備」','燒烤''「需要自己準備」','星星''「需要自己準備」','火鍋''「需要自己準備」','牛排''「需要自己準備」','麵食''「需要自己準備」','海鮮''「需要自己準備」','韓餐''「需要自己準備」','小吃''「需要自己準備」','粵菜''「需要自己準備」','default''「需要自己準備」'    };// 圖例分類,按icon.txt順序const legendTypes = [      {type'中餐'label'中餐/杭幫菜/其他'},      {type'粵菜'label'粵菜'},      {type'辣椒'label'川菜'},      {type'火鍋'label'火鍋'},      {type'燒烤'label'燒烤'},      {type'烤肉'label'烤肉'},      {type'日料'label'日料'},      {type'韓餐'label'韓餐'},      {type'牛排'label'西餐'},      {type'麵食'label'麵館/麵食'},      {type'小吃'label'小吃'},      {type'甜點'label'甜品/飲品'},      {type'咖啡'label'咖啡館'},      {type'快餐'label'快餐'},      {type'海鮮'label'海鮮'}    ];// category到icon的對映規則functiongetCategoryIcon(category){if (!category) return typeIcons['default'];if (category === '中餐' || category === '杭幫菜/浙江菜' || category === '湘菜' || category === '東北菜' || category === '素食' || category === '私房菜'return typeIcons['中餐'];if (category === '粵菜'return typeIcons['粵菜'];if (category === '川菜'return typeIcons['辣椒'];if (category === '火鍋'return typeIcons['火鍋'];if (category === '燒烤/烤肉'return typeIcons['烤肉'];if (category === '燒烤'return typeIcons['燒烤'];if (category === '日料'return typeIcons['日料'];if (category === '韓餐'return typeIcons['韓餐'];if (category === '西餐'return typeIcons['牛排'];if (category === '麵館'return typeIcons['麵食'];if (category === '小吃'return typeIcons['小吃'];if (category === '甜品/飲品'return typeIcons['甜點'];if (category === '咖啡館'return typeIcons['咖啡'];if (category === '快餐'return typeIcons['快餐'];if (category === '海鮮'return typeIcons['海鮮'];return typeIcons['default'];    }// 初始化地圖    constmap = newAMap.Map('map', {center: [120.1550730.274085], // 杭州中心zoom12    });// 移除所有 data.forEach(...) 相關的marker渲染,只保留 renderMarkers() 控制// ... existing code ...// 圖例渲染const legend = document.getElementById('legend');    legend.innerHTML = legendTypes.map(t =>`<div class="legend-item"><img class='legend-icon' src='${typeIcons[t.type]}' alt='${t.label}' />${t.label}</div>`    ).join('');// InfoWindow全域性變數let infoWindow = null;// label樣式const style = document.createElement('style');    style.innerHTML = `      .marker-label {        font-size: 16px;        color: #fff;        background: rgba(34,34,34,0.75);        border-radius: 6px;        padding: 2px 10px;        box-shadow: 02px 8px rgba(0,0,0,0.15);        white-space: nowrap;        transition: background 0.2s;        border: none;      }      .marker-label-hover {        background: rgba(34,34,34,0.95);        color: #ffe58f;        border: none;      }      /* 強制覆蓋高德地圖label的藍色邊框和背景 */      .amap-marker-label {        border: none !important;        box-shadow: none !important;        background: none !important;        padding: 0 !important;      }    `;document.head.appendChild(style);// 動態生成類別篩選項const allCategories = Array.from(newSet(data.map(d => d.category).filter(Boolean)));const filterCategoryList = document.getElementById('filter-category-list');    filterCategoryList.innerHTML = allCategories.map(cat =>`<label><input type='checkbox' name='category' value='${cat}'> ${cat}</label>`    ).join('');// 預設勾選5星document.querySelector('input[name="recommend"][value="5"]').checked = true;// 篩選邏輯functiongetSelectedRecommends() {returnArray.from(document.querySelectorAll('input[name="recommend"]:checked')).map(i => i.value);    }functiongetSelectedCategories(){returnArray.from(document.querySelectorAll('input[name="category"]:checked')).map(i => i.value);    }let allMarkers = [];functionrenderMarkers(){// 清除舊marker      allMarkers.forEach(m => m.setMap(null));      allMarkers = [];const selectedRecommends = getSelectedRecommends();const selectedCategories = getSelectedCategories();let filtered = data;// 取交集策略:都選了才展示if (selectedRecommends.length) {        filtered = filtered.filter(d => selectedRecommends.includes(d.recommend_index));      }if (selectedCategories.length) {        filtered = filtered.filter(d => selectedCategories.includes(d.category));      }// 如果都沒選,展示全部if (!selectedRecommends.length && !selectedCategories.length) {        filtered = data;      }      filtered.forEach(item => {if (!item.locationreturn;const [lng, lat] = item.location.split(',').map(Number);const iconUrl = getCategoryIcon(item.category);const marker = newAMap.Marker({position: [lng, lat],iconnewAMap.Icon({image: iconUrl,sizenewAMap.Size(3232),imageSizenewAMap.Size(3232)          }),title: item.name,offsetnewAMap.Pixel(-16, -36),label: {content`<span class='marker-label'>${item.name}</span>`,direction'top',offsetnewAMap.Pixel(0, -16),clickabletrue          }        });        marker.on('mouseover'() => marker.setLabel({ ...marker.getLabel(), content`<span class='marker-label marker-label-hover'>${item.name}</span>` }));        marker.on('mouseout'() => marker.setLabel({ ...marker.getLabel(), content`<span class='marker-label'>${item.name}</span>` }));        marker.on('click'() =>showInfo(item));        marker.on('labelClick'() =>showInfo(item));        marker.setMap(map);        allMarkers.push(marker);      });    }// 監聽篩選項變化document.querySelectorAll('.filter-panel input[type="checkbox"]').forEach(input => {      input.addEventListener('change', renderMarkers);    });// 初始化時渲染一次renderMarkers();functionshowInfo(item){// 關閉已有 infoWindowif (infoWindow) {        infoWindow.close();      }// 構建詳情內容const content = `        <div style="min-width:220px;max-width:320px;">          <div style="font-size:18px;font-weight:bold;margin-bottom:6px;">${item.name}</div>          <div style="margin-bottom:4px;">${item.address ? '📍 ' + item.address : ''}</div>${item.photo ? `<img src="${item.photo}" style="width:100%;max-height:120px;object-fit:cover;border-radius:6px;margin-bottom:6px;">` : ''}          <div>型別:${item.category || item.type || ''}</div>          <div>推薦指數:${item.recommend_index || ''}</div>          <div>評分:${item.rating || ''}</div>          <div>人均:${item.cost ? '¥' + item.cost : ''}</div>          <div>營業時間:${item.open_time || ''}</div>          <div>電話:${item.phone || ''}</div>          <div style="margin-top:4px;">${item.advantage || ''}</div>        </div>      `;// 取座標const [lng, lat] = item.location.split(',').map(Number);      infoWindow = newAMap.InfoWindow({        content,offsetnewAMap.Pixel(0, -36)      });      infoWindow.open(map, [lng, lat]);    }// 點選地圖空白處關閉詳情彈窗    map.on('click'function() {if (infoWindow) infoWindow.close();    });</script></body></html>
“去哪吃”原始碼
<!DOCTYPE html><htmllang="zh-CN"><head><metacharset="UTF-8"><title>去哪吃-AI推薦餐廳</title><metaname="viewport"content="width=device-width, initial-scale=1.0"><style>htmlbody#map { height100%margin0padding0; }.amap-info-content { font-size14px; }.legend {position: absolute;top10px;left10px;backgroundrgba(255,255,255,0.9);border-radius6px;padding10px;box-shadow02px8pxrgba(0,0,0,0.15);z-index1000;    }.legend-item { display: flex; align-items: center; margin-bottom6px; }.legend-icon { width20pxheight20pxmargin-right6px; }.marker-label {font-size16px;color#fff;backgroundrgba(34,34,34,0.75);border-radius6px;padding2px10px;box-shadow02px8pxrgba(0,0,0,0.15);white-space: nowrap;transition: background 0.2s;border: none;    }.marker-label-hover {backgroundrgba(34,34,34,0.95);color#ffe58f;border: none;    }/* 強制覆蓋高德地圖label的藍色邊框和背景 */.amap-marker-label {border: none !important;box-shadow: none !important;background: none !important;padding0!important;    }.filter-panel {position: absolute;top40px;right20px;width220px;backgroundrgba(255,255,255,0.97);border-radius10px;box-shadow02px16pxrgba(0,0,0,0.13);padding18px18px12px18px;z-index1200;font-family'PingFang SC''Microsoft YaHei', Arial, sans-serif;font-size15px;color#222;transition: box-shadow 0.2s;max-height600px;overflow-y: auto;    }.filter-title {font-size18px;font-weight: bold;margin-bottom12px;letter-spacing2px;    }.filter-section { margin-bottom14px; }.filter-label { font-size14pxmargin-bottom6pxcolor#666; }.filter-recommendlabel.filter-categorylabel {display: inline-block;margin-right10px;margin-bottom6px;cursor: pointer;font-size14px;    }.filter-category {max-height280px;overflow-y: auto;border-radius6px;background#f7f7f7;padding6px4px4px8px;border1px solid #eee;    }.filter-categorylabel { width120px; }.filter-panelinput[type="checkbox"] {      accent-color#1890ff;margin-right3px;vertical-align: middle;    }.detail-panel {position: absolute;top40px;right20px;width400px;backgroundrgba(255,255,255,0.98);border-radius14px;box-shadow04px32pxrgba(0,0,0,0.13);padding28px28px18px28px;z-index1200;font-family'PingFang SC''Microsoft YaHei', Arial, sans-serif;font-size16px;color#222;max-height80vh;overflow-y: auto;transition: box-shadow 0.2s;display: none;    }.detail-title {font-size22px;font-weight: bold;margin-bottom10px;color#1890ff;letter-spacing1px;    }.detail-recommend {background#fffbe6;color#faad14;border-radius8px;padding8px14px;font-size18px;font-weight: bold;margin-bottom16px;box-shadow02px8pxrgba(250,173,20,0.08);display: flex;align-items: center;gap8px;    }.detail-photo {width100%;max-height180px;object-fit: cover;border-radius8px;margin-bottom10px;box-shadow02px8pxrgba(0,0,0,0.08);    }.detail-field { margin-bottom8px; }.detail-label { color#888margin-right6px; }.detail-analysis {background#f6ffed;color#389e0d;border-radius8px;padding10px14px;margin-top12px;font-size15px;box-shadow02px8pxrgba(56,158,13,0.06);    }.detail-panel-title {font-size20px;font-weight: bold;text-align: center;margin-bottom18px;color#222;letter-spacing1px;    }</style><!-- 高德地圖 JS API --><scriptsrc="https://webapi.amap.com/maps?v=2.0&key=「你的高德 apikey」"></script></head><body><divid="map"></div><divid="detail-panel"class="detail-panel"></div><script>// 直接嵌入餐廳資料const data = [      {"name""杭州市阿里巴巴濱江園區(出發點)","type""出發點","location""120.190371,30.189600","address""杭州市濱江區網商路6**號","photo""https://gw.alicdn.com/imgextra/i2/O1CN014DVQlb1oVqsnsrbiT_!!6000000005231-2-tps-64-64.png","cost""-","open_time""-","rating""-","phone""-","advantage""公司園區,交通便利,地鐵直達,周邊配套齊全。","recommend_index""-","category""出發點","is_origin"true      },      {"name""海*撈火鍋(中南樂遊城店)","type""火鍋","location""120.190309,30.193994","address""江南大道10**號","photo""https://aos-comment.amap.com/B0GU9MT4N7/comment/6845185a8eedb6301996b74240ba088b_2048_2048_80.jpg","cost""80.00","open_time""09:00-07:00","rating""4.7","phone""-","advantage""服務優質,環境舒適,適合聚餐。","recommend_index""5","category""火鍋","distance_m"2030,"duration_s"459,"traffic""駕車約8分鐘,公交便利,地鐵近。","surrounding""中南樂遊城、知嘛家等商場,生活便利。","analysis""距離適中,交通便利,配套豐富,適合團隊聚餐。"      },      {"name""黃*海鮮大排檔(濱江店)","type""海鮮","location""120.195922,30.197039","address""浙商發展大廈*座1-2樓(**地鐵站G口)","photo""https://aos-comment.amap.com/B0J1B5R0EY/comment/0e8ed310fa3bb3135ddbefe27244562f_2048_2048_80.jpg","cost""139.00","open_time""11:00-15:30 17:30-02:30","rating""4.7","phone""-","advantage""菜品新鮮,適合多人聚餐,夜宵豐富。","recommend_index""5","category""海鮮","distance_m"2395,"duration_s"478,"traffic""駕車約8分鐘,地鐵直達,公交便利。","surrounding""知嘛家等商場,夜生活豐富。","analysis""交通便利,夜宵豐富,適合下班聚會。"      },      {"name""群*飯店(信誠路店)","type""中餐","location""120.174707,30.183901","address""濱安路11**號(近信誠路)","photo""http://store.is.autonavi.com/showpic/2ac9e95efffe6e27a8eda43ef8271134","cost""66.00","open_time""11:00-13:30 16:00-20:30","rating""4.7","phone""-","advantage""家常菜,價效比高,適合日常用餐。","recommend_index""4","category""中餐","distance_m"2797,"duration_s"757,"traffic""駕車約13分鐘,公交可達。","surrounding""周邊無大型商場,環境安靜。","analysis""價效比高,適合小團隊日常聚餐。"      },      {"name""龍*·濱江烤全羊(杭州總店)","type""烤肉","location""120.195890,30.184231","address""長河路47*號和瑞科技廣場S*幢樓下","photo""http://store.is.autonavi.com/showpic/45d72ae00c69cf56d4fe514b1346c55c","cost""132.00","open_time""11:00-21:00","rating""4.8","phone""-","advantage""烤全羊特色,適合聚會,環境寬敞。","recommend_index""5","category""烤肉","distance_m"1226,"duration_s"254,"traffic""駕車約4分鐘,公交可達。","surrounding""保利·時光裡等商場,配套齊全。","analysis""距離最近,評分最高,配套好,強烈推薦。"      },      {"name""東*方(杭州保利時光裡店)","type""中餐","location""120.197088,30.182094","address""長河街道長河路與濱康路交叉口保利時光裡*樓13號樓2017商鋪","photo""http://store.is.autonavi.com/query_pic?id=st1ef630c8-39ef-4d63-93ce-ba3a9732851e&user=search&operate=original","cost""-","open_time""-","rating""4.8","phone""-","advantage""環境優雅,適合家庭聚餐。","recommend_index""5","category""中餐","distance_m"2088,"duration_s"491,"traffic""駕車約8分鐘,公交便利。","surrounding""保利·時光裡等商場,生活便利。","analysis""評分高,環境好,適合家庭和小型聚會。"      }    ];// 圖示對映表const typeIcons = {'辣椒''「需要自己準備」','甜點''「需要自己準備」','咖啡''「需要自己準備」','中餐''「需要自己準備」','日料''「需要自己準備」','快餐''「需要自己準備」','烤肉''「需要自己準備」','燒烤''「需要自己準備」','星星''「需要自己準備」','火鍋''「需要自己準備」','牛排''「需要自己準備」','麵食''「需要自己準備」','海鮮''「需要自己準備」','韓餐''「需要自己準備」','小吃''「需要自己準備」','粵菜''「需要自己準備」','default''「需要自己準備」'    };functiongetCategoryIcon(category){if (!category) return typeIcons['default'];if (category === '出發點'return typeIcons['星星'];if (category === '中餐' || category === '杭幫菜/浙江菜' || category === '湘菜' || category === '東北菜' || category === '素食' || category === '私房菜'return typeIcons['中餐'];if (category === '粵菜'return typeIcons['粵菜'];if (category === '川菜'return typeIcons['辣椒'];if (category === '火鍋'return typeIcons['火鍋'];if (category === '燒烤/烤肉' || category === '烤肉'return typeIcons['烤肉'];if (category === '燒烤'return typeIcons['燒烤'];if (category === '日料'return typeIcons['日料'];if (category === '韓餐'return typeIcons['韓餐'];if (category === '西餐'return typeIcons['牛排'];if (category === '麵館'return typeIcons['麵食'];if (category === '小吃'return typeIcons['小吃'];if (category === '甜品/飲品'return typeIcons['甜點'];if (category === '咖啡館'return typeIcons['咖啡'];if (category === '快餐'return typeIcons['快餐'];if (category === '海鮮'return typeIcons['海鮮'];return typeIcons['default'];    }// 初始化地圖    constmap = newAMap.Map('map', {center: [120.19037130.189600],zoom14    });let allMarkers = [];let allLines = [];functionrenderMarkers(){// 清除舊marker和線      allMarkers.forEach(m => m.setMap(null));      allMarkers = [];      allLines.forEach(l => l.setMap(null));      allLines = [];if (!data.lengthreturn;// 出發點const origin = data.find(d => d.is_origin);// 餐廳const restaurants = data.filter(d => !d.is_origin);// 出發點markerif (origin) {const [lng, lat] = origin.location.split(',').map(Number);const marker = newAMap.Marker({position: [lng, lat],iconnewAMap.Icon({imagegetCategoryIcon('出發點'),sizenewAMap.Size(4040),imageSizenewAMap.Size(4040)          }),title: origin.name,offsetnewAMap.Pixel(-20, -40),label: {content`<span class='marker-label'>${origin.name}</span>`,direction'top',offsetnewAMap.Pixel(0, -20),clickabletrue          }        });        marker.setMap(map);        allMarkers.push(marker);      }// 餐廳marker和連線      restaurants.forEach(item => {if (!item.locationreturn;const [lng, lat] = item.location.split(',').map(Number);const iconUrl = getCategoryIcon(item.category);const marker = newAMap.Marker({position: [lng, lat],iconnewAMap.Icon({image: iconUrl,sizenewAMap.Size(3232),imageSizenewAMap.Size(3232)          }),title: item.name,offsetnewAMap.Pixel(-16, -36),label: {content`<span class='marker-label'>${item.name}</span>`,direction'top',offsetnewAMap.Pixel(0, -16),clickabletrue          }        });        marker.on('mouseover'() => marker.setLabel({ ...marker.getLabel(), content`<span class='marker-label marker-label-hover'>${item.name}</span>` }));        marker.on('mouseout'() => marker.setLabel({ ...marker.getLabel(), content`<span class='marker-label'>${item.name}</span>` }));        marker.on('click'() =>showInfo(item));        marker.on('labelClick'() =>showInfo(item));        marker.setMap(map);        allMarkers.push(marker);// 連線if (origin && origin.location) {const [olng, olat] = origin.location.split(',').map(Number);const line = newAMap.Polyline({path: [ [olng, olat], [lng, lat] ],strokeColor'#1890ff',strokeWeight4,strokeOpacity0.7,isOutlinetrue,outlineColor'#fff'          });          line.setMap(map);          allLines.push(line);        }      });    }// 智慧推薦(評分最高且距離最近)functionshowRecommend(){if (!data.lengthreturn;const restaurants = data.filter(d => !d.is_origin);// 評分優先,距離次之let best = restaurants[0];      restaurants.forEach(r => {if (Number(r.rating) > Number(best.rating) ||          (r.rating === best.rating && r.distance_m < best.distance_m)        ) {          best = r;        }      });showInfo(best, true);    }// 右側詳情面板functionshowInfo(item, isRecommend = false){const panel = document.getElementById('detail-panel');if (!item) { panel.style.display = 'none'return; }let html = '';      html += `<div class='detail-panel-title'>AI推薦餐廳</div>`;if (isRecommend) {        html += `<div class='detail-recommend'>🌟 智慧推薦:<span>${item.name}</span></div>`;      }      html += `<div class='detail-title'>${item.name}</div>`;if (item.photo) html += `<img class='detail-photo' src='${item.photo}' alt='${item.name}'>`;      html += `<div class='detail-field'><span class='detail-label'>型別:</span>${item.type || ''}</div>`;      html += `<div class='detail-field'><span class='detail-label'>地址:</span>${item.address || ''}</div>`;if (item.distance_m) html += `<div class='detail-field'><span class='detail-label'>距離:</span>${(item.distance_m/1000).toFixed(2)} km</div>`;if (item.duration_s) html += `<div class='detail-field'><span class='detail-label'>車程:</span>${Math.round(item.duration_s/60)} 分鐘</div>`;if (item.cost && item.cost !== '-') html += `<div class='detail-field'><span class='detail-label'>人均:</span>¥${item.cost}</div>`;if (item.open_time && item.open_time !== '-') html += `<div class='detail-field'><span class='detail-label'>營業時間:</span>${item.open_time}</div>`;if (item.rating && item.rating !== '-') html += `<div class='detail-field'><span class='detail-label'>評分:</span>${item.rating}</div>`;if (item.phone && item.phone !== '-') html += `<div class='detail-field'><span class='detail-label'>電話:</span>${item.phone}</div>`;if (item.traffic) html += `<div class='detail-field'><span class='detail-label'>交通:</span>${item.traffic}</div>`;if (item.surrounding) html += `<div class='detail-field'><span class='detail-label'>周邊配套:</span>${item.surrounding}</div>`;if (item.advantage) html += `<div class='detail-field'><span class='detail-label'>優點:</span>${item.advantage}</div>`;if (item.analysis) html += `<div class='detail-analysis'>${item.analysis}</div>`;      panel.innerHTML = html;      panel.style.display = 'block';    }// 地圖點選空白關閉詳情    map.on('click'function() {document.getElementById('detail-panel').style.display = 'none';    });renderMarkers();showRecommend();</script></body></html>
10分鐘微調:讓0.6B模型媲美235B模型
大引數模型效果好,但成本高、響應慢。針對該問題,可以用大引數模型的輸出去微調小引數模型,使其在特定任務中的表現接近大引數模型,這一過程也被稱為模型蒸餾。本方案介紹如何透過模型蒸餾提升 Qwen3-0.6B 模型在特定任務的表現(本案例中準確率從14%提升至90%以上)。
點選閱讀原文檢視詳情。

相關文章