目录

游必有方 · AI 文旅伴游(开封)

一碰就进、走到就讲、走完有忆——让游客在景区弱网、听不懂、记不住的场景里,把一次旅行看明白。

HarmonyOS 6 原生应用(ArkTS / ArkUI),样板城市为开封。内容包与引擎解耦:换城市只换 KaifengPack.ets 一个文件。

快速开始

用 DevEco Studio 26 打开 HarmonyOSexam/,等 Sync 完成后选模拟器或真机 → Run entry。

命令行构建(把 IDE 路径换成你本机的):

$ide = "D:\Hmeng\DevEco Studio"          # ← 改成你的 DevEco Studio 安装目录
$env:DEVECO_SDK_HOME = "$ide\sdk"
cd HarmonyOSexam
& "$ide\tools\node\node.exe" "$ide\tools\hvigor\bin\hvigorw.js" `
  --mode module -p product=default -p buildMode=debug assembleHap --no-daemon

产物:entry/build/default/outputs/default/entry-default-unsigned.hap(约 800 KB)。 真机安装需在 DevEco 里 File → Project Structure → Signing Configs 勾选自动签名。

跑单元测试

& "$ide\tools\node\node.exe" "$ide\tools\hvigor\bin\hvigorw.js" `
  --mode module -p module=entry@default -p product=default test --no-daemon

测试在 entry/src/test/LocalUnit.test.ets,覆盖检索拒答、行程约束、游记成文三块 (当前行覆盖率:Journal 96% / RagEngine 90% / RouteAgent 64%)。

目录

HarmonyOSexam/
├── entry/src/main/ets/
│   ├── pages/Index.ets          6 个 Tab:首页 / 行程 / 伴游 / 识物 / 问答 / 我的
│   ├── model/
│   │   ├── Types.ets            数据结构
│   │   └── KaifengPack.ets      ★ 开封内容包:10 个点位 × 三层讲解稿 + 出处
│   ├── data/
│   │   ├── Exhibits.ets         16 件展品 + 6 组取景样本
│   │   ├── KnowledgeBase.ets    30 条知识分块(带出处)
│   │   └── Geo.ets              点位坐标与步行时长
│   ├── service/
│   │   ├── RouteAgent.ets       ★ 行程 Agent(约束过滤 → 偏好打分 → 近邻排序 → 时间预算 → 途中重排)
│   │   ├── RagEngine.ets        ★ 本地 BM25 检索 + 阈值拒答 + 强制引用
│   │   ├── LlmClient.ets        ★ 云侧大模型接入(可选增强层,防幻觉三道闸)
│   │   ├── Journal.ets          ★ 游记成文(本地模板,只用真实到访记录)
│   │   ├── SpeechService.ets    Core Speech Kit TTS,失败降级为字幕
│   │   ├── VisionEngine.ets     识物(占位:预置取景样本)
│   │   ├── ContinueService.ets  跨端接续(分布式设备发现 + startAbility)
│   │   └── Store.ets            沙箱文件持久化(带格式版本)
│   └── view/                    HomePage / TripPage / GuidePage / ScanPage / AskPage / MinePage / PlaceDetail
├── entry/src/main/resources/rawfile/
│   └── llm_config.example.json  模型配置模板(复制为 llm_config.json 并填 apiKey)
├── entry/src/test/              单元测试(hypium,27 条)
└── docs/
    ├── 游必有方-项目设计计划书.md   完整方案(问题定义、架构、降级表、演示脚本)
    └── 雏形说明.md                当前实现状态:真做了 vs 占位,逐项标注

实现状态(不粉饰)

能力 状态
三层讲解稿(8s / 45s / 3min)+ 出处 ✅ 真实,10 点位 × 3 层
点位详情 ✅ 真实,首页推荐卡片可点,含实用信息 / 看哪里 / 三层稿 / 出处,可直连伴游页
今日推荐排序 ✅ 真实,按起点距离 + 当前是否开门 + 偏好计算,每张卡写出理由
汴梁印章 ✅ 真实,走过一处盖一枚,2/10 进度可见
行程 Agent(时间窗 / 体力 / 夜间 / 近邻 / 途中重排) ✅ 真实,规则引擎,决策轨迹界面可见
自然语言改单 ✅ 真实,有模型走模型抽槽,无模型走关键词,改完会告诉你”听懂了什么”
问答检索(BM25 + 阈值拒答 + 引用) ✅ 真实,30 条语料,检索与拒答完全本地
云侧大模型生成 ✅ 已实测通(约 1.0 s);未填密钥则全程本地抽取式
语音播报 ✅ 真实,Core Speech Kit TTS
拍照取景 ✅ 真实,Camera Kit
游记成文 ✅ 真实,本地模板编排,界面标注生成方式
本地持久化 ✅ 真实,沙箱文件(带存档版本)
账号(本地) ✅ 真实,昵称 + 手机号校验,登录态持久化,数据按账号隔离,头像由 uid 派生
数据同步 ✅ 真实(无后端):同步码 / 二维码导出导入,带到访+收藏+笔记+打卡,已实测往返与扫码

同步码 / 二维码

「我的 → 账号」生成。二维码是自研编码器(service/QrCode.ets,Byte 模式、纠错 L、版本 1-15), 不依赖第三方库;生成结果已用 zxing 实际扫回验证(含中文、多纠错块、多码字版本)。

YBF2|u56732781|LaoZhang|13800138000|yangingguan,09:07,30,0;kaifengfu,09:02,50,0|||
  • 8 段:版本 | uid | 昵称 | 手机号 | 到访 | 收藏 | 笔记 | 打卡
  • 笔记正文里的 , ; | % 会百分号转义,导入时还原
  • 兼容 v1 老码(只有到访 + 收藏)
  • 导入会覆盖本机数据,字段损坏会指出是第几条

想换成真后端时:Account 里补一个 upload()/download(),把同步码换成接口返回即可,调用方不用动。 | 跨端接续 | 🚧 已接分布式设备发现与 startAbility,需双设备联调 | | 定位围栏 | 🚧 模拟路径,界面标注「模拟定位」 | | 识物识别 | 🚧 占位,预置样本 + 证据链,未接 Core Vision Kit | | 元服务 / 服务卡片 | ⬜ 未做(已有 Form Ability 与卡片页,未上 AGC) |

详细差异与已知限制见 docs/雏形说明.md。

接入云侧大模型(可选)

默认不联网也能跑完所有功能。想让问答从”念原文”变成”答问题”,两步:

# 1. 复制模板
copy HarmonyOSexam\entry\src\main\resources\rawfile\llm_config.example.json `
     HarmonyOSexam\entry\src\main\resources\rawfile\llm_config.json
# 2. 编辑 llm_config.json,填入 apiKey(endpoint 默认 DeepSeek,任何 OpenAI 兼容接口都行)

llm_config.json 已写进 .gitignore,密钥不会进版本库。

接上之后有两处会变:

位置 无模型 有模型
问答 抽取式:把检索到的前三段原文首句拼起来 模型基于这几段组织成连贯回答,仍强制标 [1][2][3]
改单 关键词匹配(”爸妈””3 小时”) 模型抽 JSON 槽位,规则求解仍由 RouteAgent 负责

三道闸,写在代码里而不是文档里(service/LlmClient.ets):

  1. 只检索命中之后才调模型——检索为空直接拒答,模型没有自由发挥的机会;
  2. 回答必须带合法引用编号——没有 [n] 或编号越界,整条回答作废,回落到本地抽取;
  3. 任何失败即降级——没密钥 / 超时 / 非 200 / 解析失败,用户看到的仍是有出处的答案,只是措辞朴素。

界面会如实标出这条回答是怎么来的:云侧组织(金色)或 本地抽取(青色)。

账号与数据同步(没有后端也能真搬数据)

工程里没有服务端,所以**不做假的”云端同步”**。取而代之的是两条都能验证的能力:

1. 本地账号(service/Account.ets)

  • 昵称 + 手机号校验(11 位,本地校验,不发短信)
  • 登录态落沙箱文件,杀进程再开还在
  • 数据按账号隔离:youbi_store_<uid>.dat,换账号看到的是各自的数据
  • 首次登录会把游客数据归到账号下,不会出现”一登录记录全没了”
  • 头像不用图片:uid 派生底色 + 昵称首字

2. 同步码 / 二维码(导出 / 导入)

在「我的 → 账号 → 同步码」生成一行文本,同时画出二维码:

YBF2|u56732781|LaoZhang|13800138000|yangingguan,09:07,30,0;kaifengfu,09:02,50,0|||

另一台设备扫这张码(或把文本贴进「数据同步 → 导入」),到访、收藏、笔记、打卡一起过去。

二维码不是第三方库:service/QrCode.ets 自己实现了 Byte 模式、纠错 L、版本 1-15 的编码 (RS 纠错、交织、掩码择优、格式/版本信息)。正确性用 zxing 真的扫回来验证过, 单测里还锁了一张已验证矩阵的快照,防止以后改坏。

想换成真后端时:Account 里补一个 upload()/download(),把同步码换成接口返回即可,调用方不用动。

合规与诚实性约定

  1. 不编:问答查不到就明说「查不到」;游记只用真实到访记录;没去过的不写。
  2. 标注来源:每段讲解带出处(方志 / 考古简报 / 展签)。
  3. 标注模拟:定位与识物在界面上明写「模拟」「演示样本」,不把占位当模型输出。
  4. 标注生成方式:游记写明「本地模板(未调用模型)」。
  5. 不装后端:没有服务端就不写”已同步到云端”,改成同步码;离线包的下载进度标「演示」。
关于
459.0 KB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号