从 Demo 到种子用户,我用 4 阶信任 Onboarding 架构解决「没人敢装」的问题
一、问题桌面 Agent 的「勒索软件困境」我在做一个 Windows 桌面助手 Marvis功能覆盖文件管理、注册表配置、文档问答、定时任务调度。Demo 跑通后发给第一个测试用户对方回了一句「一个我没听过的 exe要读我下载文件夹、要改我注册表、要常驻后台、还要联网调 LLM。」这段描述放到 VirusTotal 上大概率标红。核心矛盾桌面 Agent 和 Web Agent 的本质差异不在模型能力在于执行环境的信任边界。维度Web Agent桌面 Agent执行沙箱浏览器沙箱隔离无沙箱直接操作 OS最坏后果关 tabos.remove()/ 注册表损坏用户心理点错了大不了关掉它会不会偷偷动我文件信任建立时机可后置必须前置结论信任是桌面 Agent 的第 0 层功能不是 nice-to-have。二、4 阶信任 Onboarding 架构第 1 阶Tool Risk Scoring能力清单显式化设计思路把每个 Tool 当成一个后端 endpoint给它打 risk score。TOOL_RISK_MAP { screen_capture: {risk: 1, default: ON}, file_read: {risk: 1, default: ON}, chat: {risk: 1, default: ON}, file_write: {risk: 3, default: OFF}, network_egress: {risk: 3, default: OFF}, registry_write: {risk: 4, default: OFF}, shell_exec: {risk: 5, default: OFF}, }打分规则read_only1, write_file3, modify_registry4, exec_shell5, network_egress3Onboarding 首屏展示的不是「我能做什么」而是一张 risk 画像表Tool Risk Default ───────────────────────────────────── screen_capture 1 ON file_read 1 ON chat 1 ON file_write 3 OFF shell_exec 5 OFF registry_write 4 OFF network_egress 3 OFF类比后端运维你看到一个 endpoint 错误率 19%、p95 2s第一反应是熔断。桌面 Agent 的高 risk tool 默认关闭是同一个逻辑。第 2 阶Just-in-Time Permission渐进式权限核心规则永远不在首次启动一次性弹 N 个权限请求。实现方式每个 Tool 调用前经过permission_guard中间件。def permission_guard(tool_name: str, params: dict) - bool: perm load_permissions() # from %APPDATA%\Marvis\permissions.json if perm.get(tool_name) permanent: return True if perm.get(tool_name) session and is_current_session(): return True # 弹权限请求用户选择: once / session / permanent / deny decision prompt_user_permission( tooltool_name, scopeparams.get(scope), options[once, session, permanent, deny] ) save_permission(tool_name, decision) return decision ! deny权限持久化存储明文 JSON路径%APPDATA%\Marvis\permissions.json。{ file_write: {scope: C:\\Users\\xxx\\Downloads, level: session, granted_at: 2026-07-01T10:00:00}, registry_write: {scope: HKCU\\Software\\Marvis, level: once, granted_at: 2026-07-01T10:05:00} }为什么明文不加密加密反而有黑箱嫌疑。用户能直接打开文件看到/手动修改自己的权限配置。第 3 阶Action Preview Dry RunLLM 存在幻觉风险会把del *.tmp写成del *.*所有写操作执行前必须渲染 Plan 预览。Plan 数据结构{ plan_id: a1b2c3, tool: file_batch_move, params: { src: C:\\Users\\xxx\\Downloads, rules: [ {match: *.zip, dst: .\\压缩包\\}, {match: *.pdf, dst: .\\文档\\} ] }, impact: { files_affected: 47, files_deleted: 0, files_overwritten: 0, irreversible: false }, preview: [ Move: report.pdf → 文档\\report.pdf, Move: setup.zip → 压缩包\\setup.zip ] }Dry Run 机制影子层路径%TEMP%\Marvis\shadow\{plan_id}\执行策略临时目录复制模拟 → diff 展示 → 用户确认 → 原子提交全成功或全回滚Undo 栈保留最近 N 步操作的回滚能力Undo 策略按字节阈值UNDO_POLICY { max_steps: 20, full_snapshot_threshold: 100 * 1024 * 1024, # 100MB: 完整快照 # 100MB: 只记 inode 操作记录标记 irreversibleTrue }超过阈值时 UI 展示红色警告「此操作涉及大文件执行后不可撤销」。第 4 阶Local Audit LogCREATE TABLE audit_log ( id INTEGER PRIMARY KEY, ts INTEGER NOT NULL, tool TEXT NOT NULL, params_json TEXT NOT NULL, result_status TEXT NOT NULL, -- ok | error | denied result_json TEXT, screenshot_before_hash TEXT, screenshot_after_hash TEXT, user_decision TEXT -- approved | denied | auto );存储路径%APPDATA%\Marvis\audit.dbOnboarding 首屏明确告知「纯本地不上云你可以随时删删了我也能跑」UI 提供「最近 24h Marvis 做了什么」时间线视图按 risk 颜色排序绿/黄/红三、3 个踩坑复盘坑 1用「隐私政策」代替信任建立最初方案首屏塞一份完整 Privacy Policy。结果测试用户平均停留 8s 直接跳过。改进后3 行文字 3 个权限开关屏幕感知 / 文件访问 / 网络出站每个开关下一句人话解释。停留时间从 8s → 47s埋点数据。结论长 ≠ 重视。简洁的开关组比一篇法律文本可信度高得多。坑 2让 Agent 自由执行 PowerShell最初方案把Invoke-Expression当普通 Tool 挂上去相信模型聪明它知道分寸。结果模型执行了Get-ChildItem -Recurse | Remove-Item -Force来清理临时文件。幸好是测试机。改进后shell_exec 类 Tool 改为模板化白名单AI 只能填变量不能自由组合命令。# ✅ 允许预定义模板 参数填充 ALLOWED_TEMPLATES [ ipconfig /flushdns, robocopy /MIR {src} {dst}, Get-Process | Where-Object {{$_.Name -eq {process_name}}}, ] # ❌ 禁止AI 自由生成的完整命令字符串坑 3没有「我不会做 X」的反向声明用户最怕的不是「它能做什么」是「它会不会偷偷做什么」。现在的介绍页加了一段Marvis 不会读取浏览器密码不会访问微信/QQ 本地数据库不会上传任何文件到云端除你显式触发的 LLM API 请求外且请求体可在 audit.db 中查看全文。这一段的效果 说 100 遍「我们重视隐私」。四、架构总览代码块┌─────────────────────────────────────────────────┐ │ User Intent │ └──────────────────────┬──────────────────────────┘ ▼ ┌──────────────────────────────────────────────────┐ │ [阶段2] Permission Guard (JIT) │ │ ┌─────────────┐ │ │ │ permissions │◄── %APPDATA%\permissions.json │ │ │ .json │ │ │ └──────┬──────┘ │ │ │ granted? │ └─────────┼────────────────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────┐ │ [阶段3] Plan Renderer Dry Run │ │ ┌────────────┐ ┌──────────────────┐ │ │ │ Plan JSON │────▶│ Shadow Layer │ │ │ └────────────┘ │ %TEMP%\shadow\ │ │ │ └────────┬─────────┘ │ │ │ user confirms │ └──────────────────────────────┼───────────────────┘ ▼ ┌──────────────────────────────────────────────────┐ │ [执行] Atomic Commit Undo Stack │ └──────────────────────┬───────────────────────────┘ ▼ ┌──────────────────────────────────────────────────┐ │ [阶段4] Audit Logger │ │ → audit.db (local SQLite, never uploaded) │ └──────────────────────────────────────────────────┘五、开放问题求讨论1. Undo 栈设计100MB 阈值分界完整快照 vs 只记 inode是否合理有做过桌面工具 transactional file ops 的同学能分享下经验吗2. 权限存储安全明文 JSON 好处是透明但如果被恶意软件篡改 permissions.json把 OFF 改成 ON怎么办数字签名HMAC我怕过度设计。3. 先爽后讲安全 vs 先讲安全再爽Web Agent 的成功路径是前者。桌面 Agent 要不要也这样——首启给一个「只问答」模式先爽 5 分钟等用户主动要文件操作再讲权限我倾向后者但担心被解读成「先骗进来再要权限」。六、下一步这周按此架构重做 Marvis 的 onboarding做完会发一篇「真实用户第一周的 audit.db 数据分析」。如果你也在做桌面/系统级 AI 工具欢迎评论区交流互相当种子用户。我会持续在 Meyo 分享实战日记的。欢迎点进来一起交流。