EdgeMemory Studio · Web 控制台规格

EdgeMemory-MVP 分册 04 | 原代号 EMP Studio | v1.0(定稿) | 2026-10-26
浏览器端控制台:连接 EdgeHippo → 引导用户生成知识库 → 打包 .emf → 一键烧录。
无后端(ADR-008):静态页面 + 浏览器直连厂商 API + 浏览器直连设备。

1. 为什么无后端

产品卖「私域记忆、数据不出设备」——如果灌库过程把所有内容过一遍我们的服务器,这个卖点当场自相矛盾。
而且这是竞品攻击时最好用的一个点。附带收益:零运维成本、零合规敞口、用户的 API Key 与知识内容均不经我方。

1.1 代价(必须提前处理)

代价原因处理
板端须加 CORS + OPTIONS 预检浏览器 fetch("http://192.168.1.46/...") 会被同源策略拦死02 号分册 8.x;M0 阶段半天冒烟验证
页面必须 http / localhosthttps 页面请求 http 板子会触发 mixed content 拦截现有 tools/serve.py 8080 恰好符合
无云端账号体系无后端则无账号MVP 不需要。碎片版本管理在板端与本地 IndexedDB
API Key 存浏览器只能存 localStorage明确告知用户;不回显明文、空提交保留旧值、__clear__ 才清除

2. 四通道连接层

序通道技术适用限制与兜底
1USB(WebUSB)WebUSB API,直连 CDCβ Dongle 主路径需 https/localhost;失败降级到 2
2USB(Web Serial)Web Serial APIWebUSB 不可用时兜底需用户手动选端口
3Wi-Fi(HTTP)fetch 直连板子 IP同局域网、α 模组须 CORS;须 http/localhost 页面
4救砖(esptool-js)串口 ROM bootloader设备变砖、固件损坏唯一救砖通道,不可移除
浏览器访问不了 USB 大容量存储(MSC)。虚拟 U 盘是 OS 层概念,JS 没有 API 枚举或写入它。
所以「拖 .emf 进虚拟 U 盘」在 Web GUI 里做不到。Studio 只能:生成 .emf 供下载 + 引导用户拖拽,执行者是文件管理器。
UX 依然成立(LED 蓝快闪 → 绿常亮可作确认),但不得当成浏览器功能排期。

2.1 连接状态机

IDLE ──选择通道──> PROBING ──成功──> AUTHED ──> READY
                      │                          │
                      └─失败→ FALLBACK(下一通道) └─心跳超时→ LOST ──重连──> PROBING
READY ──> BUSY(灌库中,进度条+断点续传) ──> READY | FAILED(已回滚,库完好)

READY 时立即拉取 /api/store/map 与 /api/mem/stat,展示容量、条数、碎片清单。LOST 状态必须明确区分「设备掉线」与「灌库失败」——后者要求库完好如初。

3. 页面结构与状态机

页签内容数据来源
① 连接四通道选择、设备卡片(ID / 形态 / 容量 / 固件版本 / 灯态)/api/status sys.info /api/store/map
② 知识库向导五步生成(第 4 章)厂商 LLM API(浏览器直连)
③ 碎片管理已装碎片清单、版本、条数、占用;导出 / 删除 / 自检/api/frag/list /api/frag/verify
④ 烧录与更新.emf 烧录(4 通道)、固件 OTA / 串口刷写、进度与断点续传/api/frag/import /ota /kbota
⑤ 账本与接力配额账本、邻居设备、接力记录mesh.ledger /api/mesh/*(03 号分册)
⑥ 设置API Key(脱敏)、场景预设、日志localStorage
API Key 脱敏三条定规:① 不回显明文;② 空提交保留旧值;③ 只有提交 __clear__ 才清除。
设备卡片按形态区分,不按角色。卡片上显示的是 form 字段(gamma-card / usb-dongle),不出现 gateway / edge / 宿主 一类角色词——两块设备都是 EdgeHippo 外设本体,对等无层级(ADR-018)。

4. 五步生成向导

向导的核心不是让用户写文档,而是用六组问题把他访谈成一份规格卡。
步名称产出对应 Prompt
1使用者与场景谁在用、什么设备、什么环境P0 第一段
2杀手问题 10 条这块记忆必须答对的 10 个问题P0 第二段
3红线与术语绝对不能答什么;同义词别名表P1
4时效与代价哪些会过期;答错的代价等级 A/B/CP0 第三段 + P3
5生成与验收知识条目 + 20 条验收用例 + 断网话术P2 / P4 / P5

六项产出(使用者 / 杀手问题 / 红线 / 术语别名 / 时效 / 答错代价)决定后面所有生成参数,必须全部收集齐才能进入第 5 步。

4.1 场景预设

场景名称向导默认值目标规模
S1工业振动故障指纹库时序主导;术语别名=故障特征频率;时效 30 天4 个碎片 2,900 条
S2野外巡检断网优先;强制开启 M3 离线投递;专家包Dev-B 4,100 条 / Dev-A 1,800 条
S3私域知识库纯语义;首销 SKU12,000 条满载
—自定义全部手填按容量上限提示

5. 预设 Prompt 全集(P0–P5)

以下为可直接复制的 Prompt 模板。{{...}} 为运行时替换变量。所有 Prompt 的共同主线:把「记忆会挑」翻译成可执行规则。

P0 · 规格卡生成(把用户访谈成规格)

你是 EdgeMemory 知识库架构师。你要为一块**设备端记忆外设**设计知识库规格。
这块设备是 MCU 级(ESP32-S3),容量约 {{cap_kb}} 条记忆,**不跑模型、不联网**,
所有检索在本地完成。因此这份规格必须极度克制:宁可少而准,不可多而杂。

【输入】
- 使用者:{{user_desc}}
- 宿主设备:{{host_desc}}
- 运行环境:{{env_desc}}(是否常断网?)
- 场景类型:{{scene}}

【请你输出一份规格卡,包含以下六项】
1. 使用者画像(3 句话内)
2. 杀手问题 10 条:这块记忆**必须答对**的 10 个问题。
   要求:每条都是**真实会被问到**的,不是百科知识;按重要性降序。
3. 红线清单:绝对不能给出的回答(如医疗剂量、法律定性、竞品价格)。
   每条给出「触发条件」与「应当如何拒答」。
4. 术语别名表:同义词 / 缩写 / 行业黑话 → 标准词。至少 15 组。
5. 时效策略:哪些类别的知识会过期?分别多少天?哪些永不过期?
6. 答错代价分级:A=可能造成人身/财产损害;B=造成返工或误判;
   C=仅造成不便。把第 2 步的 10 条杀手问题分别标级。

【约束】
- 自洽:六项之间不得矛盾。若使用者画像与杀手问题冲突,直接指出并修正。
- 容量意识:总条目数不得超过 {{cap_kb}}。若 10 条杀手问题撑不下,
  明确说明应砍掉哪些。
- 输出为 JSON,键名:persona / killer_questions / redlines /
  aliases / ttl_policy / cost_grades

P1 · 红线与拒答话术

基于以下规格卡,生成「拒答话术」清单。
规格卡:{{spec_card}}

对每一条红线,生成:
- trigger:触发条件(可用关键词或语义描述)
- reply:拒答话术(**中文,不超过 40 字**)
- alternative:能给出的替代信息(如「请查阅设备手册第 X 章」;
  若无则填 null)

【原则】
- 宁可拒答,不可编造。这一点比召回率重要。
- 话术必须**承认不知道**,不要说「根据我的知识…」之类的模糊表述。
- 同一条红线在不同上下文下可能不触发,请在 trigger 中写清边界。

输出 JSON 数组。

P2 · 知识条目生成(按记忆优先级排序生成)

基于规格卡生成知识条目。目标 {{target_count}} 条。
规格卡:{{spec_card}}
拒答清单:{{redlines}}

【生成顺序 —— 严格按此顺序,不得打乱】
1. 先覆盖 10 条杀手问题(每条 3–5 个条目变体,覆盖不同问法)
2. 再覆盖红线(每条红线 1 个条目,内容为「如何拒答」的元知识)
3. 再覆盖术语别名表的同义表述
4. 最后才是背景知识(按重要性降序,直到达到目标条数)

【每条条目格式】
{
  "text": "摘要,不超过 150 字节(UTF-8,中文按 3 字节算)",
  "meta": {"tags": ["..."], "src": "...", "scene": n},
  "prio": 0-1000,      // 杀手问题相关 ≥ 800;背景知识 ≤ 400
  "ttl_h": 0 或 小时数
}

【硬约束】
- text **必须** ≤ 150 字节。超了就重写,不要截断。
- 不得出现规格卡未定义的术语(别名表之外的同义词视为噪音)。
- 不得生成与已有条目**语义重复**的内容(见 P3)。
- 一次输出不超过 50 条,我会分批请求。

P3 · 去重与合并

以下是本批次新生成的条目,以及库中已有的条目摘要(仅向量相似度 > 0.85 的候选)。
新条目:{{new_items}}
相似候选:{{similar_items}}

对每一对新条目 × 候选,判断:
- MERGE:语义重复,合并(保留 prio 更高者,hit_count 累加)
- KEEP_BOTH:语义不同,都保留
- DROP_NEW:新条目是候选的子集,丢弃

【判据】
余弦相似度 > 0.95 → MERGE
0.85–0.95 → 人工判断(输出你的理由)
< 0.85 → KEEP_BOTH

输出 JSON 数组:{"new_id":..., "action":..., "reason":...}

P4 · 验收用例 20 条(会打进 .emf 包里)

基于规格卡生成 20 条验收用例,用于**现场断网自检**。
规格卡:{{spec_card}}

每条用例:
{
  "q": "提问(真实问法,不要书面语)",
  "expect_top1": "期望命中的条目 text 片段",
  "must_refuse": false,       // true = 必须拒答
  "min_score": 0.0-1.0
}

【分布要求】
- 10 条来自杀手问题(其中至少 3 条 must_refuse = true)
- 5 条来自术语别名(问法用别名,期望命中标准词条目)
- 3 条来自背景知识
- 2 条**故意问库中没有的知识**(must_refuse = true,验证「会挑」)

这些用例会被写进 .emf 包,设备端可执行 /api/frag/verify 离线自检。

P5 · 断网话术模板

生成「断网时怎么说不知道」的话术模板。
规格卡:{{spec_card}}

这是本产品最独特的部分:竞品的记忆引擎**全在云端**,断网即失忆。
我们的设备断网仍可检索,但必须诚实告知能力边界。

生成三类模板:
1. 命中但置信度低(top-1 分数介于 min_score 与阈值之间)
2. 完全没命中
3. 命中了但知识已过期(ttl 已过,条目标记待更新)

每类给出:
- 中文话术(≤ 40 字)
- 是否提示「联网后可更新」
- 是否提示「附近设备可能有」(EdgeMesh 接力可用时)

输出 JSON。
P4 生成的 20 条验收用例会打进 .emf 包里,现场断网也能自检——这是「记忆健康检查」卖点的实现基础,也是 P5 存在的理由。

6. .emf 打包与烧录通路矩阵

6.1 打包流程

  1. 收集条目(P2 生成 + P3 去重)
  2. 调用厂商 embedding API(浏览器直连,不经我方)→ 384 维 → int8 量化
  3. 组装 .emf(02 号分册第 5 章):32 B 头 + 记录数组,向量置记录末尾
  4. 嵌入 P4 的 20 条验收用例(作为特殊 frag_id = 0xFFFFFFFF 的元数据块)
  5. 计算 payload_crc32;生成 .emr 回执(M3 离线投递用,03 号分册 7.1)
  6. 下载到本地(供拖进虚拟 U 盘)或直接走连接通路烧录

6.2 烧录通路矩阵

通路适用对象G5 判据进度与续传失败行为
HTTP固件 / .emf≤ 60 s4 KB 分块 + CRC32 + 断点续传abort,库完好
USB bulk固件 / .emf≤ 90 s同上abort,库完好
串口 921600固件 / .emf≤ 240 s同上。进度条必须清晰abort,库完好
MSC(虚拟 U 盘).emf 仅≤ 60 sOS 层拷贝;LED 蓝快闪 → 绿常亮拒绝错误包,库完好
BLE控制消息 / 单条不用于灌满库——
铁律:任何通路的失败路径,都不得破坏已有库。这是 UI 必须向用户明确承诺的(「失败会自动回滚,您的记忆不会丢」)。
不要为了把串口压到 60 s 而砍掉它——它是最可靠的救砖通道。

6.3 固件更新(与知识库更新分离)

方式入口说明
OTAPOST /ota + token日常升级。只写 app 分区,不碰 edgehippom —— 升级不会破坏已灌入的记忆
KB-OTAPOST /kbota(?dry=1 预检)知识库镜像更新。改前必 --backup
串口刷写esptool-js / eme首刷与救砖
UF2 拖拽MSC 虚拟盘β 形态可选第三选项(省 2.5 MB,但单槽中断会变砖)。α 模组不采用

7. 板端 API 需求清单

Studio 依赖以下板端能力。标 ★ 的是 Studio 阻塞项,须与 FW-B 对齐交付顺序。

能力阻塞接口说明
CORS + OPTIONS 预检★全部 /api/*整个 Web 方案的地基
设备状态与容量★/api/status /api/store/map连接页与容量展示。状态里带 form 字段(gamma-card / usb-dongle,ADR-018)
碎片清单与自检★/api/frag/list /api/frag/verify碎片管理页
.emf 分块导入★/api/frag/import4 KB 分块 + CRC32 + 断传
查询(用于验收自检)★/api/mem/query跑 P4 的 20 条用例
固件 / KB OTA/ota /kbota已有,需补 dry=1
账本与邻居mesh.ledger /api/mesh/*账本页(03 号分册)
USB CDC 行协议串口命令集WebUSB / Web Serial 通道
排期解耦:Studio 的 C/D 段(向导 + 打包,35 人日)不依赖 emlite,可在 W3 立即开工,比等引擎就绪早约 2 个月拿到可对外演示的东西。上表的 ★ 项中,只有「查询」与「.emf 导入」真正依赖引擎,其余可在 W3 前由 FW-B 提供桩接口。

8. 可复用的现有资产

现有复用方式说明
web/index.html改造页签现有页签:主板信息 / 模块数据 / 设备·知识库 / 固件刷写(串口)/ 无线 OTA。Studio 页签结构为全新设计(见第 3 章六页签),旧 Gateway 控制台的页签划分仅作素材来源,不继承其结构假设——尤其不得沿用「按角色分区设备」的假设
web/js/protocol.js直接继承行协议封装。注意参数名遮蔽模块变量(connect(baud, port) → 改名 extPort)
web/js/flasher.js直接继承esptool-js 封装,救砖通道
web/js/ota.js(24 KB)改造OTA 流程
web/js/ble_client.js改造BLE 通道 → EdgeMesh 邻居发现
tools/serve.py 8080直接继承本地 http 服务(满足 mixed content 要求)

整体可复用约 60%。Web 控制台真源 = EdgeMemory-Gateway/web。

9. WP7 任务摘要与用例索引

段内容人日依赖说明
WP7-A连接层:四通道 + 状态机 + 设备卡片28板端 CORS可并行
WP7-B碎片管理页 + 账本页22/api/frag/*可并行
WP7-C五步向导 + 状态机20无(可立即开工)核心差异化
WP7-D.emf 打包器 + P0–P5 集成15无(可立即开工)核心差异化
WP7-E烧录通路:分块 / CRC / 断传 / 进度30/api/frag/importG5 相关
WP7-F固件更新页(OTA / 串口 / UF2)15/ota—
WP7-G联调、兼容性、文档8全部—
WP7 合计(31 项)138×1.3 缓冲 ≈ 179 人日

9.1 用例索引(28 条,详见 05 号分册 TC-W-*)

分组条数覆盖
TC-W-01…088四通道连接与降级、断线重连、设备卡片字段正确
TC-W-09…168五步向导状态机、必填校验、Prompt 变量替换、API Key 脱敏
TC-W-17…226.emf 打包正确性(头 / CRC / 版本兼容 / 向量置末尾)
TC-W-23…286烧录分块、断传、失败回滚、进度显示