腾讯位置服务开发者征文大赛:“独行侠”智能路线官
一个关于城市夜跑者、算法盲区与AI情感化路线推荐的真实技术实践关键词Go、地图SDK抽象、LLM Agent、Prompt工程、情感化推荐目录背景需求都市独行侠的运动品质困境痛点诊断为什么传统地图工具听不懂人话Module-SDK给地图API装上通用翻译器Module-Agent从指令执行到情绪理解的跃迁一次完整的夜跑请求系统在背后做了什么数据飞轮从AI预点亮到用户共建的闭环进化共建闭环探路者信用与路线升降级途点灯塔让运动变成城市探索游戏写在最后一、背景需求随着马拉松与骑行文化的盛行都市独行侠独自运动的个体对运动品质的要求日益提高。传统地图产品腾讯/高德/百度侧重于位移效率最短/最快路径忽略了运动场景下的安全、舒适与环境体验。用户痛点集中在安全焦虑夜跑无路灯、骑行情势复杂、人车混行。体验折损路线拥挤如广场舞干扰、路面材质差伤膝盖、红绿灯多打断骑行节奏。选择困难想去好的路段却不知道在哪缺乏个性化推荐。1.1 产品愿景构建一个AI驱动的体验优先型运动路网让每一位独行侠都能在安全、舒适、不被打扰的环境中享受运动并通过人机共创点亮城市让孤独的汗水产生公共价值。1.2 核心价值主张懂你的AI路线官不止导航更懂你的心情与体能推荐最适合当下的路径。人机共创路网你不再是过客而是城市路线的拓荒者与净化者。弱PK的地缘归属将个人运动转化为城市能量以共建取代内卷。二、痛点诊断为什么传统地图工具听不懂人话要解决这个问题首先要理解传统架构的局限性。第一层困境算法优化目标的单一性地图App的路线规划算法核心是最短路径、最快路径、避开拥堵。这些目标可以被精确量化但也导致了一个盲区所有不能被编码进权重函数的诉求都会被忽略。安静怎么量化疗愈怎么建模不想看到写字楼怎么表达传统架构里没有为这些维度留位置自然也就不可能生成满足这些需求的路线。第二层困境推荐文案的冰冷感即便你勉强跑完了一条路线App给你反馈的也是本次跑步3.5公里配速6分12秒消耗热量287大卡。数据准确但毫无温度。用户想要的不是数据报表而是一个能理解他今晚为什么出门跑步的同行者。三、Module-SDK给地图API装上通用翻译器解决第一层困境的方案是在后端构建一个地图服务抽象层把不同地图的差异封装在内部对外暴露统一的服务接口。核心设计接口抽象 工厂模式我们定义了一个MapSDK接口把路线规划、POI搜索、地理编码等能力抽象为一组与厂商无关的方法签名typeMapSDKinterface{PlanRoute(ctx context.Context,req*RoutePlanRequest)(*RoutePlan,error)PlanAlternativeRoutes(ctx context.Context,req*RoutePlanRequest)([]*RoutePlan,error)SearchNearby(ctx context.Context,req*POISearchRequest)([]*POI,error)Geocode(ctx context.Context,addressstring)(*Location,error)ReverseGeocode(ctx context.Context,lat,lngfloat64)(*Address,error)Name()stringVersion()string}配套的数据模型也彻底脱离第三方术语RoutePlan用Distance和Duration表示距离和耗时POI用统一的Category字段描述类型。高德返回的path、腾讯返回的polyline在各自的实现层被解析后统一写入RoutePlan.Polyline。接口的实现分散在sdk/amap/和sdk/tencent/两个子包中各自负责HTTP客户端封装、请求转换、响应解析。业务层只依赖MapSDK接口不需要知道数据最终来自哪家厂商。为了管理多实例生命周期我们引入了一个带缓存的工厂typeSDKFactorystruct{config*Config cachemap[string]MapSDK mu sync.RWMutex}工厂根据配置中的DefaultProvider决定默认使用哪家地图服务同时维护一个读写锁保护的缓存映射避免每次请求重复创建 HTTP 客户端。业务层调用factory.GetDefaultSDK()时整个过程完全透明。降级容错从单点依赖到多活冗余依赖第三方SaaS服务容错是不可妥协的底线。我们在RoutePlanningService中实现了planWithFailover当默认提供商失败时自动遍历所有已注册的提供商依次重试直到成功或全部失败。func(s*RoutePlanningService)PlanOptimalRoute(ctx context.Context,from,to geo.Point,modestring)(*sdk.RoutePlan,error){mapSDK,err:s.factory.GetDefaultSDK()iferr!nil{returnnil,fmt.Errorf(获取SDK失败: %w,err)}req:sdk.RoutePlanRequest{From:from,To:to,Mode:mode}plan,err:mapSDK.PlanRoute(ctx,req)iferr!nil{returns.planWithFailover(ctx,req)// 自动降级到备用提供商}returnplan,nil}这意味着即使某个接口突然挂了用户的请求也能无缝切换到腾讯继续执行前端完全无感知。四、Module-Agent从指令执行到情绪理解的跃迁SDK抽象层解决了怎么调用地图能力的问题但核心难题仍未触及系统怎么知道用户想要安静而不是最快答案是让大语言模型充当意图翻译官把自然语言中的情感诉求转化为机器可执行的结构化约束。可插拔LLM架构不把鸡蛋放一个篮子里和地图服务一样我们不希望AI能力绑定在单一模型上。Module-Agent的LLM层采用接口抽象 路由器的模式typeProviderinterface{Complete(ctx context.Context,req*CompletionRequest)(*CompletionResponse,error)StreamComplete(ctx context.Context,req*CompletionRequest)(-chan*StreamChunk,error)Name()string}目前实现了腾讯混元hunyuan-lite、OpenAIGPT-3.5-turbo和本地模型的适配器全部注册到llm.Router中。支持按默认提供商调用也支持显式指定为后续A/B测试和模型灰度留下空间。更关键的是同步与流式双接口的设计意图解析用Complete同步调用获取完整结果对话交互场景通过 WebSocket 连接GET /api/v1/agent/stream后端用StreamComplete逐块推送LLM生成结果让用户看到打字机式的实时输出。Prompt工程把黑盒变成可控的黑盒LLM很强大但输入决定输出质量。我们把Prompt从代码中剥离用YAML模板 变量替换集中管理。以意图解析为例intent_parser.yaml被结构化为system:|你是独行侠路线官一个资深运动向导...instruction:|请根据用户的输入提取并推断以下寻路约束条件。 你必须严格考虑运动模式的安全特性 - 跑步避开人车混行、主干道无隔离段output_schema:|{ intent_analysis: { emotion_intent: 情绪疗愈/健身锻炼/探索城市, ... }, route_constraints: { target_distance_km: 5.0, must_avoid: [...], ... }, weight_adjustment: { safety_weight: 1.5, quietness_weight: 1.8, ... } }examples:-user_input:今晚想跑个5公里要安静点的最近工作压力大output:|{ intent_analysis: { emotion_intent: 情绪疗愈, core_demand: 低人流、环境放松 }, ... }产品经理可以直接改YAML调整措辞、补充示例无需重新编译后端。版本控制也让Prompt迭代可追溯、可回滚。四维评分让安静和风景变成可计算的量路线评估不能凭感觉。我们设计了一套可量化的四维评分体系每项根据用户意图动态调整权重维度含义典型权重安全性人车分流比例、路灯覆盖率、夜间路况1.5x清净度人流密度估算、远离商圈和广场舞区域1.8x风景值沿途公园、水系、自然景观密度1.2x路面质量塑胶/沥青/水泥路面占比与平整度1.0x当用户说压力大、想疗愈时系统自动提升清净度1.8x和风景值1.2x的权重降低对速度效率的优先度。当用户说想骑车探索城市时风景值上升安全性保持高权重以应对骑行特殊风险。双模切换跑步和骑行的画风完全不同PRD 中一个关键的产品设计是双模切换——顶部 Tab 切换「漫步者跑步」与「破风手骑行」。这不仅是 UI 主题色的变化森林绿 vs 破晓橙背后是整个算法权重的重新编排。跑步模式的核心诉求是护膝、清净、不被打断。意图解析 Prompt 中明确写入约束避开人车混行路段、优先塑胶和沥青路面、绕开广场舞聚集区。LLM 在解析想跑五公里时会自动把surface_preference置为[塑胶, 沥青]把quietness_weight拉到 1.8x。骑行模式的核心诉求是流畅、少停、安全隔离。红绿灯是骑行体验的头号杀手——每等一次红灯刚热起来的大腿就凉半截。因此骑行模式的寻路算法中红绿灯密度被提升到与安全性同等的权重级别traffic_light_preference强制设为avoid同时优先选择有非机动车道隔离的路段。这种模式驱动权重的设计让我们的 Agent 不是一套通用推荐逻辑打天下而是根据用户的运动类型调用不同的意图解析策略和寻路参数模板。同一句话今晚想出去动动在跑步模式下被解读为疗愈慢跑在骑行模式下则被解读为城市夜骑刷街——推荐的目的地、路线风格、甚至文案语气都截然不同。五、一次完整的夜跑请求系统在背后做了什么让我们回到小陈的场景看看当他输入今晚想跑5公里要安静点的最近工作压力大时系统在4秒内完成了什么。Step 1意图解析LLM约1.2秒intent_parser.yaml的Prompt被填充上用户输入和北京、夜晚、跑步等上下文提交给LLM。模型返回结构化JSON{intent_analysis:{emotion_intent:情绪疗愈,core_demand:低人流、环境放松},route_constraints:{target_distance_km:5.0,must_avoid:[繁华商圈,广场舞区域,无路灯路段]},weight_adjustment:{safety_weight:1.5,quietness_weight:1.8,scenery_weight:1.2,surface_weight:1.0},poi_preferences:[公园,水系,安静街巷]}Step 2路线规划SDK约1.5秒RoutePlanningService根据约束条件调用 Module-SDK 执行三条并行动作地理编码将家附近转化为具体坐标POI搜索搜索半径2公里内的公园、水系、安静街巷路线规划生成3条候选路线分别侧重绕公园“沿水系”“穿静巷”。过程中如果一方接口超时自动降级到另一方继续执行用户无感知。Step 3路线评估LLM约1.0秒三条候选路线的坐标、距离、预估清净度评分、沿途POI列表连同用户的原始意图一起输入route_evaluator.yaml。LLM从解析者切换为评审官选出最优路线并生成推荐文案。Step 4返回结果约0.3秒小陈的手机屏幕上出现推荐路线亮马河畔静巷环线今晚不去挤工体带你走亮马河畔的静巷。这条线清净度拉满听着水声慢慢跑把工作的烦心事都丢在风里。全程人车分流很安全1.2公里处注意下井盖。去放空吧独行侠。安全性4.5/5清净度4.8/5风景值4.2/5路面4.0/5亮点水系疗愈、极致清净注意1.2km处有井盖这不是一条最短或最快的路线而是一条最懂他今晚为什么想出门跑步的路线。整个流程封装在agent.Core的一个方法中func(a*Core)ProcessUserInput(ctx context.Context,input UserInput)(*AgentResponse,error){intent,err:a.ParseIntent(ctx,input)// Step 1听懂你想干什么routes,err:a.PlanRoutes(ctx,intent,input.Context)// Step 2去找符合条件的路线evaluation,err:a.EvaluateRoutes(ctx,intent,routes,input.Context)// Step 3选出最好的一条写出推荐理由response:buildResponse(intent,routes,evaluation)// Step 4打包返回returnresponse,nil}六、数据飞轮从AI预点亮到用户共建的闭环进化一次成功的推荐只是起点。真正的产品壁垒在于如何让系统越用越懂用户——这需要一个持续运转的数据飞轮。PRD 中定义的核心闭环非常清晰AI预点亮/生成路线→用户探索与体验→四维打分 路况上报→数据反哺(置信度更新/权重进化)→AI推荐更精准。这个闭环回答了所有UGC类产品的终极问题冷启动之后内容从哪里来AI预点亮冷启动期的种子路线在产品上线初期没有用户轨迹、没有社区验证推荐引擎面临典型的冷启动困境。我们的策略是AI预点亮——在 seed 城市北京、上海基于地图路网数据和POI分布由AI Agent批量生成一批S级和A级候选路线。这些预生成路线带有初始置信度标签 精选数据交叉验证充分社区初步认证可直接推荐 待探AI生成缺乏实况数据标注欢迎探路标签邀请用户验证 风险近期差评或路况异常隐藏或强提示。这不是一个静态的榜单而是会呼吸的生命体。一条待探路线如果被足够多的用户验证并通过就会逐步升级为精选反之一条曾经的精选路线如果近期因施工、路况恶化导致评分暴跌也会被降级甚至隐藏。用户验证从消费者到共建者的身份转换传统地图产品里用户是被动消费内容的角色——打开App搜索跟随导航结束。但在 Map Games 的设计中每一次运动完成后用户都会被邀请参与共建为刚才跑过的路线进行四维打分、上报途中发现的路况问题。这种设计让个人运动数据产生了公共价值用户不再只是过客而是城市运动路网的拓荒者与净化者。这个身份转换的心理价值不容忽视。当一个人知道他的打分会影响后续 thousands of runners 的路线选择时他会更认真地回忆刚才那段路上的路灯够不够亮、路面有没有坑。这种微小的责任感是UGC内容质量的第一道防线。七、共建闭环探路者信用与路线升降级数据飞轮要跑起来需要一套可信的评分和升降级机制。否则刷分、恶意差评、随机打分都会让置信度体系崩塌。四维滑块打分把主观体验变成结构化数据运动结束页会弹出四维滑动条用户用1-5分0.5步长为刚才的路线打分️ 安全感路灯够不够车流大不大 清净度有没有广场舞大妈有没有施工噪音 风景值沿途有没有公园水系还是全是写字楼围墙️ 路面质塑胶跑道还是碎砖烂路膝盖疼不疼这四项评分通过后端实时回传直接参与路线置信度的加权计算。快捷路况上报人人都是路况传感器除了打分我们还提供了一组标签式上报按钮[施工] [坑洼] [逆行] [野狗] [无灯]。用户不需要写长文描述点击即提交。后端将上报内容与轨迹片段绑定不包含用户ID作为路况热图的数据源。探路者信用分让认真的人更有话语权这里隐藏着一个关键的反作弊设计——探路者信用分。系统根据用户的历史活跃度运动频次、打分一致性是否总是极端分、以及上报真实性与后续其他用户上报的交叉验证为每个用户计算一个隐形的信用分。高信用用户的打分会获得1.5x 到 2x 的权重加成。这意味着一个经常跑步、打分规律、上报准确的老炮他的一次四维度评分可能抵得上三个新用户的随机打分。这个设计在不暴露算法细节的前提下用博弈论机制激励了真实、持续的高质量UGC。路线升降级社区自治的算法实现后台有一个定时任务定期扫描所有路线的评分数据一条路线如果积累超过50人打分且均分超过4.0待探自动升级为精选进入城市金路线榜反之如果近期均分跌破3.5曾经的精选会被降级为风险从推荐列表中隐藏。这套规则看似简单但实际上构成了一个社区自治的算法实现不是产品经理决定哪条路线值得被推荐而是真实跑过这条路的人用他们的汗水和评分投票。八、途点灯塔让运动变成城市探索游戏如果只有路线和数据运动依然是枯燥的。我们需要一种方式把一条线性的跑步轨迹变成一段有节点、有惊喜、有成就感的探索旅程。途点设计从景点到心流里程碑PRD 中定义了三种途点类型沿途标注在路线上 风景点河边、公园、观景点——让你在疲惫时抬头就能看到值得停下来的理由 挑战点坡顶、长坡段——用击败这段坡的成就感对抗放弃的念头 特殊点城市边界、历史地标——把运动变成认识城市的媒介。MVP 阶段我们为每个城市预置了至少100个途点。这些途点不是地图上已有的POI而是基于运动体验重新设计的心流里程碑——它们的存在不是为了提供信息而是为了在正确的时机给用户一个情绪锚点。无感打卡不打扰的仪式感传统打卡需要用户掏出手机、打开App、点击按钮。对跑者而言这意味着打断节奏、影响心率。我们的设计是GPS无感自动触发当系统检测到用户进入途点半径20米范围内自动完成打卡语音播报已点亮亮马河观景点。这种不强制停留、不主动操作的设计尊重了运动状态的连续性。但它依然创造了仪式感——当用户跑完一段路线回顾轨迹时发现沿途亮起了三个已点亮的途点标记那种探索地图的成就感是传统运动App的本次跑步3.5公里无法比拟的。九、写在最后Map Games 项目目前完成了 Module-SDK 的核心功能路线规划、POI搜索、地理编码、降级容错和 Module-Agent 的 Phase 1多LLM支持、意图解析、路线评估、HTTP/WebSocket双接口以及数据飞轮与共建闭环的初步设计。整体完成度约60%。回顾这个项目的技术路径我们始终在做一件事把不能被传统算法量化的用户诉求通过LLM转化为可以被工程系统执行的结构化约束。地图SDK的抽象层解决了底层能力的可插拔问题Agent工作流解决了意图理解的问题数据飞轮解决了冷启动后内容持续进化的问题。三者叠加构成了一个从听懂用户到服务用户再到与用户共建的完整闭环。接下来的重点包括基于腾讯地图Skills文档增强SDK能力沿途搜索、距离矩阵Flutter前端对话界面与双模切换UI的完整实现以及Redis缓存、LLM响应缓存、Prompt持续调优。如果你也在做类似的智能地理应用或者在思考怎么让LLM真正落地到垂直业务里而不是停留在Demo层面希望这篇实践能给你一些启发。特别想听听大家的想法你觉得地图服务还能和哪些AI能力结合除了跑步场景通勤、骑行、Citywalk还有哪些情感化需求被现有产品忽视了共建闭环里的信用分机制你觉得还有哪些反作弊策略值得尝试欢迎在评论区留言讨论。觉得有启发的话点个赞或者转发给正在做相关项目的朋友——你的每一次互动都是我们继续分享技术实践的最大动力。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2605286.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!