1. 从一句标题说起这个项目到底在做什么国庆黄金周八亿人次的出行规模这个数字每年都在刷新。但凡在这个时间段规划过一次跨省行程的人都知道痛点从来不是没有地方去而是信息太多、决策太难、时间太碎。机票价格波动、高铁余票、酒店溢价、景区预约、天气突变、同行人偏好冲突——这些变量叠加在一起靠人脑在十几个App之间来回切换基本等于自虐。我这次做的事情说白了就是把大模型的能力通过MaaS平台接进来再塞进鸿蒙生态的应用里做一个能真正帮普通人规划国庆行程的AI行程规划师。它不是那种你问我答的聊天机器人而是一个能理解模糊需求、能拆解多约束条件、能给出可执行方案、还能在行程中动态调整的东西。为什么选这个时间点做因为国庆是极端场景。平时规划行程容错率高错了大不了改签。国庆不行酒店订晚了就是三倍价格景区约不上就是白跑一趟。极端场景才能检验一个AI规划系统到底有没有用。这个项目适合谁看如果你是做鸿蒙应用开发的想了解怎么把大模型能力集成到端侧应用里这篇有完整的接入思路。如果你是做AI应用的产品或技术负责人想搞清楚MaaS平台在实际项目里怎么选型、怎么调优、怎么控制成本这篇有踩坑记录。如果你只是个普通开发者想看看一个AI出行的项目从零到一长什么样这篇也能给你一个完整的参照。我尽量把每个决策背后的为什么讲清楚把参数怎么算、坑怎么踩、方案怎么选都摊开来说。不堆概念不绕弯子。2. 整体架构设计为什么是MaaS鸿蒙这个组合2.1 核心需求拆解一个行程规划师到底要解决什么问题先把需求拆干净。一个能用的AI行程规划师至少要处理四类任务。第一类是意图理解与约束提取。用户说国庆想带爸妈去个不太累的地方预算五千左右从杭州出发三天两晚这句话里包含了出发地、同行人结构、体力约束、预算约束、时间约束。传统规则引擎处理这种模糊表达基本没戏必须靠大模型的语义理解能力。第二类是多源信息聚合与推理。交通、住宿、景点、天气、人流预测这些数据分散在不同系统里。大模型本身不产生这些数据但它可以做信息的中转站和推理引擎——把结构化数据和非结构化数据揉在一起输出一个逻辑自洽的方案。第三类是方案生成与可执行化。光说建议去苏州没用得给出具体车次、酒店区域、景点顺序、用餐建议、备选方案。这一步对输出格式的稳定性要求极高因为下游要直接渲染成UI。第四类是动态调整。行程中天气变了、某个景点临时关闭、同行人累了想改计划系统得能实时响应。这要求端侧有足够的交互能力不能什么都等云端返回。把这四类需求翻译成技术指标意图理解准确率要够高、信息聚合延迟要够低、方案输出格式要够稳、端侧交互要够流畅。这四个指标直接决定了后面的技术选型。2.2 为什么选MaaS而不是自己部署模型自己部署大模型这条路我认真评估过。结论是对于这个项目不划算。算一笔账。如果自己部署一个70B参数级别的模型至少需要两张A100 80G的卡做推理硬件成本按市场价算一张卡月租在万元级别两张就是两万多。这还只是推理不算微调、不算运维、不算容灾。而国庆这种场景流量是脉冲式的——平时可能每天几百次调用国庆前一周可能每天几十万次。自己部署的话要么平时资源浪费要么峰值扛不住。MaaS平台解决的就是这个问题。按量付费弹性伸缩峰值来了自动扩容峰值过了自动缩容。而且MaaS平台通常会提供多个模型版本可选我可以根据任务复杂度动态切换——简单的意图识别用小模型复杂的行程推理用大模型。这种灵活性是自部署很难做到的。当然MaaS也不是没有代价。最大的代价是数据出域和响应延迟。数据出域的问题我的处理方式是敏感信息比如用户真实姓名、手机号在端侧做脱敏只把脱敏后的行程需求发给云端。响应延迟的问题后面会讲怎么通过端云协同来优化。2.3 为什么选鸿蒙而不是其他端侧平台鸿蒙在这个项目里的价值不是国产替代这种口号层面的东西而是实打实的技术特性。第一个是分布式能力。国庆出行用户可能手机、平板、手表都在用。鸿蒙的分布式软总线可以让行程信息在设备间无缝流转。手机上规划到一半平板上接着看手表上收到出发提醒。这种体验在单设备应用里很难做到。第二个是元服务卡片。鸿蒙的元服务可以做到服务直达用户不需要下载完整App通过卡片就能看到今天的行程安排、下一个景点的人流预测、天气提醒。对于出行场景这种轻量级交互比打开一个重App要友好得多。第三个是端侧AI能力。鸿蒙本身提供了一些端侧推理框架可以把一些轻量级的模型放在端侧跑。比如意图分类、实体抽取这种任务完全可以在端侧完成不用每次都请求云端。这样既降低了延迟又减少了数据出域的范围。第四个是开发效率。ArkTS的声明式UI写起来确实快状态管理比传统命令式UI清晰很多。对于一个需要快速迭代的项目这一点很关键。2.4 整体架构图与数据流架构上分三层端侧、MaaS平台、数据服务层。端侧负责交互和轻量推理。用户在鸿蒙应用里输入需求端侧先做一轮预处理——脱敏、意图初筛、实体抽取。然后把处理后的请求发给MaaS平台。MaaS平台负责重推理。根据请求类型路由到不同的模型意图理解走小模型行程生成走大模型动态调整走中等模型。平台层还负责调用外部数据服务——交通数据、天气数据、景点数据——把这些结构化信息作为上下文喂给模型。数据服务层是独立的一套系统负责从各个数据源拉取信息、做清洗和缓存。这一层不直接暴露给端侧只对MaaS平台开放。数据流是这样的用户输入 → 端侧预处理 → MaaS平台路由 → 模型推理数据聚合 → 结构化方案返回 → 端侧渲染 → 用户反馈 → 动态调整。整个链路里最关键的优化点是端侧预处理和模型路由。端侧预处理做得好云端请求量能降一半以上。模型路由做得好推理成本能降三分之二。3. 核心细节解析MaaS接入与鸿蒙端侧实现3.1 MaaS平台选型我对比了哪些维度选MaaS平台我主要看五个维度模型丰富度、推理延迟、并发能力、计费方式、SDK成熟度。模型丰富度决定了你能不能做模型路由。如果一个平台只有一两个模型那所有任务都得用同一个模型成本下不来。我选的平台提供了从7B到70B的多个版本还有专门做embedding和rerank的模型这样我才能做分层处理。推理延迟这块实测下来7B模型的首token延迟在200ms左右70B模型在800ms到1.2s之间。对于行程规划这种场景用户对延迟的容忍度大概在3秒以内所以70B模型是可以接受的。但如果做实时对话就必须用7B或者更小的模型。并发能力是国庆场景的生死线。我做过压测平台在并发1000的时候P99延迟还能控制在2.5秒以内。超过2000并发延迟开始明显上升。所以我在端侧做了请求队列和降级策略——高峰期如果云端响应慢端侧先用缓存方案顶上。计费方式我选的是按token计费不是按调用次数。因为行程规划的输出长度差异很大简单查询可能只要100个token复杂规划可能要2000个token。按token计费更公平也更容易做成本预估。SDK成熟度这块我踩过坑。有些平台的SDK文档写得含糊错误码定义不清晰调试起来很痛苦。最后选的这个平台SDK提供了完整的类型定义和错误处理示例接入效率高很多。3.2 鸿蒙端侧工程结构模块怎么划分鸿蒙端侧的工程结构我按功能拆成了四个模块。entry模块是主入口负责页面路由和全局状态管理。ArkTS的状态管理用的是AppStorage和LocalStorage我在这里维护了用户的基本偏好和当前行程的全局状态。feature模块按业务拆分行程规划、行程展示、动态调整各一个子模块。每个子模块内部再分UI层、逻辑层、数据层。这样拆的好处是动态调整模块可以独立迭代不影响规划模块。core模块放公共能力包括网络请求封装、MaaS SDK封装、端侧推理封装、数据模型定义。这个模块不依赖任何feature模块保证复用性。share模块放跨模块共享的UI组件和工具函数。比如行程卡片组件、时间格式化工具、预算计算工具。模块间的依赖关系是单向的feature依赖core和shareentry依赖feature。不允许feature之间互相依赖需要通信就走entry层的事件总线。这样避免了循环依赖也方便做单元测试。3.3 端侧预处理怎么把请求量降下来端侧预处理是这个项目里最值得说的优化点。没有它云端成本至少翻倍。预处理分三步。第一步是敏感信息脱敏。用户输入里如果包含手机号、身份证号、真实姓名端侧用正则匹配后替换成占位符。比如张三替换成用户A138xxxx1234替换成联系电话1。这样发给云端的数据就不包含个人身份信息。第二步是意图初筛。端侧跑一个轻量级的文本分类模型把用户输入分成几类行程规划、景点查询、交通查询、住宿查询、闲聊。只有前三类需要走云端大模型闲聊和简单查询端侧直接处理。实测下来这一步能过滤掉大约40%的请求。第三步是实体抽取。端侧用规则小模型的方式把出发地、目的地、时间、人数、预算这些关键实体抽出来结构化成JSON。云端模型拿到的是结构化数据原始文本比纯文本推理的准确率高不少。这三步做完云端请求量大概降到原始输入量的50%到60%而且每次请求的token数也少了因为结构化数据比自然语言更紧凑。3.4 模型路由策略什么任务用什么模型模型路由的核心逻辑是任务复杂度决定模型规模。意图理解用7B模型。这个任务本质上是分类抽取7B模型足够。实测准确率在92%左右比70B模型只低3个百分点但延迟只有四分之一成本只有十分之一。行程生成用70B模型。这个任务需要多步推理、多约束满足、多方案对比小模型容易漏约束或者生成不可行的方案。70B模型的输出质量明显更好用户满意度高很多。动态调整用13B模型。这个任务介于两者之间需要理解上下文但推理深度不如行程生成。13B模型在延迟和质量之间取得了比较好的平衡。还有一个特殊场景多轮对话中的指代消解。用户说那第二天呢这个那指代什么需要结合上下文理解。这个任务我用的是7B模型规则后处理因为纯模型推理有时候会跑偏。路由策略不是静态的会根据实时负载动态调整。如果70B模型的队列积压超过阈值部分请求会自动降级到13B模型同时给用户一个正在优化方案的提示。这种降级策略在国庆高峰期救过好几次场。3.5 输出格式控制怎么让模型稳定输出JSON大模型输出格式不稳定这是做AI应用最头疼的问题之一。你让它输出JSON它有时候给你加个好的以下是方案的前缀有时候把JSON包在markdown代码块里有时候字段名拼错。我的解决方案是三层保障。第一层是prompt约束。在系统提示词里明确写清楚只输出JSON不要任何额外文字字段名必须严格按照给定的schema。同时给一个few-shot示例让模型模仿。第二层是输出解析容错。端侧收到响应后先用正则提取JSON部分忽略前后的多余文字。然后用JSON schema做校验字段缺失或类型错误的尝试用默认值填充。第三层是重试机制。如果解析失败把错误信息作为反馈重新发给模型让它修正。重试最多两次两次都失败就降级到模板方案。实测下来第一层能解决80%的格式问题第二层能解决15%第三层解决剩下的5%。整体格式稳定率在99.5%以上。4. 实操过程从零搭建一个可运行的行程规划Demo4.1 环境准备与依赖配置先列一下我用的环境和工具版本。开发IDEDevEco Studio 4.0及以上鸿蒙SDKAPI 11及以上语言ArkTSMaaS平台SDK通过npm安装版本号以平台最新为准端侧推理框架鸿蒙提供的端侧AI框架依赖配置这块重点说两个。一个是MaaS SDK的初始化需要在应用启动时配置API Key和endpoint。API Key不要硬编码在代码里我放在应用的加密存储里运行时读取。另一个是端侧推理模型的加载模型文件放在rawfile目录下首次启动时拷贝到应用沙箱后续从沙箱加载。网络权限、存储权限这些基础配置就不展开了鸿蒙的权限声明在module.json5里配置按官方文档来就行。4.2 端侧预处理模块的实现端侧预处理模块的核心是一个Pipeline输入是用户原始文本输出是结构化请求对象。第一步脱敏用正则表达式匹配手机号、身份证号、邮箱等模式。这里要注意正则不要写得太激进否则会把正常的数字序列误判。我的做法是先用宽松正则匹配候选再用校验规则比如手机号必须是1开头、11位做二次确认。第二步意图分类端侧跑一个轻量级的文本分类模型。模型输入是脱敏后的文本输出是意图标签和置信度。置信度低于阈值的标记为不确定走云端兜底。第三步实体抽取用规则模型结合的方式。规则负责抽取格式固定的实体日期、金额、人数模型负责抽取格式不固定的实体地名、景点名。抽取结果统一转成JSON格式。整个Pipeline的耗时控制在200ms以内这样用户几乎无感知。4.3 MaaS平台调用封装MaaS平台的调用封装我做了三层抽象。最底层是HTTP客户端负责实际的网络请求、重试、超时处理。超时时间设的是5秒重试次数2次重试间隔用指数退避。中间层是模型调用器封装了不同模型的调用参数。比如7B模型的temperature设0.370B模型的temperature设0.7。temperature这个参数控制输出的随机性意图理解需要确定性高所以设低行程生成需要多样性所以设高。最上层是业务调用器把业务逻辑翻译成模型调用。比如生成行程这个业务动作实际上会触发多次模型调用先调意图理解模型确认需求再调行程生成模型出方案最后调格式校验模型做输出检查。封装的好处是业务层不需要关心底层用的是哪个模型、参数怎么设。换模型或者调参数只改中间层就行。4.4 行程生成的核心Prompt设计Prompt设计是这个项目里最需要反复打磨的部分。我前后改了十几版才找到一个比较稳定的结构。系统提示词的核心结构是这样的先定义角色你是一个专业的行程规划师再定义任务根据用户需求生成可执行的行程方案然后定义约束必须考虑交通时间、景点开放时间、用餐时间最后定义输出格式JSON schema。用户提示词里我把端侧抽取的结构化实体和原始文本都放进去。结构化实体放在前面原始文本放在后面用分隔符隔开。这样模型能先看到关键信息再看细节。Few-shot示例我放了两个一个简单的两天行程一个复杂的三天行程。示例的作用是让模型理解输出的粒度和格式。还有一个技巧是分步推理。我在prompt里要求模型先输出推理过程再输出最终方案。推理过程不返回给用户只用于调试和日志。这样模型的输出质量会明显提升因为它被迫想清楚再回答。4.5 鸿蒙端侧UI与交互实现UI这块我重点说三个页面。需求输入页用户可以用自然语言输入需求也可以用表单选择出发地、目的地、时间、人数、预算。两种方式的结果会合并成一个请求。输入框做了防抖处理用户停止输入500ms后才触发端侧预处理。方案展示页用卡片列表展示每天的行程。每个卡片包含时间、地点、活动、交通方式、预计花费。卡片可以展开查看详情也可以左右滑动切换备选方案。顶部有一个总览条显示总预算、总时长、关键提醒。动态调整页用户可以对任意一天或任意一个活动做调整。调整请求会实时发给MaaS平台返回新的方案后局部刷新UI。这里用了鸿蒙的LazyForEach做列表渲染优化只刷新变化的卡片。交互上有一个细节所有网络请求都有loading状态和错误状态。loading状态用骨架屏错误状态给明确的错误信息和重试按钮。不要用那种转圈转到天荒地老的loading用户会以为卡死了。4.6 端云协同的动态调整机制动态调整是端云协同的典型场景。用户改了行程端侧先做一轮本地校验——比如时间冲突、预算超支——如果本地能解决直接返回不走云端。本地解决不了的才发给云端。云端返回新方案后端侧做增量更新只刷新变化的UI部分。同时把这次调整记录到本地历史里方便用户回滚。还有一个优化是预加载。根据用户当前的位置和时间端侧会提前预判用户可能需要的调整提前向云端请求备选方案。比如用户正在去景点的路上端侧会提前请求如果用户想改去附近另一个景点的方案。这样用户真正操作时方案已经准备好了响应几乎是瞬时的。5. 常见问题与排查技巧实录5.1 模型输出格式不稳定的排查思路格式不稳定是最常见的问题。排查思路是先看prompt再看解析逻辑最后看模型本身。Prompt的问题通常是约束不够明确。比如你写输出JSON模型可能输出带markdown代码块的JSON。你要写直接输出JSON对象不要用代码块包裹。再比如你写包含时间字段模型可能用time也可能用时间。你要明确写字段名必须是time类型是字符串格式是HH:mm。解析逻辑的问题通常是容错不够。我的解析器会先尝试直接JSON.parse失败后用正则提取再失败后用括号匹配算法提取。三层都失败才报错。模型本身的问题通常是模型规模不够。7B模型在复杂格式约束下确实容易跑偏换成13B或70B会好很多。如果成本允许格式要求高的任务尽量用大模型。5.2 高峰期响应超时的降级方案国庆高峰期云端响应超时是必然的。我的降级方案分三级。一级降级切换模型。70B超时了自动切到13B。质量会下降但至少能返回结果。二级降级使用缓存。如果用户请求的是热门目的地端侧缓存里可能有相似方案。直接返回缓存方案并标注基于历史数据。三级降级模板方案。如果前两级都失败返回一个通用模板让用户手动填充关键信息。虽然体验差但比一直转圈好。降级策略要提前配置好阈值。我的配置是70B模型P99延迟超过3秒触发一级降级超过5秒触发二级降级超过8秒触发三级降级。5.3 端侧推理性能优化的几个手段端侧推理的性能瓶颈主要在模型加载和推理速度。模型加载优化模型文件不要放在rawfile里直接加载先拷贝到沙箱用内存映射的方式加载。这样加载速度能快3到5倍。推理速度优化端侧模型尽量用量化版本。FP16量化后模型体积减半推理速度提升约40%精度损失在可接受范围内。内存优化推理完成后及时释放中间张量避免内存泄漏。鸿蒙的端侧AI框架有自动内存管理但手动释放能更及时。还有一个技巧是预热。应用启动时在后台线程先跑一次空推理把模型加载到内存里。这样用户第一次真正使用时不需要等模型加载。5.4 常见问题速查表问题现象可能原因排查方法解决方案模型输出格式错误prompt约束不明确检查系统提示词增加格式约束和few-shot示例响应超时模型队列积压查看平台监控触发降级策略切换小模型端侧推理慢模型未量化检查模型文件大小使用FP16或INT8量化版本行程方案不可行约束未完整传递检查请求参数补全约束条件增加校验步骤动态调整不生效缓存未更新检查缓存失效策略调整缓存TTL增加主动失效内存占用过高中间张量未释放查看内存监控手动释放优化推理批次5.5 几个踩过的坑和独家技巧第一个坑MaaS平台的并发限制。有些平台默认并发数很低国庆高峰期直接被打满。解决方法是提前申请提额或者在端侧做请求队列控制并发数。第二个坑鸿蒙端侧AI框架的版本兼容性。不同API版本的端侧推理接口有差异升级SDK后代码可能跑不通。解决方法是锁定SDK版本升级前先在测试环境验证。第三个坑JSON schema校验的性能。如果schema很复杂校验本身就会耗时。解决方法是简化schema只校验关键字段非关键字段用默认值。一个独家技巧用模型输出日志做持续优化。我把每次模型调用的输入输出都记到日志里定期分析哪些请求的格式错误率高、哪些意图识别不准。根据这些数据反过来优化prompt和路由策略。这个闭环做了两个月整体准确率提升了15个百分点。还有一个技巧给用户提供反馈入口。用户可以对生成的方案点赞或点踩点踩时可以选择原因时间不合理、预算超了、景点不喜欢。这些反馈数据是优化模型和prompt的宝贵素材。6. 成本控制与性能调优的实战经验6.1 Token消耗的估算与控制成本控制的核心是控制token消耗。我做过统计一次完整的行程规划平均消耗输入token约800个输出token约1500个。按平台定价算单次成本在可接受范围内。但国庆高峰期每天几十万次调用总成本就很可观了。控制手段有几个。第一是压缩输入。端侧预处理后的结构化数据比原始文本短很多能省30%左右的输入token。第二是限制输出长度。在prompt里明确要求方案不超过500字避免模型生成冗长的描述。第三是缓存复用。相似请求直接返回缓存结果不走模型。还有一个策略是分级服务。免费用户用7B模型付费用户用70B模型。这样既能控制成本又能做商业化。6.2 缓存策略的设计与实现缓存设计的关键是缓存粒度和失效策略。缓存粒度我分了两级。一级缓存是完整方案缓存key是出发地目的地天数人数的哈希。命中后直接返回完整方案。二级缓存是片段缓存比如某个景点的介绍、某段交通的建议。片段缓存用于动态调整时快速拼装方案。失效策略用的是TTL主动失效。TTL设的是6小时因为交通和天气信息变化快。主动失效是在检测到数据源更新时主动清除相关缓存。缓存命中率实测在35%左右。国庆高峰期因为请求集中命中率能到50%以上。6.3 端云协同的延迟优化延迟优化的目标是让用户感觉快。人的感知阈值大概是1秒1秒内返回用户觉得很快1到3秒觉得正常超过3秒觉得慢。我的优化手段是并行请求和流式返回。并行请求是指端侧同时发起多个模型调用谁先返回用谁的结果。流式返回是指模型生成一部分就返回一部分端侧边接收边渲染。这样用户看到第一个字的时间能提前到500ms以内。还有一个手段是预判。根据用户的历史行为和当前上下文端侧提前请求可能需要的方案。比如用户刚打开应用端侧就根据他的偏好预请求一个默认方案。用户真正操作时方案已经在了。6.4 监控与告警体系的搭建监控体系分三层端侧监控、平台监控、业务监控。端侧监控主要看崩溃率、ANR率、端侧推理耗时。平台监控看模型调用量、延迟分布、错误率。业务监控看方案生成成功率、用户满意度、动态调整触发率。告警阈值我设的是端侧崩溃率超过0.5%告警平台P99延迟超过3秒告警方案生成成功率低于95%告警。告警通过即时通讯工具推送到开发群响应时间要求在15分钟以内。监控数据还会用来做容量规划。比如根据历史数据预测国庆高峰期的调用量提前向MaaS平台申请扩容。7. 这个项目后续还能怎么扩展7.1 多模态输入的接入思路现在只支持文本输入后续可以接入图片和语音。用户拍一张景点照片系统识别出景点名称自动加入行程。用户说一段话语音转文字后走现有流程。多模态接入的技术路径是端侧做初步的多模态处理图片压缩、语音降噪云端做深度识别图像分类、语音转写。识别结果作为额外上下文喂给行程生成模型。7.2 社交化行程规划的可行性一个人规划行程是孤独的一群人规划行程是吵架的。社交化行程规划的核心是偏好聚合和冲突消解。技术上的做法是每个参与者输入自己的偏好系统用投票算法或加权算法聚合出一个集体偏好。冲突消解用大模型做调解比如A想去博物馆B想去游乐园系统建议上午去博物馆下午去游乐园。这个功能的技术难点不在模型在交互设计。怎么让用户觉得公平、透明、可参与比模型本身更重要。7.3 从行程规划到行程执行的闭环现在的系统止步于给出方案后续可以延伸到执行方案。比如自动预约景点门票、自动叫车、自动提醒出发时间。这需要和外部服务做深度集成。技术上的挑战是服务标准化——不同景点的预约接口不一样不同打车平台的API不一样。需要一个中间层做适配。商业上的挑战是信任。用户愿不愿意让AI代替自己做一些有金钱成本的操作这需要时间验证。7.4 模型微调与个性化现在的模型是通用的后续可以用用户反馈数据做微调让模型更懂特定用户的偏好。比如有的用户喜欢早起有的用户喜欢睡懒觉微调后的模型能自动适配。微调的数据来源是用户的历史行程和反馈。技术路径是用LoRA做轻量级微调每个用户一个adapter。这样既个性化又不用为每个用户部署完整模型。我在实际做这个项目的过程中最大的体会是AI应用的价值不在于模型有多强而在于工程细节做得多扎实。同样的模型prompt设计得好不好、端侧预处理做得细不细、降级策略配得全不全最终的用户体验差距是巨大的。模型是引擎但决定车跑得稳不稳的是底盘和悬挂。