国庆第三天,我在故宫午门广场被人群挤得怀疑人生。旁边一位大哥举着手机,屏幕怼着太和殿的脊兽,嘴里反复念叨“这排小兽到底哪个是仙人、哪个是骑凤仙人”。那一刻我突然意识到,与其租一台像砖头一样的官方讲解器、排队等人工导游,不如利用手头能调动的技术,给自己现场搭一个真正顺手的“AI导游”试试水。于是就有了这篇全记录:在鸿蒙HarmonyOS上用元服务做客户端,后端接蓝耘元生代MaaS平台的模型能力,实现一个在故宫里边走边问、拍照即识的AI应用。整个过程有惊喜也有翻车,我把从设计、开发、真机调试到现场排障的完整链路都写在这里,希望对想在鸿蒙上做AI应用、或者对MaaS模式感兴趣的朋友有些参考价值。
1. 故宫现场的真实痛点:为什么传统讲解器和人工导游都不够用
1.1 人多、环境吵,传统讲解器体验打对折
故宫国庆期间日均客流动辄数万人,太和殿、中和殿这些核心殿宇前基本是人挨人、人挤人。我租过故宫官方的自动讲解器,操作逻辑是“走到某个点,机器自动感应开始讲”。想法很好,但现场实际情况完全不是那么回事:机器感应经常延迟,人已经走到下一个殿了,耳机里还在讲上一个殿的内容;人多的时候信号互相干扰,你根本分不清耳机里那点声音是自己的讲解器,还是旁边大叔外放的小视频。租借要排队、押金要排队、归还还要再排队,一天下来光是和讲解器打交道就花掉了将近四十分钟。
人工导游当然更灵活,但国庆高峰期价格不便宜,而且非常难约。更关键的是,跟着导游走其实是一种被动接收——导游讲什么你听什么,你想问一个冷门问题,往往没有时间得到解答,一队人浩浩荡荡往前走,你根本来不及在一个感兴趣的细节前多停留三秒钟。对于我这种喜欢在一个檐角下站五分钟反复琢磨的人来说,传统导游模式确实不够用。
1.2 故宫场景的特殊约束:文物安全、内容严谨、信号复杂
故宫不是普通公园,它对技术方案有一堆隐性的硬约束。
第一,文物不能触摸,很多建筑细节你只能在栏杆外面眯着眼睛看,这时候需要借助技术去“放大”那些肉眼容易忽略的细节,比如屋脊兽的排列顺序、斗拱的结构层次、彩画里隐藏的纹样。第二,开放区域里信号环境并不理想,人一多,基站负载高,4G/5G的实际体验会明显下降,再加上故宫里高大的墙体、厚重的殿宇对信号也有遮挡效应,你不能假设用户随时都有畅通的网络。第三,内容讲究严谨性——故宫相关的历史知识,游客问错了没关系,AI如果答错了就是误导,这种场景对生成内容有很现实的可信度要求,模型给出的每一个年代、每一个事件背景都必须能经得起推敲。第四,使用场景是碎片化的,游客不会坐在一个点前听十分钟,通常是在一个位置站三十秒、拍个照、又赶往下一个点,所以AI导游的交互也必须轻快、短促、即问即答。
1.3 我的诉求清单:一个AI导游到底该干哪些活
基于上面这些约束,我给这个“AI导游”列了一份非常明确的需求清单:
- 免安装:我不想在景点门口为了一个半天的用途下载一个上百兆的App,占用存储、还要注册登录。
- 拍照识别:对准建筑、牌匾、文物拍一张,能直接告诉我这是什么、它有什么故事。
- 语音交互:解放双手,一边看文物一边听讲解,最好能支持连续追问。
- 内容可控:生成的历史讲解必须经过审核或来源约束,不能一本正经地瞎编。
- 离线兜底:信号差的时候,至少要有缓存内容兜底,而不是直接转圈圈卡死。
- 轻量触达:最好能从桌面卡片或扫码直接拉起入口,用完即走,不留下任何负担。
这些诉求其实已经直接指向了一个技术组合:鸿蒙元服务做客户端外壳,蓝耘元生代MaaS做云端大脑。下面说说为什么这么选。
2. 技术选型推演:为什么是“蓝耘元生代MaaS + 鸿蒙元服务”而不是纯App
2.1 端侧AI和云侧大模型的分工逻辑
在鸿蒙端跑AI,有两种极端思路。一种是纯端侧小模型,比如在设备上做简单的图像分类、OCR,好处是不依赖网络、响应快、隐私好;缺点也很明显——端侧模型的语义理解能力有限,你让它回答“为什么故宫的屋顶要做成这种弧度,而不是像西方建筑那样平直”,它基本给不出让人满意的答案,它只能识别“这是个屋顶”“这是红色”。
另一种是云侧大模型,理解能力强、知识丰富,对开放性问题回答得漂亮,但依赖网络,而且把所有逻辑全塞给云端,会有延迟成本和费用问题,每次拍照都上传原图、每次问答都带完整历史,很快就把请求体积和费用撑爆了。
我的方案是取两者之长:端上做轻量的预识别,比如先判断“这大概是建筑、文物还是牌匾”,把照片做裁剪、压缩和降噪预处理;云端MaaS负责真正“烧脑”的部分——识别具体物件、生成讲解文本、根据上下文回答追问。这样既保证了核心问答质量,又把不必要的云调用砍掉了一截,也降低了网络传输压力。
2.2 鸿蒙元服务:免安装、即点即用,刚好命中景点场景
景点这种“用完即走”的场景,天然适合鸿蒙元服务。元服务是HarmonyOS提供的一种轻量级应用形态,用户点击服务卡片、扫描二维码或通过系统推荐即可拉起使用,不需要走完整的下载安装流程。对我来说,朋友在故宫门口发我一个元服务链接,我点开就能用AI导游,用完划走就行,完全不占手机空间。
鸿蒙元服务还支持服务卡片和意图框架,可以把“入口”直接推到桌面负一屏或智能推荐卡片上。对游客来说,门槛比下载App低太多——不需要搜索、不需要下载、不需要注册,扫一个码或者点一张卡片,AI导游就出现了。从开发角度讲,元服务基于ArkTS语言和ArkUI框架,和完整的HarmonyOS应用开发体系一脉相承,熟悉鸿蒙开发的开发者上手成本并不高。
2.3 蓝耘元生代MaaS:模型按需调用,省掉自建部署的坑
蓝耘元生代MaaS是模型即服务平台,通俗说就是你不自己部署大模型,而是通过API按量调用别人已经跑起来的模型能力。对这个项目来说非常关键:我不可能在国庆前专门租几台GPU服务器部署一个开源模型,算力成本、运维成本、容器编排、弹性伸缩,哪一样都够我喝一壶。直接用MaaS API,注册、开通服务、拿到密钥,几十分钟就能把模型能力接进应用。
而且MaaS平台通常不只提供一个模型,而是给你一个模型池——文本对话、多模态识图、语音合成这些能力可以在同一个平台下统一管理和计费。对个人开发者来说,省去了对接多家服务商、维护多套鉴权体系的麻烦,一个SDK或一套RESTful接口就能打通主要能力。蓝耘元生代这种形态,本质上就是把“大模型能力”做成了像水电一样按需取用的公共服务,我只需要关注应用层逻辑。
2.4 多AI协作:规划、识别、讲解、审核各司其职
这个项目的实现里,我刻意没有做“一个大模型干所有事”的架构,而是拆成了几个AI Agent角色,各自负责一个边界清晰的任务:
- 规划Agent:根据当前位置、时间、游客兴趣爱好,生成参观路线和推荐下一个景点。
- 识别Agent:多模态模型对拍照内容做识别,输出建筑或文物的名称、标签和置信度。
- 讲解Agent:根据识别结果生成有趣、有深度的讲解文本,负责“说人话”。
- 审核Agent:对讲解文本做一次事实性和合规性检查,拦截明显不合适的表述。
这种多AI协作的好处是每个Agent的任务边界清晰,可以分别做优化、替换和灰度测试。比如识别Agent用多模态模型,讲解Agent用对话模型,互不干扰;审核Agent甚至可以随时换成更严格的内容安全模型。坏处也明显——链路变长,任何一个环节出问题都会影响整体体验。这个问题我在后面讲现场翻车时会细说,因为国庆当天它实实在在地发生在了我面前。
3. 实战落地:从DevEco Studio到真机运行的完整链路
3.1 工程创建与元服务配置
开发环境我用的是DevEco Studio,华为官方IDE。新建工程时选择“Empty Ability(元服务)”模板,语言选ArkTS,兼容版本按我当时手上的真机选HarmonyOS 5.x。
这里有个需要注意的细节:元服务的工程结构和普通应用不完全一样,它的入口不一定是UIAbility,而是可能以服务卡片、快捷方式等作为触发入口。我在工程里建了一个Entry模块用来承载主要交互页面,然后额外创建了一个服务卡片模块,做桌面级的“AI导游”入口。工程配置里还要单独声明元服务的图标、标签和路由信息,否则上架测试时会被审核拦下来。
几个关键配置项供参考:
bundleName:建议用反域名方式命名,便于区分不同元服务。abilityName:入口Ability名称,服务卡片跳转时要用到。metadata:在module.json5里声明MaaS平台的密钥索引、网络权限用途等。
我当时在这一步踩了个小坑:元服务对merge配置有要求,如果同时存在多个卡片模块,路由表的配置必须显式声明所有可用页面,否则真机点击卡片时会提示“找不到页面”。
3.2 权限申请与隐私合规
AI导游需要定位、相机、麦克风三样权限。HarmonyOS的权限模型是“按需申请、动态弹窗”,元服务对权限审核更严格,不能像普通App那样一股脑全要到。
我在代码里做了三层处理:
- 只在实际使用时申请:用户真正准备拍照或说话时才弹权限请求,不做启动时一口气全要,减少首屏阻力。
- 说明文案写清楚:每种权限都配上明确的用途说明,同时在元服务内提供完整的隐私政策弹窗,说明“图片仅用于识别、语音仅用于转写、定位仅用于推荐附近景点”。
- 最小化授权:定位权限使用“模糊定位”即可满足场景需求——我需要知道的是“你在哪个殿附近”,而不是“你在哪个经纬度”。
权限越小,审核越容易过,对用户也越友好。这点在开发鸿蒙元服务时特别重要,因为元服务的目标是轻量触达,如果一打开就要五个权限,用户大概率会直接划走。
3.3 接入MaaS接口:拍照识别+语音问答的代码骨架
代码结构大致分六步:
- 拍照或从相册选择图片,读取为PixelMap对象。
- 端上预处理:压缩图片到640x480以内,裁剪主体,计算主色调用于场景初判。
- 调MaaS多模态识别接口,上传图片并携带提示词:“请识别故宫中的建筑或文物,给出名称和简要背景”。
- 拿回结构化结果(名称、标签、置信度)。
- 调MaaS文本对话接口,把识别结果和用户的追问一起发给讲解Agent。
- 返回讲解文本,嵌入小型审核调用,确认通过后交给ArkUI渲染并播报。
ArkTS示例代码(示意):
import { image } from '@kit.ImageKit'; import { http } from '@kit.NetworkKit'; async function identifyAndExplain(imageUri: string, question: string): Promise<string> { // 1. 解码图片并压缩 let source = image.createImageSource(imageUri); let pixelMap = await source.createPixelMap({ desiredSize: { width: 640, height: 480 } }); // 2. 调用MaaS识别接口(示意请求头) let recognizeResp = await http.createHttp().request( 'https://api.example-maas.com/v1/multimodal/recognize', { method: http.RequestMethod.POST, header: { 'Authorization': 'Bearer YOUR_MAAS_API_KEY', 'Content-Type': 'application/json' }, extraData: { imageBase64: await pixelMapToBase64(pixelMap), prompt: '请识别故宫中的建筑或文物,输出名称和简要背景' } } ); let recognizeResult = JSON.parse(recognizeResp.result as string); let objectName = recognizeResult.data.name; // 3. 调用MaaS文本对话接口,组装讲解请求 let chatResp = await http.createHttp().request( 'https://api.example-maas.com/v1/chat/completions', { method: http.RequestMethod.POST, header: { 'Authorization': 'Bearer YOUR_MAAS_API_KEY', 'Content-Type': 'application/json' }, extraData: { model: 'maas-turbo-chat', messages: [ { role: 'system', content: '你是故宫AI导游,回答要准确、通俗、有趣。' }, { role: 'user', content: `识别到:${objectName}。游客追问:${question},请给出讲解。` } ] } } ); let chatData = JSON.parse(chatResp.result as string); return chatData.choices[0].message.content; }生产环境里还需要做超时控制、重试、鉴权信息加密存储等处理,这段代码只是演示主流程。有一点提醒:不要把MaaS的API密钥直接硬编码在元服务代码里,我测试阶段为了方便明文写在了配置里,后来真机调试被安全扫描工具提醒,才改成了动态获取并加密存储。
3.4 服务卡片与语音播报:把AI导游“放”到桌面上
鸿蒙的服务卡片能在桌面上直接展示信息,这是元服务区别于普通App的典型体验。我给AI导游做了两种卡片:
- 路线卡片:显示当前所在区域和推荐下一个景点,点击直接跳转导航页。
- 今日一问:每天推一个故宫冷知识,点开直接进入问答页。
语音播报我用了双通道:鸿蒙自带的文本转语音能力作为默认通道,MaaS云端语音合成作为备选。实测下来,端侧TTS延迟低、但音色偏机械;云端合成效果好、但多一次网络往返。考虑到故宫现场信号不稳,我默认用端侧TTS,只有用户主动选择“沉浸讲解”模式时才走云端高音色合成。在钟表馆、珍宝馆这种安静室内展厅,云端音色的“讲解感”确实好很多,能明显感觉到语气停顿和重音分布更像真人。
3.5 真机调试:从模拟器到实物的跨越
模拟器上跑得好好的,一到真机就露馅,这是AI应用最常见的坑。我遇到几个典型问题:
- 模拟器默认网络状态太好,MaaS接口500毫秒返回,真机上因为基站负载,2秒甚至3秒才返回,整个交互节奏立刻变得拖沓。
- 相机权限在模拟器上可以随便给,真机上有明显的授权弹窗流程,用户在景点门口手忙脚乱的时候根本不想点“允许”。
- 模拟器的图片处理管线更快,真机上图片压缩、Base64编码这些操作会占用明显的时间,拍照后立刻识别时甚至出现等待动画卡顿。
我的建议是:这种强依赖真实环境的AI应用,从第一天起就要真机调试,别在模拟器上自我感觉良好。我还专门把测试手机挂了一个低带宽限制模式来模拟拥堵环境,比模拟器的网络模拟真实得多。开发过程中我基本保持“一小时真机一测”的节奏,很多体验问题就这样被提前暴露了。
4. 国庆故宫现场翻车实录:问题定位与修复思路
4.1 现象一:太和殿门口模型响应超时
国庆当天上午十点,太和殿广场人流量达到峰值。我拍了一张太和殿的照片,等了大概4秒,转圈圈,再等4秒,直接超时。这个现象在御花园、养心殿附近也出现了,而且越是热门景点越严重。
定位原因分两层:第一层是网络,现场基站拥塞,图片上传耗时比平时多了近一倍;第二层是MaaS服务端推理队列排队,多模态模型本身计算量大,高峰期请求集中在同一时段,排队时间明显拉长。
修复办法从三个方向入手:
- 端上压缩彻底一点:图片统一压到640x480,体积控制在300KB以内,大幅减少上传耗时。
- 额外增强弱网模式:在故宫里默认开启“弱网模式”,把超时时间从5秒放宽到10秒,同时增加“转圈圈文案”,让游客知道系统还在尽力处理。
- 引入语义缓存:同一座太和殿,不同游客拍的其实差不多,第一次识别成功后,后面30分钟内相同建筑的请求直接命中本地缓存,不再重复调用云端识别接口。
实测下来,缓存命中率高得惊人——太和殿、乾清宫这种热门点的识别结果,缓存可以覆盖六成以上的重复请求。这个方案在人多时几乎是救命的。
4.2 现象二:人声嘈杂,语音识别率骤降
在钟表馆里,我想语音问“这件展品是哪国的”,结果旁边一个小孩尖叫了一声,我的语音被识别成完全不相干的一句话。纯端侧语音识别在这种环境里根本扛不住。
我的解决思路是双通道校验:先端侧语音转文字,再把文字交给MaaS做一次“意图澄清”,如果置信度低于阈值,不直接执行,而是回问一句“你问的是这件展品的来源,对吗”。虽然多一步对话,但避免了答非所问带来的更大挫败感。毕竟在景点现场,游客问一遍没得到答案,通常就不会再问第二遍了。
4.3 现象三:拍照识别张冠李戴
在慈宁宫附近,我对着一个琉璃影壁拍照,识别Agent返回的是“故宫宫墙”。原因是那个位置宫墙和琉璃影壁颜色接近、构图相似,多模态模型对小样本的琉璃构件识别精度确实不够。
我做了两个处理:第一,增加提示词约束,明确告诉模型“如果在故宫内识别到琉璃装饰,优先判断是否为影壁、照壁类建筑构件的组成部分”,把领域知识写进提示,模型的表现立刻改善;第二,引入“用户纠偏”机制——识别结果页面提供一个可编辑框,如果识别错了,用户可以直接打字纠正。纠正后的数据会进入本地样本库,同区域后续识别会优先参考。这个机制实测下来很有用,多位朋友试用后都主动纠正过,样本积累越多,同区域识别越准。
4.4 现象四:讲解内容太“一本正经”,游客根本听不进去
第一次现场测试讲解,模型给的回答是标准的百科式语言:“太和殿,是明清两代皇帝举行大典的地方,面阔十一间,进深五间,建筑面积2377平方米……”不能说不对,但人在景点现场真的听不进去。站在太和殿前面,谁想听建筑面积数据?
后来我在提示词里加了一条:“像朋友聊天一样介绍,先讲一个有趣的故事或细节,再补充理性背景。”同样一个太和殿,改成:
“你抬头看屋脊上那排小兽,第十个叫行什,全故宫只有太和殿能放满十个。传说它是雷公的化身,放在屋顶是为了镇殿避雷。你数一数,别的殿最多九个,只有太和殿敢放满。”
这个改动效果立竿见影,现场当时就好几个人抬头去数屋脊上的小兽。讲解内容生成不能只喂“事实参数”,还得喂“叙事方式”,这是AI导游体验的重要分水岭。
4.5 排查方法论:先分层再归因
回头看,所有翻车都遵循同一个排查链路:
- 先判断是端上问题还是云上问题:用抓包工具看请求耗时分布,等待响应的时间占总耗时大头,问题多在云侧或网络;端上处理占大头,问题多在端侧代码。
- 再判断是网络问题还是模型问题:网络问题表现为整体变慢、连接超时;模型问题表现为返回快但结果不对。
- 最后判断是逻辑问题还是数据问题:提示词写错、上下文传错是逻辑问题;样本库不足、识别边界模糊是数据问题。
另外提醒一点,不要把“模型生成内容有误”归因于“参数没调好”就草草收场。把提示词设计、置信度阈值、缓存策略、用户纠偏当成一个整体来优化,效果会好很多。我这次最深的感觉是,AI应用现场翻车不是模型“笨”,而是集成方式没匹配上真实场景的约束。
5. 整体反思:AI导游的价值边界与鸿蒙+MaaS的组合拳
5.1 实测数据与体验评分
国庆当天实测,从午门到神武门走完全程大约4小时,我的AI导游完成了约80次问答交互,其中拍照识别约35次,语音问约45次。我记录的几组关键数据:
| 指标 | 实测结果 |
|---|---|
| 人流密集区响应时间 | 平均3秒以上 |
| 正常区域响应时间 | 平均1.5秒左右 |
| 建筑大类识别准确率 | 约90% |
| 构件级识别准确率 | 约70% |
| 需要用户纠偏次数 | 约10次 |
| 内容被二次追问的比例 | 约40% |
总体体验打7分。扣分点主要在弱网场景下的卡顿,以及部分构件识别不够精准。但“想用就拉起来,用完就划走”的元服务体验和“问不倒”的AI讲解能力,确实是传统讲解器完全给不到的。
5.2 AI导游不是替代真人,而是补充信息密度
这次实测让我深刻体会到一个朴素的道理:AI导游最大的价值不是替代导游,而是把“信息密度”提上来。真人导游受限于体力、时间和路线,只能挑重点讲;AI导游可以做到每个物件都能问、每条问题都有回应,哪怕是“这个屋顶为什么是斜的”“宫女的画像为什么都长一个样”这种跳脱问题,它也能接住。
但AI导游也有明显短板:缺乏对游客状态的感知。真人导游能看出你累了、眼神飘了、对哪个方向好奇,AI做不到。你站在太和殿前累得直喘,AI还在那滔滔不绝讲斗拱结构,这种体验就很出戏。所以我的结论是,AI导游在景区更像一个“问不倒的百科全书加即时讲解器”,更适合自由行和深度爱好者,不适合需要被安排得明明白白的跟团游客。
5.3 对鸿蒙元服务+MaaS模式的后续想法
这个组合几乎就是为“高频触点、轻量使用”的AI应用量身定做的:元服务解决触达和分发问题,MaaS解决模型能力和成本问题。对个人开发者来说,不用自己买显卡、不用管运维、不用承担复杂的大模型部署工程,就能把一个相对完整的AI应用跑在真实的系统生态里,这个门槛确实被拉得很低。鸿蒙的分布式能力和元服务卡片体系,让AI服务能以很低打扰度的方式出现在用户眼前,这一点是传统“下载App”模式做不到的。
后续如果继续做这个项目,我考虑三个方向:
- 一是加入用户画像,让讲解风格和内容深度能自适应不同人群——小朋友和历史爱好者需要的完全是两种语言。
- 二是做离线增量模型,把高频识别场景的样本在端上持续微调,逐步减少对云端的依赖。
- 三是把审核Agent做得更细,建立针对景区语境的专业词表,避免AI在文物命名、年代判定上出现低级的“一本正经胡说八道”,这件事对文化场景尤其重要。
最后说点实在话。这次“国庆故宫AI导游”与其说是一个能上架的产品,不如说是一次技术可行性的充分验证:鸿蒙元服务加蓝耘元生代MaaS,确实能把AI应用做到“想用就拉起来,用完就划走”的程度。但我也不回避,现场那几次识别错误和超时卡顿,让我意识到AI应用在真实公共场景里离“丝滑”还有距离。如果你也想做类似的东西,我的建议是:先想清楚场景约束——信号、噪音、用户耐心——再做技术选型;先真机测试,再追求体验优化。别被“大模型无所不能”的说法冲昏头,落地的细节才决定你做出来的AI导游,是被人夸好用,还是被人当场划走。